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

メッシュ・ポリゴン

  • 3dsMax
  • MaxScript
  • チートシート
MaxScript チートシート の章一覧

メッシュの中身(頂点・面)を読み書きする操作です。ポリゴンは polyop、メッシュ(TriMesh)は meshop / グローバル関数 と、対象で関数群が分かれます。編集可能ポリゴン(Editable_Poly)には polyop. で始まる関数、編集可能メッシュ(Editable_Mesh。三角形メッシュ = TriMesh)には getVert のような接頭辞なしの関数と meshop. で始まる関数を使います。対象のクラスで関数群が分かれるのが最大の落とし穴です。

編集可能ポリゴン(Editable_Poly)

以下は convertToPoly $ で編集可能ポリゴンにしてから実行します(Box のパラメータは失われます → 「モディファイヤ」章)。

polyop.getNumVerts $          -- 頂点数
polyop.getVert $ 1            -- 頂点1の座標(point3)
polyop.setVert $ 1 [0,0,10]   -- 頂点1を移動
polyop.getNumFaces $          -- 面数
polyop.getFaceVerts $ 1       -- 面1を構成する頂点番号
polyop.getNumEdges $          -- エッジ数
  • ⚠️ 頂点・面の番号は 1始まり です。書き換え後に表示が更新されないときは update $ を呼びます。
  • 座標はノード経由で読み書きすると 現在の座標系コンテキスト(既定はワールド)になります。ローカル座標が欲しいときは in coordsys local (polyop.getVert $ 1) のように書きます。
  • 頂点はまとめて渡すこともできます(polyop.getVerts $ #{1..8} / polyop.setVert $ #{1..8} posArray)。このとき頂点リストは 配列ではなく BitArray で渡します(配列だとパフォーマンスに重大な影響が出るとヘルプにあります)。

編集可能メッシュ(Editable_Mesh / TriMesh)

以下は convertToMesh $ で編集可能メッシュにしてから実行します。

getNumVerts $        -- 頂点数
getVert $ 1          -- 頂点1の座標
setVert $ 1 [0,0,0]  -- 頂点1を移動
getNumFaces $        -- 面数(三角形)
getFace $ 1          -- 面1の 3 頂点の番号(Point3。.x .y .z に番号が入る)
update $             -- 変更を反映
  • ⚠️ メッシュ(getVert 等)とポリゴン(polyop.getVert 等)は 別 API です。対象のクラスに合わせて使い分けます。

サブオブジェクト選択(ビット配列)

polyop.setVertSelection $ #{1..4}      -- 頂点1〜4を選択
polyop.getVertSelection $              -- 選択中の頂点(BitArray)
polyop.setFaceSelection $ #{1,3,5}     -- 面を選択
polyop.getFaceSelection $              -- 選択中の面
  • #{1..4} は 1〜4、#{1,3,5} は 1・3・5 の番号を表す BitArray(番号ごとのオン/オフの並び)です。サブオブジェクト選択の標準形式です。#{} で全解除、番号の配列にしたいときは (polyop.getVertSelection $) as array にします。

全頂点をループする

-- 全頂点を Z 方向に持ち上げる(編集可能ポリゴン)
for i in 1 to (polyop.getNumVerts $) do
(
    v = polyop.getVert $ i
    polyop.setVert $ i [v.x, v.y, v.z + 10]
)
update $

法線・UV

-- 編集可能ポリゴン
polyop.getFaceNormal $ 1         -- 面1の法線
polyop.getMapSupport $ 1         -- マップチャネル1(UV)があるか
polyop.getMapVert $ 1 5          -- マップチャネル1の頂点5(UV座標)
polyop.getNumMapVerts $ 1        -- マップチャネル1の UV頂点数
polyop.getMapFace $ 1 3          -- マップチャネル1の面3(UV頂点の番号の配列)
-- 編集可能メッシュ
getNormal $ 1                    -- 頂点1の法線(スムージンググループを考慮した頂点法線。面法線は getFaceNormal $ 1)
meshop.getMapSupport $ 1         -- マップチャネル1(UV)があるか
meshop.getMapFace $ 1 3          -- マップチャネル1の面3(UV頂点の番号。Point3)
  • ⚠️ UV 頂点と幾何の頂点は別の番号 です。面ごとに getMapFace で対応を取ります。getMapVert の戻り値は Point3 で、x=U・y=V です。
  • ⚠️ polyop は編集可能ポリゴン用、getNormal や meshop は編集可能メッシュ用です。種類の違うオブジェクトに使うとエラーになります(例: 編集可能ポリゴンに getNormal を実行すると「非メッシュにメッシュ」エラーになります)。
  • ⚠️ マップ チャネルが無い状態で読むとエラーになります(例: mapcoords が false のまま変換したオブジェクトに polyop.getMapVert $ 1 1 を実行すると「指定されたマップ チャネルではマップ サポートを使用できません」エラー)。先に getMapSupport で確かめます。スクリプトで作ったプリミティブは既定で UV を持たないので、UV が要るときは作るときに mapcoords:true を付けます(例: Box mapcoords:true)。
  • UV はマップチャネル番号(既定は 1)を指定して読み書きします。チャネル 0 は頂点カラー、-2 はビューポートの頂点アルファ用の内部チャネルです。

スナップショット(変形結果を固定メッシュ化)

m = snapshotAsMesh $    -- 現在の評価結果を TriMesh として取得
getNumVerts m            -- モディファイヤ適用後の頂点数
  • snapshotAsMesh はモディファイヤ・位置・回転をすべて反映した ワールド座標の TriMesh を返し、元のオブジェクトは変えません。シーンに実体(ノード)を作りたいときは snapshot $ を使います。

落とし穴まとめ

  • 頂点・面の番号は 1 始まり。
  • ポリゴン(polyop)とメッシュ(meshop/グローバル関数)は別 API。
  • サブオブジェクト選択は #{...} の BitArray。配列で渡すとパフォーマンスに影響するので、まとめて処理するときも BitArray のまま渡す。
  • UV 頂点(マップ頂点)は幾何の頂点とは別番号。面や頂点を消すと番号が詰まるので、大きい番号から消す。
  • 頂点を書き換えたら、表示が更新されないときは update $ で反映する。

関連

← MaxScript チートシート へ