モディファイヤ
MaxScript チートシート の章一覧
モディファイヤスタックの操作です。追加(addModifier)、アクセス(.modifiers[] や名前)、集約(collapse)が中心です。モディファイヤは Bend angle:45 のように クラスを呼んで作り、addModifier でノードに載せる のが基本です。スタック(.modifiers)は [1] が一番上 で、3ds Max はスタックを 下から上へ 評価します。
追加する
addModifier $Box001 (Bend angle:45) -- スタックの一番上に追加
addModifier $Box001 (TurboSmooth()) before:1 -- 上から1番目(Bend)の下に挿入
-- 作成と同時にプロパティ指定($ は現在の選択。Box001 を選択しておく)
addModifier $ (Taper amount:0.5 curve:1.0)
- ⚠️
before:Nは「上から N 番目のモディファイヤの すぐ下」に入ります。スタックは下から上に評価されるので、「評価順では N 番目の直前」ということです。上の例のスタックは上から Taper / Bend / TurboSmooth になります。
スタックにアクセスする
$Box001.modifiers -- スタック全体(配列。[1] が最上段)
$Box001.modifiers.count -- モディファイヤ数
$Box001.modifiers[1] -- 一番上のモディファイヤ
$Box001.bend -- 名前で直接アクセス(スタックに表示される名前。空白は `_`)
$Box001.modifiers[#Bend] -- 名前(Name 値)でアクセス。同名なら一番上
$Box001.modifiers[Bend] -- クラスで指定(3ds Max 2013 以降。名前を変えられていても届く)
$Box001.baseObject -- 一番下のオブジェクト(この例では Box)
#Bendのように#を付けた値は Name 値(MaxScript の識別子)です。スタックに表示されている名前で探します。- 名前・クラスで指定すると 一番上の 1 つ が返るので、同じものが複数あるときは
$.modifiers[1]のように インデックス で指定します(モディファイヤ名が同じ場合は一番上のモディファイヤが返されます)。
プロパティを変える
$Box001.bend.angle = 90
$Box001.modifiers[2].angle = 90 -- 同じ意味(番号で指定。上の「追加する」例のスタックの続きで、上から2番目が Bend)
$Box001.bend.enabled = false -- オフにする(ビューポートもレンダリングも)
$Box001.bend.enabledInViews = false -- ビューポートでだけオフ
$Box001.bend.name = "Bend_Main" -- スタックでの表示名を変更
showProperties $Box001.bend -- 変更できるプロパティを一覧(→ デバッグ章)
削除する
-- 上の「追加する」例のスタックの続き(上から Taper / Bend / TurboSmooth)
deleteModifier $Box001 1 -- インデックスで削除(上から1番目=Taperが消える)
deleteModifier $Box001 $Box001.bend -- 参照で削除(Bendが消え、TurboSmoothだけ残る)
- 特定のクラスのモディファイヤをまとめて消すときは、削除で番号がずれても影響を受けないよう 逆順(大きいインデックスから) でループします。
for i = $Box001.modifiers.count to 1 by -1 where classOf $Box001.modifiers[i] == Bend do deleteModifier $Box001 i
集約する(collapse)
maxOps.CollapseNode $Box001 true -- スタック全体を集約(true=確認プロンプトを抑制)
collapseStack $Box001 -- スタックを集約(結果のクラスは最上段の結果に従う。モディファイヤが無いと何もしない)
convertToPoly $Box001 -- モディファイヤを集約したうえで編集可能ポリゴンにする(モディファイヤが無くても変換される)
convertToMesh $Box001 -- 編集可能メッシュに変換
CollapseNodeは 常にスタック全体 を集約します。第 2 引数はnoWarningです。trueにすると確認ダイアログを出しません(バッチ処理向け)。- ⚠️ 集約すると モディファイヤは消えて結果メッシュだけ が残ります。スクリプト実行後は Ctrl+Z で戻せないことがあるので、必要なら複製を残します。
一部だけ集約する(CollapseNodeTo)
CollapseNodeTo node index noWarning は、上から index 番目とそれより下 を 1 つに集約し、それより上のモディファイヤは残します。第 3 引数は CollapseNode と同じ noWarning です。
-- スタック: [1]Bend [2]Taper [3]Twist ─ baseobject
maxOps.CollapseNodeTo $Box001 3 true -- [3]Twist だけを集約(焼き込み)する([1][2] は残る)
-- この時点のスタックは [1]Bend [2]Taper。[1] を指定すると全部(CollapseNode と同等)
maxOps.CollapseNodeTo $Box001 1 true
- インデックスは
[1]が最上段、数字が大きいほどベースオブジェクトに近い 並びです([1].[2].[3].baseobject)。
インデックスのずれに注意(追加・集約で番号が移動する)
-- 追加は既定で最上段に入るため、既存のインデックスが繰り下がる
-- 追加前: [1]Bend
addModifier $Box001 (Taper())
-- 追加後: [1]Taper [2]Bend ← 元の [1]Bend が [2] に移動した
addModifierは既定で 最上段(index 1)に挿入 するので、元の[1]が[2]へ、というように 番号が 1 つずつ後ろにずれます。deleteModifierで途中のモディファイヤを消すと、それより下の番号が 1 つずつ繰り上がります(ヘルプも「削除すると配列が付け直されるので下から数える」としています)。
下から順に集約する(逆順の活用)
毎回 modifiers.count(=最下段)を取り直せば、番号のずれに影響されずに、上のモディファイヤを保ったまま下から 1 つずつ集約できます。
-- 一番下のモディファイヤだけを焼き込む(上は残す)
maxOps.CollapseNodeTo $Box001 $Box001.modifiers.count true
-- 上から keepTop 個を残し、それより下を全部集約する
keepTop = 1 -- 上から残したい数
while $Box001.modifiers.count > keepTop do
(
maxOps.CollapseNodeTo $Box001 $Box001.modifiers.count true
)
- ⚠️ ループ内で固定のインデックスを使い回すと、ずれで対象を取り違えます。毎回
modifiers.count(=最下段)を取り直す か、逆順(大きいインデックスから)で処理するのが安全です。
1つのモディファイヤを複数オブジェクトで共有する
b = Bend angle:45 -- 先に作っておく
for o in selection do addModifier o b -- 同じインスタンスを全員に追加
b.angle = 90 -- 1か所変えると全オブジェクトに反映
- 同じモディファイヤインスタンスを
addModifierすると インスタンスモディファイヤ になり、一括編集できます。 - 別々に編集したいときは
for o in selection do addModifier o (Bend angle:45)のように ループの中で毎回作ります。addModifierは mapped 関数なのでaddModifier selection bのように選択セットを渡しても同じ結果になります。 - ⚠️ インスタンス複製(Instance)したノードは互いに 同じモディファイヤスタックを共有 しています。そのうちの 1 つに
addModifierすると、他のインスタンスにも同じモディファイヤが追加されます。
落とし穴まとめ
modifiers[1]が最上段。数字が大きいほどベースオブジェクトに近い。評価順は下から上。CollapseNodeは全スタック、CollapseNodeTo node indexは指定位置から下だけを集約する(上は残る)。addModifierや集約でインデックスがずれる。ループでは固定番号を使わず毎回modifiers.countを取り直すか逆順で処理する。- 名前・クラス指定は一番上の 1 つを返す。同じものが複数あるときはインデックスで指定する。
- collapse / convertTo* は基本的に Ctrl+Z で戻せない。元が必要なら複製を残す。
- 同じインスタンスを複数ノードに追加するとインスタンスモディファイヤになる。
関連
- 対象オブジェクトを集める: 「選択・取得」章
- 変更できるプロパティ名を調べる: 「デバッグ・調査」章
コメント