1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-05 18:16:23 +03:00
occt/src/BOPAlgo/BOPAlgo_BuilderSolid.cxx
isn 488e5b9da0 0026515: Exponential memory usage problems with BOPDS_IndexedMapOfPaveBlock and NCollection_IncAllocator
Correcting the usage of NCollection_IncAllocator

Conflicts:
	src/BOPAlgo/BOPAlgo_BOP.cxx
	src/BOPAlgo/BOPAlgo_Builder.cxx
	src/BOPAlgo/BOPAlgo_BuilderSolid.cxx
	src/BOPAlgo/BOPAlgo_Builder_2.cxx
	src/BOPAlgo/BOPAlgo_MakerVolume.cxx
	src/BOPAlgo/BOPAlgo_PaveFiller.cdl
	src/BOPAlgo/BOPAlgo_PaveFiller_1.cxx
	src/BOPAlgo/BOPAlgo_PaveFiller_10.cxx
	src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx
	src/BOPAlgo/BOPAlgo_PaveFiller_4.cxx
	src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
	src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
	src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
	src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx
	src/BOPAlgo/BOPAlgo_Section.cxx
	src/BOPDS/BOPDS_DS.cxx
	src/BOPDS/BOPDS_Iterator.cxx
	src/BOPDS/BOPDS_IteratorSI.cxx
	src/BOPDS/BOPDS_SubIterator.cxx
	src/BOPTest/BOPTest_BOPCommands.cxx
	src/BOPTest/BOPTest_PartitionCommands.cxx
	src/IntTools/IntTools_Context.cxx

additional corrections

Adaptation of test case bugs fclasses bug7287_1 (limit for detection of memory leak reduced due to leak reduction)

Adjusting test-case bugs fclasses bug7287_1
2015-09-17 17:00:57 +03:00

1082 lines
28 KiB
C++

// Created by: Peter KURNEV
// Copyright (c) 2010-2014 OPEN CASCADE SAS
// Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
// Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
// EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
//
#include <BOPAlgo_BuilderSolid.hxx>
#include <BOPAlgo_ShellSplitter.hxx>
#include <BOPCol_BoxBndTree.hxx>
#include <BOPCol_DataMapOfShapeListOfShape.hxx>
#include <BOPCol_DataMapOfShapeShape.hxx>
#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
#include <BOPCol_IndexedDataMapOfShapeShape.hxx>
#include <BOPCol_ListOfInteger.hxx>
#include <BOPCol_ListOfShape.hxx>
#include <BOPCol_MapOfOrientedShape.hxx>
#include <BOPCol_MapOfShape.hxx>
#include <BOPCol_NCVector.hxx>
#include <BOPCol_Parallel.hxx>
#include <BOPTools.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BOPTools_AlgoTools3D.hxx>
#include <BOPTools_CoupleOfShape.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepBndLib.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
#include <gp_Dir.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <IntTools_Context.hxx>
#include <NCollection_DataMap.hxx>
#include <NCollection_List.hxx>
#include <NCollection_UBTreeFiller.hxx>
#include <TColStd_MapIntegerHasher.hxx>
#include <TopAbs.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
//
static
Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
const BOPCol_IndexedMapOfShape& );
static
Standard_Boolean IsHole(const TopoDS_Shape& ,
Handle(IntTools_Context)& );
static
Standard_Boolean IsInside(const TopoDS_Shape& ,
const TopoDS_Shape& ,
Handle(IntTools_Context)& );
static
void MakeInternalShells(const BOPCol_IndexedMapOfShape& ,
BOPCol_ListOfShape& );
//=======================================================================
//class : BOPAlgo_BuilderSolid_ShapeBox
//purpose : Auxiliary class
//=======================================================================
class BOPAlgo_BuilderSolid_ShapeBox {
public:
BOPAlgo_BuilderSolid_ShapeBox() {
myIsHole=Standard_False;
};
//
~BOPAlgo_BuilderSolid_ShapeBox() {
};
//
void SetShape(const TopoDS_Shape& aS) {
myShape=aS;
};
//
const TopoDS_Shape& Shape()const {
return myShape;
};
//
void SetBox(const Bnd_Box& aBox) {
myBox=aBox;
};
//
const Bnd_Box& Box()const {
return myBox;
};
//
void SetIsHole(const Standard_Boolean bFlag) {
myIsHole=bFlag;
};
//
Standard_Boolean IsHole()const {
return myIsHole;
};
//
protected:
Standard_Boolean myIsHole;
TopoDS_Shape myShape;
Bnd_Box myBox;
};
//
typedef NCollection_DataMap
<Standard_Integer,
BOPAlgo_BuilderSolid_ShapeBox,
TColStd_MapIntegerHasher> BOPAlgo_DataMapOfIntegerBSSB;
//
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,
Precision::Confusion(),
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_ContextFunctor
<BOPAlgo_FaceSolid,
BOPAlgo_VectorOfFaceSolid,
Handle(IntTools_Context),
IntTools_Context> BOPAlgo_FaceSolidFunctor;
//
typedef BOPCol_ContextCnt
<BOPAlgo_FaceSolidFunctor,
BOPAlgo_VectorOfFaceSolid,
Handle(IntTools_Context)> BOPAlgo_FaceSolidCnt;
//
//=======================================================================
//=======================================================================
//function :
//purpose :
//=======================================================================
BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid()
:
BOPAlgo_BuilderArea()
{
}
//=======================================================================
//function :
//purpose :
//=======================================================================
BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid
(const Handle(NCollection_BaseAllocator)& theAllocator)
:
BOPAlgo_BuilderArea(theAllocator)
{
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid()
{
}
//=======================================================================
//function : SetSolid
//purpose :
//=======================================================================
void BOPAlgo_BuilderSolid::SetSolid(const TopoDS_Solid& aS)
{
mySolid=aS;
}
//=======================================================================
//function : Solid
//purpose :
//=======================================================================
const TopoDS_Solid& BOPAlgo_BuilderSolid::Solid()const
{
return mySolid;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void BOPAlgo_BuilderSolid::Perform()
{
myErrorStatus=0;
//
if (myContext.IsNull()) {
myContext=new IntTools_Context;
}
//
TopoDS_Compound aC;
BRep_Builder aBB;
BOPCol_ListIteratorOfListOfShape aIt;
//
aBB.MakeCompound(aC);
aIt.Initialize(myShapes);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
aBB.Add(aC, aF);
}
//
UserBreak();
//
PerformShapesToAvoid();
if (myErrorStatus) {
return;
}
//
UserBreak();
//
PerformLoops();
if (myErrorStatus) {
return;
}
//
UserBreak();
//
PerformAreas();
if (myErrorStatus) {
return;
}
//
UserBreak();
//
PerformInternalShapes();
if (myErrorStatus) {
return;
}
}
//=======================================================================
//function :PerformShapesToAvoid
//purpose :
//=======================================================================
void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
{
Standard_Boolean bFound;
Standard_Integer i, iCnt, aNbE, aNbF;
TopAbs_Orientation aOrE;
BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
BOPCol_ListIteratorOfListOfShape aIt;
//
myShapesToAvoid.Clear();
//
iCnt=0;
for(;;) {
++iCnt;
bFound=Standard_False;
//
// 1. MEF
aMEF.Clear();
aIt.Initialize (myShapes);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
if (!myShapesToAvoid.Contains(aF)) {
BOPTools::MapShapesAndAncestors(aF,
TopAbs_EDGE,
TopAbs_FACE,
aMEF);
}
}
aNbE=aMEF.Extent();
//
// 2. myFacesToAvoid
for (i=1; i<=aNbE; ++i) {
const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aMEF.FindKey(i)));
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
aNbF=aLF.Extent();
if (!aNbF) {
continue;
}
//
aOrE=aE.Orientation();
//
const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
if (aNbF==1) {
if (aOrE==TopAbs_INTERNAL) {
continue;
}
bFound=Standard_True;
myShapesToAvoid.Add(aF1);
}
else if (aNbF==2) {
const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
if (aF2.IsSame(aF1)) {
if (BRep_Tool::IsClosed(aE, aF1)) {
continue;
}
//
if (aOrE==TopAbs_INTERNAL) {
continue;
}
//
bFound=Standard_True;
myShapesToAvoid.Add(aF1);
myShapesToAvoid.Add(aF2);
}
}
}// for (i=1; i<=aNbE; ++i) {
//
if (!bFound) {
break;
}
//
}//for(;;) {
}
//=======================================================================
//function : PerformLoops
//purpose :
//=======================================================================
void BOPAlgo_BuilderSolid::PerformLoops()
{
Standard_Integer iErr, i, aNbSh;
BOPCol_ListIteratorOfListOfShape aIt;
TopoDS_Iterator aItS;
Handle(NCollection_BaseAllocator) aAlr;
//
myErrorStatus=0;
myLoops.Clear();
//
aAlr=
NCollection_BaseAllocator::CommonBaseAllocator();
BOPAlgo_ShellSplitter aSSp(aAlr);
//
// 1. Shells Usual
aIt.Initialize (myShapes);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
if (myContext->IsInfiniteFace(aF)) {
TopoDS_Shell aSh;
BRep_Builder aBB;
//
aBB.MakeShell(aSh);
aBB.Add(aSh, aF);
myLoops.Append(aSh);
continue;
}
//
if (!myShapesToAvoid.Contains(aF)) {
aSSp.AddStartElement(aF);
}
}
//
aSSp.SetRunParallel(myRunParallel);
aSSp.Perform();
iErr=aSSp.ErrorStatus();
if (iErr) {
return;
}
//
const BOPCol_ListOfShape& aLSh=aSSp.Shells();
aIt.Initialize (aLSh);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aSh=aIt.Value();
myLoops.Append(aSh);
}
//=================================================
//
// 2. Post Treatment
BRep_Builder aBB;
BOPCol_MapOfOrientedShape AddedFacesMap;
BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
BOPCol_MapOfOrientedShape aMP;
//
// a. collect all edges that are in loops
aIt.Initialize (myLoops);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aS=aIt.Value();
aItS.Initialize(aS);
for (; aItS.More(); aItS.Next()) {
const TopoDS_Shape& aF=aItS.Value();
aMP.Add(aF);
}
}
//
// b. collect all edges that are to avoid
aNbSh = myShapesToAvoid.Extent();
for (i = 1; i <= aNbSh; ++i) {
const TopoDS_Shape& aF = myShapesToAvoid(i);
aMP.Add(aF);
}
//
// c. add all edges that are not processed to myShapesToAvoid
aIt.Initialize (myShapes);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
if (!myContext->IsInfiniteFace(aF)) {
if (!aMP.Contains(aF)) {
myShapesToAvoid.Add(aF);
}
}
}
//=================================================
//
// 3.Internal Shells
myLoopsInternal.Clear();
//
aEFMap.Clear();
AddedFacesMap.Clear();
//
aNbSh = myShapesToAvoid.Extent();
for (i = 1; i <= aNbSh; ++i) {
const TopoDS_Shape& aFF = myShapesToAvoid(i);
BOPTools::MapShapesAndAncestors(aFF,
TopAbs_EDGE, TopAbs_FACE,
aEFMap);
}
//
for (i = 1; i <= aNbSh; ++i) {
const TopoDS_Shape& aFF = myShapesToAvoid(i);
if (!AddedFacesMap.Add(aFF)) {
continue;
}
//
// make a new shell
TopExp_Explorer aExp;
TopoDS_Shell aShell;
aBB.MakeShell(aShell);
aBB.Add(aShell, aFF);
//
aItS.Initialize(aShell);
for (; aItS.More(); aItS.Next()) {
const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value()));
//
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
aIt.Initialize(aLF);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aIt.Value()));
if (AddedFacesMap.Add(aFL)){
aBB.Add(aShell, aFL);
}
}
}
}
aShell.Closed (BRep_Tool::IsClosed (aShell));
myLoopsInternal.Append(aShell);
}
}
//=======================================================================
//function : PerformAreas
//purpose :
//=======================================================================
void BOPAlgo_BuilderSolid::PerformAreas()
{
Standard_Boolean bIsGrowth, bIsHole;
Standard_Integer i, k, aNbInOut, aNbMSH;
BRep_Builder aBB;
BOPCol_ListIteratorOfListOfShape aItLS;
BOPCol_ListOfShape aNewSolids, aHoleShells;
BOPCol_IndexedDataMapOfShapeShape aInOutMap;
BOPCol_IndexedMapOfShape aMHF;
BOPCol_ListIteratorOfListOfInteger aItLI;
BOPCol_BoxBndTreeSelector aSelector;
BOPCol_BoxBndTree aBBTree;
NCollection_UBTreeFiller
<Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
BOPAlgo_DataMapOfIntegerBSSB aDMISB(100);
BOPCol_IndexedDataMapOfShapeListOfShape aMSH;
BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB;
//
myErrorStatus=0;
//
myAreas.Clear();
//
// Draft solids [aNewSolids]
aItLS.Initialize(myLoops);
for (k=0; aItLS.More(); aItLS.Next(), ++k) {
TopoDS_Solid aSolid;
Bnd_Box aBox;
BOPAlgo_BuilderSolid_ShapeBox aSB;
//
const TopoDS_Shape& aShell = aItLS.Value();
aSB.SetShape(aShell);
//
BRepBndLib::Add(aShell, aBox);
bIsHole=Standard_False;
//
bIsGrowth=IsGrowthShell(aShell, aMHF);
if (bIsGrowth) {
// make a growth solid from a shell
aBB.MakeSolid(aSolid);
aBB.Add (aSolid, aShell);
//
aNewSolids.Append (aSolid);
aSB.SetShape(aSolid);
}
else{
// check if a shell is a hole
bIsHole=IsHole(aShell, myContext);
if (bIsHole) {
aHoleShells.Append(aShell);
BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
aSB.SetShape(aShell);
}
else {
// make a growth solid from a shell
aBB.MakeSolid(aSolid);
aBB.Add (aSolid, aShell);
//
aNewSolids.Append (aSolid);
aSB.SetShape(aSolid);
}
}
//
aSB.SetBox(aBox);
aSB.SetIsHole(bIsHole);
aDMISB.Bind(k, aSB);
}
//
// 2. Prepare TreeFiller
aItDMISB.Initialize(aDMISB);
for (; aItDMISB.More(); aItDMISB.Next()) {
k=aItDMISB.Key();
const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
//
bIsHole=aSB.IsHole();
if (bIsHole) {
const Bnd_Box& aBox=aSB.Box();
aTreeFiller.Add(k, aBox);
}
}
//
// 3. Shake TreeFiller
aTreeFiller.Fill();
//
// 4. Find outer growth shell that is most close
// to each hole shell
aItDMISB.Initialize(aDMISB);
for (; aItDMISB.More(); aItDMISB.Next()) {
k=aItDMISB.Key();
const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
bIsHole=aSB.IsHole();
if (bIsHole) {
continue;
}
//
const TopoDS_Shape aSolid=aSB.Shape();
const Bnd_Box& aBoxSolid=aSB.Box();
//
aSelector.Clear();
aSelector.SetBox(aBoxSolid);
//
aBBTree.Select(aSelector);
//
const BOPCol_ListOfInteger& aLI=aSelector.Indices();
//
aItLI.Initialize(aLI);
for (; aItLI.More(); aItLI.Next()) {
k=aItLI.Value();
const BOPAlgo_BuilderSolid_ShapeBox& aSBk=aDMISB.Find(k);
const TopoDS_Shape& aHole=aSBk.Shape();
//
if (!IsInside(aHole, aSolid, myContext)){
continue;
}
//
if (aInOutMap.Contains (aHole)){
const TopoDS_Shape& aSolidWas = aInOutMap.FindFromKey(aHole);
if (IsInside(aSolid, aSolidWas, myContext)) {
aInOutMap.ChangeFromKey(aHole) = aSolid;
}
}
else{
aInOutMap.Add(aHole, aSolid);
}
}
}//for (i = 1; i <= aNbDMISB; ++i) {
//
// 5. Map [Solid/Holes] -> aMSH
aNbInOut = aInOutMap.Extent();
for (i = 1; i <= aNbInOut; ++i) {
const TopoDS_Shape& aHole = aInOutMap.FindKey(i);
const TopoDS_Shape& aSolid = aInOutMap(i);
//
if (aMSH.Contains(aSolid)) {
BOPCol_ListOfShape& aLH = aMSH.ChangeFromKey(aSolid);
aLH.Append(aHole);
}
else {
BOPCol_ListOfShape aLH;
aLH.Append(aHole);
aMSH.Add(aSolid, aLH);
}
}
//
// 6. Add aHoles to Solids
aNbMSH = aMSH.Extent();
for (i = 1; i <= aNbMSH; ++i) {
TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&(aMSH.FindKey(i))));
const BOPCol_ListOfShape& aLH = aMSH(i);
//
aItLS.Initialize(aLH);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aHole = aItLS.Value();
aBB.Add (aSolid, aHole);
}
//
// update classifier
BRepClass3d_SolidClassifier& aSC=
myContext->SolidClassifier(aSolid);
aSC.Load(aSolid);
//
}
//
// 7. These aNewSolids are draft solids that
// do not contain any internal shapes
aItLS.Initialize(aNewSolids);
for ( ; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aSx=aItLS.Value();
myAreas.Append(aSx);
}
// Add holes that outside the solids to myAreas
aItLS.Initialize(aHoleShells);
for (; aItLS.More(); aItLS.Next()) {
const TopoDS_Shape& aHole = aItLS.Value();
if (!aInOutMap.Contains(aHole)){
TopoDS_Solid aSolid;
//
aBB.MakeSolid(aSolid);
aBB.Add (aSolid, aHole);
//
myAreas.Append(aSolid);
}
}
}
//=======================================================================
//function : PerformInternalShapes
//purpose :
//=======================================================================
void BOPAlgo_BuilderSolid::PerformInternalShapes()
{
myErrorStatus=0;
//
Standard_Integer aNbFI=myLoopsInternal.Extent();
if (!aNbFI) {// nothing to do
return;
}
//
Standard_Boolean bIsInternalFace;
Standard_Integer k, aNbVFS, aNbSLF, aNbVFP, aNbA;
BRep_Builder aBB;
TopoDS_Iterator aIt;
TopExp_Explorer aExp;
BOPCol_ListIteratorOfListOfShape aItLS;
BOPCol_IndexedMapOfShape 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);
//
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_Face& aF=*((TopoDS_Face*)&aIt.Value());
//
if (!aMFs.Contains(aF)) {
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);
}
}
}
//
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);
//
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);
}
//
aLSI.Clear();
MakeInternalShells(aMFs, aLSI);
//
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);
//
const TopoDS_Face& aF=aFS.Face();
if (!aMFProcessed.Contains(aF)) {
aMFs.Add(aF);
}
}
//
aNbFI=aMFs.Extent();
if (aNbFI) {
TopoDS_Solid aSolid;
aBB.MakeSolid(aSolid);
//
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 :
//=======================================================================
void MakeInternalShells(const BOPCol_IndexedMapOfShape& theMF,
BOPCol_ListOfShape& theShells)
{
Standard_Integer i, aNbF;
BRep_Builder aBB;
BOPCol_ListIteratorOfListOfShape aItF;
BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
BOPCol_MapOfShape aAddedFacesMap;
//
aNbF = theMF.Extent();
for (i = 1; i <= aNbF; ++i) {
TopoDS_Shape aF = theMF(i);
BOPTools::MapShapesAndAncestors(aF,
TopAbs_EDGE, TopAbs_FACE,
aMEF);
}
//
for (i = 1; i <= aNbF; ++i) {
TopoDS_Shape aFF = theMF(i);
if (!aAddedFacesMap.Add(aFF)) {
continue;
}
//
// make a new shell
TopoDS_Shell aShell;
aBB.MakeShell(aShell);
aFF.Orientation(TopAbs_INTERNAL);
aBB.Add(aShell, aFF);
//
TopoDS_Iterator aItAddedF (aShell);
for (; aItAddedF.More(); aItAddedF.Next()) {
const TopoDS_Shape& aF =aItAddedF.Value();
//
TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
for (; aEdgeExp.More(); aEdgeExp.Next()) {
const TopoDS_Shape& aE =aEdgeExp.Current();
const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
aItF.Initialize(aLF);
for (; aItF.More(); aItF.Next()) {
TopoDS_Shape aFL=aItF.Value();
if (aAddedFacesMap.Add(aFL)){
aFL.Orientation(TopAbs_INTERNAL);
aBB.Add(aShell, aFL);
}
}
}
}
aShell.Closed (BRep_Tool::IsClosed (aShell));
theShells.Append(aShell);
}
}
//=======================================================================
//function : IsHole
//purpose :
//=======================================================================
Standard_Boolean IsHole(const TopoDS_Shape& theS2,
Handle(IntTools_Context)& theContext)
{
TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
//
aClsf.PerformInfinitePoint(::RealSmall());
//
return (aClsf.State()==TopAbs_IN);
}
//=======================================================================
//function : IsInside
//purpose :
//=======================================================================
Standard_Boolean IsInside(const TopoDS_Shape& theS1,
const TopoDS_Shape& theS2,
Handle(IntTools_Context)& theContext)
{
TopExp_Explorer aExp;
TopAbs_State aState;
//
TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
//
aExp.Init(theS1, TopAbs_FACE);
if (!aExp.More()){
BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
aClsf.PerformInfinitePoint(::RealSmall());
aState=aClsf.State();
}
else {
BOPCol_IndexedMapOfShape aBounds;
BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds);
const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current()));
aState=BOPTools_AlgoTools::ComputeState(aF, *pS2,
Precision::Confusion(),
aBounds, theContext);
}
return (aState==TopAbs_IN);
}
//=======================================================================
//function : IsGrowthShell
//purpose :
//=======================================================================
Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
const BOPCol_IndexedMapOfShape& theMHF)
{
Standard_Boolean bRet;
TopoDS_Iterator aIt;
//
bRet=Standard_False;
if (theMHF.Extent()) {
aIt.Initialize(theShell);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
if (theMHF.Contains(aF)) {
return !bRet;
}
}
}
return bRet;
}