3dsmax/Pythonの連載も9回目になりました。一旦ここで3dsmaxはお休みして、8月からはMaya-Pyhtonの連載を再開します。
では今回のプログラムです。今回も長いですが、細かくコメントを入れています。
元のHELPにあったプログラムはこちらです。
import MaxPlus as mp # ------------- ピラミッドのポリゴンメッシュを作成する関数 def makePyramidMesh(mesh, size = 30.0): # ------------- 頂点数の指定 mesh.SetNumVerts(4) # ------------- 面の指定 mesh.SetNumFaces(4) # ------------- 4つの頂点座標の指定。引数sizeを利用 mesh.SetVert(0, mp.Point3(0.0, 0.0, size*2)) mesh.SetVert(1, mp.Point3(-size/2, -size/2, 0.0)) mesh.SetVert(2, mp.Point3(-size/2, size/2, 0.0)) mesh.SetVert(3, mp.Point3(size, 0.0, 0.0)) # ------------- 4つの頂点を組み合わせてポリゴンを生成 mesh.GetFace(0).SetVerts(0, 1, 2) mesh.GetFace(0).SetEdgeVisFlags(1,1,0) mesh.GetFace(1).SetVerts(0, 2, 3) mesh.GetFace(1).SetEdgeVisFlags(1,1,0) mesh.GetFace(2).SetVerts(0, 3, 1) mesh.GetFace(2).SetEdgeVisFlags(1,1,0) mesh.GetFace(3).SetVerts(1, 2, 3) mesh.GetFace(3).SetEdgeVisFlags(1,1,0) # -------------ジオメトリとトポロジーキャッシュを無効化して再構築 mesh.InvalidateGeomCache() mesh.InvalidateTopologyCache() # -------------メインプログラム def main(): # -------------ポリゴンメッシュオブジェクトの生成 geom = mp.Factory.CreateGeomObject(mp.ClassIds.TriMeshGeometry) tri = mp.TriObject._CastFrom(geom) mesh = tri.GetMesh() # ------------- 上のピラミッド作成関数を実行。nodeに設定 makePyramidMesh(mesh) node = mp.Factory.CreateNode(tri) # ------------- バーテックスカラーの設定を3つ mesh.ColorPerVertexMap.SetNumTextureVertices(3) # ------------- 3つのバーテックスカラーの色をRGBに設定 mesh.ColorPerVertexMap.SetTextureVertex(0, mp.Point3(1, 0, 0)) mesh.ColorPerVertexMap.SetTextureVertex(1, mp.Point3(0, 1, 0)) mesh.ColorPerVertexMap.SetTextureVertex(2, mp.Point3(0, 0, 1)) # ------------- 各バーテックスに3つの色を設定 mesh.ColorPerVertexMap.SetTextureFace(0, 0, 0, 0) mesh.ColorPerVertexMap.SetTextureFace(1, 1, 1, 1) mesh.ColorPerVertexMap.SetTextureFace(2, 2, 2, 2) mesh.ColorPerVertexMap.SetTextureFace(3, 0 ,1, 2) node.VertexColorMode = True # -------------リセットしてメインを実行 mp.FileManager.Reset(True) main() # -------------ファイルセーブする fm = mp.FileManager fm.Save('E:\Bros_test.max') print fm.GetFileNameAndPath()
これを実行すると、このように頂点カラーが付いたピラミッドを作成します。
というわけで今回はポリゴンメッシュをPythonだけで生成する、というのをチャレンジしてみます。
3行名:def makePyramidMeshで、モデリングをしています。引数sizeで大きさを決めています。
5行目と7行目、mesh.SetNumVerts(4)とmesh.SetNumFaces(4)で頂点数とフェイスの数を4つづつと定義します。
9~12行目でmesh.SetVert(X,Y,Z)という命令でポリゴンの頂点(バーテックス)0~3の座標をXYZを設定します。以下の図とプログラムを見比べてください。
14,16,18,20行のmesh.GetFace(ポリゴン番号).SetVerts(頂点番号, 頂点番号, 頂点番号)でポリゴン生成します。
15,17,19,21行のmesh.GetFace(ポリゴン番号).SetEdgeVisFlags(1,1,0)でそのエッジの表示をONにしています。3dsmaxはご存知の通り、全て3角ですが、4角以上のポリゴンにエッジを非表示にできます。
23,24行でジオメトリとトポロジーキャッシュを無効化して再構築しておくことで、モデルが正しく表示されます。
26行目からメインプログラムです。
28~30は毎回おなじみのジオメトリ作成の一連の流れです。違うのは、CreateGeomObject(mp.ClassIds.TriMeshGeometry)の最後のTriMeshGeometryで三角形ポリゴン生成する設定です。
32、33行目でmakePyramidMesh関数を実行します。
35行目から頂点カラーを設定します。
ポリゴンに色を付ける基本機能です。これに本来はライティングと組み合わせて、シェーディングを行います。
35行目でmesh.ColorPerVertexMap.SetNumTextureVertices(3)で頂点カラーを3つ定義します。 37~39行目のmesh.ColorPerVertexMap.SetTextureVertex(頂点カラー番号, mp.Point3(赤, 青,緑))で色を定義しています。RGBは0~1で設定します。
41~44行のmesh.ColorPerVertexMap.SetTextureFace(ポリゴン番号, 1つめの頂点カラー番号, 2つめの頂点カラー番号, 3つめの頂点カラー番号)と定義しています。
1つのポリゴンに3つ頂点があり、定義した色をそれぞれ割り当てます。
0~2までは3つを同じにしたので、1の面が同じ色で塗りつぶしますが、そこの面は3つの頂点をRGBで塗ったので間は補完され、グラデーションになります。
48、49行でシーンリセットして、メインを実行です。
51~53行目で、このシーンを自動でファイルセーブします。同時にファイルのパスを表示します。
fm = mp.FileManager fm.Save('E:\Bros_test.max') print fm.GetFileNameAndPath()
これも便利ですので、ぜひ活用ください。
出来上がったオブジェクトはちょっと変な性質を持っています。
この物体はモディファイアが追加できません。
編集可能メッシュに変換すると、何でもできるようになります。
しかし、レンダリングできません。法線モディファイアを入れてやればOKです。
今回は簡単な例でしたが、3dsmaxやMayaなど3DCGの根本的な仕組みの理解にもなりますし、CSVなど頂点情報を外部から読み込んでモデル生成なども可能でしょう。