やかんブログ

ポリゴンのお手軽DXF出力 by ruby

2008年08月11日(月)09:00|天方

頂点データのDXFファイルへの変換

最近、3Dポリゴンデータのデータ(しかも形式が一般的でないもの)を扱うことがありました。とりあえず出力されたデータを3Dモデラー等で確認したかったので、昔にRubyで書いた3DデータのDXF出力ルーチンを修正して使ってみました。

ASCII形式のDXFフォーマットは非常に構造が単純なフォーマットです。

具体的には、

[Code1]
[Value1]
[Code2]
[Value2]
・・・
[Code n]
[Value n]

のようにコードと値が連なっている形になっています。 DXFでは、コードと値のペアをグループと呼びます。

これらのデータを出力するRubyのクラスを作成してみました。

実装の基本方針としては

  1. データはコンストラクタで設定し、その後オブジェクトが変化するようなことはない。
  2. DXFのある定義要素は一つのクラスになっている

です。1はデータの生成タイミング等がシンプルになるのでとりあえず素早くプロトタイピングするにはいい方法ではないかと思います。2は見通しのよさ、拡張のしやすさを得るためです。

まずグループは、

class DXFGroup
  def initialize(code, value)
    @code = code
    @value = value
  end
  def to_s
    sprintf("%3d\n%s\n", @code, @value)
  end
end

としてクラス化してみました。

次にグループの連なりは

class DXFGroups
  def initialize(groups)
    @groups = groups
  end
  def to_s
    @groups.collect{|group| group.to_s}.join
  end
end

で表現してみました。

あとは、DXFの仕様にしたがって、ポリゴンなら、この形式、 メッシュならこの形式と出力するクラスを定義していけばいいだけです。

たとえば、1枚の3角ポリゴンは次のような形式になります。

  0
3DFACE
  8
[名前]
 10
[x1]
 20
[y1]
 30
[z1]
 11
[x2]
 21
[y2]
 31
[z2]
 12
[x3]
 22
[y3]
 32
[z3]
 13
[x3]
 23
[y3]
 33
[z3]

これをクラスで記述するとこんな感じになります。

class DXF3DFace < DXFGroups
  def initialize(name, x1, y1, z1, x2, y2, z2, x3, y3, z3)
    super( [
      DXFGroup.new("0", "3DFACE"), # Entity type
      DXFGroup.new("8", name),     # Layer name
      DXFGroup.new("10", x1.to_s), # X1 value
      DXFGroup.new("20", y1.to_s), # Y1 value
      DXFGroup.new("30", z1.to_s), # Z1 value
      DXFGroup.new("11", x2.to_s), # X2
      DXFGroup.new("21", y2.to_s), # Y2
      DXFGroup.new("31", z2.to_s), # Z2
      DXFGroup.new("12", x3.to_s), # X3
      DXFGroup.new("22", y3.to_s), # Y3
      DXFGroup.new("32", z3.to_s), # Z3
      DXFGroup.new("13", x3.to_s), # 三角3DFaceの場合X3と同じ
      DXFGroup.new("23", y3.to_s), # 三角3DFaceの場合Y3と同じ
      DXFGroup.new("33", z3.to_s), # 三角3DFaceの場合Z3と同じ
      ])
  end
end

より詳しい仕組みは、添付ファイルでご覧ください。

DXF変換のRubyスクリプト

ただ添付のコードは

  1. 3DFACEのみ対応
  2. 本来は、あるXML形式からDXFファイルを出力するコードだったが、簡略化のためテキスト形式からの変換としている。

ので注意が必要です。

rubyで記述すると、XMLなど他形式からの読み込みも結構楽なのでいいですね。

この記事に関するお問い合わせはこちら

ページの先頭へ