1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-08 18:40:55 +03:00
occt/src/BOPAlgo/BOPAlgo_BuilderSolid.cxx
emv 1155d05a06 0025609: Clean up the duplicate classes in TKBO project
1. The package BOPCol has been fully removed:
- *BOPCol_BaseAllocator* is replaced with *Handle(NCollection_BaseAllocator)*;
- *BOPCol_BoxBndTree* is replaced with *BOPTools_BoxBndTree*;
- *BOPCol_Box2DBndTree* is removed as unused;
- *BOPCol_DataMapOfIntegerInteger* is replaced with *TColStd_DataMapOfIntegerInteger*;
- *BOPCol_DataMapOfIntegerListOfInteger* is replaced with *TColStd_DataMapOfIntegerListOfInteger*;
- *BOPCol_DataMapOfIntegerListOfShape* is replaced with *TopTools_DataMapOfIntegerListOfShape*;
- *BOPCol_DataMapOfIntegerMapOfInteger.hxx* is removed as unused;
- *BOPCol_DataMapOfIntegerReal* is replaced with *TColStd_DataMapOfIntegerReal*;
- *BOPCol_DataMapOfIntegerShape* is replaced with *TopTools_DataMapOfIntegerShape*;
- *BOPCol_DataMapOfShapeBox* is replaced with *TopTools_DataMapOfShapeBox*;
- *BOPCol_DataMapOfShapeInteger* is replaced with *TopTools_DataMapOfShapeInteger*;
- *BOPCol_DataMapOfShapeListOfShape* is replaced with *TopTools_DataMapOfShapeListOfShape*;
- *BOPCol_DataMapOfShapeReal* is replaced with *TopTools_DataMapOfShapeReal*;
- *BOPCol_DataMapOfShapeShape* is replaced with *TopTools_DataMapOfShapeShape*;
- *BOPCol_DataMapOfTransientAddress* is removed as unused;
- *BOPCol_IndexedDataMapOfIntegerListOfInteger* is removed as unused;
- *BOPCol_IndexedDataMapOfShapeBox* is removed as unused;
- *BOPCol_IndexedDataMapOfShapeInteger* is removed as unused;
- *BOPCol_IndexedDataMapOfShapeListOfShape* is replaced with *TopTools_IndexedDataMapOfShapeListOfShape*;
- *BOPCol_IndexedDataMapOfShapeReal* is removed as unused;
- *BOPCol_IndexedDataMapOfShapeShape* is replaced with *TopTools_IndexedDataMapOfShapeShape*;
- *BOPCol_IndexedMapOfInteger* is replaced with *TColStd_IndexedMapOfInteger*;
- *BOPCol_IndexedMapOfOrientedShape* is replaced with *TopTools_IndexedMapOfOrientedShape*;
- *BOPCol_IndexedMapOfShape* is replaced with *TopTools_IndexedMapOfShape*;
- *BOPCol_ListOfInteger* is replaced with *TColStd_ListOfInteger*;
- *BOPCol_ListOfListOfShape* is replaced with *TopTools_ListOfListOfShape*;
- *BOPCol_ListOfShape* is replaced with *TopTools_ListOfShape*;
- *BOPCol_MapOfInteger* is replaced with *TColStd_MapOfInteger*;
- *BOPCol_MapOfOrientedShape* is replaced with *TopTools_MapOfOrientedShape*;
- *BOPCol_MapOfShape* is replaced with *TopTools_MapOfShape*;
- *BOPCol_PListOfInteger* is removed as unused;
- *BOPCol_PInteger* is removed as unused
- *BOPCol_SequenceOfPnt2d* is replaced with *TColgp_SequenceOfPnt2d*;
- *BOPCol_SequenceOfReal* is replaced with *TColStd_SequenceOfReal*;
- *BOPCol_SequenceOfShape* is replaced with *TopTools_SequenceOfShape*;
- *BOPCol_Parallel* is replaced with *BOPTools_Parallel*;
- *BOPCol_NCVector* is replaced with *NCollection_Vector*;

2. The class *BOPDS_PassKey* and containers for it have been removed as unused;

3. The unused containers from *IntTools* package have been removed:
- *IntTools_DataMapOfShapeAddress* is removed as unused;
- *IntTools_IndexedDataMapOfTransientAddress* is removed as unused;

4. The container *BiTgte_DataMapOfShapeBox* is replaced with *TopTools_DataMapOfShapeBox*;

5. The class *BOPTools* has been removed as duplicate of the class *TopExp*;
2017-11-30 12:11:15 +03:00

823 lines
22 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 <BOPAlgo_Alerts.hxx>
#include <BOPAlgo_Tools.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BOPTools_AlgoTools3D.hxx>
#include <BOPTools_BoxBndTree.hxx>
#include <BOPTools_CoupleOfShape.hxx>
#include <BOPTools_Parallel.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 <NCollection_Vector.hxx>
#include <TColStd_MapIntegerHasher.hxx>
#include <TopAbs.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.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>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeShape.hxx>
#include <TColStd_ListOfInteger.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfOrientedShape.hxx>
#include <TopTools_MapOfShape.hxx>
//
static
Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
const TopTools_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 TopTools_IndexedMapOfShape& ,
TopTools_ListOfShape& );
//=======================================================================
//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()
{
GetReport()->Clear();
//
if (myShapes.IsEmpty())
return;
if (myContext.IsNull()) {
myContext=new IntTools_Context;
}
myBoxes.Clear();
TopoDS_Compound aC;
BRep_Builder aBB;
TopTools_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 (HasErrors()) {
return;
}
//
UserBreak();
//
PerformLoops();
if (HasErrors()) {
return;
}
//
UserBreak();
//
PerformAreas();
if (HasErrors()) {
return;
}
//
UserBreak();
//
PerformInternalShapes();
if (HasErrors()) {
return;
}
}
//=======================================================================
//function :PerformShapesToAvoid
//purpose :
//=======================================================================
void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
{
Standard_Boolean bFound;
Standard_Integer i, iCnt, aNbE, aNbF;
TopAbs_Orientation aOrE;
TopTools_IndexedDataMapOfShapeListOfShape aMEF;
TopTools_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)) {
TopExp::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;
}
//
TopTools_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 i, aNbSh;
TopTools_ListIteratorOfListOfShape aIt;
TopoDS_Iterator aItS;
Handle(NCollection_BaseAllocator) aAlr;
//
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();
if (aSSp.HasErrors()) {
// add warning status
{
TopoDS_Compound aFacesSp;
BRep_Builder().MakeCompound(aFacesSp);
TopTools_ListIteratorOfListOfShape aItLF(aSSp.StartElements());
for (; aItLF.More(); aItLF.Next()) {
BRep_Builder().Add(aFacesSp, aItLF.Value());
}
AddWarning (new BOPAlgo_AlertShellSplitterFailed (aFacesSp));
}
return;
}
//
const TopTools_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;
TopTools_MapOfOrientedShape AddedFacesMap;
TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
TopTools_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);
TopExp::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 TopTools_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()
{
myAreas.Clear();
BRep_Builder aBB;
// The new solids
TopTools_ListOfShape aNewSolids;
// The hole shells which has to be classified relatively new solids
TopTools_IndexedMapOfShape aHoleShells;
// Map of the faces of the hole shells for quick check of the growths.
// If the analyzed shell contains any of the hole faces, it is considered as growth.
TopTools_IndexedMapOfShape aMHF;
// Analyze the shells
TopTools_ListIteratorOfListOfShape aItLL(myLoops);
for (; aItLL.More(); aItLL.Next())
{
const TopoDS_Shape& aShell = aItLL.Value();
Standard_Boolean bIsGrowth = IsGrowthShell(aShell, aMHF);
if (!bIsGrowth)
{
// Fast check did not give the result, run classification
bIsGrowth = !IsHole(aShell, myContext);
}
// Save the solid
if (bIsGrowth)
{
TopoDS_Solid aSolid;
aBB.MakeSolid(aSolid);
aBB.Add (aSolid, aShell);
aNewSolids.Append (aSolid);
}
else
{
aHoleShells.Add(aShell);
TopExp::MapShapes(aShell, TopAbs_FACE, aMHF);
}
}
if (aHoleShells.IsEmpty())
{
// No holes, stop the analysis
TopTools_ListIteratorOfListOfShape aItLS(aNewSolids);
for (; aItLS.More(); aItLS.Next())
{
const TopoDS_Shape& aSol = aItLS.Value();
myAreas.Append(aSol);
// Build box
Bnd_Box aBox;
BRepBndLib::Add(aSol, aBox);
myBoxes.Bind(aSol, aBox);
}
return;
}
// Classify holes relatively solids
// Prepare tree filler with the boxes of the hole shells
BOPTools_BoxBndTree aBBTree;
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
Standard_Integer i, aNbH = aHoleShells.Extent();
for (i = 1; i <= aNbH; ++i)
{
const TopoDS_Shape& aHShell = aHoleShells(i);
//
Bnd_Box aBox;
BRepBndLib::Add(aHShell, aBox);
aTreeFiller.Add(i, aBox);
myBoxes.Bind(aHShell, aBox);
}
// Shake TreeFiller
aTreeFiller.Fill();
// Find outer growth shell that is most close to each hole shell
TopTools_IndexedDataMapOfShapeShape aHoleSolidMap;
TopTools_ListIteratorOfListOfShape aItLS(aNewSolids);
for (; aItLS.More(); aItLS.Next())
{
const TopoDS_Shape& aSolid = aItLS.Value();
// Build box
Bnd_Box aBox;
BRepBndLib::Add(aSolid, aBox);
myBoxes.Bind(aSolid, aBox);
BOPTools_BoxBndTreeSelector aSelector;
aSelector.SetBox(aBox);
aBBTree.Select(aSelector);
const TColStd_ListOfInteger& aLI = aSelector.Indices();
TColStd_ListIteratorOfListOfInteger aItLI(aLI);
for (; aItLI.More(); aItLI.Next())
{
Standard_Integer k = aItLI.Value();
const TopoDS_Shape& aHole = aHoleShells(k);
// Check if it is inside
if (!IsInside(aHole, aSolid, myContext))
continue;
// Save the relation
TopoDS_Shape* pSolidWas = aHoleSolidMap.ChangeSeek(aHole);
if (pSolidWas)
{
if (IsInside(aSolid, *pSolidWas, myContext))
{
*pSolidWas = aSolid;
}
}
else
{
aHoleSolidMap.Add(aHole, aSolid);
}
}
}
// Make the back map from solids to holes
TopTools_IndexedDataMapOfShapeListOfShape aSolidHolesMap;
aNbH = aHoleSolidMap.Extent();
for (i = 1; i <= aNbH; ++i)
{
const TopoDS_Shape& aHole = aHoleSolidMap.FindKey(i);
const TopoDS_Shape& aSolid = aHoleSolidMap(i);
//
TopTools_ListOfShape* pLHoles = aSolidHolesMap.ChangeSeek(aSolid);
if (!pLHoles)
pLHoles = &aSolidHolesMap(aSolidHolesMap.Add(aSolid, TopTools_ListOfShape()));
pLHoles->Append(aHole);
}
// Add Holes to Solids and add them to myAreas
aItLS.Initialize(aNewSolids);
for ( ; aItLS.More(); aItLS.Next())
{
TopoDS_Solid& aSolid = *(TopoDS_Solid*)&aItLS.Value();
const TopTools_ListOfShape* pLHoles = aSolidHolesMap.Seek(aSolid);
if (pLHoles)
{
// update solid
TopTools_ListIteratorOfListOfShape aItLH(*pLHoles);
for (; aItLH.More(); aItLH.Next())
{
const TopoDS_Shape& aHole = aItLH.Value();
aBB.Add(aSolid, aHole);
}
// update classifier
myContext->SolidClassifier(aSolid).Load(aSolid);
}
myAreas.Append(aSolid);
}
// Add holes that outside the solids to myAreas
aNbH = aHoleShells.Extent();
for (i = 1; i <= aNbH; ++i)
{
const TopoDS_Shape& aHole = aHoleShells(i);
if (!aHoleSolidMap.Contains(aHole))
{
TopoDS_Solid aSolid;
aBB.MakeSolid(aSolid);
aBB.Add (aSolid, aHole);
//
myAreas.Append(aSolid);
// Make an infinite box for the hole
Bnd_Box aBox;
aBox.SetWhole();
myBoxes.Bind(aSolid, aBox);
}
myBoxes.UnBind(aHole);
}
}
//=======================================================================
//function : PerformInternalShapes
//purpose :
//=======================================================================
void BOPAlgo_BuilderSolid::PerformInternalShapes()
{
if (myAvoidInternalShapes)
// user-defined option to avoid internal parts is in force
return;
if (myLoopsInternal.IsEmpty())
// no internal parts
return;
// Get all faces to classify
TopTools_IndexedMapOfShape aMFs;
TopTools_ListIteratorOfListOfShape aItLS(myLoopsInternal);
for (; aItLS.More(); aItLS.Next())
{
const TopoDS_Shape& aShell = aItLS.Value();
TopoDS_Iterator aIt(aShell);
for (; aIt.More(); aIt.Next())
aMFs.Add(aIt.Value());
}
BRep_Builder aBB;
// Check existence of the growths solids
if (myAreas.IsEmpty())
{
// No areas.
// Just make solid of the faces
TopoDS_Solid aSolid;
aBB.MakeSolid(aSolid);
//
TopTools_ListOfShape aLSI;
MakeInternalShells(aMFs, aLSI);
//
aItLS.Initialize(aLSI);
for (; aItLS.More(); aItLS.Next())
aBB.Add(aSolid, aItLS.Value());
myAreas.Append(aSolid);
return;
}
// Classify faces relatively solids
// Prepare list of faces to classify
TopTools_ListOfShape aLFaces;
Standard_Integer i, aNbF = aMFs.Extent();
for (i = 1; i <= aNbF; ++i)
aLFaces.Append(aMFs(i));
// Map of solids with IN faces
TopTools_IndexedDataMapOfShapeListOfShape aMSLF;
// Perform classification
BOPAlgo_Tools::ClassifyFaces(aLFaces, myAreas, myRunParallel, myContext, aMSLF, myBoxes);
// Update Solids by internal Faces
TopTools_MapOfShape aMFDone;
Standard_Integer aNbS = aMSLF.Extent();
for (i = 1; i <= aNbS; ++i)
{
const TopoDS_Shape& aSolid = aMSLF.FindKey(i);
TopoDS_Shape *pSolid = (TopoDS_Shape*)&aSolid;
const TopTools_ListOfShape& aLF = aMSLF(i);
if (aLF.IsEmpty())
continue;
TopTools_IndexedMapOfShape aMF;
aItLS.Initialize(aLF);
for (; aItLS.More(); aItLS.Next())
{
const TopoDS_Shape& aF = aItLS.Value();
aMF.Add(aF);
aMFDone.Add(aF);
}
//
TopTools_ListOfShape aLSI;
MakeInternalShells(aMF, aLSI);
//
aItLS.Initialize(aLSI);
for (; aItLS.More(); aItLS.Next())
{
const TopoDS_Shape& aSI = aItLS.Value();
aBB.Add (*pSolid, aSI);
}
}
// Make solid from the unused faces (if any)
TopTools_IndexedMapOfShape aMFUnUsed;
for (i = 1; i <= aNbF; ++i)
{
const TopoDS_Shape& aF = aMFs(i);
if (!aMFDone.Contains(aF))
aMFUnUsed.Add(aF);
}
if (aMFUnUsed.Extent())
{
TopoDS_Solid aSolid;
aBB.MakeSolid(aSolid);
//
TopTools_ListOfShape aLSI;
MakeInternalShells(aMFUnUsed, aLSI);
//
aItLS.Initialize(aLSI);
for (; aItLS.More(); aItLS.Next())
{
const TopoDS_Shape& aSI = aItLS.Value();
aBB.Add (aSolid, aSI);
Bnd_Box aBox;
BRepBndLib::Add(aSolid, aBox);
myBoxes.Bind(aSolid, aBox);
}
myAreas.Append(aSolid);
}
}
//=======================================================================
//function : MakeInternalShells
//purpose :
//=======================================================================
void MakeInternalShells(const TopTools_IndexedMapOfShape& theMF,
TopTools_ListOfShape& theShells)
{
Standard_Integer i, aNbF;
BRep_Builder aBB;
TopTools_ListIteratorOfListOfShape aItF;
TopTools_IndexedDataMapOfShapeListOfShape aMEF;
TopTools_MapOfShape aAddedFacesMap;
//
aNbF = theMF.Extent();
for (i = 1; i <= aNbF; ++i) {
TopoDS_Shape aF = theMF(i);
TopExp::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 TopTools_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 {
TopTools_IndexedMapOfShape aBounds;
TopExp::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 TopTools_IndexedMapOfShape& theMHF)
{
if (theMHF.Extent())
{
TopoDS_Iterator aIt(theShell);
for(; aIt.More(); aIt.Next())
{
if (theMHF.Contains(aIt.Value()))
return Standard_True;
}
}
return Standard_False;
}