3ds Max には、マウスで自由にスプラインを描くためのビルトイン関数がありません。従来の Autodesk 3D Studio DOS には、そのような機能がありました。
MAXScript を利用して、この機能を単純な MacroScript として実装することができます。このスクリプトによって、マウスでグラウンド平面にスプラインを描くことができるようになります。
関連トピック:
MAXScript のメッセージ ボックスおよび問い合わせダイアログ ボックス
全体の流れ:
ボタン、メニュー項目またはショートカットとして使用できる macroScript としてコードをパッケージ化します。
直前のマウス位置と現在のマウス位置の間の距離を測定し、しきい値を超えたときに新しいノットをスプラインに加える関数を定義します。
組み込み pickPoint 関数を使用してマウスの動きを捕捉する描画関数を定義します。
描画を元に戻すことができるように、アンドゥ コンテキスト内に完全な作成コードを配置します。
新しい splineShape オブジェクトを作成します。
スプラインの開始点を定義するために、ユーザにビューポート内をクリックしてもらいます。
ユーザが右クリックした場合は、操作をキャンセルします。
ユーザが左クリックした場合は、ノットをスプラインに加え、描画関数を呼び出します。
ユーザがマウスを動かしているかぎり、pickPoint コールバックはセグメントの長さを測定し、必要に応じて新しいノットを追加する作業を続けます。
ユーザが再度クリックしたときに、スプラインを閉じるかどうかをユーザに尋ねます。
答えが「はい」の場合は、スプラインを閉じて選択し、スクリプトを終了します。
答えが「いいえ」の場合は、スプラインをただ選択し、スクリプトを終了します。
MAXScript
macroscript FreeSpline category:"HowTo" tooltip:"FreeSpline" ( local old_pos local new_spline local second_knot_set fn get_mouse_pos pen_pos old_pen_pos = ( if old_pos == undefined then old_pos = old_pen_pos if distance pen_pos old_pos > 10 then ( if second_knot_set then addKnot new_spline 1 #smooth #curve pen_pos else ( setKnotPoint new_spline 1 2 pen_pos second_knot_set = true ) old_pos = pen_pos updateShape new_spline )-- end if )-- end fn fn draw_new_line old_pen_pos = ( pickPoint mouseMoveCallback:#(get_mouse_pos,old_pen_pos) ) undo"Free Spline"on ( new_spline = splineShape () old_pen_pos = pickPoint () if old_pen_pos == #RightClick then ( delete new_spline ) else ( select new_spline new_spline.pos = old_pen_pos addNewSpline new_spline addKnot new_spline 1 #smooth #curve old_pen_pos addKnot new_spline 1 #smooth #curve old_pen_pos second_knot_set = false draw_new_line old_pen_pos q = querybox "Close Spline?" title:"Free Spline" if q then ( close new_spline 1 updateshape new_spline ) select new_spline )--end else )--end undo )--end script
macroscript FreeSpline category:"HowTo" tooltip:"FreeSpline"
(
macroScript は FreeSpline
と呼ばれます。スクリプトを使用する場合は、[カスタマイズ...] (Customize...)に移動してスクリプトを[HowTo]カテゴリからツールバー、メニュー、またはクアッド メニューにドラッグするか、キーボード ショートカットを割り当てることができます。
local old_pos
local new_spline
local second_knot_set
スクリプトによって作成された最後のノット位置と新しいオブジェクトを格納するローカル変数がいくつか必要です。3 番目の変数は、スプラインの作成を始めたばかりかどうかを示すフラグとして使用されます。
これらの変数は、ローカルとして宣言したため、この macroScript のコンテキスト内部にのみ存在します。
fn get_mouse_pos pen_pos old_pen_pos =
(
splineShape 内での新しいノットの描画を処理する独自の関数を作成します。この関数は、2 つのパラメータ、つまりマウスの現在位置と、pickPoint 関数 (下を参照) によって捕捉された最初のクリックの結果を受け取ります。
if old_pos == undefined then old_pos = old_pen_pos
既存のノットがわからない (開始した直後にもかかわらず) 場合は、old_pos ローカル変数の値を old_pen_pos パラメータによって指定された最初のチェック ポイントに設定します。
if distance pen_pos old_pos > 10 then
(
ここで、直前の既知のノット位置と現在のマウス位置との間の距離をチェックします。距離が 10 単位よりも長いかどうかをチェックします。
if second_knot_set then
定義したフラグ変数には、true または false が含まれます。変数が false を含んでいる場合は、スプラインの作成が始まったばかりです。スプラインは少なくとも 2 つのノット (頂点) を含んでいる必要があるので、最初のノットを 2 回作成して、このフラグを false に設定します。次のノット位置が設定されるときに、新しいノットを作成する代わりに、既存の 2 番目のノットを新しい座標に再配置して、フラグを true に設定します。
フラグが true に設定されている場合は、次の新しいノットを作成します。 次の行を参照してください。
addKnot new_spline 1 #smooth #curve pen_pos
次に進んで新しいノットを配置するので、新しいセグメントがスプライン シェイプに追加されます。addKnot 関数には、splineShape オブジェクト、スプラインのインデックス (1 つだけあります)、ノットのタイプ(この例では #smooth)、およびノットを配置する位置が必要です。
else
(
setKnotPoint new_spline 1 2 pen_pos
フラグが false に設定されていると、新しいノットを作成するのではなく、既存の 2 番目のノットを動かす必要があります。
second_knot_set = true
次に、このフラグを true に設定します。次回に新しいノットが作成されます。
)
old_pos = pen_pos
次に、次のマウス移動のチェックに使用される新しいノット位置を覚えておきます。
updateShape new_spline
スプラインに対して行われた変更を観察するために、splineShape オブジェクトを更新します。
) -- end if
) -- end fn
fn draw_new_line old_pen_pos =
(
マウス移動の捕捉を処理する別の関数を作成します。
pickPoint mouseMoveCallback:#(get_mouse_pos,old_pen_pos)
この関数は、オプションのコールバックを提供する組み込み pickPoint 関数のみを呼び出します。 pickPoint 関数は、直前に定義した get_mouse_point 関数を呼び出し、現在のマウス位置とユーザ指定のパラメータ (この場合は old_pen_pos) を渡します。
マウスが動いていてクリックされないかぎり、pickPoint の mouseMoveCallback は定期的にここで定義した関数を呼び出すので、10 単位の距離で新しいノットが作成されます。
)
undo "Free Spline" on
(
描画結果全体を元に戻すことができるように、アンドゥ コンテキスト内に完全なコードを配置します。
new_spline = splineShape ()
スクリプトの開始時に、最初に空の splineShape オブジェクトを作成します。
old_pen_pos = pickpoint ()
次に、pickPoint モードになりますが、今回はマウスのコールバックはありません。数はビューポート内でクリックを待機し、選択されたポイントの位置を返すか、またはマウスの右ボタンが押された場合は #RightClick を返します。
if old_pen_pos == #RightClick then
(
delete new_spline
)
マウスの右ボタンが実際に押された場合は、新しく作成された splineShape を削除し、スクリプトを終了します。
else
(
select new_spline
pickButton が位置の値を返し、#RightClick を返さない場合は、splineShape を選択することができます。
new_spline.pos = old_pen_pos
splineShape の位置をクリックされたポイントに設定します。
addNewSpline new_spline
新しいスプラインを空の splineShape に追加します。
addKnot new_spline 1 #smooth #curve old_pen_pos
addKnot new_spline 1 #smooth #curve old_pen_pos
さらに、2 つの新しいノットを splineShape 内の新しく作成されたスプラインに追加します。前に説明したように、スプラインには少なくとも 2 つのノットが必要なので、同じ位置に最初の 2 つのノットを作成してから、新しいノットを作成する代わりに 2 番目のノットを動かします。
second_knot_set = false
フラグを false に設定します。これで、スクリプトは最初の 2 つのノットが作成されたことがわかり、2 番目のノットはスクリプトによって捕捉された次のマウス位置に設定されます。この作業が get_mouse_pos
関数内で行われると、フラグを再度 true に設定します。 したがって、最初のスプライン作成のステップが終了したことがわかります。
draw_new_line old_pen_pos
次に、ここで定義した draw_new_line
関数を呼び出し、パラメータとして最初にクリックされたポイントを渡します。 新しいクリックが発生するまで、この関数でマウスの動きを監視します。
q = querybox "Close Spline?" title:"Free Spline"
新しいクリックが pickPoint
関数によって捕捉されると、draw_new_line
関数によってそのポイントが返されます。ここで、新しく描画されたスプラインを閉じるかどうかをユーザに尋ねることができます。
MAXScript のメッセージ ボックスおよび問い合わせダイアログ ボックス
if q then
(
close new_spline 1
updateshape new_spline
クエリに対する答が「はい」の場合は、splineShape 内の最初で唯一のスプラインを閉じ、変更を反映させるために内部のデータ構造体を更新します。
)
select new_spline
最後に、終了する前にシーン内で新しく作成された splineShape を選択します。
)--end else
)--end undo
)--end script
スクリプトを評価します。スクリプトを使用する場合は、[カスタマイズ...] (Customize...)を使用して、スクリプトを[HowTo]カテゴリからツールバー、メニュー、またはクアッド メニューにドラッグするか、キーボード ショートカットを割り当てることができます。
FreeSpline スクリプトを実行し、トップまたはパース ビューポート内を左クリックします。マウスを自由にドラッグして、スプラインを描きます。再度左クリックして、描画を終了します。プロンプトに「はい」と答えてスプラインを閉じるか、「いいえ」と答えて開いたままにします。
これは基本コードにすぎません。セグメント長のしきい値、スプライン セグメントとノットのタイプ (線形、スムーズ、ベジェなど) のためのコントロール付きの UI を追加してみてください。
戻る