トポロジーオブジェクトの種類
OpenCASCADE には、次のようなトポロジカルな形状があります。※トポロジーとジオメトリーに関しては、別記事をご覧ください。
- Vertex バーテックス
ジオメトリの Point に相当する0次元の形状。 - Edge エッジ
始終点に Vertex を持つ曲線や直線。 - Wire ワイヤ
連続した Edge の集合。曲線を含む複数のEdgeからなるポリラインや、閉じた輪形状などを表わす。単にEdge が複数連なっているだけではなく、どのEdgeがどのEdgeに連結しているか、という結びつけの情報や、「自身が Closed であるか」(輪形状か)という属性値を持つ。
- Face フェイス
閉じたWireによって囲まれた曲面。平面も含む。 - Shell シェル
Edgeにより連結されたFaceの集合。複数の面から構成されたものや、閉じた空間などを表す。Faceを並べただけではなく、あるFaceは別のFaceと、あるEdgeを共有して連結している、という結びつけの情報を持つ。
- Solid ソリッド
閉じたシェルによって構成される空間を内と外に分けたもの。空間が分けられることにより、ボリューム(容積)を計算することが可能。シェルを空の箱に例えると、ソリッドは中身が積まった固体。 - CompSolid コンプ・ソリッド
Faceにより連結された Solid の集合。 - Compound コンパウンド
上記、7種類を全て含むことができる「複合体」。種類の違う一つ以上のオブジェクトをまとめる為に利用される形状なので、「形状のグループ」として考えても相違ない。Compound自身もCompoundの中に詰め込むことができる。
それぞれ、プログラムコード中では、TopoDS_Edge や TopoDS_Face というように、TopoDS_ 接頭辞が付きます。また、これらの形状をまとめて Shape (形状)と言い、TopoDS_Shape 型で表わされます。TopoDS_Shape 型は、これらの形状の型の親クラスとなっているので、ワイルドカード的な利用ができます。
TopoDS_Shape 型
OpenCASCADE では、幾何演算の結果をよく TopoDS_Shape 型でユーザに返却します。これは、前述のとおり、点だろうが面だろうが関係なく、漠然と「形状(Shape)」を表している型なので、ユーザが正しく形状を扱うには、Shape の実体として何が詰まっているかを知らなければなりません。そこで、TopoDS_Shape には、ShapeType() というメンバ関数が準備されており、このタイプを見ることによって、TopoDS_Edge や TopoDS_Face に安全にダウンキャストすることができます。
[cpp]
// 何らかの処理で Shape 型の S を受け取る
TopoDS_Shape S = …
if (S.ShapeType() == TopAbs_FACE) { // Face かな?
TopoDS_Face F = TopoDS::Face(S); // Shape を Face にダウンキャスト
…
}
else …
[/cpp]
ShapeType() の戻り値はTopAbs_ShapeEnum 列挙型で、この列挙型の内容は上で紹介した型と対応しています。また、TopoDS_Shape のそれぞれの派生クラスへのダウンキャストは、TopoDS::Face(S) のように行ないます。
トポロジー・エクスプローラ
上で紹介したとおり、ある形状は子要素となる形状によって構成されています。例えばFaceの場合、Faceを構成しているWireやEdge、Vertexといった子要素が含まれています。これらの親要素と子要素は、ともにトポロジカルな関係を持っていますので、例えば、Edgeの集合(つまりWire)からFaceを作成した後に、Edgeの一部を変更した場合、それに追従してFaceの形状も変化することになります。
ある形状を構成している子要素を取得するには、トポロジー・エクスプローラ TopExp_Explorer を用います。
[cpp]
// ソリッド作成
gp_Pnt opos(0.0, 0.0, 0.0);
BRepPrimAPI_MakeBox box(opos, 10.0, 10.0, 10.0);
TopoDS_Solid solid = box.Solid();
// ソリッドに対し、構成要素のFaceを取得するエクスプローラを作成
TopExp_Explorer ex(solid, TopAbs_FACE);
// Face を取得
for (; ex.More(); ex.Next()) {
TopoDS_Face face = TopoDS::Face(ex.Current());
std::cout << "Face: " << face.HashCode(0xFF) << std::endl;
}
[/cpp]
上記のように、対象物を solid とし、取得したい型の TopAbs_FACE を指定して TopExp_Explorer のインスタンスを作成してあげます。TopExp_Explorer はイテレータ型ではありませんが、イテレータのように振る舞うオブジェクトですので、::More() や ::Next()、::Current() メソッドを使って、構成している子要素を取得していきます。列挙される順番は保証されていないようです。
上記の例では、6 枚の Face を取得することができます。また、取得した子要素 Face に対して、さらに別のエクスプローラ(TopAbs_EDGE を指定)を作成して、Edge を取ってくることもできますし、直に TopAbs_VERTEX を指定すると子要素の Vertex を取得することも可能です。
[cpp]
TopExp_Explorer ex(solid, TopAbs_FACE);
for (; ex.More(); ex.Next()) {
TopoDS_Face face = TopoDS::Face(ex.Current());
// エクスプローラで取得したFaceに対して、今度はFaceを構成するEdgeを取得しに行く
TopExp_Explorer ex_edge(face, TopAbs_EDGE);
for (; ex_edge.More(); ex_edge.Next()) {
TopoDS_Edge edge = TopoDS::Edge(ex_edge.Current());
…
}
}
[/cpp]
本日のまとめ
- OpenCASCADE のトポロジー形状には、Vertex、Edge、Wire、Face、Shell、Solid、CompSolid、Compaundがある。
- これらの型は、総じてShape(TopoDS_Shape)として扱われる。
- Shape オブジェクトの内容物は ShapeType() で判別できる。また、TopoDS::トポロジー形状の名前(TopoDS_Shapeオブジェクト)でダウンキャストができる。
- トポロジー形状を構成する子要素の取得は、トポロジーエクスプローラ(TopExp_Explorer)を用いる。
[…] OpenCASCADE では、標準のファイル形式として OpenCASCADE BRep ファイルというものを用いています。一般的に BREP というと、Boundary REPresentation (境界表現) 自体のことを差しますが、ここでは、「OpenCASCADE で表現できるトポロジー形状を保存するためのファイルフォーマット」とし区別して、BRepファイルと呼ぶことにします。 […]