BRepGraph:OCCT 8.0 で登場する新しいトポロジ・ジオメトリグラフ
Open CASCADE Technology(OCCT)の次期メジャーバージョン 8.0 に、BRepGraph という新しいデータモデルが導入されます。これは、境界表現(B-Rep)データをインデックスベース・変更追跡対応・アセンブリネイティブな形で扱うグラフモデルです。本記事では、BRepGraph の概要、既存の TopoDS/BRep モデルとの違い、そして何を可能にするのかを解説します。
背景:現在の TopoDS と BRep_T* の仕組み
OCCT の形状表現は、25 年以上にわたってプラットフォームの基盤となってきた 2 つの層から構成されています。
TopoDS はトポロジ層です。形状をオカレンスのツリーとして表現します。TopoDS_Solid が TopoDS_Shell を含み、各シェルが TopoDS_Face を含み、各フェイスが TopoDS_Wire を含み……と TopoDS_Vertex まで続きます。隣接する 2 つのフェイスが共有するエッジは、複数の親コンテキストに現れる同一の TopoDS_TShape ポインタで表されます。
BRep_T* はジオメトリ層です。BRep_TVertex は 3D 点を、BRep_TEdge は曲線表現のリストを、BRep_TFace はサーフェスハンドルや三角形メッシュ、トレランスを格納します。
このデザインは柔軟で実績もありますが、隣接クエリ・制御された変更・並列処理を必要とするアルゴリズムにとっては構造的な限界があります。
BRepGraph で何が変わるのか
BRepGraph は TopoDS を置き換えるものではありません。同じ B-Rep データの上に構築されたインデックスベースのグラフビューであり、TopoDS_Shape から構築し、逆変換も可能です。
1. オカレンスツリーから隣接テーブルへ
TopoDS では、あるエッジを共有するフェイスを探すには TopExp_Explorer でツリーを歩き、TopTools_IndexedDataMapOfShapeListOfShape のようなマップを構築する必要があります(O(N))。
BRepGraph では、トポロジがフラットなエンティティベクタと整数クロスリファレンスで格納されます。逆インデックス(エッジ→フェイス、頂点→エッジなど)により O(1) の上向きナビゲーションが可能です。ハッシュテーブルもポインタ比較も不要です。
2. 暗黙的な共有から明示的な同一性へ
BRepGraph はエンティティの同一性を 3 段階で定義します:
- NodeId(Kind + Index):エンティティの種類と位置によるアドレス。高速だが位置依存
- UID(Kind + Counter):単調増加するカウンタによる永続識別子。コンパクション後も有効
- RepId(Kind + Index):ジオメトリや三角形メッシュ表現へのアドレス。重複排除を可能にする
3. BRep_Tool ルックアップから直接 CoEdge アクセスへ
現在のモデルでは、特定のフェイス上のエッジの PCurve(パラメトリック曲線)を取得するために BRep_Tool::CurveOnSurface がリストを反復検索します。これはサーフェスハンドルや TopLoc_Location の一致に依存しており、脆弱な場合があります。
BRepGraph は Parasolid/Weiler のハーフエッジ規約に倣い、CoEdge エンティティを導入します。フェイス上のエッジの各使用に対して独自の CoEdge が存在し、UV 空間でのパラメトリック曲線、パラメータ範囲、UV 端点、方向などを直接所有します。シームエッジも自然に 2 つの CoEdge に分解されます。
4. 手動の無効化から RAII による変更管理へ
BRepGraph はスコープ付きの変更ガードを提供します:
{
auto aMutEdge = aGraph.MutEdge(anEdgeIdx);
aMutEdge->Tolerance = 0.01;
// スコープ終了時:MutationGen インクリメント、キャッシュクリア、
// 親エンティティへの変更フラグ伝播、レイヤー通知
}
バッチ操作には遅延無効化モードがあり、並列ループでのパフォーマンスを最大化します。
5. 外部アセンブリラッパーから組み込みプロダクトへ
現在の OCCT ではアセンブリ構造は XCAF 層に分離されています。BRepGraph ではアセンブリ構造が組み込みになり、Product(再利用可能な形状定義)と Occurrence(配置済みインスタンス)が Solid や Face と並ぶファーストクラスのノード種別として扱われます。
パフォーマンス
Apple M4(10 コア、16GB RAM)でのベンチマーク結果:
| 操作 | 改善率 |
|---|---|
| 隣接クエリ(10K フェイス) | 97% 高速化 |
| ソーイング 500 フェイス(並列) | 58% 高速化 |
| ソーイング 500 フェイス(逐次) | 44% 高速化 |
| 重複排除 + コンパクション | 43% 高速化 |
バンプポインタアロケータ、密なベクタ逆インデックス、KDTree 候補検索が主な要因です。
使い始め方
最小限のコード例:
#include <BRepGraph.hxx>
#include <BRepGraph_Tool.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
BRepGraph aGraph;
aGraph.Build(BRepPrimAPI_MakeBox(10, 20, 30).Shape());
int aNbFaces = aGraph.Defs().NbFaces(); // 6
int aFaceCount = aGraph.Defs().FaceCountOfEdge(0); // O(1) で隣接取得
const auto& aSurface = BRepGraph_Tool::Face::Surface(aGraph, 0);
TopoDS_Shape aFace = aGraph.Shapes().Node(BRepGraph_NodeId::Face(0));
// ワンライナーソーイング
TopoDS_Shape aSewn = BRepGraphAlgo_Sewing::Sew(aCompound, {.Tolerance = 1e-4});
TopExp_Explorer も TopTools_IndexedDataMap も BRep_Tool::CurveOnSurface によるサーフェスマッチングも不要です。
まとめ
BRepGraph は、トポロジアルゴリズム・形状修復・CAD データ交換のワークフローをより高速・安全・保守しやすいものにするために設計されています。OCCT 8.0 でリリース予定です。API はリリース前に変更される可能性がありますが、コアアーキテクチャと設計思想はこの記事で紹介した通りです。
参考