チュートリアル - ジオメトリ データのテキスト ファイルへの出力 - 第 1 部

チュートリアル > ジオメトリ データの読み取りと書き込み > ジオメトリ データのテキスト ファイルへの出力 - 第 1 部

これは、メッシュ ジオメトリ データを外部のテキスト ファイルに書き込む非常に基本的な例です。書き込まれたファイルは、後で MAXScript、またはスクリプトと ASCII ファイルの読み取りをサポートする他の 3D アプリケーションによって解析することができます。第 1 部では、頂点と面のリストのみを固定パス名に書き込みます。第 2 部では、第 1 部で作成したコードを拡張して、ユーザが書き込み先のファイルを選択できるようにし、エッジの可視性、スムージング グループ、テクスチャ座標などのメッシュ機能をいくつかサポートします。

別のチュートリアルで、ジオメトリ データを読み戻してシーン内にメッシュを再作成するスクリプトを開発します。

関連トピック:

Editable_Mesh : GeometryClass および TriMesh : 値

FileStream 値

全体の流れ:

最初に選択したオブジェクトのスナップショットを取得します。

出力ファイル名を定義します。

ファイル名を使用して新規ファイルを作成します。

メッシュ内の頂点と面の数を取得します。

頂点と面の数をファイルに出力します。

すべての頂点を巡回します。

位置を変数に読み取ります。

頂点の位置をファイルに書き出します。

すべての面を巡回します。

面の定義を変数に読み取ります。

面の定義をファイルに書き出します。

ファイルを閉じます。

ファイルを開いて、結果を確認します。

MAXScript

tmesh = snapshotAsMesh selection[1]
out_name = ((GetDir #export)+"/testmesh.dat")
out_file = createfile out_name
num_verts = tmesh.numverts
num_faces = tmesh.numfaces
format "%,%\n" num_verts num_faces to:out_file
for v = 1 to num_verts do
(
 vert = getVert tmesh v
 format "%," vert to:out_file
)
format "\n" to:out_file
for f = 1 to num_faces do
(
 face = getFace tmesh f
 format "%," face to:out_file
)
close out_file
delete tmesh
edit out_name

ステップごとの解説

tmesh = snapshotAsMesh selection[1]

シーン選択内で最初に検出されたオブジェクトの TriMesh スナップショットを作成します。このメソッドで、[スペース ワープ](Space Warp)バインドも含めて、モディファイヤ スタックの頂点の状態を評価します。その結果、シーンではなく、メモリ内に TriMesh 値が格納されます。シーン オブジェクトであるかのようにしてすべての頂点と面にアクセスすることができます。

この時点では、ユーザがシーン内のオブジェクトを選択したかどうか、および最初に選択したオブジェクトがジオメトリ クラスかどうかをまだチェックしていないことに注意してください。これは最終コードの単なるラフ スケッチです。ユーザが、有効なオブジェクトが選択されたことを確認する必要があります。チュートリアルの第 2 部で、このようなテストを追加します。

snapshotAsMesh

out_name = ((GetDir #export)+"/testmesh.dat")

次に、ファイルの書き込み先を含む変数を定義します。キーワードの #export を使用した GetDir 関数を使用して、書き込み操作用の 3ds Max システム パスの設定を取得します。ここでは、ファイル名 testmesh.dat を追加しています。この名前は、実際に使用する任意の有効な名前にすることができます。第 2 部では、ファイルを開くためのダイアログ ボックスを使用して、ユーザがパスとファイル名を選択できるようにします。

3ds Max システム ディレクトリ

out_file = createfile out_name

定義された出力パスを使用して新規ファイルを作成し、ユーザ変数の out_file に結果の fileStream 値を格納します。この変数を書き込み先として使用し、ファイルに出力することができます。

FileStream 値

num_verts = tmesh.numverts num_faces = tmesh.numfaces

作成した TriMesh 値には、シーン内の各メッシュ オブジェクトと同様に、プロパティの .numverts と .numfaces があります。両方の値がこれから何度も必要になるので、これらの値を取得してユーザ変数に格納します。

Editable_Mesh : GeometryClass および TriMesh : 値

format "%,%\n" num_verts num_faces to:out_file

ここで、初めてファイルに出力できます。コンマで区切った 2 つのユーザ要素を書き込むことを指定するフォーマット パターンを定義します。この行は、円記号と n で指定する改行の制御文字で終了します。 フォーマット文字列の後に、フォーマット文字列内の % 記号の数と同じ出力の式を用意する必要があります。

頂点と面の数がそれぞれ 8 と 12 の場合 (典型的なボックス)、出力結果は次のようになります。

8,12

フォーマット関数の最後の to: で出力先を指定します。指定しないと、既定により MAXScript リスナーに出力されます。

FileStream 値

for v = 1 to num_verts do (

次のステップで、メッシュのすべての頂点を出力します。1 で始まり TriMesh 内の頂点の数で終わる for ループを使用して、すべての頂点を巡回します。ループが繰り返されるごとに、変数 v の値が 1 から num_verts まで変化します。v の値が num_verts の値を超えたときに、ループが終了します。

for ループ

vert = getVert tmesh v

ループの変数内に現在格納されている値を使用して、tmesh 値に getVert メソッドを呼び出すことによって、対応するインデックス付きの頂点を取得します。その結果はユーザ変数に格納され、頂点のワールド位置を表わす Point3 の値 (3D 位置の値) になります。

Editable_Mesh : GeometryClass および TriMesh : 値

format "%," vert to:out_file

頂点の位置をファイルに書き出す必要があります。vert 変数の値にコンマを続けて出力するために、フォーマット文字列をフォーマット関数に指定します。改行は必要ありません。すべての頂点位置はコンマで区切られて単一の行に表示されます。

)

ここで v ループは終了し、v 変数が num_verts の値に達しないかぎり、for v ステートメントに戻ります。つまり、ブラケットで囲まれたブロックは、num_verts 内の数だけ繰り返されます。

format "\n" to:out_file

頂点のリストと面のリストを区切るために、単一の改行文字をファイルに出力します。% のプレースホルダを何も含めなかったので、フォーマット文字列にはユーザ式がないとみなされます。

for f = 1 to num_faces do (

面リストの出力は頂点リストのコードにとても似ています。ここでは、他の変数を使用します。

face = getFace tmesh f

さらに、頂点の位置の代わりに面の定義を取得します。平面定義も Point3 値ですが、位置の代わりに面を定義する 3 つの頂点へのインデックスを含みます。したがって、Point3 に格納された数値は、1 から num_verts までの間の整数です。この結果をユーザ変数の face に格納します。

format "%," face to:out_file

そしてそれを、頂点で行ったのと同じようにファイルに出力します。

)

ここで f ループは終了し、f 変数が num_faces の値に達しないかぎり、for f ステートメントに戻ります。つまり、ブラケットで囲まれたブロックは、num_faces 内の数だけ繰り返されます。

close out_file

最後に、ファイルを閉じ、読み取り用に開くことができるようにします。これを実行しないと、Windows OS によってファイルが開いているとマークされ、MAXScript で読み取ることができません。ファイルが明示的に閉じる前にスクリプトでエラーが発生した場合は、 gc() を呼び出して、ガベージ コレクションを実行することができます。この場合、ロックされているすべてのファイルが解除されるという影響があります。

delete tmesh

TriMesh の値を削除して、使用したメモリをガーベジ コレクションに解放します。これを行なわないと、スクリプトを複数回実行することによってメモリ リークが発生する可能性があります。

edit out_name

出力が予期したとおりになるように、MAXScript エディタ内でスクリプトの先頭に定義された名前のファイルを開きます。

ワールド原点にある単純な立方体の場合、出力は次のようになります。

立方体の出力例

8,12
[-50,-50,0],[50,-50,0],[-50,50,0],[50,50,0],[-50,-50,100],[50,-50,100],[-50,50,100],[50,50,100],
[1,3,4],[4,2,1],[5,6,8],[8,7,5],[1,2,6],[6,5,1],[2,4,8],[8,6,2],[4,3,7],[7,8,4],[3,1,5],[5,7,3],

スクリプトの使い方

スクリプトをテストするには、ジオメトリ オブジェクトを作成し、シーンでそのオブジェクトを選択して、MAXScript エディタのメニューから[ツール](Tools) > [評価](Evaluate)を選択するか、Ctrl+Eを押します。結果の出力ファイルが、新しい MAXScript エディタで開きます。

コードの最適化

前に説明したように、これはジオメトリを出力する基本コードです。このコードは、さらにコンパクトにすることができます。以下のコードは、エディタ内でプレビュー用にファイルを開かない、同じコードの短縮バージョンです。2 つのスクリプトを比較して、多少異なる表現があっても同じことを実行している理由を考えてください。

MAXScript

tmesh = snapshotAsMesh selection[1]
out_file = createfile ((GetDir #export)+"/testmesh.dat")
format "%,%\n" tmesh.numverts tmesh.numfaces to:out_file
for v = 1 to tmesh.numverts do
format "%," (getVert tmesh v)to:out_file
format "\n" to:out_file
for f = 1 to tmesh.numfaces do
format "%," (getFace tmesh f) to:out_file
close out_file

関連項目

ここで出力を入手したので、対応する入力スクリプトに進んでそのスクリプトを記述し、データを読み戻して新しいシーン オブジェクトを作成します。

チュートリアル - ジオメトリ データのテキスト ファイルからの読み取り - 第 1 部

また、「ジオメトリの出力」チュートリアルの第 2 部で、より堅牢でいくつかの機能を追加したコードを作成します。

戻る

「チュートリアル」のインデックス ページ

次へ

チュートリアル - ジオメトリ データのテキスト ファイルからの読み取り - 第 1 部

チュートリアル - ジオメトリ データのテキスト ファイルへの出力 - 第 2 部

チュートリアル - ジオメトリ データのテキスト ファイルからの読み取り - 第 2 部