チュートリアル - フリーハンドのスプラインの描画

チュートリアル > フリーハンドのスプラインの描画

3ds Max には、マウスで自由にスプラインを描くためのビルトイン関数がありません。従来の Autodesk 3D Studio DOS には、そのような機能がありました。

MAXScript を利用して、この機能を単純な MacroScript として実装することができます。このスクリプトによって、マウスでグラウンド平面にスプラインを描くことができるようになります。

関連トピック:

Macro Script の定義

SplineShape : シェイプ

スプライン シェイプの共通プロパティ、演算子、メソッド

ビューポート内でのポイント選択

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 式

Undefined 値

if distance pen_pos old_pos > 10 then
(

ここで、直前の既知のノット位置と現在のマウス位置との間の距離をチェックします。距離が 10 単位よりも長いかどうかをチェックします。

If 式

Point3_distance

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)、およびノットを配置する位置が必要です。

SplineShape : シェイプ

else
(
setKnotPoint new_spline 1 2 pen_pos

フラグが false に設定されていると、新しいノットを作成するのではなく、既存の 2 番目のノットを動かす必要があります。

second_knot_set = true

次に、このフラグを true に設定します。次回に新しいノットが作成されます。

)
old_pos = pen_pos

次に、次のマウス移動のチェックに使用される新しいノット位置を覚えておきます。

updateShape new_spline

スプラインに対して行われた変更を観察するために、splineShape オブジェクトを更新します。

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
(

描画結果全体を元に戻すことができるように、アンドゥ コンテキスト内に完全なコードを配置します。

undo

new_spline = splineShape ()

スクリプトの開始時に、最初に空の splineShape オブジェクトを作成します。

SplineShape : シェイプ

old_pen_pos = pickpoint ()

次に、pickPoint モードになりますが、今回はマウスのコールバックはありません。数はビューポート内でクリックを待機し、選択されたポイントの位置を返すか、またはマウスの右ボタンが押された場合は #RightClick を返します。

ビューポート内でのポイント選択

if old_pen_pos == #RightClick then
(
delete new_spline
)

マウスの右ボタンが実際に押された場合は、新しく作成された splineShape を削除し、スクリプトを終了します。

If 式

else
(
select new_spline

pickButton が位置の値を返し、#RightClick を返さない場合は、splineShape を選択することができます。

new_spline.pos = old_pen_pos

splineShape の位置をクリックされたポイントに設定します。

addNewSpline new_spline

新しいスプラインを空の splineShape に追加します。

SplineShape : シェイプ

addKnot new_spline 1 #smooth #curve old_pen_pos
addKnot new_spline 1 #smooth #curve old_pen_pos

さらに、2 つの新しいノットを splineShape 内の新しく作成されたスプラインに追加します。前に説明したように、スプラインには少なくとも 2 つのノットが必要なので、同じ位置に最初の 2 つのノットを作成してから、新しいノットを作成する代わりに 2 番目のノットを動かします。

SplineShape : シェイプ

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 内の最初で唯一のスプラインを閉じ、変更を反映させるために内部のデータ構造体を更新します。

If 式

SplineShape : シェイプ

) 
select new_spline

最後に、終了する前にシーン内で新しく作成された splineShape を選択します。

)--end else
)--end undo
)--end script

スクリプトの使い方

スクリプトを評価します。スクリプトを使用する場合は、[カスタマイズ...](Customize..)を使用して、スクリプトを[HowTo]カテゴリからツールバー、メニュー、またはクアッド メニューにドラッグするか、キーボード ショートカットを割り当てることができます。

FreeSpline スクリプトを実行し、トップまたはパース ビューポート内を左クリックします。マウスを自由にドラッグして、スプラインを描きます。再度左クリックして、描画を終了します。プロンプトに「はい」と答えてスプラインを閉じるか、「いいえ」と答えて開いたままにします。

関連項目

これは基本コードにすぎません。セグメント長のしきい値、スプライン セグメントとノットのタイプ (線形、スムーズ、ベジェなど) のためのコントロール付きの UI を追加してみてください。

戻る

「チュートリアル」のインデックス ページ