以下のチュートリアルでは、スプラインとそのノット (頂点)、および SplineShape の接線にアクセスして変更する方法を示します。作成された macroScript によってすべてのノットがシェイプの Z 位置で定義される Z の高さに移動するので、グラウンドの XY ワールド作図平面に平行な平面にそれらのノットが揃えられます。
関連トピック:
全体の流れ:
ボタン、メニュー項目またはショートカットとして使用できる macroScript としてコードをパッケージ化します。
モディファイヤのない単独の編集可能なスプラインが選択された場合にのみ、スクリプトを有効にします。
実行されると、シェイプ内のすべてのスプラインを巡回します。
各スプラインでは、すべてのノット (頂点) を巡回します。
各ノットでは、入接線と出接線の Z 座標をシェイプの Z 位置に設定します。
また、ノットの Z 座標をシェイプの Z 位置に設定します。
すべてのスプラインとノットの準備が整ったら、シェイプを更新します。
MAXScript
macroscript FlattenSpline category:"HowTo" tooltip:"Flatten Spline" ( on isEnabled return ( selection.count == 1 and \ (classof selection[1] == SplineShape or\ classof selection[1] == Line) \ and selection[1].modifiers.count == 0 ) on execute do ( new_z = $.pos.z for s = 1 to (numSplines $) do ( for k = 1 to (numKnots $ s) do ( knt = getKnotPoint $ s k in_vec = getInVec $ s k out_vec = getOutVec $ s k knt.z = in_vec.z = out_vec.z = new_z setInVec $ s k in_vec setOutVec $ s k out_vec setKnotPoint $ s k knt )--end k loop )--end s loop updateshape $ )--end execute )--end script
macroscript FlattenSpline category:"HowTo" tooltip:"Flatten Spline" (
macroScript は FlattenSpline
と呼ばれます。スクリプトを使用する場合は、[カスタマイズ...] (Customize...)に移動してスクリプトを[HowTo]カテゴリからツールバー、メニュー、またはクアッド メニューにドラッグするか、キーボード ショートカットを割り当てることができます。
on isEnabled return
(
selection.count == 1 and \
(classof selection[1] == SplineShape or \
classof selection[1] == Line) \
and selection[1].modifiers.count == 0
)
macroScript の ActionItem (ボタン、メニュー項目、ショートカット) は、シーン選択が単独のオブジェクトを含み、しかも、MAXScript では頂点にモディファイヤがあるスプラインを変更できないため、そのオブジェクトがモディファイヤのない SplineShape クラス (つまり、編集可能なスプライン) である場合にのみ、有効にされます。return ステートメントの後の式の結果は、true または false と評価されます。true の場合、スクリプトは有効になります。
現在のシーン選択を 1 と比較し、次に、最初に選択されたオブジェクトのクラスを SplineShape と比較します。新しく描かれたラインが例外である可能性があるので、次に、最初に選択されたオブジェクトのクラスを再度 Line と比較します。 これを変更することはできますが、編集可能なスプラインに集約されるまで、クラスは SplineShape ではありません。最後に、モディファイヤの数をカウントし、0 と比較します。
最初の条件と、2 番目または 3 番目の条件のどちらか、および 4 番目の条件が true の場合に、選択されたオブジェクトは有効であり、スクリプトで変更することができます。
Macroscript_Body_Event_Handlers
on execute do
(
on execute
ハンドラに、実際のコードが含まれます。このハンドラは、ボタンのクリック、メニューからの項目の選択、キーボード ショートカットの使用などによってスクリプトが起動されると、常に実行されます。
Macroscript_Body_Event_Handlers
new_z = $.pos.z
すべてのノットと接線を移動させるために、splineShape の Z 座標が必要です。 シーン選択の位置の Z コンポーネントを、ユーザ変数の new_z に格納します。既に isEnabled ハンドラ内で選択されたオブジェクトがただ 1 つであることをチェックしているため、最初の選択されたオブジェクトにアクセスするための selected[1] を使う必要はありません。 現在の選択を表わす $ が実際にただ 1 つのオブジェクトであることが確実だからです。
for s = 1 to (numSplines $) do
(
splineShape には、任意の数のスプラインを含めることができます (たとえば、ドーナツシェイプには 2 つの円が含まれます)。各単独スプラインを変更するために、1 から始めて選択したオブジェクト内のスプラインの数までカウントする for ループを作成します。
for k = 1 to (numKnots $ s) do
(
シェイプ内の各スプラインには、任意の数のノットを含めることができます。各単独ノットを変更するために、1 から s 番目のスプラインのノット数までをカウントする別の for ループを作成します。 スプラインのインデックスは、外側の for ループによってコントロールされます。s ループを繰り返すごとに、for k... ループが何度も実行されることに注意してください。そのため、これらはネストされたループです。
knt = getKnotPoint $ s k
getKnotPoint を使用して、選択された splineShape 内の S 番目のスプラインの K 番目のノットを読み取ります。ユーザ変数の knt に、その Point3 ワールド座標を格納します。
in_vec = getInVec $ s k
次に、選択された splineShape 内の S 番目のスプラインの K 番目のノットのイン ベクトルを読み取ります。ユーザ変数の in_vec に、その Point3 ワールド座標を格納します。
out_vec = getOutVec $ s k
選択された splineShape 内の S 番目のスプラインの K 番目のノットのアウト ベクトルを読み取ります。ユーザ変数の out_vec に、その Point3 ワールド座標を格納します。
knt.z = in_vec.z = out_vec.z = new_z
ここで、ベクトルとノットの両方の Z 座標を new_z 変数に設定することができます。MAXScript は、最初に代入の右辺を評価してからその結果を左辺に代入することによって式を評価するため、同じ値を複数の変数に代入できることに注意してください。
setInVec $ s k in_vec
setOutVec $ s k out_vec
ここで、新しいイン ベクトルおよびアウト ベクトルを対応するノットとスプラインに戻すことができます。
setKnotPoint $ s k knt
次に、新しいノット位置を対応するノットとスプラインに代入して戻します。
)--end k loop
)--end s loop
updateshape $
)--end execute
最後に、splineShape を更新することが非常に重要です。内部的なデータ構造を更新することによって、すべての変更が目に見えるようになります。これを行わないと、3ds Max 内が不安定になります。
)--end script
スクリプトを評価します。スクリプトを使用する場合は、[カスタマイズ...] (Customize...)を使用して、スクリプトを[HowTo]カテゴリからツールバー、メニュー、またはクアッド メニューにドラッグするか、キーボード ショートカットを割り当てることができます。
シーン内で単独のスプラインを選択し、スクリプトを実行します。すべてのノットが、スプラインの基点の高さで XY 平面に合わせて移動します。
他の作図平面に合わせるためのオプション付きの UI を追加するか、new_Z の代わりに単に 0.0 を使用してグラウンド平面にノットを移動することができます。
戻る