布爾數(shù)據(jù) BOPDS_DS
eryar@163.com
1 Introduction
在OpenCASCADE中,布爾相關(guān)的算子Operator有General Fuse Operator(GFA),Boolean Operator(BOA),Section Operator(SA),Splitter Operator(SPA),這些布爾算子都共用一套數(shù)據(jù)結(jié)構(gòu)BOPDS_DS,其中存儲了輸入數(shù)據(jù)及中間結(jié)果數(shù)據(jù)。布爾算子包含兩部分:
- Intersection Part(IP)相交部分:相交部分IP主要用來計算模型之間的相交情況,并將計算結(jié)果保存到BOPDS_DS中;
- Building Part(BP)構(gòu)建部分:構(gòu)建部件BP從BOPDS_DS中獲取相交和其他數(shù)據(jù)來構(gòu)建相應(yīng)的結(jié)果;
由此可見,布爾數(shù)據(jù)BOPDS_DS是布爾操作中的數(shù)據(jù)中轉(zhuǎn)站,將布爾操作的輸入數(shù)據(jù)及中間計算結(jié)果數(shù)據(jù)都保存起來。本文主要介紹BOPDS_DS保存的數(shù)據(jù)。
2 BOPDS_DS
BOPDS_DS中存儲的信息有:
- Arguments:輸入模型數(shù)據(jù);
- Shapes:模型信息;
- Interferences:相交數(shù)據(jù);
- Pave Blocks:字面意思是鋪路磚,我理解的是對邊Edge分塊;
- Common Blocks:公共部分,邊與邊,邊與面的重疊部分;
這里的Shapes是模型信息BOPDS_ShapeInfo,存儲模型類型,包圍盒等數(shù)據(jù):

這里應(yīng)該不需要再另外保存myType,因為在myShape中可以直接獲取類型信息。模型信息在初始化函數(shù)Init()中來設(shè)置,主要是包圍盒等信息:
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void BOPDS_DS::Init(const Standard_Real theFuzz)
{
Standard_Integer i1, i2, j, aI, aNb, aNbS, aNbE, aNbSx;
Standard_Integer n1, n2, n3, nV, nW, nE, aNbF;
Standard_Real aTol, aTolAdd;
TopAbs_ShapeEnum aTS;
TopoDS_Iterator aItS;
TColStd_ListIteratorOfListOfInteger aIt1, aIt2, aIt3;
TopTools_ListIteratorOfListOfShape aIt;
BOPDS_IndexRange aR;
Handle(NCollection_BaseAllocator) aAllocator;
TopTools_MapOfShape aMS;
//
// 1 Append Source Shapes
aNb=myArguments.Extent();
if (!aNb) {
return;
}
//
myRanges.SetIncrement(aNb);
//
aNbS=0;
aIt.Initialize(myArguments);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSx=aIt.Value();
//
aNbSx=0;
TotalShapes(aSx, aNbSx, aMS);
//
aNbS=aNbS+aNbSx;
}
aMS.Clear();
//
myLines.SetIncrement(2*aNbS);
//-----------------------------------------------------scope_1 f
aAllocator=
NCollection_BaseAllocator::CommonBaseAllocator();
//
//
i1=0;
i2=0;
aIt.Initialize(myArguments);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS=aIt.Value();
if (myMapShapeIndex.IsBound(aS)) {
continue;
}
aI=Append(aS);
//
InitShape(aI, aS);
//
i2=NbShapes()-1;
aR.SetIndices(i1, i2);
myRanges.Append(aR);
i1=i2+1;
}
//
aTolAdd = Max(theFuzz, Precision::Confusion()) * 0.5;
myNbSourceShapes = NbShapes();
//
// 2 Bounding Boxes
//
// 2.1 Vertex
for (j=0; j<myNbSourceShapes; ++j) {
BOPDS_ShapeInfo& aSI=ChangeShapeInfo(j);
//
const TopoDS_Shape& aS=aSI.Shape();
//
aTS=aSI.ShapeType();
//
if (aTS==TopAbs_VERTEX) {
Bnd_Box& aBox=aSI.ChangeBox();
const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aS);
const gp_Pnt& aP=BRep_Tool::Pnt(aV);
aTol = BRep_Tool::Tolerance(aV);
aBox.SetGap(aTol + aTolAdd);
aBox.Add(aP);
}
}
在初始化函數(shù)中通過兩個遞歸函數(shù)TotalShapes()和InitShape()來收集所有模型數(shù)據(jù),然后再分別計算點、邊、面的包圍盒。這些包圍盒數(shù)據(jù)為后面使用BVH相交檢測做準備。
3 Interferences
相交數(shù)據(jù)Interferences主要用來保存求交結(jié)果數(shù)據(jù),使用了簡單的派生關(guān)系,不同的相交類型得到不同的相交結(jié)果。

保存的數(shù)據(jù)有:

其中Index1和Index2為相交的兩個模型在BOPDS_DS中的索引號。對于點Vertex和邊Edge的相交結(jié)果,保存了相交點在邊上的參數(shù)myParam:

4 DRAW
在DRAW中輸入相關(guān)的命令可以方便地對這些數(shù)據(jù)結(jié)構(gòu)進行Debug。

從源碼可以看出,在做求交的初始函數(shù)中準備了三部分數(shù)據(jù),一個是BOPDS_DS,一個是BOPDS_Iterator,還有一部分是緩存的求交工具的數(shù)據(jù)IntTools_Context。后面將結(jié)合DRAW代碼對C++源碼調(diào)試,分析布爾操作中求交數(shù)據(jù)BOPDS_DS保存的具體數(shù)據(jù)。