1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

0024157: Parallelization of assembly part of BO

The branch CR24157_12 deals with the parallelization of building the solids in case of lot internal faces.
Test case for issue CR24157
This commit is contained in:
pkv
2014-06-26 13:00:17 +04:00
committed by apn
parent 2d2aa6f1a6
commit 465d1fba7c
10 changed files with 501 additions and 145 deletions

View File

@@ -14,7 +14,7 @@
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//
#include <BOPAlgo_BuilderSolid.ixx>
//
#include <NCollection_List.hxx>
@@ -61,10 +61,13 @@
#include <BOPCol_MapOfShape.hxx>
#include <BOPCol_BoxBndTree.hxx>
#include <BOPCol_ListOfInteger.hxx>
#include <BOPCol_NCVector.hxx>
#include <BOPCol_TBB.hxx>
//
#include <BOPTools.hxx>
#include <BOPTools_CoupleOfShape.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BOPTools_AlgoTools3D.hxx>
//
#include <IntTools_Context.hxx>
//
@@ -127,14 +130,143 @@ class BOPAlgo_BuilderSolid_ShapeBox {
Bnd_Box myBox;
};
//
typedef NCollection_DataMap\
<Standard_Integer, BOPAlgo_BuilderSolid_ShapeBox, TColStd_MapIntegerHasher> \
BOPAlgo_DataMapOfIntegerBSSB;
typedef NCollection_DataMap
<Standard_Integer,
BOPAlgo_BuilderSolid_ShapeBox,
TColStd_MapIntegerHasher> BOPAlgo_DataMapOfIntegerBSSB;
//
typedef BOPAlgo_DataMapOfIntegerBSSB::Iterator \
typedef BOPAlgo_DataMapOfIntegerBSSB::Iterator
BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB;
//
//=======================================================================
//function : BOPAlgo_FacePnt
//purpose :
//=======================================================================
class BOPAlgo_FacePnt {
public:
BOPAlgo_FacePnt() {
}
//
virtual ~BOPAlgo_FacePnt() {
}
//
void SetFace(const TopoDS_Face& aFace) {
myFace=aFace;
}
//
const TopoDS_Face& Face()const {
return myFace;
}
//
void SetPnt(const gp_Pnt& aPnt) {
myPnt=aPnt;
}
//
const gp_Pnt& Pnt()const {
return myPnt;
}
//
protected:
gp_Pnt myPnt;
TopoDS_Face myFace;
};
//
typedef BOPCol_NCVector
<BOPAlgo_FacePnt> BOPAlgo_VectorOfFacePnt;
//
//=======================================================================
//function : BOPAlgo_FaceSolid
//purpose :
//=======================================================================
class BOPAlgo_FaceSolid : public BOPAlgo_Algo {
public:
DEFINE_STANDARD_ALLOC
BOPAlgo_FaceSolid() :
myIsInternalFace(Standard_False) {
}
//
virtual ~BOPAlgo_FaceSolid() {
}
//
void SetFace(const TopoDS_Face& aFace) {
myFace=aFace;
}
//
const TopoDS_Face& Face()const {
return myFace;
}
//
void SetSolid(const TopoDS_Solid& aSolid) {
mySolid=aSolid;
}
//
const TopoDS_Solid& Solid()const {
return mySolid;
}
//
void SetPnt(const gp_Pnt& aPnt) {
myPnt=aPnt;
}
//
const gp_Pnt& Pnt()const {
return myPnt;
}
void SetContext(const Handle(IntTools_Context)& aContext) {
myContext=aContext;
}
//
const Handle(IntTools_Context)& Context()const {
return myContext;
}
//
Standard_Boolean IsInternalFace() const {
return myIsInternalFace;
}
//
virtual void Perform () {
TopAbs_State aState;
//
BOPAlgo_Algo::UserBreak();
//
aState=BOPTools_AlgoTools::ComputeState(myPnt, mySolid,
1.e-14, myContext);
//
myIsInternalFace=(aState==TopAbs_IN);
}
//
protected:
Standard_Boolean myIsInternalFace;
gp_Pnt myPnt;
TopoDS_Face myFace;
TopoDS_Solid mySolid;
Handle(IntTools_Context) myContext;
};
//=======================================================================
typedef BOPCol_NCVector
<BOPAlgo_FaceSolid> BOPAlgo_VectorOfFaceSolid;
//
typedef BOPCol_TBBContextFunctor
<BOPAlgo_FaceSolid,
BOPAlgo_VectorOfFaceSolid,
Handle(IntTools_Context),
IntTools_Context> BOPAlgo_FaceSolidFunctor;
//
typedef BOPCol_TBBContextCnt
<BOPAlgo_FaceSolidFunctor,
BOPAlgo_VectorOfFaceSolid,
Handle(IntTools_Context)> BOPAlgo_FaceSolidCnt;
//
//=======================================================================
typedef NCollection_DataMap
<TopoDS_Shape,
gp_Pnt,
TopTools_ShapeMapHasher> BOPAlgo_DataMapOfShapePnt;
typedef BOPAlgo_DataMapOfShapePnt::Iterator
BOPAlgo_DataMapIteratorOfDataMapOfShapePnt;
//
//=======================================================================
//function :
//purpose :
//=======================================================================
@@ -252,7 +384,10 @@ void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
if (!myShapesToAvoid.Contains(aF)) {
BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
BOPTools::MapShapesAndAncestors(aF,
TopAbs_EDGE,
TopAbs_FACE,
aMEF);
}
}
aNbE=aMEF.Extent();
@@ -442,7 +577,8 @@ void BOPAlgo_BuilderSolid::PerformAreas()
BOPCol_ListIteratorOfListOfInteger aItLI;
BOPCol_BoxBndTreeSelector aSelector;
BOPCol_BoxBndTree aBBTree;
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
NCollection_UBTreeFiller
<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
BOPAlgo_DataMapOfIntegerBSSB aDMISB(100);
BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB;
BOPCol_DataMapOfShapeListOfShape aMSH;
@@ -628,101 +764,206 @@ void BOPAlgo_BuilderSolid::PerformInternalShapes()
return;
}
//
Standard_Boolean bIsInternalFace;
Standard_Integer k, aNbVFS, aNbSLF, aNbVFP, aNbF, aNbA;
BRep_Builder aBB;
TopoDS_Iterator aIt;
BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
BOPCol_MapIteratorOfMapOfShape aItMF;
//
BOPCol_MapOfShape aMF, aMFP, aMFx;
BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
TopExp_Explorer aExp;
BOPCol_ListIteratorOfListOfShape aItLS;
BOPCol_MapOfShape aMFs;
BOPCol_ListOfShape aLSI;
BOPAlgo_VectorOfFaceSolid aVFS;
BOPAlgo_VectorOfFacePnt aVFP;
BOPCol_ListIteratorOfListOfInteger aItLI;
BOPCol_BoxBndTreeSelector aSelector;
BOPCol_BoxBndTree aBBTree;
NCollection_UBTreeFiller
<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
//
// 1. All internal faces
aShellIt.Initialize(myLoopsInternal);
for (; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aShell=aShellIt.Value();
aNbA=myAreas.Extent();
//
// 1. aVFP
aItLS.Initialize(myLoopsInternal);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aShell=aItLS.Value();
aIt.Initialize(aShell);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
aMF.Add(aF);
}
}
aNbFI=aMF.Extent();
//
// 2 Process solids
aSolidIt.Initialize(myAreas);
for ( ; aSolidIt.More(); aSolidIt.Next()) {
TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aSolidIt.Value()));
//
TopExp_Explorer anExpSol(aSolid, TopAbs_FACE);;
for (; anExpSol.More(); anExpSol.Next()) {
const TopoDS_Shape& aF = anExpSol.Current();
TopoDS_Shape aFF=aF;
const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
//
aFF.Orientation(TopAbs_FORWARD);
aMFx.Add(aFF);
aFF.Orientation(TopAbs_REVERSED);
aMFx.Add(aFF);
}
aMEF.Clear();
BOPTools::MapShapesAndAncestors(aSolid,
TopAbs_EDGE, TopAbs_FACE,
aMEF);
//
// 2.1 Separate faces to process aMFP
aMFP.Clear();
aItMF.Initialize(aMF);
for (; aItMF.More(); aItMF.Next()) {
const TopoDS_Face& aF=(*(TopoDS_Face*)(&aItMF.Key()));
if (!aMFx.Contains(aF)) {
if (BOPTools_AlgoTools::IsInternalFace(aF,
aSolid,
aMEF,
1.e-14,
myContext)) {
aMFP.Add(aF);
if (aMFs.Add(aF)) {
gp_Pnt aP;
gp_Pnt2d aP2D;
//
if (aNbA) {
BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2D, myContext);
}
//
BOPAlgo_FacePnt& aFP=aVFP.Append1();
aFP.SetFace(aF);
aFP.SetPnt(aP);
}
}
aMFx.Clear();
}
//
if (!aNbA) {
// 7b. "Rest" faces treatment
TopoDS_Solid aSolid;
aBB.MakeSolid(aSolid);
//
MakeInternalShells(aMFs, aLSI);
//
aItLS.Initialize(aLSI);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aSI=aItLS.Value();
aBB.Add (aSolid, aSI);
}
myAreas.Append(aSolid);
//
return; // =>
}//if (!aNbA) {
//
// 2. Prepare TreeFiller
aNbVFP=aVFP.Extent();
for(k=0; k<aNbVFP; ++k) {
Bnd_Box aBox;
//
const BOPAlgo_FacePnt& aFP=aVFP(k);
const TopoDS_Face& aF=aFP.Face();
//
BRepBndLib::Add(aF, aBox);
aTreeFiller.Add(k, aBox);
}
//
aTreeFiller.Fill();
//
// 3. Face/Solid candidates: aVFS
aItLS.Initialize(myAreas);
for (; aItLS.More(); aItLS.Next()) {
Bnd_Box aBox;
//
TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aItLS.Value()));
BRepBndLib::Add(aSolid, aBox);
//
aMFs.Clear();
aExp.Init(aSolid, TopAbs_FACE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Shape& aFs=aExp.Current();
aMFs.Add(aFs);
}
//
aSelector.Clear();
aSelector.SetBox(aBox);
//
aNbF=aBBTree.Select(aSelector);
//
const BOPCol_ListOfInteger& aLI=aSelector.Indices();
aItLI.Initialize(aLI);
for (; aItLI.More(); aItLI.Next()) {
k=aItLI.Value();
const BOPAlgo_FacePnt& aFP=aVFP(k);
const TopoDS_Face& aF=aFP.Face();
if (aMFs.Contains(aF)) {
continue;
}
//
const gp_Pnt& aP=aFP.Pnt();
//
BOPAlgo_FaceSolid& aFS=aVFS.Append1();
aFS.SetPnt(aP);
aFS.SetFace(aF);
aFS.SetSolid(aSolid);
}
}
//
aNbVFS=aVFS.Extent();
if (!aNbVFS) {
return;
}
// 4. Refine candidares
//=============================================================
BOPAlgo_FaceSolidCnt::Perform(myRunParallel, aVFS, myContext);
//=============================================================
//
// 5. Solid/Faces: aMSLF
BOPCol_IndexedDataMapOfShapeListOfShape aMSLF;
BOPCol_MapOfShape aMFProcessed;
//
for (k=0; k < aNbVFS; ++k) {
const BOPAlgo_FaceSolid& aFS=aVFS(k);
//
const TopoDS_Solid& aSolid=aFS.Solid();
const TopoDS_Face& aF=aFS.Face();
//
bIsInternalFace=aFS.IsInternalFace();
if (!bIsInternalFace) {
continue;
}
//
if (aMSLF.Contains(aSolid)) {
BOPCol_ListOfShape& aLF=aMSLF.ChangeFromKey(aSolid);
aLF.Append(aF);
}
else {
BOPCol_ListOfShape aLF;
//
aLF.Append(aF);
aMSLF.Add(aSolid, aLF);
}
}// for (k=0; k < aNbVE; ++k) {
//
// 6. Update Solids by internal Faces
aNbSLF=aMSLF.Extent();
for (k=1; k <= aNbSLF; ++k) {
const TopoDS_Shape& aSolid=aMSLF.FindKey(k);
TopoDS_Shape *pSolid=(TopoDS_Shape*)&aSolid;
//
const BOPCol_ListOfShape& aLF=aMSLF(k);
//
aMFs.Clear();
aItLS.Initialize(aLF);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aF=aItLS.Value();
aMFs.Add(aF);
aMFProcessed.Add(aF);
}
//
// 2.2 Make Internal Shells
aLSI.Clear();
MakeInternalShells(aMFP, aLSI);
MakeInternalShells(aMFs, aLSI);
//
// 2.3 Add them to aSolid
aShellIt.Initialize(aLSI);
for (; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aSI=aShellIt.Value();
aBB.Add (aSolid, aSI);
aItLS.Initialize(aLSI);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aSI=aItLS.Value();
aBB.Add (*pSolid, aSI);
}
}
//
// 7. "Rest" faces treatment (if there are)
aMFs.Clear();
for (k=0; k < aNbVFS; ++k) {
const BOPAlgo_FaceSolid& aFS=aVFS(k);
//
// 2.4 Remove faces aMFP from aMF
aItMF.Initialize(aMFP);
for (; aItMF.More(); aItMF.Next()) {
const TopoDS_Shape& aF=aItMF.Key();
aMF.Remove(aF);
const TopoDS_Face& aF=aFS.Face();
if (!aMFProcessed.Contains(aF)) {
aMFs.Add(aF);
}
//
aNbFI=aMF.Extent();
if (!aNbFI) {
break;
}
} //for ( ; aSolidIt.More(); aSolidIt.Next()) {
}
//
aNbFI=aMFs.Extent();
if (aNbFI) {
TopoDS_Solid aSolid;
aBB.MakeSolid(aSolid);
//
MakeInternalShells(aMF, aLSI);
aShellIt.Initialize(aLSI);
for (; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aSI=aShellIt.Value();
aLSI.Clear();
MakeInternalShells(aMFs, aLSI);
//
aItLS.Initialize(aLSI);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aSI=aItLS.Value();
aBB.Add (aSolid, aSI);
}
myAreas.Append(aSolid);
}
}
//=======================================================================
//function : MakeInternalShells
//purpose :