建築でコンピュータ、する?
2025年1月20日(月) 04:17 JST
前回の更新から随分あいてしまいましたが、今回はGDLのプリミティブ要素と呼ばれるコマンド類を使ったモデリングについて紹介したいと思います。
GDLでは、BLOCK、CYLINDをはじめとして沢山の基本形状コマンドが用意されていますがやはりこれらのコマンドを駆使しても描けない(描きにくい)モデルというものは出てきてしまいます。例えば、下のような四面体のコマンドは用意されておらず、単純には描くことはできません。さて、この四面体をモデリングするにはどのような方法があるでしょうか?
まず一番目の方法としては、PLANEコマンドによって四枚の面を描く方法があります(PLANEについてはこちらを参照してください)。PLANEコマンドを使ってモデリングした場合、そのモデルはサーフェイスモデルになります。つまり、モデルは表面のみで構成されていて、中身は空です。サーフェイスモデルはソリッド演算を行う際に問題になることがあります。四面体から球体を減算すると下図左のようになり中身が空であることが確認でき、逆に球体から四面体を減算すると中身がないため下図右のように減算できません(分かりにくいため四面体をワイヤーフレームで表示しています)。また、このモデルの体積を積算で求めると0という結果が返ってきます。
二番目の方法は、ソリッド演算によって四面体を覆う程度の大きさの直方体から減算を行うといった方法です。この方法では、コードは複雑になるものの、中身が詰まったモデルを生成することができます。減算するための形状をパラメトリックに制御するのに手間が掛かりそうですね。
三番目の方法は今回紹介するプリミティブ要素と呼ばれるコマンドによってモデリングする方法です。GDLには、プリミティブ要素として、VERT(座標点)、TEVE(座標点+テクスチャ座標)、VECT(法線)などとビジュアル化を含めたコマンドがありますが、ここでは、三次元モデル(形状)の生成に必要なVERT(頂点)、VECT(法線)、EDGE(エッジ)、PGON(面)、BODYについて説明します。
早速ですが、上に示した四面体のコードを見てみましょう。GDLの基本形状コマンドでは、三次元の形状をひとつのコマンドで生成しますが、プリミティブ要素コマンドでは、三次元形状を構成する要素(プリミティブ要素)を各コマンドで定義していき、BASEとBODYで囲む※ことで形状を生成します。
※必ずしもこの限りではないようですが僕はBASEとBODYで囲んでしまうのが分かりやすいと考えています。
!!変数(座標値)に値を代入 x1 = 0.0 : y1 = 0.0 : z1 = 0.0 x2 = 2.5 : y2 = 2.0 : z2 = 0.8 x3 = 0.3 : y3 = 1.5 : z3 = 0.5 x4 = 1.0 : y4 = 1.0 : z4 = 2.0 !!プリミティブによるモデリングでは、簡単には頂点、 !!エッジ、面の順にプリミティブを定義していきます。 !!それぞれ、定義した順に1、2、3、、とindexが割り当てられます。 !!BASEコマンドは、indexのカウントをリセットする役割があります。 BASE !!頂点の定義 !!VERT x, y, z VERT x1, y1, z1 !v1(index: 1) VERT x2, y2, z2 !v2(index: 2) VERT x3, y3, z3 !v3(index: 3) VERT x4, y4, z4 !v4(index: 4) !!エッジの定義 !!EDGE vert1, vert2, pgon1, pgon2, status !!エッジの始点(vert1)と終点(vert2)と隣り合う面(pgon1、pgon2)を指定しエッジを定義。 !!隣り合う面は「-1」としておくと自動的に計算してくれるみたいです。 !!vert1、vert2はそれぞれindexで指定する必要があり、 !!↓のEDGEは、index: 1とindex: 3を繋ぐエッジなので、v1とv3を繋ぐエッジを意味します。 EDGE 1, 3, - 1, - 1, 0 !e1(index: 1) EDGE 3, 2, - 1, - 1, 0 !e2(index: 2) EDGE 2, 1, - 1, - 1, 0 !e3(index: 3) EDGE 1, 2, - 1, - 1, 0 !e4(index: 4) EDGE 2, 4, - 1, - 1, 0 !e5(index: 5) EDGE 4, 1, - 1, - 1, 0 !e6(index: 6) EDGE 2, 3, - 1, - 1, 0 !e7(index: 7) EDGE 3, 4, - 1, - 1, 0 !e8(index: 8) EDGE 4, 2, - 1, - 1, 0 !e9(index: 9) EDGE 1, 4, - 1, - 1, 0 !e10(index: 10) EDGE 4, 3, - 1, - 1, 0 !e11(index: 11) EDGE 3, 1, - 1, - 1, 0 !e12(index: 12) !!面(ポリゴン)の定義 !!PGON n, vect, status, edge1, edge2, ... , edgen !!n角形のポリゴンをedge1, edge2, ... , edgenをつなぐことで生成します。 !!面の法線(vect)は[0]としておくと自動的に計算してくれます。 !!エッジは一筆書きとなるように記述する必要があります。 !!エッジはベクトルであり方向を持っています。 !!逆向きのエッジはindexに「-」を付けて表します。 !!次のコードの説明では、「-」を付けることで同じ意味となるエッジを重複と呼んでいます。 PGON 3, 0, 0, 1, 2, 3 !p1(index: 1) PGON 3, 0, 0, 4, 5, 6 !p2(index: 2) PGON 3, 0, 0, 7, 8, 9 !p3(index: 3) PGON 3, 0, 0, 10, 11, 12 !p4(index: 4) !!ボディの生成 !!BODY status !!status: 1 は閉じたボディ、2は曲線を含むボディ、4はサーフェイスといった指定を行う。 BODY 1
下のような図を見ながらだと分かりやすいと思います。ちょっと見にくいですが、p1(index: 1)は底面(v1、v2、v3からなる面)、p2(index: 2)は向かって右側の面(v1、v2、v4からなる面)です。
このモデル、実は中身が空のサーフェイスモデルです。ソリッド演算に用いると、上で示したPLANEで描いた四面体と同じ挙動をします。"BODY 1"としてあるのに中身の詰まった閉じたボディとなっていないのは、エッジが重複(indexに「-」を付けると同じ意味となる)しているからです。上図でいうと、e3とe4は重複しており、e4は-e3として表すことができます。こういった重複を整理したコードが以下です。重複していたエッジをコメントしてからPGONで指定しているエッジのindexを指定しなおします。今度は中身の詰まったモデルが出来ていると思います。SUBGROUPなどを利用して中身が詰まっているか確認してみましょう。下図のように問題なくソリッド演算出来ています。
!!頂点の定義 VERT x1, y1, z1 !v1(index: 1) VERT x2, y2, z2 !v2(index: 2) VERT x3, y3, z3 !v3(index: 3) VERT x4, y4, z4 !v4(index: 4) !!エッジの定義 EDGE 1, 3, - 1, - 1, 0 !e1(index: 1) EDGE 3, 2, - 1, - 1, 0 !e2(index: 2) EDGE 2, 1, - 1, - 1, 0 !e3(index: 3) !!EDGE 1, 2, - 1, - 1, 0 !e4(index: 4→x)→ -e3 EDGE 2, 4, - 1, - 1, 0 !e5(index: 5→4) EDGE 4, 1, - 1, - 1, 0 !e6(index: 6→5) !!EDGE 2, 3, - 1, - 1, 0 !e7(index: 7→x)→ -e2 EDGE 3, 4, - 1, - 1, 0 !e8(index: 8→6) !!EDGE 4, 2, - 1, - 1, 0 !e9(index: 9→x)→ -e4 !!EDGE 1, 4, - 1, - 1, 0 !e10(index: 10→x)→ -e5 !!EDGE 4, 3, - 1, - 1, 0 !e11(index: 11→x)→ -e6 !!EDGE 3, 1, - 1, - 1, 0 !e12(index: 12→x)→ -e1 !!面(ポリゴン)の定義 PGON 3, 0, 0, 1, 2, 3 !p1(index: 1) PGON 3, 0, 0, -3, 4, 5 !p2(index: 2) PGON 3, 0, 0, -2, 6, -4 !p3(index: 3) PGON 3, 0, 0, -5, -6, -1 !p4(index: 4) !!ボディの生成 BODY 1
以上で今回のGDLメモはおしまいです。GDLリファレンスのプリミティブ要素のところを眺めてみると曲面の記述に関する記述がいくつかあることがわかります。実は、このプリミティブ要素によるモデリングにとって前回、前々回で扱ったメビウスの輪や掃引体を滑らかにモデリングすることが可能です。次回のGDLメモではプリミティブ要素を利用した滑らかな形状のモデリングについて紹介したいと思います。