MAXScript を使って処理する値の多くはシーケンス処理済みコレクションで、配列やワイルド カード パス名 選択、および組み込みの オブジェクト セットです。
多くの OS シェル コマンド言語と同様、MAXScript は自動的にターゲット コレクション内の各メンバに適切な演算を適用します。これは、マップされた演算と呼ばれます。
例: | |
---|---|
hide $lights/key* |
シーン内の 'key' ライトすべてを隠します。 |
$box*.position = [0,0,0] |
すべてのボックスを中心に再配置します。 |
delete dead_objects |
配列 'dead_objects' 内のすべてのオブジェクトを削除します。 |
obj.pos.keys.intangent=#fast |
すべてのオブジェクトの位置キーに対して接線を高速に設定します。 |
lights.value *= 0.8 |
すべてのライトを 20% まで暗くします |
MAXScript では、関数に対する最初の引数やプロパティ割り当てのターゲットを見て、それがシーケンス処理済みコレクションかどうかを判断してからマップされた演算を行います。関数呼び出しの場合、その関数が適切な種類かどうかを判断してその他すべての引数式を 1 度だけ評価します。
次に、MAXScript は最初の引数コレクションの各メンバでその関数を呼び出し、その他の評価された引数を渡します。プロパティ割り当ての場合は、右辺式を 1 度だけ評価してから、ターゲット値コレクション内の各要素に指定されたプロパティにその値を割り当てます。
つまり、コレクション内のどの要素も、その関数に対して有効なターゲットでなければならず、指定されたプロパティを持たなければなりません。MAXScript が不適切なターゲットに遭遇すると、エラーとなり演算を自動的に停止します。
現在の MAXScript では、特定の共通プロパティを除き、1 レベル深いプロパティ割り当ての自動コレクション マッピングだけが可能です。
例
次の行は ObjectSet 内の複数のオブジェクトに対してコレクション マッピングを実行します。
objects.pos = [0,0,0] --move all objects to world center
指定の最終レベルの名前が次のいずれかに該当する場合は、前のプロパティに自動コレクション マッピングが実行されます。
.angle .b .blue .axis .controller .g .green .isAnimated .keys .r .red .track .x .x_rotation .y .y_rotation .z .z_rotation
例
次の行は ObjectSet 内の複数のオブジェクトに対してコレクション マッピングを実行します。
objects.pos.z = 0.0 --move all objects to world XY plane
あるコレクションのすべての要素に関数を呼び出す動作は、マッピングと言われています。各コレクションのタイプの解説にあるとおり、この種のマップされるシーケンス処理済みコレクションには mappable というラベルが付いています。
このマニュアルで解説されている多くの関数および演算子には、コレクション内で各要素の役割を果たすものがあり、それらには mapped というラベルが付いています。
一般に、マップされる関数は移動、削除、および非表示のように、取得する値にはある種の副作用があります。
テスト関数 isHidden()
などのその他の関数では、結果で複数のオブジェクトの状態を表現することができません。マッピングは意味をなさないことからマップnot
。
MAXScript で定義された copy()
、delete()
、move()
などのマップされた関数は、オプションで最後の引数に #noMap
を指定できます。これにより、配列などのコレクション引数を呼び出したとき、関数がマップされることを防ぎます。特に、配列に対して copy()
で使用すると、配列の各要素に対して個別に copy()
を実行するのではなく、配列自体のトップ レベルのコピーを返します。
関数定義の前に予約語 mapped
を付けると、マップされるスクリプト関数 を作成できます。
例
次の行は ObjectSet 内の複数のオブジェクトに対してコレクション マッピングを実行します。
mapped function rand_color x = (x.wireColor = random black white)
こうすると、コレクションがその関数の最初の引数として指定されている場合、コレクションの要素に関数が繰り返し自動的に呼び出されます。#noMap
は、ユーザ定義の関数では使用できません。
「For ループ」で解説されているように、for
ループでは、コレクション セットを繰り返し処理し、コレクションの連続要素をループ処理のたびにループ値に代入するよう設定できます。For
ループは、結果に配列コレクション セットを返すよう設定することもできます。
例:
-- sequence an array: for item in table1 do x = x + item.height
-- you can sequence pathnames: bigones = for obj in $box* where obj.height > 100 collect obj -- collect the big boxes into an array
for
ループでコレクション セットを反復したり、コレクションをマップされた関数に渡すとき、for
ループまたは関数内で要素を並べ替えたり削除しないでください。
以下で、選択されたすべてのスプラインを NURBS カーブに変換するスクリプトを例に説明します。
はじめに、正しく実行されない 2 つのスクリプトを示します。
for obj in selection do ( convertToNURBSCurve obj)
convertToNURBSCurve selection
どちらのコマンドも正しく実行されない理由は、
convertToNURBSCurve()
関数で現在の選択が解除されるからです。そのため、最初のスプラインだけがconvertToNURBSCurve()
に渡されて変換されます。convertToNURBSCurve()
は組み込み関数のため、この動作を修正することはできません。この問題を回避するには、最初に選択コレクション セットの「スナップショット」を
as
演算子を使って配列として作成するか、現在の選択セットを配列として返すgetCurrentSelection()
関数を使用します。次の 2 つのスクリプトは正常に実行されます。
for obj in (selection as array) do ( convertToNURBSCurve obj)
convertToNURBSCurve (getCurrentSelection())