コールバック スクリプトを使用して、一定のシステム イベントが発生したときに MAXScript によって常に特定の動作が実行されるようにすることができます。以下の例では、レンダリングに先立ってシーン内のすべての球体のセグメント数を増やし、終了した後に再びその数を減らします。これは、球体用の一種のカスタム レンダリング解像度コントロールの実装です。同様のアプローチで、他のレンダリング前の準備を実装することができます。
関連トピック:
全体の流れ:
ボタン、メニュー項目またはショートカットとして使用できる macroScript としてコードをパッケージ化します。
サンプル用の固有の ID を持つ既存のコールバックを削除します。
球のセグメント数を増やすコールバック スクリプトが含まれた文字列を作成します。
スクリプト内ですべてのジオメトリ オブジェクトを巡回し、基本オブジェクトの sphere クラスをチェックして、セグメント カウント値を 8 倍に増やします。
レンダリング開始の前に呼び出されるようにコールバックを登録し、固有の ID を付けます。
球のセグメント数を減らすコールバック スクリプトが含まれた 2 番目の文字列を作成します。
スクリプト内ですべてのジオメトリ オブジェクトを巡回し、基本オブジェクトの sphere クラスをチェックして、セグメント カウント値を 8 分の 1 に減らします。
レンダリングの終了後に呼び出されるようにコールバックを登録し、同じ固有の ID を付けます。
ID によってコールバックを削除する 2 番目の macroScript を作成します。
MAXScript
macroscript SphereSegsOn category: "HowTo" ( callbacks.removescripts id:#sphere_segs txt ="for o in geometry do(\n" txt +="if classof o.baseObject == Sphere then \n" txt +="o.baseObject.segments *= 8.0\n" txt +=")\n" callbacks.addscript #preRender txt id:#sphere_segs txt ="for o in geometry do(\n" txt +="if classof o.baseObject == Sphere then \n" txt +="o.baseObject.segments /= 8.0\n" txt +=")\n" callbacks.addscript #postRender txt id:#sphere_segs )
macroscript SphereSegsOff category: "HowTo" ( callbacks.removescripts id:#sphere_segs )
macroscript SphereSegsOn category:"HowTo"
(
macroScript は SphereSegsOn
と呼ばれます。スクリプトを使用する場合は、[カスタマイズ...] (Customize...)に移動してスクリプトを[HowTo]カテゴリからツールバー、メニュー、またはクアッド メニューにドラッグするか、キーボード ショートカットを割り当てることができます。
callbacks.removescripts id:#sphere_segs
新しいコールバックを作成する前に、前のセッションからある既存のコールバックを削除します。指定された ID のコールバックがその時点で存在しない場合でも、callbacks.removescripts
を呼び出すことができます。コールバックが存在しない場合、この呼び出しは何も実行しません。存在する場合は、それらが削除されます。
このコード全体を通じて、同じ ID である #sphere_segs
を使用します。したがって、他のコールバックに対しては何も行わずに、この例のコールバックにだけ影響を与えることができます。
txt = "for o in geometry do(\n"
txt +="if classof o.baseObject == Sphere then \n"
txt +="o.baseObject.segments *= 8.0\n"
txt +=")\n"
コールバックを定義するためには、実行されるコードを含む文字列が必要です。新しいユーザ変数の txt を定義し、コードをそこに代入します。円記号と n の連続した組み合わせで、改行を示します。このスクリプトでは、シーン内のすべてのジオメトリ オブジェクトをループで巡回し、それぞれが基本オブジェクト (モディファイヤ スタックの一番下にあるオブジェクト) かどうかを調べます。基本オブジェクトのクラスが Sphere の場合に、既存のセグメント数に 8 を乗算します。つまり、スタック上にメッシュ スムーズやベンドなどのモディファイヤがある場合でも、球は変更されます。
callbacks.addscript #preRender txt id:#sphere_segs
ここで、コードをコールバック スクリプトとして割り当てることができます。キーワード #preRender
は、このスクリプトがレンダリングの開始前に実行されることをコールバックに通知します。コールバックには固有の ID である #sphere_segs
が付いているので、任意の時点で ID を指定して削除することができます。
txt = "for o in geometry do(\n"
txt +="if classof o.baseObject == Sphere then \n"
txt +="o.baseObject.segments /= 8.0\n"
txt +=")\n"
これは前のコードと基本的に同じですが、乗算する代わりにセグメント数を 8 で除算しています。これで、すべての球が元の状態に戻ります。
callbacks.addscript #postRender txt id:#sphere_segs
新しいコードを再度コールバック スクリプトとして割り当てます。キーワード #postRender
は、このスクリプトがレンダリングの終了後に実行されることをコールバックに通知します。このコールバックには同じ一意の ID があります。
)
macroscript SphereSegsOff category:"HowTo"
(
コールバックの効果をオフにするための 2 番目の macroScript を定義します。これは同じカテゴリ内に表示され、SphereSegsOff
という名前になります。
callbacks.removescripts id:#sphere_segs
サンプルの ID を持つ既存のコールバックを削除します。球のあるシーンのレンダリングは、この行の呼び出し後に通常どおり機能します。
)
コードを評価します。2 つのスクリプトを使用する場合は、[カスタマイズ...] (Customize...)を使用して、スクリプトを[HowTo]カテゴリからツールバー、メニュー、またはクアッド メニューにドラッグするか、キーボード ショートカットを割り当てることができます。
このスクリプトを使用するために、2、3 の球があるシーンを作成し、セグメント数を 4 などのかなり少ない数に設定します。シーンをレンダリングします。すべての球はビューポート内で表示した場合とまったく同じように見えます(最初のイメージを参照)。次に、SphereSegsOn script を実行します。ビューポート内では何の変化も起きませんが、再びシーンをレンダリングすると、すべての球が完全に滑らかに表示されます(2 番目のイメージを参照)。SphereSegsOff スクリプトを実行すると、レンダリングが以前の状態に戻ります。
戻る