リファレンス / 3ds Max / 3ds Max Python チートシート

表示・名前・色・ユーザ定義

  • 3dsMax
  • Python
  • pymxs
  • チートシート
3ds Max Python チートシート の章一覧

ノードの見た目と名札まわりの操作です。ほとんどが プロパティへの代入 で済みます。

表示 / 非表示

b = rt.getNodeByName("Box001")
b.isHidden = True                  # MXS: b.isHidden = true(true にするのは hide b と同じ)
b.isHidden                         # True
rt.hide(rt.getNodeByName("Sphere001"))     # MXS: hide $Sphere001(ノード 1 つを渡す)
rt.unhide(rt.objects)                      # MXS: unhide objects(ObjectSet をそのまま渡せる、全部表示)
  • rt.hide / rt.unhide はノード 1 つでも、rt.objects のようなオブジェクト集合(ObjectSet)でも渡せます。
  • 非表示のノードも rt.objects には含まれます。見えているものだけ欲しいときは not o.isHidden で絞ります。

フリーズ / 解除

b = rt.getNodeByName("Box001")
b.isFrozen = True                    # MXS: b.isFrozen = true(true にするのは freeze b と同じ)
b.showFrozenInGray = False           # フリーズしても元の色で表示
rt.unfreeze(list(rt.objects))        # MXS: unfreeze objects

名前を変える

b = rt.getNodeByName("Box001")
b.name = "Crate"                                   # MXS: b.name = "Crate"

for o in rt.selection:                             # 接頭辞を付ける
    o.name = "PROP_" + o.name

for o in rt.objects:                               # 置換する(Python の str.replace)
    o.name = o.name.replace("001", "_A")
  • o.name は Python の str なので、replace / upper / スライス / 正規表現(re.sub)がそのまま使えます。

連番でリネームする

nodes = sorted(rt.objects, key=lambda o: o.pos.x)       # X 座標の順に並べてから
for i, o in enumerate(nodes, start=1):
    o.name = "Item_{:03d}".format(i)                    # Item_001, Item_002, ...
  • sorted(..., key=...) で並び順を決めてから番号を振ると、毎回同じ結果になります。
  • ⚠️ 3ds Max は 同じ名前のノードを許します。名前が重ならないことを保証したいなら o.name = rt.uniqueName("Item_") のように代入します。ただし一意性が保証されるのは次のシーンノードが作られるまでの間だけです。

色(ワイヤフレームカラー)

import random

b = rt.getNodeByName("Box001")
b.wirecolor = rt.Color(255, 0, 0)                   # MXS: b.wirecolor = red
b.wirecolor.r                                       # 255.0
reds = [o for o in rt.objects if o.wirecolor == rt.red]   # 色で絞り込む(この時点では b が該当)

for o in rt.objects:                                # ランダムな色
    o.wirecolor = rt.Color(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
  • 色の成分は .r / .g / .b(0〜255 の float)で読めます。成分だけ書き換えたいときは、pos と同じく 取り出して戻す 必要があります。

    c = b.wirecolor
    c.r = 0
    b.wirecolor = c
  • rt.red / rt.green / rt.blue / rt.white / rt.black などの色定数も使えます。

ビューポートの表示プロパティ

b = rt.getNodeByName("Box001")
b.displayByLayer = False     # 表示設定を[レイヤー別]ではなく[オブジェクト別]にする(先に外しておく)
b.boxMode = True             # バウンディングボックス表示
b.xray = True                # シースルー表示(UI では Alt + X)
b.backfaceCull = True        # 裏面を表示しない
b.renderable = False         # レンダリングしない
b.castShadows = False        # 影を落とさない
  • オブジェクトプロパティ(右クリック → [オブジェクトプロパティ])の項目は、ほとんどがノードのプロパティとして読み書きできます。
  • [レイヤー別]の設定は 3 種類あります。displayByLayer は xray / boxMode などの表示設定、colorByLayer は wirecolor、renderByLayer は renderable / castShadows などのレンダリング関連の設定に対応します。ノード側を変えても見た目が変わらないときは、対応する設定を確かめます。

ユーザ定義プロパティ(ノードにメモを持たせる)

b = rt.getNodeByName("Box001")
rt.setUserProp(b, "export", True)             # MXS: setUserProp b "export" true
rt.setUserProp(b, "lod", 2)
rt.getUserProp(b, "lod")                      # 2(数値に自動変換される。⚠️ 下記)
rt.getUserPropVal(b, "lod", asString=True)    # '2'(文字列のまま欲しいとき)
rt.getUserPropBuffer(b)                       # 全文(オブジェクトプロパティ > ユーザ定義の欄)
  • ユーザ定義プロパティは シーンファイルに保存される ので、書き出し設定やツール用の目印を持たせるのに便利です。
  • ⚠️ getUserProp は値を数値やブール値に 自動変換 します(1m のような値は時間として解釈されることもあります)。文字列のまま読みたいときは getUserPropVal(..., asString=True) を使います。
  • 3ds Max 2019.1 Update 以降では、getUserProp / setUserProp の代わりに getUserPropVal / setUserPropVal を使うことが公式ヘルプで推奨されています。setUserPropVal は文字列を既定で引用符付きで保存し、getUserPropVal は読み出すときに文字列の先頭と末尾が引用符ならそれを取り除きます。

構造のあるデータを持たせる(JSON)

import json

b = rt.getNodeByName("Box001")
data = {"tags": ["prop", "wood"], "weight": 1.5}
rt.setUserProp(b, "myToolData", json.dumps(data, ensure_ascii=False))       # 1 行の JSON にして保存

loaded = json.loads(rt.getUserPropVal(b, "myToolData", asString=True))     # 読み戻す
  • ユーザ定義プロパティは「キー = 値」の 1 行ずつのテキストです。json.dumps は既定で 1 行になるので、そのまま値として入れられます。
  • ⚠️ JSON のトップレベルは辞書か配列にします。文字列だけを保存すると、前後が引用符に見えて getUserPropVal で外されることがあります。

落とし穴まとめ

  • 非表示のノードも rt.objects に含まれる。
  • 同じ名前のノードを作れてしまう。一意にしたいなら uniqueName。
  • wirecolor.r = ... のような成分だけの代入は効かない(取り出して戻す)。
  • ノード側の表示設定が効かないときは[レイヤー別]の設定になっていないか確かめる。
  • getUserProp は自動で型変換する。文字列のまま欲しいなら getUserPropVal(..., asString=True)。

関連

← 3ds Max Python チートシート へ