ポリゴンのお手軽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のクラスを作成してみました。
実装の基本方針としては
- データはコンストラクタで設定し、その後オブジェクトが変化するようなことはない。
- 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スクリプト
ただ添付のコードは
- 3DFACEのみ対応
- 本来は、あるXML形式からDXFファイルを出力するコードだったが、簡略化のためテキスト形式からの変換としている。
ので注意が必要です。
rubyで記述すると、XMLなど他形式からの読み込みも結構楽なのでいいですね。