布爾數(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,其中存儲(chǔ)了輸入數(shù)據(jù)及中間結(jié)果數(shù)據(jù)。布爾算子包含兩部分:
- Intersection Part(IP)相交部分:相交部分IP主要用來(lái)計(jì)算模型之間的相交情況,并將計(jì)算結(jié)果保存到BOPDS_DS中;
- Building Part(BP)構(gòu)建部分:構(gòu)建部件BP從BOPDS_DS中獲取相交和其他數(shù)據(jù)來(lái)構(gòu)建相應(yīng)的結(jié)果;
由此可見(jiàn),布爾數(shù)據(jù)BOPDS_DS是布爾操作中的數(shù)據(jù)中轉(zhuǎn)站,將布爾操作的輸入數(shù)據(jù)及中間計(jì)算結(jié)果數(shù)據(jù)都保存起來(lái)。本文主要介紹BOPDS_DS保存的數(shù)據(jù)。
2 BOPDS_DS
BOPDS_DS中存儲(chǔ)的信息有:
- Arguments:輸入模型數(shù)據(jù);
- Shapes:模型信息;
- Interferences:相交數(shù)據(jù);
- Pave Blocks:字面意思是鋪路磚,我理解的是對(duì)邊Edge分塊;
- Common Blocks:公共部分,邊與邊,邊與面的重疊部分;
這里的Shapes是模型信息BOPDS_ShapeInfo,存儲(chǔ)模型類型,包圍盒等數(shù)據(jù):

這里應(yīng)該不需要再另外保存myType,因?yàn)樵趍yShape中可以直接獲取類型信息。模型信息在初始化函數(shù)Init()中來(lái)設(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ù)中通過(guò)兩個(gè)遞歸函數(shù)TotalShapes()和InitShape()來(lái)收集所有模型數(shù)據(jù),然后再分別計(jì)算點(diǎn)、邊、面的包圍盒。這些包圍盒數(shù)據(jù)為后面使用BVH相交檢測(cè)做準(zhǔn)備。
3 Interferences
相交數(shù)據(jù)Interferences主要用來(lái)保存求交結(jié)果數(shù)據(jù),使用了簡(jiǎn)單的派生關(guān)系,不同的相交類型得到不同的相交結(jié)果。

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

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

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

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