geom/src/GEOMAlgo/GEOMAlgo_BuilderSolid.cxx

932 lines
26 KiB
C++
Raw Normal View History

2013-04-01 18:25:01 +06:00
// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
//
2012-08-09 13:58:02 +06:00
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
2012-08-09 13:58:02 +06:00
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License.
2009-02-13 17:16:39 +05:00
//
2012-08-09 13:58:02 +06:00
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
2009-02-13 17:16:39 +05:00
//
2012-08-09 13:58:02 +06:00
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2009-02-13 17:16:39 +05:00
//
2012-08-09 13:58:02 +06:00
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
2012-08-09 13:58:02 +06:00
// File: GEOMAlgo_BuilderSolid.cxx
// Created:
// Author: Peter KURNEV
2009-02-13 17:16:39 +05:00
//
2012-08-09 13:58:02 +06:00
#include <GEOMAlgo_BuilderSolid.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Pln.hxx>
#include <gp_Vec.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
#include <Geom2d_Curve.hxx>
#include <TopAbs.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Compound.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepTools.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_MapIteratorOfMapOfShape.hxx>
#include <TopTools_MapOfOrientedShape.hxx>
#include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_DataMapOfShapeShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_DataMapOfShapeListOfShape.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
#include <IntTools_Context.hxx>
#include <BOPTools_Tools2D.hxx>
#include <BOPTools_Tools3D.hxx>
#include <NMTTools_ListOfCoupleOfShape.hxx>
#include <NMTTools_CoupleOfShape.hxx>
#include <NMTTools_ListIteratorOfListOfCoupleOfShape.hxx>
#include <GEOMAlgo_Tools3D.hxx>
#include <GEOMAlgo_BuilderTools.hxx>
//
static
Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
2012-08-09 13:58:02 +06:00
const TopTools_IndexedMapOfShape& );
static
Standard_Boolean IsHole(const TopoDS_Shape& ,
2012-08-09 13:58:02 +06:00
const Handle(IntTools_Context)& );
static
Standard_Boolean IsInside(const TopoDS_Shape& ,
2012-08-09 13:58:02 +06:00
const TopoDS_Shape& ,
const Handle(IntTools_Context)& );
static
void MakeInternalShells(const TopTools_MapOfShape& ,
2012-08-09 13:58:02 +06:00
TopTools_ListOfShape& );
static
Standard_Boolean IsClosedShell(const TopoDS_Shell& );
2009-02-13 17:16:39 +05:00
static
2012-08-09 13:58:02 +06:00
Standard_Boolean RefineShell(const TopoDS_Shell& ,
2013-06-17 18:15:50 +06:00
TopoDS_Shell& );
//=======================================================================
2012-08-09 13:58:02 +06:00
//function :
//purpose :
//=======================================================================
2012-08-09 13:58:02 +06:00
GEOMAlgo_BuilderSolid::GEOMAlgo_BuilderSolid()
:
GEOMAlgo_BuilderArea()
{
}
//=======================================================================
//function : ~
2012-08-09 13:58:02 +06:00
//purpose :
//=======================================================================
2012-08-09 13:58:02 +06:00
GEOMAlgo_BuilderSolid::~GEOMAlgo_BuilderSolid()
{
}
//=======================================================================
//function : Perform
2012-08-09 13:58:02 +06:00
//purpose :
//=======================================================================
2012-08-09 13:58:02 +06:00
void GEOMAlgo_BuilderSolid::Perform()
{
myErrorStatus=0;
//
2012-08-09 13:58:02 +06:00
// Initialize the context
GEOMAlgo_BuilderArea::Perform();
//
TopoDS_Compound aC;
BRep_Builder aBB;
TopTools_ListIteratorOfListOfShape aIt;
2012-08-09 13:58:02 +06:00
aBB.MakeCompound(aC);
aIt.Initialize(myShapes);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
aBB.Add(aC, aF);
}
//
PerformShapesToAvoid();
if (myErrorStatus) {
return;
}
//
PerformLoops();
if (myErrorStatus) {
return;
}
PerformAreas();
if (myErrorStatus) {
return;
}
2012-08-09 13:58:02 +06:00
if (myComputeInternalShapes) {
PerformInternalShapes();
if (myErrorStatus) {
return;
}
}
}
//=======================================================================
//function :PerformShapesToAvoid
2012-08-09 13:58:02 +06:00
//purpose :
//=======================================================================
2012-08-09 13:58:02 +06:00
void GEOMAlgo_BuilderSolid::PerformShapesToAvoid()
{
Standard_Boolean bFound;
Standard_Integer i, iCnt, aNbE, aNbF;
TopAbs_Orientation aOrE;
TopTools_IndexedDataMapOfShapeListOfShape aMEF;
TopTools_ListIteratorOfListOfShape aIt;
//
myShapesToAvoid.Clear();
//
iCnt=0;
while (1) {
++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)) {
2012-08-09 13:58:02 +06:00
TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
}
2012-08-09 13:58:02 +06:00
/*
else {
2013-06-17 18:15:50 +06:00
int a=0;
}
2012-08-09 13:58:02 +06:00
*/
}
aNbE=aMEF.Extent();
//
// 2. myFacesToAvoid
for (i=1; i<=aNbE; ++i) {
2012-08-09 13:58:02 +06:00
const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aMEF.FindKey(i)));
if (BRep_Tool::Degenerated(aE)) {
2012-08-09 13:58:02 +06:00
continue;
}
//
TopTools_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
//
aNbF=aLF.Extent();
if (!aNbF) {
2012-08-09 13:58:02 +06:00
continue;
}
//
aOrE=aE.Orientation();
//
2012-08-09 13:58:02 +06:00
const TopoDS_Face& aF1=*((TopoDS_Face*)(&aLF.First()));
if (aNbF==1) {
2012-08-09 13:58:02 +06:00
if (aOrE==TopAbs_INTERNAL) {
continue;
}
bFound=Standard_True;
myShapesToAvoid.Add(aF1);
}
else if (aNbF==2) {
2012-08-09 13:58:02 +06:00
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);
}
}
2012-08-09 13:58:02 +06:00
/*//DEB
2009-02-13 17:16:39 +05:00
else {
2012-08-09 13:58:02 +06:00
TopTools_ListIteratorOfListOfShape aItLF;
//
aItLF.Initialize (aLF);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Shape& aFx=aItLF.Value();
int a=0;
}
2009-02-13 17:16:39 +05:00
}
2012-08-09 13:58:02 +06:00
*///DEB
}// for (i=1; i<=aNbE; ++i) {
//
if (!bFound) {
break;
}
//
2012-08-09 13:58:02 +06:00
}//while (1)
}
//=======================================================================
//function : PerformLoops
2012-08-09 13:58:02 +06:00
//purpose :
//=======================================================================
2012-08-09 13:58:02 +06:00
void GEOMAlgo_BuilderSolid::PerformLoops()
{
myErrorStatus=0;
//
myLoops.Clear();
//
2012-08-09 13:58:02 +06:00
Standard_Integer aNbLF, aNbOff, aNbFP;
TopAbs_Orientation anOr;
TopoDS_Edge aEL;
BRep_Builder aBB;
NMTTools_CoupleOfShape aCSOff;
2012-08-09 13:58:02 +06:00
TopTools_MapOfOrientedShape AddedFacesMap;
TopTools_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
2009-02-13 17:16:39 +05:00
TopTools_ListIteratorOfListOfShape aItF, aIt;
TopTools_MapIteratorOfMapOfOrientedShape aItM;
TopoDS_Iterator aItS;
//
//=================================================
//
// 1. Shells Usual
//
aItF.Initialize (myShapes);
for (; aItF.More(); aItF.Next()) {
const TopoDS_Shape& aFF = aItF.Value();
TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
}
//
aItF.Initialize (myShapes);
for (; aItF.More(); aItF.Next()) {
const TopoDS_Shape& aFF = aItF.Value();
if (myShapesToAvoid.Contains(aFF)) {
continue;
}
if (!AddedFacesMap.Add(aFF)) {
continue;
}
//
// make a new shell
TopoDS_Shell aShell;
aBB.MakeShell(aShell);
aBB.Add(aShell, aFF);
//
aMEFP.Clear();
TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
//
// loop on faces added to Shell; add their neighbor faces to Shell and so on
TopoDS_Iterator aItAddedF (aShell);
for (; aItAddedF.More(); aItAddedF.Next()) {
2012-08-09 13:58:02 +06:00
const TopoDS_Face& aF = *((TopoDS_Face*)(&aItAddedF.Value()));
//
// loop on edges of aF; find a good neighbor face of aF by aE
TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
for (; aEdgeExp.More(); aEdgeExp.Next()) {
2012-08-09 13:58:02 +06:00
const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aEdgeExp.Current()));
//
//1
if (aMEFP.Contains(aE)) {
const TopTools_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
aNbFP=aLFP.Extent();
if (aNbFP>1) {
continue;
}
}
//2
anOr=aE.Orientation();
if (anOr==TopAbs_INTERNAL) {
continue;
}
//3
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
// candidate faces list
const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
2012-08-09 13:58:02 +06:00
aNbLF=aLF.Extent();
if (!aNbLF) {
continue;
2012-08-09 13:58:02 +06:00
}
//
// try to select one of neighbors
// check if a face already added to Shell shares E
Standard_Boolean bFound;
TopTools_ListIteratorOfListOfShape aItLF;
NMTTools_ListOfCoupleOfShape aLCSOff;
//
aItLF.Initialize(aLF);
for (; aItLF.More(); aItLF.Next()) {
const TopoDS_Face& aFL=*((TopoDS_Face*)(&aItLF.Value()));
if (myShapesToAvoid.Contains(aFL)) {
continue;
}
if (aF.IsSame(aFL)) {
continue;
}
if (AddedFacesMap.Contains(aFL)){
continue;
}
//
bFound=GEOMAlgo_Tools3D::GetEdgeOff(aE, aFL, aEL);
if (!bFound) {
continue;
}
//
aCSOff.SetShape1(aEL);
aCSOff.SetShape2(aFL);
aLCSOff.Append(aCSOff);
}//for (; aItLF.More(); aItLF.Next()) {
//
aNbOff=aLCSOff.Extent();
if (!aNbOff){
continue;
}
//
TopoDS_Face aSelF;
if (aNbOff==1) {
aSelF=*((TopoDS_Face*)(&aLCSOff.First().Shape2()));
}
else if (aNbOff>1){
GEOMAlgo_Tools3D::GetFaceOff(aE, aF, aLCSOff, aSelF);
}
//
if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
aBB.Add(aShell, aSelF);
2012-08-09 13:58:02 +06:00
TopExp::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
}
} // for (; aEdgeExp.More(); aEdgeExp.Next()) {
} //for (; aItAddedF.More(); aItAddedF.Next()) {
2012-08-09 13:58:02 +06:00
//
2009-02-13 17:16:39 +05:00
if (IsClosedShell(aShell)) {
myLoops.Append(aShell);
}
else {
2012-08-09 13:58:02 +06:00
Standard_Boolean bRefine;
TopoDS_Shell aShx;
//
bRefine=RefineShell(aShell, aShx);
if (bRefine) {
2013-06-17 18:15:50 +06:00
myLoops.Append(aShx);
2009-02-13 17:16:39 +05:00
}
}
} // for (; aItF.More(); aItF.Next()) {
2009-02-13 17:16:39 +05:00
//
// Post Treatment
TopTools_MapOfOrientedShape aMP;
2012-08-09 13:58:02 +06:00
//
2009-02-13 17:16:39 +05:00
// 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);
}
}
2012-08-09 13:58:02 +06:00
//
// b. collect all faces that are to avoid
2009-02-13 17:16:39 +05:00
aItM.Initialize(myShapesToAvoid);
for (; aItM.More(); aItM.Next()) {
const TopoDS_Shape& aF=aItM.Key();
aMP.Add(aF);
}
//
2012-08-09 13:58:02 +06:00
// c. add all faces that are not processed to myShapesToAvoid
2009-02-13 17:16:39 +05:00
aIt.Initialize (myShapes);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
if (!aMP.Contains(aF)) {
myShapesToAvoid.Add(aF);
}
}
//=================================================
//
// 2.Internal Shells
//
myLoopsInternal.Clear();
//
aEFMap.Clear();
AddedFacesMap.Clear();
//
2012-08-09 13:58:02 +06:00
if (myComputeInternalShapes) {
aItM.Initialize(myShapesToAvoid);
for (; aItM.More(); aItM.Next()) {
const TopoDS_Shape& aFF=aItM.Key();
TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
}
//
2012-08-09 13:58:02 +06:00
aItM.Initialize(myShapesToAvoid);
for (; aItM.More(); aItM.Next()) {
const TopoDS_Shape& aFF=aItM.Key();
if (!AddedFacesMap.Add(aFF)) {
continue;
}
//
2012-08-09 13:58:02 +06:00
// make a new shell
TopoDS_Shell aShell;
aBB.MakeShell(aShell);
aBB.Add(aShell, aFF);
//
TopoDS_Iterator aItAddedF (aShell);
for (; aItAddedF.More(); aItAddedF.Next()) {
const TopoDS_Face& aF = *((TopoDS_Face*)(&aItAddedF.Value()));
//
TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
for (; aEdgeExp.More(); aEdgeExp.Next()) {
const TopoDS_Edge& aE = *((TopoDS_Edge*)(&aEdgeExp.Current()));
const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
aItF.Initialize(aLF);
for (; aItF.More(); aItF.Next()) {
const TopoDS_Face& aFL=*((TopoDS_Face*)(&aItF.Value()));
if (AddedFacesMap.Add(aFL)){
aBB.Add(aShell, aFL);
}
}
}
}
2012-08-09 13:58:02 +06:00
myLoopsInternal.Append(aShell);
}
}
}
//=======================================================================
//function : PerformAreas
2012-08-09 13:58:02 +06:00
//purpose :
//=======================================================================
2012-08-09 13:58:02 +06:00
void GEOMAlgo_BuilderSolid::PerformAreas()
{
myErrorStatus=0;
//
Standard_Boolean bIsGrowthShell, bIsHole;
2012-08-09 13:58:02 +06:00
TopTools_ListOfShape aNewSolids, aHoleShells;
TopoDS_Shape anInfinitePointShape;
TopTools_DataMapOfShapeShape aInOutMap;
TopTools_DataMapOfShapeListOfShape aMSH;
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt;
TopTools_IndexedMapOfShape aMHF;
BRep_Builder aBB;
//
myAreas.Clear();
//
// Draft solids [aNewSolids]
aShellIt.Initialize(myLoops);
for ( ; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aShell = aShellIt.Value();
//
bIsGrowthShell=IsGrowthShell(aShell, aMHF);
if (bIsGrowthShell) {
// make a growth solid from a shell
TopoDS_Solid Solid;
aBB.MakeSolid(Solid);
aBB.Add (Solid, aShell);
//
aNewSolids.Append (Solid);
}
else{
// check if a shell is a hole
bIsHole=IsHole(aShell, myContext);
2012-08-09 13:58:02 +06:00
//
if (bIsHole) {
2012-08-09 13:58:02 +06:00
aHoleShells.Append(aShell);
TopExp::MapShapes(aShell, TopAbs_FACE, aMHF);
}
else {
2012-08-09 13:58:02 +06:00
// make a growth solid from a shell
TopoDS_Solid Solid;
aBB.MakeSolid(Solid);
aBB.Add (Solid, aShell);
//
aNewSolids.Append (Solid);
}
}
}
//
// 2. Find outer growth shell that is most close to each hole shell
aShellIt.Initialize(aHoleShells);
for (; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aHole = aShellIt.Value();
//
aSolidIt.Initialize(aNewSolids);
for ( ; aSolidIt.More(); aSolidIt.Next()) {
const TopoDS_Shape& aSolid = aSolidIt.Value();
//
if (!IsInside(aHole, aSolid, myContext)){
continue;
}
//
if ( aInOutMap.IsBound (aHole)){
const TopoDS_Shape& aSolid2 = aInOutMap(aHole);
if (IsInside(aSolid, aSolid2, myContext)) {
aInOutMap.UnBind(aHole);
aInOutMap.Bind (aHole, aSolid);
}
}
else{
aInOutMap.Bind (aHole, aSolid);
}
}
//
// Add aHole to a map Solid/ListOfHoles [aMSH]
if (aInOutMap.IsBound(aHole)){
const TopoDS_Shape& aSolid=aInOutMap(aHole);
if (aMSH.IsBound(aSolid)) {
2012-08-09 13:58:02 +06:00
TopTools_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
aLH.Append(aHole);
}
else {
2012-08-09 13:58:02 +06:00
TopTools_ListOfShape aLH;
aLH.Append(aHole);
aMSH.Bind(aSolid, aLH);
}
//aBB.Add (aSolid, aHole);
}
}// for (; aShellIt.More(); aShellIt.Next()) {
//
// 3. Add aHoles to Solids
aItMSH.Initialize(aMSH);
for (; aItMSH.More(); aItMSH.Next()) {
2012-08-09 13:58:02 +06:00
TopoDS_Solid aSolid=*((TopoDS_Solid*)(&aItMSH.Key()));
//
const TopTools_ListOfShape& aLH=aItMSH.Value();
aShellIt.Initialize(aLH);
for (; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aHole = aShellIt.Value();
aBB.Add (aSolid, aHole);
}
//
// update classifier
BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid);
aSC.Load(aSolid);
//
}
//
2012-08-09 13:58:02 +06:00
// These aNewSolids are draft solids that
// do not contain any internal shapes
//
myAreas.Append(aNewSolids);
}
//=======================================================================
//function : PerformInternalShapes
2012-08-09 13:58:02 +06:00
//purpose :
//=======================================================================
2012-08-09 13:58:02 +06:00
void GEOMAlgo_BuilderSolid::PerformInternalShapes()
{
myErrorStatus=0;
//
Standard_Integer aNbFI=myLoopsInternal.Extent();
if (!aNbFI) {// nothing to do
return;
}
2012-08-09 13:58:02 +06:00
//
Standard_Integer bFlag;
BRep_Builder aBB;
TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt;
2012-08-09 13:58:02 +06:00
TopoDS_Iterator aIt;
TopTools_MapOfShape aMF, aMFP, aMFS;
TopTools_MapIteratorOfMapOfShape aItMF;
TopTools_IndexedDataMapOfShapeListOfShape aMEF;
TopTools_ListOfShape aLSI;
//
// 1. All internal faces
aShellIt.Initialize(myLoopsInternal);
for (; aShellIt.More(); aShellIt.Next()) {
const TopoDS_Shape& aShell=aShellIt.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()) {
2012-08-09 13:58:02 +06:00
TopoDS_Solid& aSolid=*((TopoDS_Solid*)(&aSolidIt.Value()));
//
2012-08-09 13:58:02 +06:00
//modified by NIZNHY-PKV Wed Mar 07 08:52:18 2012f
aMFS.Clear();
{
TopExp_Explorer aExp(aSolid, TopAbs_FACE);
while (aExp.More()) {
2013-06-17 18:15:50 +06:00
aMFS.Add(aExp.Current());
aExp.Next();
2012-08-09 13:58:02 +06:00
}
}
//modified by NIZNHY-PKV Wed Mar 07 08:52:20 2012t
aMEF.Clear();
TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
//
// 2.1 Separate faces to process aMFP
aMFP.Clear();
aItMF.Initialize(aMF);
for (; aItMF.More(); aItMF.Next()) {
2012-08-09 13:58:02 +06:00
const TopoDS_Face& aF=*((TopoDS_Face*)(&aItMF.Key()));
//modified by NIZNHY-PKV Wed Mar 07 08:54:56 2012f
if (!aMFS.Contains(aF)) {
2013-06-17 18:15:50 +06:00
bFlag=GEOMAlgo_Tools3D::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext);
if (bFlag) {
aMFP.Add(aF);
}
}
2012-08-09 13:58:02 +06:00
//if (GEOMAlgo_Tools3D::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext)) {
// aMFP.Add(aF);
//}
//modified by NIZNHY-PKV Wed Mar 07 08:56:07 2012t
}
//
// 2.2 Make Internal Shells
aLSI.Clear();
MakeInternalShells(aMFP, 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);
}
//
// 2.4 Remove faces aMFP from aMF
aItMF.Initialize(aMFP);
for (; aItMF.More(); aItMF.Next()) {
const TopoDS_Shape& aF=aItMF.Key();
aMF.Remove(aF);
}
//
aNbFI=aMF.Extent();
if (!aNbFI) {
break;
}
} //for ( ; aSolidIt.More(); aSolidIt.Next()) {
}
//=======================================================================
//function : MakeInternalShells
2012-08-09 13:58:02 +06:00
//purpose :
//=======================================================================
void MakeInternalShells(const TopTools_MapOfShape& theMF,
2012-08-09 13:58:02 +06:00
TopTools_ListOfShape& theShells)
{
TopTools_MapIteratorOfMapOfShape aItM;
TopTools_MapOfShape aAddedFacesMap;
TopTools_ListIteratorOfListOfShape aItF;
TopTools_IndexedDataMapOfShapeListOfShape aMEF;
BRep_Builder aBB;
//
aItM.Initialize(theMF);
for (; aItM.More(); aItM.Next()) {
const TopoDS_Shape& aF=aItM.Key();
TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
}
//
aItM.Initialize(theMF);
for (; aItM.More(); aItM.Next()) {
TopoDS_Shape aFF=aItM.Key();
if (!aAddedFacesMap.Add(aFF)) {
continue;
}
//
// make a new shell
TopoDS_Shell aShell;
2012-08-09 13:58:02 +06:00
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();
2012-08-09 13:58:02 +06:00
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);
}
}
}
}
theShells.Append(aShell);
}
}
//=======================================================================
//function : IsHole
2012-08-09 13:58:02 +06:00
//purpose :
//=======================================================================
Standard_Boolean IsHole(const TopoDS_Shape& theS2,
2012-08-09 13:58:02 +06:00
const 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
2012-08-09 13:58:02 +06:00
//purpose :
//=======================================================================
Standard_Boolean IsInside(const TopoDS_Shape& theS1,
2012-08-09 13:58:02 +06:00
const TopoDS_Shape& theS2,
const 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;
const TopoDS_Face& aF = TopoDS::Face(aExp.Current());
2012-08-09 13:58:02 +06:00
aState=GEOMAlgo_Tools3D::ComputeState(aF, *pS2, 1.e-14, aBounds, theContext);
}
return (aState==TopAbs_IN);
}
//=======================================================================
//function : IsGrowthShell
2012-08-09 13:58:02 +06:00
//purpose :
//=======================================================================
Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
2012-08-09 13:58:02 +06:00
const TopTools_IndexedMapOfShape& theMHF)
{
Standard_Boolean bRet;
TopoDS_Iterator aIt;
2012-08-09 13:58:02 +06:00
//
bRet=Standard_False;
if (theMHF.Extent()) {
aIt.Initialize(theShell);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
if (theMHF.Contains(aF)) {
2012-08-09 13:58:02 +06:00
return !bRet;
}
}
}
return bRet;
}
2009-02-13 17:16:39 +05:00
//=======================================================================
//function : IsClosedShell
2012-08-09 13:58:02 +06:00
//purpose :
2009-02-13 17:16:39 +05:00
//=======================================================================
Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
{
Standard_Integer aNbE;
Standard_Boolean bRet;
TopoDS_Iterator aIt;
TopExp_Explorer aExp;
TopTools_MapOfShape aM;
2012-08-09 13:58:02 +06:00
//
2009-02-13 17:16:39 +05:00
bRet=Standard_False;
aIt.Initialize(theShell);
for(; aIt.More(); aIt.Next()) {
const TopoDS_Face& aF=TopoDS::Face(aIt.Value());
aExp.Init(aF, TopAbs_EDGE);
for (; aExp.More(); aExp.Next()) {
2012-08-09 13:58:02 +06:00
const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aExp.Current()));
2009-02-13 17:16:39 +05:00
if (BRep_Tool::Degenerated(aE)) {
2012-08-09 13:58:02 +06:00
continue;
2009-02-13 17:16:39 +05:00
}
2012-08-09 13:58:02 +06:00
//
2009-02-13 17:16:39 +05:00
if (aE.Orientation()==TopAbs_INTERNAL) {
2012-08-09 13:58:02 +06:00
continue;
2009-02-13 17:16:39 +05:00
}
2012-08-09 13:58:02 +06:00
//
2009-02-13 17:16:39 +05:00
if (!aM.Add(aE)) {
2012-08-09 13:58:02 +06:00
aM.Remove(aE);
2009-02-13 17:16:39 +05:00
}
}
}
//
aNbE=aM.Extent();
if (!aNbE) {
bRet=!bRet;
}
return bRet;
}
2012-08-09 13:58:02 +06:00
//=======================================================================
//function : RefineShell
//purpose :
//=======================================================================
Standard_Boolean RefineShell(const TopoDS_Shell& aShell,
2013-06-17 18:15:50 +06:00
TopoDS_Shell& aShx)
2012-08-09 13:58:02 +06:00
{
Standard_Boolean bRet;
Standard_Integer i, aNbE, aNbF;
TopAbs_Orientation aOrE;
TopTools_IndexedDataMapOfShapeListOfShape aMEF;
TopTools_MapOfOrientedShape aMFx;
//
bRet=Standard_False;
//
TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
aNbE=aMEF.Extent();
for (i=1; i<=aNbE; ++i) {
const TopoDS_Edge &aE=*((TopoDS_Edge*)(&aMEF.FindKey(i)));
//
if (BRep_Tool::Degenerated(aE)) {
continue;
}
//
aOrE=aE.Orientation();
//
const TopTools_ListOfShape& aLF=aMEF(i);
aNbF=aLF.Extent();
if (!aNbF) {
continue;
}
//
const TopoDS_Face& aF1=*((TopoDS_Face*)(&aLF.First()));
if (aNbF==1) {
if (aOrE==TopAbs_INTERNAL) {
2013-06-17 18:15:50 +06:00
continue;
2012-08-09 13:58:02 +06:00
}
aMFx.Add(aF1);
}
//
else if (aNbF==2) {
const TopoDS_Face& aF2=*((TopoDS_Face*)(&aLF.Last()));
if (aF2.IsSame(aF1)) {
2013-06-17 18:15:50 +06:00
if (BRep_Tool::IsClosed(aE, aF1)) {
continue;
}
if (aOrE==TopAbs_INTERNAL) {
continue;
}
aMFx.Add(aF1);
aMFx.Add(aF2);
2012-08-09 13:58:02 +06:00
}
}
}
//
aNbF=aMFx.Extent();
if (!aNbF) {
return bRet;
}
//
BRep_Builder aBB;
TopoDS_Iterator aIt;
//
aNbF=0;
aBB.MakeShell(aShx);
aIt.Initialize(aShell);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Shape& aF=aIt.Value();
if (!aMFx.Contains(aF)) {
aBB.Add(aShx, aF);
++aNbF;
}
}
//
if (aNbF) {
bRet=IsClosedShell(aShx);
}
//
return bRet;
}
//
// ErrorStatus :
// 11 - Null Context