-using namespace std;
-// File : Partition_Inter3d.cxx
-// Created : Thu Aug 02 16:20:37 2001
-// Author : Benedicte MARTIN
-// Project : SALOME
-// Module : PARTITION
-// Copyright : Open CASCADE
+// 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.
+//
+// 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_Inter3d.cxx
+// Author : Benedicte MARTIN
+// Module : GEOM
// $Header$
-
-#include "Partition_Inter3d.ixx"
+//
#include "Partition_Inter2d.hxx"
+#include "Partition_Inter3d.ixx"
#include "utilities.h"
-#include <BRepOffset_Tool.hxx>
-#include <BRep_Builder.hxx>
-#include <BRep_Tool.hxx>
#include <BRepAlgo_AsDes.hxx>
#include <BRepAlgo_Image.hxx>
#include <BRepLib.hxx>
+#include <BRepOffset_Tool.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
+#include <TopOpeBRepTool_BoxSort.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
#include <TopoDS.hxx>
-#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
-#include <TopoDS_Compound.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
-#include <TopOpeBRepTool_BoxSort.hxx>
+#include <TopoDS_Vertex.hxx>
#ifdef DEB
#include <DBRep.hxx>
#endif
-#include <stdio.h>
-#include <TopOpeBRepDS_HDataStructure.hxx>
-#include <TopOpeBRep_DSFiller.hxx>
-#include <TopOpeBRepTool_GeomTool.hxx>
-#include <TopOpeBRepTool_OutCurveType.hxx>
-#include <TopOpeBRepDS_BuildTool.hxx>
+#include <BRepLib_MakeVertex.hxx>
+#include <BRepTools.hxx>
+#include <Extrema_ExtPS.hxx>
+#include <Extrema_POnSurf.hxx>
+#include <Geom2dAPI_ProjectPointOnCurve.hxx>
+#include <Geom2d_Curve.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomAdaptor_Surface.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+#include <Geom_SphericalSurface.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <Precision.hxx>
+#include <TColStd_MapOfInteger.hxx>
#include <TopOpeBRepBuild_Builder.hxx>
+#include <TopOpeBRepDS_BuildTool.hxx>
#include <TopOpeBRepDS_CurveExplorer.hxx>
-#include <Geom2d_Curve.hxx>
+#include <TopOpeBRepDS_HDataStructure.hxx>
+#include <TopOpeBRepDS_Interference.hxx>
#include <TopOpeBRepDS_PointIterator.hxx>
#include <TopOpeBRepDS_Transition.hxx>
-#include <Geom_Curve.hxx>
#include <TopOpeBRepTool_CurveTool.hxx>
-#include <TopOpeBRepDS_Interference.hxx>
+#include <TopOpeBRepTool_GeomTool.hxx>
+#include <TopOpeBRepTool_OutCurveType.hxx>
+#include <TopOpeBRep_DSFiller.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
-#include <BRepLib_MakeVertex.hxx>
-#include <Precision.hxx>
-#include <TColStd_MapOfInteger.hxx>
-#include <BRepTools.hxx>
-#include <Geom_RectangularTrimmedSurface.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom_TrimmedCurve.hxx>
-#include <Geom2dAPI_ProjectPointOnCurve.hxx>
-#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <stdio.h>
+
+using namespace std;
//=======================================================================
//function : Partition_Inter3d
// avoid intersecting faces of one shape
TopoDS_Shape S1;
if (FaceShapeMap.IsBound(F1)) S1 = FaceShapeMap.Find(F1);
- // avoid intersecting faces sharing vertices, suppose they belong to
- // shapes sharing same faces
- TopTools_IndexedMapOfShape VM;
- TopExp::MapShapes( F1, TopAbs_VERTEX, VM);
+
+ // to filter faces sharing an edge
+ TopTools_IndexedMapOfShape EM;
+ TopExp::MapShapes( F1, TopAbs_EDGE, EM);
TColStd_ListIteratorOfListOfInteger itLI = BOS.Compare(F1);
for (; itLI.More(); itLI.Next()) {
if (!S1.IsNull() && S1.IsSame(S2))
continue; // descendants of one shape
- TopExp_Explorer expV (F2, TopAbs_VERTEX);
- for ( ; expV.More(); expV.Next())
- if (VM.Contains( expV.Current() ))
+ TopExp_Explorer expE (F2, TopAbs_EDGE);
+ for ( ; expE.More(); expE.Next())
+ if (EM.Contains( expE.Current() ))
break;
- if (expV.More())
- continue; // faces have a common edge
-
+ if (expE.More())
+ {
+ // faces have a common edge, check if they are a tool and a face
+ // generated by the tool in another shape; in that case they are
+ // to be intersected
+ TopLoc_Location L1, L2;
+ Handle(Geom_Surface) S1 = BRep_Tool::Surface( F1, L1 );
+ Handle(Geom_Surface) S2 = BRep_Tool::Surface( F2, L2 );
+ if ( S1 != S2 || L1 != L2 )
+ continue;
+ }
+
F1.Orientation(TopAbs_FORWARD);
F2.Orientation(TopAbs_FORWARD);
FacesPartition(F1,F2);
if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
S = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
}
- //---------------
- // Recadre en U.
- //---------------
- if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
+ if (!S->IsUPeriodic() && !S->IsVPeriodic())
+ return;
BRepTools::UVBounds(F,umin,umax,vmin,vmax);
+ gp_Pnt2d Pf = C2d->Value(f);
+ gp_Pnt2d Pl = C2d->Value(l);
+ const Standard_Real Um = 0.34*f + 0.66*l;
+ gp_Pnt2d Pm = C2d->Value( Um );
+
+ // sometimes on shpere, pcurve is out of domain by V though S is
+ // UPeriodic, sometimes it is in domain but nontheless it has
+ // wrong position.
+ // Check pcurve position by 3D point
+ if (S->IsKind(STANDARD_TYPE( Geom_SphericalSurface )))
+ {
+ // get point on the surface
+ gp_Pnt Ps = S->Value( Pm.X(), Pm.Y() );
+ // get point on the edge
+ Handle(Geom_Curve) C = BRep_Tool::Curve( E, f, l );
+ gp_Pnt Pc = C->Value( Um );
+ // compare points
+ Standard_Real TolE = BRep_Tool::Tolerance( E );
+ if ( Pc.SquareDistance( Ps ) * 0.95 < TolE * TolE )
+ return; // OK
+
+ // find good UV for Pc: project Pc on S
+ GeomAdaptor_Surface SA (S);
+ Extrema_ExtPS anExtPS (Pc, SA,
+ SA.UResolution( TolE ), SA.VResolution( TolE ));
+ if (anExtPS.IsDone())
+ {
+ Standard_Integer i, nbExt = anExtPS.NbExt();
+ Extrema_POnSurf aPOnSurf;
+ for (i = 1; i <= nbExt; ++i )
+ if (anExtPS.Value( i ) <= TolE) {
+ aPOnSurf = anExtPS.Point( i );
+ break;
+ }
+ if (i <= nbExt) {
+ // a point found
+ Standard_Real u, v;
+ aPOnSurf.Parameter( u, v );
+ gp_Pnt2d aGoodPm ( u, v );
+ C2d->Translate( Pm , aGoodPm );
+ }
+ }
+ }
+
+ //---------------
+ // Recadre en U.
+ //---------------
if (S->IsUPeriodic()) {
Standard_Real period = S->UPeriod();
Standard_Real eps = period*1.e-6;
- gp_Pnt2d Pf = C2d->Value(f);
- gp_Pnt2d Pl = C2d->Value(l);
- gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
Standard_Real du = 0.;
if (S->IsVPeriodic()) {
Standard_Real period = S->VPeriod();
Standard_Real eps = period*1.e-6;
- gp_Pnt2d Pf = C2d->Value(f);
- gp_Pnt2d Pl = C2d->Value(l);
- gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
Standard_Real dv = 0.;
while (itLE.More()) {
TopoDS_Edge E = TopoDS::Edge(itLE.Value());
-// Standard_Real f,l;
-// BRep_Tool::Range(E,f,l);
PutInBounds (F1,E,pc1);
PutInBounds (F2,E,pc2);
}
}
- // ===================================================
- // Store section edges, same domain faces and verives
- // ===================================================
+ // ========================
+ // store same domain faces
+ // ========================
- TopTools_ListOfShape empty, LSP, LSE;
- if ( DatStr->HasSameDomain( F1 )) { // same domain faces
+ if ( DatStr->HasSameDomain( F1 ))
+ {
+ TopTools_ListOfShape emptyList;
if (!mySameDomainFM.IsBound(F1))
- mySameDomainFM.Bind(F1,empty);
+ mySameDomainFM.Bind(F1,emptyList);
if (!mySameDomainFM.IsBound(F2))
- mySameDomainFM.Bind(F2,empty);
+ mySameDomainFM.Bind(F2,emptyList);
mySameDomainFM(F1).Append(F2);
mySameDomainFM(F2).Append(F1);
}
+ // ====================
+ // Store section edges
+ // ====================
+
const TopOpeBRepDS_DataStructure& DS = DatStr->DS();
- Standard_Integer j,i,nes = DS.NbSectionEdges();
- if (!nes) return;
+ Standard_Integer j,i,nse = DS.NbSectionEdges();
+ if (nse == 0) return;
TopoDS_Vertex V, sdeV1, sdeV2;
TopTools_MapOfShape MV;
+ TopTools_ListOfShape LSE; // list of section edges
+ TopoDS_Face dummyF;
- // put vertices on section edges
- for (i=1;i<=nes;i++) {
-
- TopoDS_Edge se, sde, oe; // section, same domain, other edge
- se = DS.SectionEdge(i);
+ for (i = 1; i <= nse; i++)
+ {
+ const TopoDS_Edge & se = DS.SectionEdge(i);
if (! TopB.IsSplit(se,TopAbs_ON))
continue;
+ LSE.Append( se );
+ // add vertices where section edges interferes with other
+ // edges as its descendant in myAsDes
+
+ TopoDS_Edge sde, oe; // same domain, other edge
if (DatStr->HasSameDomain(se)) {
sde = TopoDS::Edge( DatStr->SameDomain(se).Value() );
TopExp::Vertices( sde, sdeV1, sdeV2);
}
-
- TColStd_MapOfInteger MIV;
+ TColStd_MapOfInteger MIV; // indices of added edges
TopOpeBRepDS_PointIterator itP (DS.ShapeInterferences( se ));
itP.SupportKind( TopOpeBRepDS_EDGE );
+ // loop on intersections of se
for (; itP.More(); itP.Next()) {
oe = TopoDS::Edge( DS.Shape( itP.Support()));
if (itP.IsVertex()) {
+ // there is a vertex at intersection
if ( !MIV.Add( itP.Current() ))
continue;
V = TopoDS::Vertex( DS.Shape( itP.Current()));
oe = sde;
V = ReplaceSameDomainV( V , oe );
V.Orientation( TopAbs_INTERNAL);
- B.UpdateVertex( V, itP.Parameter(), se, 0.);
+ B.UpdateVertex( V, itP.Parameter(), se, 0.); // AddVonE() sets real U
}
else {
+ // create a new vertex at the intersection point
const TopOpeBRepDS_Point& DSP = DS.Point( itP.Current());
V = BRepLib_MakeVertex( DSP.Point() );
V.Orientation( TopAbs_INTERNAL);
}
}
}
- TopoDS_Vertex addedV = Partition_Inter2d::AddVonE( V,se,oe,myAsDes);
+ // add V on the both intersecting edges
+ TopoDS_Vertex addedV = Partition_Inter2d::AddVonE( V,se,oe,myAsDes,dummyF);
if (!addedV.IsSame( V ))
- mySameDomainVM.Bind (V, addedV);
- MV.Add( addedV );
+ mySameDomainVM.Bind (V, addedV); // equal vertex is already there
+
+ MV.Add( addedV ); // to ease storage of vertices of ON splits
}
}
- TopB.SplitSectionEdges();
+ // add section edge to the face it intersects and find
+ // splits ON that do not have same domain pair
+
+ TopB.SplitSectionEdges(); // let TopB find ON splits
- TopTools_DataMapOfShapeShape SEM; // map split - section edge
+ TopTools_MapOfShape SPM; // map of ON splits
TopTools_IndexedMapOfShape ME[2];
TopExp::MapShapes( F1, TopAbs_EDGE, ME[1]);
TopExp::MapShapes( F2, TopAbs_EDGE, ME[0]);
- // add section edge to the face it intersects and find
- // splits ON that do not have same domain pair
-
- for (i=1;i<=nes;i++) {
+ TopTools_ListIteratorOfListOfShape itSP, itLSE (LSE);
+ while ( itLSE.More() ) {
- const TopoDS_Edge& se = DS.SectionEdge(i);
- if (! TopB.IsSplit(se,TopAbs_ON))
- continue;
+ TopoDS_Edge se = TopoDS::Edge( itLSE.Value() );
+ // move itLSE to the next se
Standard_Integer ancRank = DS.AncestorRank(se);
if (ME[ancRank-1].Contains( se ))
- continue; // se is an edge of face it intersects
+ {
+ LSE.Remove( itLSE ); // se is an edge of face it intersects
+ continue;
+ }
+ else
+ {
+ itLSE.Next();
+ }
const TopoDS_Face& F = (ancRank == 1) ? F2 : F1;
// add se to face but dont add twice
- TopTools_ListIteratorOfListOfShape itE;
+ TopTools_ListIteratorOfListOfShape itE( myAsDes->Descendant( F ));
if (myAsDes->HasDescendant( F )) {
- for (itE.Initialize( (myAsDes->Descendant( F )) ); itE.More(); itE.Next())
+ for ( ; itE.More(); itE.Next())
if (se.IsSame( itE.Value() ))
break;
}
- if (!itE.More()) {
+ if (!itE.More())
+ {
myAsDes->Add( F, se );
+
+ // check se pcurve on F
Standard_Real tol, f,l, umin=1e100, umax=-1e100;
Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( se, F, f,l);
if (pc.IsNull()) {
- TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) );
- for ( ;it.More();it.Next()) {
- const TopoDS_Edge& E = TopoDS::Edge ( it.Value());
+ itSP.Initialize( TopB.Splits(se,TopAbs_ON) );
+ for ( ; itSP.More(); itSP.Next()) {
+ const TopoDS_Edge& E = TopoDS::Edge ( itSP.Value());
BRep_Tool::Range(E, f, l);
umin = Min( umin, f);
umax = Max( umax, l);
B.UpdateEdge( se, pc, F, tol);
}
}
-
+
// to detect splits that do not have same domain pair
- TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) );
- for ( ;it.More();it.Next()) {
- const TopoDS_Edge& S = TopoDS::Edge ( it.Value());
- if (SEM.IsBound( S ))
- SEM.UnBind( S );
- else
- SEM.Bind( S, se);
+ // ie which split a face into parts and not pass by its boundary
+ itSP.Initialize( TopB.Splits(se,TopAbs_ON) );
+ for ( ; itSP.More(); itSP.Next()) {
+ const TopoDS_Shape& SP = itSP.Value();
+ if (!SPM.Add( SP ))
+ SPM.Remove( SP );
}
}
// store vertices of ON splits and bind section edges to faces
- for (i=1;i<=nes;i++) {
-
- const TopoDS_Edge& se = DS.SectionEdge(i);
- if (! TopB.IsSplit(se,TopAbs_ON))
- continue;
+
+ for (itLSE.Initialize (LSE); itLSE.More(); itLSE.Next())
+ {
+ const TopoDS_Shape& se = itLSE.Value();
Standard_Integer ancRank = DS.AncestorRank(se);
- if (ME[ancRank-1].Contains( se ))
- continue; // se is an edge of face it intersects
-
TopoDS_Face F = (ancRank == 1) ? F2 : F1;
- // add vertices of splits
+ // add vertices of ON splits which have no same domain pair
Standard_Boolean added = Standard_False;
- TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) );
- for ( ;it.More();it.Next()) {
- const TopoDS_Edge& S = TopoDS::Edge ( it.Value());
- if (!SEM.IsBound( S ))
+ itSP.Initialize( TopB.Splits(se,TopAbs_ON) );
+ for ( ; itSP.More(); itSP.Next())
+ {
+ if (!SPM.Contains( itSP.Value() ))
continue;
+
+ const TopoDS_Edge& S = TopoDS::Edge ( itSP.Value());
added = Standard_True;
mySectionEdgesAD->Add( F, se );
TopoDS_Vertex VS[2];
TopExp::Vertices (S, VS[0], VS[1]);
- for (j=0; j<2; ++j) {
+ for (j=0; j<2; ++j)
+ {
if (mySameDomainVM.IsBound( VS[j] ))
VS[j] = TopoDS::Vertex( mySameDomainVM( VS[j] ));
if ( !MV.Contains( VS[j] )) {
TopTools_ListIteratorOfListOfShape itV( myAsDes->Descendant(se) );
for (; itV.More(); itV.Next()) {
V = TopoDS::Vertex( itV.Value() );
+ if ( V.IsSame( VS[j] ))
+ break;
gp_Pnt P2 = BRep_Tool::Pnt( V );
if (P1.IsEqual( P2, Precision::Confusion())) {
mySameDomainVM.Bind (VS[j], V);
if (!itV.More()) // no interferences with edges
myAsDes->Add( se, VS[j]);
}
+
+ // add ends of ON splits to F in order to detect later
+ // if a split is on face in IsSplitOn()
mySectionEdgesAD->Add( F, VS[j]);
}
+ // in the descendants of F, first go ends of an ON split and
+ // then a split itself
mySectionEdgesAD->Add( F, S );
}
if (!added)
const TopoDS_Face& F2)
{
if (!myDone.IsBound(F1)) {
- TopTools_ListOfShape empty;
- myDone.Bind(F1,empty);
+ TopTools_ListOfShape emptyList;
+ myDone.Bind(F1,emptyList);
}
myDone(F1).Append(F2);
if (!myDone.IsBound(F2)) {
- TopTools_ListOfShape empty;
- myDone.Bind(F2,empty);
+ TopTools_ListOfShape emptyList;
+ myDone.Bind(F2,emptyList);
}
myDone(F2).Append(F1);
}
const TopoDS_Face& F2,
const TopTools_ListOfShape& LInt)
{
-
if (!LInt.IsEmpty()) {
myAsDes->Add( F1,LInt);
myAsDes->Add( F2,LInt);
if (mySameDomainFM.IsBound( F ))
return mySameDomainFM (F);
- static TopTools_ListOfShape empty;
- return empty;
+ static TopTools_ListOfShape emptyList;
+ return emptyList;
}
//=======================================================================