スクリプト SimpleMod プラグイン

SimpleMod プラグインは頂点を移動する変形タイプのモディファイヤですが、トポロジの変更(頂点、面、サーフェス、線などの追加または削除)は行いません。

3ds Max モディファイヤの例としては、Bend、Stretch、および Taper があります。

これらの種類のモディファイヤで頂点を移動するには、単一の map ハンドラだけが必要であり、3D ボックス変形ギズモと中心のサブオブジェクトは自動的に指定されます。

スクリプト化された単純な Modifier プラグインを宣言するには、<superclass>simpleMod として指定します。

スクリプト:

    plugin simpleMod saddle
    name:"SaddleDeform"
    classID:#(685325,452281)
    version:1
    (
      parameters main rollout:params
      (
        amount type:#integer ui:amtSpin default:20
      )
      rollout params "Saddle Parameters"
      (
        spinner amtSpin "Amount: " type:#integer range:[0,1000,20]
      )
      on map i p do
      (
        p.z += amount * sin((p.x * 22.5/extent.x) * (p.y * 22.5/extent.y))
        p
      )
    )

これは、SaddleDeform という新しい SimpleMod プラグインを定義します。このスクリプトは saddle タイプ変形をオブジェクトに適用し、2 つの向かい合ったコーナーに上カーブを描き、別の 2 つの向かい合ったコーナーに下カーブを描きます(平面オブジェクト上に描くと効果的です)。適用する変形の量を指定する amount という単一のパラメータ スピナーがあります。SimpleMod プラグインのキー コンポーネントは、map ハンドラです。

この形式は、次のとおりです。

on map <index> <point>    do <expr>     

このイベント ハンドラは、修正中のオブジェクト内のすべての各ポイント(またはオブジェクト内での現在の選択ポイント)について 1 回呼び出されます。ハンドラが呼び出されるポイントには、メッシュ頂点、スプライン頂点、NURBS CV などがあります。<index> 引数によってポイントの数が指定されますが、この index はメッシュまたはスプライン内の頂点数に対応していないことがあります。<point> 引数が map ハンドラに指定されると、ポイントの現在のオブジェクト空間座標が Point3 として与えられます。関数では、与えられたポイント値を適切に修正し、それを map ハンドラ呼び出しの結果として返す必要があります。°上の例では、map ハンドラで式 z = sin(x * y) を使用して Z 座標変形が適用されており、すべてのポイントで X 座標および Y 座標がそのまま保持され、saddle 関数に従って Z 座標が上下に移動されます。すべての座標はオブジェクト ローカルであることに注意してください。

<index> 値は 1 をベースとしています。ただし、スクリプト プラグインは 0 の <index> 値で呼び出されて、この特定のマップ呼び出しがギズモ バウンディング ボックスを描画するコードによって使用され、描画するギズモ ボックスのポイントが計算されることを示します。これにより、SimpleMod モディファイヤが適用されるオブジェクト上でテストが実行され、ギズモ バウンディング ボックスが表示されます。これは、オブジェクトが選択されている場合、[モディファイヤ] (Modifier)パネルがアクティブな場合、およびオブジェクトのモディファイヤ スタックで SimpleMod モディファイヤが選択されている場合に当てはまります。

基本的に、これは修正されるオブジェクトに渡す値のインデックスで決まります。たとえば、メッシュの場合、これは実際のメッシュ頂点インデックスです。パッチの場合、1 つのシーケンスの後に、各コントロール ポイントに対するインおよびアウト ベクトルがコントロール ポイント順に続くコントロール ポイントです。スプラインの場合、これはカーブ シーケンス内のコントロール シーケンスにあるイン ベクトルおよびアウト ベクトルです。この順番は、3ds Max の将来のバージョンで変更される可能性があります。

map ハンドラは単純なオブジェクト上でも何度も呼び出されることがあるため、map ハンドラで作成される値の数を最小にすることを強くお勧めします。数を最少にするとガベージ コレクションが実行される回数を減らすことができます。map ハンドラ内で複数のローカル変数が必要な場合、1 つ以上の Point2 または Point3 値をスクリプト プラグイン定義内で宣言してから、値を Point2 または Point3 値のコンポーネント値に格納することをお勧めします。このようにすると、新しいローカル変数が map ハンドラに割り当てられることを防ぐことができます。

map ハンドラ内から、修正中のオブジェクトにアクセスしないでください。このようなアクセスをすると、スクリプト化されたモディファイヤの評価が再度実行されます。これは無限ループとなり、3ds Max がハング アップする結果となります。

map ハンドラでアクセスできる定義済みプラグイン ローカルには、以下の 3 つがあります。

min -- the modifier context's bounding box min coordinate     
max -- the modifier context's bounding box max coordinate     
center -- the modifier context's bounding box center coordinate     
extent -- the modifier context's bounding box extent or size   

上記の例で、map ハンドラによって定義済みの extent ローカル変数を使用して saddle 関数に対するスケーリングが計算され、オブジェクト全体にまたがって関数の 1/8 サイクル(22.5 度)が取得されます。これらのバウンディング ボックス ローカルは、モディファイヤのコンテキストに対応しています。シーン ノード選択に適用される場合はオブジェクト全体またはオブジェクト グループに対応し、その下にある Mesh Select のようなスタックにサブオブジェクト選択モディファイヤが存在する場合はサブオブジェクト選択に対応します。

SimpleMod のその他のビルトイン機能を使用して、モディファイヤ制限表示を実装することもできます。これを行うには、次のハンドラを実装します(実装する場合は、すべてのハンドラを実装する必要があります)。

on modLimitZMin do <expr>   
on modLimitZMax do <expr>   
on modLimitAxis do <expr>

呼び出された場合、on modLimitZMin および on modLimitZMax ハンドラ式によって最小および最大の制限値に対応する浮動小数点値が評価され、on modLimitAxis ハンドラ式によって #x#y#z が返されて制限軸が指定される必要があります。MAXScript グローバル変数 currentTime にはこれらの値が計算される時間が含まれています。通常はパラメータ値への単純なアクセスは正しい currentTime 値を自動的に生成します。これらのハンドラを最も簡単に実行するには、制限パラメータと関連付けされたスピナーおよびチェックボックスを管理し、これらのパラメータ値を単に戻す方法があります。

これらのハンドラは、制限値に対する実際の効果の制限を実装するのではなく、制限のギズモ表示のみを実装します。制限を実際に適用するには、on map ... do() イベント ハンドラで必要なロジックと計算を指定する必要があります。

次の例では、Z 軸と相関する放射状バルジ効果を実装し、バウンディング ボックスの Z 高さのパーセンテージで表して制限値を指定します。有効にすると、バウンディング ボックスの高さによって平均化された p.z 座標が上下の限界値と比較され、値が制限値の範囲内にある場合にのみ効果が適用されます。効果と制限は常に Z 軸を使用して適用されるため、modLimitAxis do() ハンドラは常に #z を返します。

スクリプト:

    plugin simpleMod bulgeZ
    name:"BulgeZ"
    classID:#(0xa4741be, 0x953eaf3)
    version:1
    (
    parameters main rollout:params
    (
        amplitude type:#float ui:spn_amplitude default:1
        wavecount type:#float ui:spn_wavecount default:1
        phase type:#float ui:spn_phase default:0
        limit type:#boolean ui:chk_limit default:false
        maxLimit type:#float ui:spn_maxLimit default:100
        minLimit type:#float ui:spn_minLimit default:0
    )
    rollout params "BulgeZ Parameters"
    (
        spinner spn_amplitude "Amplitude: " type:#float range:[0,1000,1]
        spinner spn_wavecount "Wave Count: " type:#float range:[0,1000,1]
        spinner spn_phase "Phase:" type:#float range:[-100000,100000,0] scale:0.01
        group "Limits"
        (
            checkbox chk_limit "Limit Effect" align:#right offset:[8,-5]
            spinner spn_maxLimit "Upper Limit %:" range:[-1000,1000,100]
            spinner spn_minLimit "Lower Limit %:" range:[-1000,1000,0]
        )
    )
    on map i p do
    (
        local v = normalize [p.x-center.x, p.y-center.y,0]
        local pzn = p.z/(max.z-min.z)
        if not limit or (pzn >= minLimit*0.01 and pzn <= maxLimit*0.01) do
            p +=  v*amplitude*(cos (360*(pzn-phase)*wavecount))
        p
    )
    on modLimitZMin do if limit then minLimit*0.01*(max.z-min.z) else 0.0
    on modLimitZMax do if limit then maxLimit*0.01*(max.z-min.z) else 0.0
    on modLimitAxis do #z
    )

[修正] (Modify)パネルでは、モディファイヤのインスタンスが[モディファイヤ] (Modifiers)リストまたは[モディファイヤ] (Modifiers)ロールアウト内のボタンに表示されるとき、すべてのモディファイヤの新しいインスタンスが実際に作成されます。これにより、create ハンドラがスクリプト化された SimpleMod プラグインに対して呼び出されます。この場合、create ハンドラ内で特別な処理は必要ありません。