STL の読み込み2022年9月25日 | |
はじめにSTL ファイルの読み込みについて。 STL とはSTL は CAD で用いられるファイルフォーマットである。曲面を三角形の集まりで表す。フォーマットとして ASCII 形式とバイナリ形式がある。 ASCII 形式の読み込みたとえば、単純に三角形 1 つからなる形状が 2 つある場合は、次のようになる。 triangle.stl
solid triangle
facet normal 0 0 1
outer loop
vertex 0 0 0
vertex 1 0 0
vertex 1 1 0
endloop
endfacet
endsolid triangle
solid triangle2
facet normal 0 0 1
outer loop
vertex 0 0 0
vertex 1 1 0
vertex 0 1 0
endloop
endfacet
endsolid triangle2
STL は solid という単位で形状を扱う。 solid <name> ... endsolid <name> 任意の名前を指定できる (指定しない場合もある)。 solid は facet と呼ばれる三角形から構成される。
facet normal <nx> <ny> <nz>
outer loop
vertex <x1> <y1> <z1>
vertex <x2> <y2> <z2>
vertex <x3> <y3> <z3>
endloop
endfacet
...
facet ではまず面の表側の法線ベクトル (nx ny nz) を指定する。そのあと、三角形を構成する点 (vertex) の座標を指定する。手で打ち込むと間違えがちだが、"outer loop"、"endloop"、"endfacet" などの空白の有無は区別される ("end loop" としてはダメ)。 この形式の読み取り手順は、次のようになる。
mode: 読み取りモード (none, solid, facet, outer_loop)
vi: vertex のインデックス
while ファイルの末尾まで do
line に 1 行読み取る
line を空白で分割して、リストとして itmes に入れる
if mode = none
if items[0] = "solid" then
mode = solid
名前があれば読み取る
end if
else if mode = solid then
if items[0] = "facet" and items[1] = "normal" then
mode = facet
ベクトルを読み取る
vi = 0
else if items[0] = "endsolid" then
solid の読み取り完了処理
mode = mode_none
else
構文エラー
end if
else if mode = facet then
if items[0] = "outer" and items[1] = "loop"
mode = outer_loop
else if items[0] = "endfacet" then
facet の読み取り完了処理
mode = solid
else
構文エラー
end if
else if mode = outer_loop then
if items[0] = "vertex" then
if vi >= 3 then
構文エラー
else
ベクトルを読み取る
vi = vi + 1
end if
else if items[0] = "endloop" then
mode = facet
else
構文エラー
end if
else
内部エラー
end if
end do
バイナリ形式の読み込みバイナリ形式は単純である。最初にヘッダーと三角形の数がある。 header (80バイト) num_triangle (4バイト) あとは三角形の数の分だけ法線ベクトル、点3つ、あと謎の属性が並んでいる。 normal (4バイト x 3) vertex1 (4バイト x 3) vertex2 (4バイト x 3) vertex3 (4バイト x 3) attribute (2バイト) attribute は読み飛ばせばよいようである。 ASCIIとバイナリの判別ASCII かバイナリかを判別するには、1行読んでみて空行か "solid" が出てくるなら ASCII、そうでなければバイナリと判断すればよい (たぶん)。 参考 | |
| PENGUINITIS | |