ビューポートの再描画コールバック機能
3ds Max ビューポートが再描画されるときに呼び出される関数を 1 つまたは複数登録できます。
また、3ds Max 2012 での Nitrous グラフィックス マネージャの導入により、描画プロセスの性質がプログレッシブ リファインになったため、MAXScript グラフィック ウィンドウ(gw.)の
ビューポート描画メソッドを使用して結果を生成するには、これらのメソッドをビューポートの再描画コールバック機能でラップする必要があります。
以下の関数によって、このコールバックを登録または登録解除します。
registerRedrawViewsCallback <fn>
unRegisterRedrawViewsCallback <fn>
関数は、必要に応じていくつでも登録できます。ビューポートが再描画されると、それぞれの関数が別々に呼び出されます。登録する関数に引数を指定することはできません。
例:
|
fn redrawviews_p = print "Viewports Redrawn"
registerRedrawViewsCallback redrawviews_p
|
上の例では、3ds Max ビューポートが再描画されるたびに、登録した関数によって文字列「Viewports Redrawn」が[リスナー](Listener)ウィンドウに出力されます。
|
特に注意すべき点
-
コールバック関数の実行中にランタイム エラーが発生した場合は、エラー メッセージが表示され、コールバック関数は永久にオフになります。
-
登録した関数は、関数を作成したコードのコンテキストではなく、特別なコンテキストで実行されます。つまり、関数には、その関数の定義の前後にある外部コード ネスト内のローカル変数への参照を含めることはできません。これらの変数は、関数が呼び出されるときには存在しない実行スタックにあるためです。これに関する重要な例外は、ユーティリティとロールアウトのパネル
ローカル(ローカル関数、ロールアウト変数、ネストされたロールアウトなど)です。これらは直接ロールアウトやユーティリティ オブジェクトと関連付けられているため、ロールアウト
コード内の変更ハンドラで参照できます。
-
登録されるものは関数値で、関数名またはグローバル変数ではありません。つまり、同じ名前の関数を登録した後でその関数を再定義しても、コールバックは自動的には変更されず、呼び出しの対象となる別の関数値が登録され、結果として
2 つの個別のコールバックが作成されます。古いコールバック関数を登録解除してから再定義してそれをもう一度登録するか(詳細はこのページのこの後の説明を参照してください)、または、登録した関数を、別の関数を呼び出す中間の関数にする必要があります。
例:
|
fn redrawviews_cb = print currentTime
fn rvcb = redrawviews_cb()
registerRedrawViewsCallback rvcb
|
この場合、登録されたコールバック関数 rvcb は実際のコールバック redrawviews_cb を(定義されているグローバル変数を参照して)呼び出します。したがって、必要に応じて何回でも redrawviews_cb() を再定義することができ、コールバックによって常に最新の定義が呼び出されます。これは、コールバックの開発とデバッグを行っている場合に便利です。
redrawviews_cb() 関数だけを定義しなおすのであり、その他の 2 行を再評価する必要はないことに注意してください。この再評価を行ってしまうと、再描画を行うたびに複数のコールバックから同じ関数を呼び出すことになります。
|
例:
|
unregisterRedrawViewsCallback redrawviews_callback_function
fn redrawviews_callback_function = print "Viewport Redraw 1"
registerRedrawViewsCallbackredrawviews_callback_function
|
このような評価を行うことで、最初にコールバック関数の登録解除を試みることができます。登録されていなければ、処理は何も行われません。関数が定義され、その値はコールバックとして登録されます。たとえば、ビューポートで軌道回転を行うと、文字列がリスナーに出力されます。
文字列を「Viewport Redraw 2」に変更して同じコードを評価したい場合は、古い関数は登録解除され、新しい関数が定義され、新しいコールバックが登録されます。ビューポートを軌道回転すると、新しい文字列だけが出力されます。
|
良くない例:
|
fn redrawviews_callback_function = print "Viewport Redraw2"
unregisterRedrawViewsCallback redrawviews_callback_function
registerRedrawViewsCallback redrawviews_callback_function
|
unregister 関数呼び出しが 1 行目ではなく 2 行目に来る場合は、新しい関数を先に定義すると unregister の試みは暗黙的に失敗します。これは、新しい関数が使用され、古い関数の値にアクセスできないからです。このようにするとビューポートを再描画したときに古い関数と新しい関数が両方とも実行され、リスナーには「Viewport
Redraw 1」と「Viewport Redraw 2」の両方が出力されます。
|
ローカル スコープの例:
|
(--open a local scope
global redrawviews_cb_function --ensure variable visibility
unregisterRedrawViewsCallback redrawviews_cb_function
fn redrawviews_cb_function= print "Redraw Test1"
registerRedrawViewsCallback redrawviews_cb_function
)--end local scope
|
登録解除と登録を実行する関数定義とコールバックがローカル スコープで行われている場合は、グローバル スコープおよび private ローカル スコープ(現在のセッション中の関数値を保護する
MacroScript のトップレベル ローカル スコープなど)で、コールバック関数からのコードに対する可視性を確実にすることが重要です。グローバル宣言のない上記のコードを評価すると、一番外側のブラケットによって定義される
LOCAL スコープ内に関数値が作成され、スクリプトの 2 番目の評価で unregisterRedrawViewsCallback() を呼び出そうとしても、変数は最初に実行された後に存在しなくなっているので、変数内の元の関数内を参照できません。このように、直前の関数値を正常に登録解除するためのスクリプトを
2 回目に実行できるようにするためには、関数値を保管する変数をグローバルとして宣言する必要があります。
出力される文字列を「Redraw Test 2」に変更してコードをもう一度評価すると、グローバル変数に保管されている古い値を正常に登録解除することができるため、新しい値で上書きして再描画表示コールバックとして登録することができます。
|