-// GEOM PARTITION : partition algorithm
+// Copyright (C) 2007-2008 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 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.
//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// 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.
-//
-// 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.
-//
-// 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
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+// 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.
//
+// 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
//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+// GEOM PARTITION : partition algorithm
// File : Partition_Spliter.cxx
// Author : Benedicte MARTIN
// Module : GEOM
// $Header$
-
-using namespace std;
+//
#include "Partition_Inter2d.hxx"
#include "Partition_Inter3d.hxx"
#include "Partition_Loop2d.hxx"
# include <OSD_Chronometer.hxx>
#endif
+using namespace std;
+
//=======================================================================
//function : isClosed
//purpose : check id a shape is closed, ie is a solid or a closed shell
myListShapes.Clear();
myMapFaces.Clear();
myMapTools.Clear();
- myClosedShapes.Clear();
myEqualEdges.Clear();
myNewSection.Clear();
+ myClosedShapes.Clear();
+ mySharedFaces.Clear();
myWrappingSolid.Clear();
myFaceShapeMap.Clear();
myInter3d.CompletPart3d(aListFaces, myFaceShapeMap);
#ifdef PART_PERF
- cout << "+++ CompletPart3d()" << endl;
+ MESSAGE("+++ CompletPart3d()");
aCron.Show( cout );
aCron.Reset();
aCron.Start();
FindToolsToReconstruct();
#ifdef PART_PERF
- cout << "+++ FindToolsToReconstruct()" << endl;
+ MESSAGE("+++ FindToolsToReconstruct()");
aCron.Show( cout );
aCron.Reset();
aCron.Start();
myDoneStep = TopAbs_VERTEX;
#ifdef PART_PERF
- cout << "+++ CompletPart2d()" << endl;
+ MESSAGE("+++ CompletPart2d()");
aCron.Show( cout );
aCron.Reset();
aCron.Start();
}
}
#ifdef PART_PERF
- cout << "+++ Cut Edges" << endl;
+ MESSAGE("+++ Cut Edges");
aCron.Show( cout );
aCron.Reset();
aCron.Start();
myDoneStep = TopAbs_EDGE;
#ifdef PART_PERF
- cout << "+++ MergeEqualEdges()" << endl;
+ MESSAGE("+++ MergeEqualEdges()");
aCron.Show( cout );
aCron.Reset();
aCron.Start();
myDoneStep = TopAbs_FACE;
#ifdef PART_PERF
- cout << "+++ MakeFaces()" << endl;
+ MESSAGE("+++ MakeFaces()");
aCron.Show( cout );
aCron.Reset();
aCron.Start();
MakeShells (S , NSL);
if (makeSolids && S.ShapeType() == TopAbs_SOLID )
MakeSolids( S, NSL );
-
+
+ // store new shells or solids
TopTools_ListIteratorOfListOfShape itNSL (NSL);
for ( ; itNSL.More(); itNSL.Next())
myBuilder.Add (myShape, itNSL.Value());
}
#ifdef PART_PERF
- cout << "+++ MakeShells()" << endl;
+ MESSAGE("+++ MakeShells()");
aCron.Show( cout );
#endif
}
}
- // find outer a shell most close to each hole shell
+ // find an outer shell most close to each hole shell
TopTools_DataMapOfShapeShape aInOutMap;
for (aShellIt.Initialize( aHoleShells ); aShellIt.More(); aShellIt.Next())
{
Standard_Boolean isSolid = (theShape.ShapeType() == TopAbs_SOLID);
if (All || isSolid) // All is for sub-result removal
{
+ // loop on not used faces; checked faces will be removed from MFP
+ // during the loop
for ( itm.Initialize( MFP ); itm.More(); itm.Next() ) {
- TopoDS_Shape aFace = itm.Key();
+ const TopoDS_Shape & aFace = itm.Key();
- // find a shape aFace originates from
+ // a shape which aFace originates from
TopoDS_Shape anOrigShape = GetOriginalShape( aFace );
- // find out if all faces of anOrigShape are not in MFP
+ // find out if all split faces of anOrigShape are not in MFP
// and by the way remove them from MFP
Standard_Boolean isAllOut = Standard_True;
TopoDS_Shape aSplitFaces = anOrigShape;
if (myImageShape.HasImage(anOrigShape))
aSplitFaces = myImageShape.Image(anOrigShape).First();
- TopTools_ListOfShape aSplitFaceL;
+ TopTools_ListOfShape aSplitFaceL; // faces candidate to be kept
for (expl.Init( aSplitFaces, TopAbs_FACE ); expl.More(); expl.Next())
{
const TopoDS_Shape & aSpFace = expl.Current();
- // a tool face which become object has image but the whole tool shape has not
+ // a tool face which became object has image but the whole tool shape has not
if (myImageShape.HasImage( aSpFace ))
{
TopExp_Explorer exF (myImageShape.Image( aSpFace ).First(), TopAbs_FACE );
for ( ; exF.More(); exF.Next() )
{
aSplitFaceL.Append( exF.Current() );
- if ( ! MFP.Remove( exF.Current() ))
- isAllOut = Standard_False;
+ if ( ! MFP.Remove( exF.Current() ) && isAllOut )
+ // a shared face might be removed from MFP during a prev loop
+ isAllOut = mySharedFaces.Contains( exF.Current() );
}
}
else
{
aSplitFaceL.Append( aSpFace );
- if ( ! MFP.Remove( aSpFace ))
- isAllOut = Standard_False;
+ if ( ! MFP.Remove( aSpFace ) && isAllOut)
+ // a shared face might be removed from MFP during a prev loop
+ isAllOut = mySharedFaces.Contains( aSpFace );
}
}
- itm.Initialize( MFP );
+ itm.Initialize( MFP ); // iterate remaining faces
if ( !isAllOut )
continue;
myImagesFaces.Bind(F,LNF);
// replace the result faces that have already been built
- // during same domain faces reconstruction
- if (myInter3d.HasSameDomainF( F )) {
- // build map edge to same domain faces
+ // during same domain faces reconstruction done earlier
+ if (myInter3d.HasSameDomainF( F ))
+ {
+ // build map edge to same domain faces: EFM
TopTools_IndexedDataMapOfShapeListOfShape EFM;
TopTools_MapOfShape SDFM; // avoid doubling
itl.Initialize( myInter3d.SameDomain( F ));
for (; itl.More(); itl.Next()) {
if ( !myImagesFaces.HasImage( itl.Value() ))
continue;
+ // loop on splits of a SD face
TopTools_ListIteratorOfListOfShape itNF;
itNF.Initialize (myImagesFaces.Image( itl.Value() ));
for ( ; itNF.More(); itNF.Next()) {
TopExp::MapShapesAndAncestors(SDF, TopAbs_EDGE, TopAbs_FACE, EFM);
}
}
- // do replace
+ // do replace faces in the LNF
TopTools_ListOfShape LOF;
if ( !EFM.IsEmpty() )
itl.Initialize( LNF );
Standard_Real dot;
Partition_Loop3d::IsInside (E, TopoDS::Face(NF), TopoDS::Face(SDF),
1, dot, GoodOri);
- if (dot < 0) {
+ if (dot < 0)
+ {
+ // NF and SDF are on different side of E
if (SDFL.Extent() == 1) {
itl.Next();
continue;
}
else
- SDF = SDFL.Last();
+ SDF = SDFL.Last(); // next face must be on the same side
}
gp_Vec V1 = Partition_Loop3d::Normal( E, TopoDS::Face( NF ));
gp_Vec V2 = Partition_Loop3d::Normal( E, TopoDS::Face( SDF ));
if (!myImagesFaces.HasImage( NF ))
myImagesFaces.Bind( NF, SDF );
+ // mySharedFaces is used in FindFacesInside()
+ mySharedFaces.Add( SDF );
+
LOF.Prepend ( SDF );
LNF.Remove (itl);
}
myImagesFaces.Bind(F,LNF);
}
} // if (myImagesFaces.HasImage( F ))
-
+
+ // fill the resulting compound
for (itl.Initialize(LNF); itl.More(); itl.Next())
myBuilder.Add ( C, itl.Value());
+
} // loop on faces of S
return C;