1 // GEOM PARTITION : partition algorithm
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : Partition_Inter3d.cxx
25 // Author : Benedicte MARTIN
30 #include "Partition_Inter2d.hxx"
31 #include "Partition_Inter3d.ixx"
32 #include "utilities.h"
34 #include <BRepAlgo_AsDes.hxx>
35 #include <BRepAlgo_Image.hxx>
36 #include <BRepLib.hxx>
37 #include <BRepOffset_Tool.hxx>
38 #include <BRep_Builder.hxx>
39 #include <BRep_Tool.hxx>
42 #include <TopExp_Explorer.hxx>
44 #include <TopOpeBRepTool_BoxSort.hxx>
45 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
46 #include <TopTools_ListIteratorOfListOfShape.hxx>
47 #include <TopTools_ListOfShape.hxx>
49 #include <TopoDS_Compound.hxx>
50 #include <TopoDS_Edge.hxx>
51 #include <TopoDS_Face.hxx>
52 #include <TopoDS_Vertex.hxx>
58 #include <BRepLib_MakeVertex.hxx>
59 #include <BRepTools.hxx>
60 #include <Extrema_ExtPS.hxx>
61 #include <Extrema_POnSurf.hxx>
62 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
63 #include <Geom2d_Curve.hxx>
64 #include <GeomAPI_ProjectPointOnCurve.hxx>
65 #include <GeomAdaptor_Surface.hxx>
66 #include <Geom_Curve.hxx>
67 #include <Geom_RectangularTrimmedSurface.hxx>
68 #include <Geom_SphericalSurface.hxx>
69 #include <Geom_Surface.hxx>
70 #include <Geom_TrimmedCurve.hxx>
71 #include <Precision.hxx>
72 #include <TColStd_MapOfInteger.hxx>
73 #include <TopOpeBRepBuild_Builder.hxx>
74 #include <TopOpeBRepDS_BuildTool.hxx>
75 #include <TopOpeBRepDS_CurveExplorer.hxx>
76 #include <TopOpeBRepDS_HDataStructure.hxx>
77 #include <TopOpeBRepDS_Interference.hxx>
78 #include <TopOpeBRepDS_PointIterator.hxx>
79 #include <TopOpeBRepDS_Transition.hxx>
80 #include <TopOpeBRepTool_CurveTool.hxx>
81 #include <TopOpeBRepTool_GeomTool.hxx>
82 #include <TopOpeBRepTool_OutCurveType.hxx>
83 #include <TopOpeBRep_DSFiller.hxx>
84 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
87 //=======================================================================
88 //function : Partition_Inter3d
90 //=======================================================================
92 Partition_Inter3d::Partition_Inter3d()
95 //=======================================================================
96 //function : Partition_Inter3d
98 //=======================================================================
100 Partition_Inter3d::Partition_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes)
103 mySectionEdgesAD = new BRepAlgo_AsDes;
106 //=======================================================================
107 //function : CompletPart3d
108 //purpose : FaceShapeMap is just to know the shape a face belongs to
109 //=======================================================================
111 void Partition_Inter3d::CompletPart3d(const TopTools_ListOfShape& SetOfFaces1,
112 const TopTools_DataMapOfShapeShape& FaceShapeMap)
114 if (myAsDes.IsNull())
115 myAsDes = new BRepAlgo_AsDes;
117 TopTools_ListIteratorOfListOfShape it;
119 //---------------------------------------------------------------
120 // Construction of bounding boxes.
121 //---------------------------------------------------------------
124 TopoDS_Compound CompOS;
125 B.MakeCompound(CompOS);
126 for (it.Initialize(SetOfFaces1); it.More(); it.Next())
127 B.Add(CompOS, it.Value());
129 TopOpeBRepTool_BoxSort BOS;
130 BOS.AddBoxesMakeCOB(CompOS,TopAbs_FACE);
132 for (it.Initialize(SetOfFaces1); it.More(); it.Next()) {
133 TopoDS_Face F1 = TopoDS::Face(it.Value());
135 // avoid intersecting faces of one shape
137 if (FaceShapeMap.IsBound(F1)) S1 = FaceShapeMap.Find(F1);
139 // to filter faces sharing an edge
140 TopTools_IndexedMapOfShape EM;
141 TopExp::MapShapes( F1, TopAbs_EDGE, EM);
143 TColStd_ListIteratorOfListOfInteger itLI = BOS.Compare(F1);
144 for (; itLI.More(); itLI.Next()) {
145 TopoDS_Face F2 = TopoDS::Face(BOS.TouchedShape(itLI));
146 if (F1.IsSame(F2) || IsDone(F1,F2))
150 if (FaceShapeMap.IsBound(F2)) S2 = FaceShapeMap.Find(F2);
151 if (!S1.IsNull() && S1.IsSame(S2))
152 continue; // descendants of one shape
154 TopExp_Explorer expE (F2, TopAbs_EDGE);
155 for ( ; expE.More(); expE.Next())
156 if (EM.Contains( expE.Current() ))
160 // faces have a common edge, check if they are a tool and a face
161 // generated by the tool in another shape; in that case they are
163 TopLoc_Location L1, L2;
164 Handle(Geom_Surface) S1 = BRep_Tool::Surface( F1, L1 );
165 Handle(Geom_Surface) S2 = BRep_Tool::Surface( F2, L2 );
166 if ( S1 != S2 || L1 != L2 )
170 F1.Orientation(TopAbs_FORWARD);
171 F2.Orientation(TopAbs_FORWARD);
172 FacesPartition(F1,F2);
175 // mark as modified a face which has at least one new edge
176 if (!myAsDes->HasDescendant( F1 ))
178 TopTools_ListIteratorOfListOfShape itE (myAsDes->Descendant( F1 ));
179 for ( ; itE.More(); itE.Next()) {
180 if (myNewEdges.Contains( itE.Value())) {
188 //=======================================================================
189 //function : PutInBounds
191 //=======================================================================
193 static void PutInBounds (const TopoDS_Face& F,
194 const TopoDS_Edge& E,
195 Handle(Geom2d_Curve)& C2d)
197 Standard_Real umin,umax,vmin,vmax;
199 BRep_Tool::Range(E,f,l);
201 TopLoc_Location L; // Recup S avec la location pour eviter la copie.
202 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
204 if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
205 S = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
207 if (!S->IsUPeriodic() && !S->IsVPeriodic())
210 BRepTools::UVBounds(F,umin,umax,vmin,vmax);
212 gp_Pnt2d Pf = C2d->Value(f);
213 gp_Pnt2d Pl = C2d->Value(l);
214 const Standard_Real Um = 0.34*f + 0.66*l;
215 gp_Pnt2d Pm = C2d->Value( Um );
217 // sometimes on shpere, pcurve is out of domain by V though S is
218 // UPeriodic, sometimes it is in domain but nontheless it has
220 // Check pcurve position by 3D point
221 if (S->IsKind(STANDARD_TYPE( Geom_SphericalSurface )))
223 // get point on the surface
224 gp_Pnt Ps = S->Value( Pm.X(), Pm.Y() );
225 // get point on the edge
226 Handle(Geom_Curve) C = BRep_Tool::Curve( E, f, l );
227 gp_Pnt Pc = C->Value( Um );
229 Standard_Real TolE = BRep_Tool::Tolerance( E );
230 if ( Pc.SquareDistance( Ps ) * 0.95 < TolE * TolE )
233 // find good UV for Pc: project Pc on S
234 GeomAdaptor_Surface SA (S);
235 Extrema_ExtPS anExtPS (Pc, SA,
236 SA.UResolution( TolE ), SA.VResolution( TolE ));
237 if (anExtPS.IsDone())
239 Standard_Integer i, nbExt = anExtPS.NbExt();
240 Extrema_POnSurf aPOnSurf;
241 for (i = 1; i <= nbExt; ++i )
242 if (anExtPS.Value( i ) <= TolE) {
243 aPOnSurf = anExtPS.Point( i );
249 aPOnSurf.Parameter( u, v );
250 gp_Pnt2d aGoodPm ( u, v );
251 C2d->Translate( Pm , aGoodPm );
259 if (S->IsUPeriodic()) {
260 Standard_Real period = S->UPeriod();
261 Standard_Real eps = period*1.e-6;
262 Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
263 Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
264 Standard_Real du = 0.;
265 if (minC< umin - eps) {
266 du = (int((umin - minC)/period) + 1)*period;
268 if (minC > umax + eps) {
269 du = -(int((minC - umax)/period) + 1)*period;
274 minC += du; maxC += du;
276 // Ajuste au mieux la courbe dans le domaine.
277 if (maxC > umax +100*eps) {
278 Standard_Real d1 = maxC - umax;
279 Standard_Real d2 = umin - minC + period;
280 if (d2 < d1) du =-period;
290 if (S->IsVPeriodic()) {
291 Standard_Real period = S->VPeriod();
292 Standard_Real eps = period*1.e-6;
293 Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
294 Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
295 Standard_Real dv = 0.;
296 if (minC< vmin - eps) {
297 dv = (int((vmin - minC)/period) + 1)*period;
299 if (minC > vmax + eps) {
300 dv = -(int((minC - vmax)/period) + 1)*period;
305 minC += dv; maxC += dv;
307 // Ajuste au mieux la courbe dans le domaine.
308 if (maxC > vmax +100*eps) {
309 Standard_Real d1 = maxC - vmax;
310 Standard_Real d2 = vmin - minC + period;
311 if (d2 < d1) dv =-period;
320 //=======================================================================
323 //=======================================================================
325 void Partition_Inter3d::Inter3D(const TopoDS_Face& F1,
326 const TopoDS_Face& F2,
327 TopTools_ListOfShape& L)
331 // fill the data Structure
332 Handle(TopOpeBRepDS_HDataStructure) DatStr = new TopOpeBRepDS_HDataStructure();
333 TopOpeBRep_DSFiller DSFiller;
334 DSFiller.Insert(F1,F2,DatStr);
336 // define the GeomTool used by the DSFiller :
337 // compute BSpline of degree 1 on intersection curves.
338 Standard_Real tol3dAPPROX = 1e-7;
339 Standard_Real tol2dAPPROX = 1e-7;
340 TopOpeBRepTool_GeomTool GT2 (TopOpeBRepTool_APPROX);
341 GT2.SetTolerances(tol3dAPPROX,tol2dAPPROX);
342 TopOpeBRepDS_BuildTool BT(GT2);
345 TopOpeBRepBuild_Builder TopB(BT);
346 TopB.Perform(DatStr);
353 TopOpeBRepDS_CurveExplorer cex(DatStr->DS());
354 for (; cex.More(); cex.Next()) {
355 const TopOpeBRepDS_Curve& CDS = cex.Curve();
356 Standard_Integer ic = cex.Index();
357 Handle(Geom2d_Curve) pc1 = CDS.Curve1();
358 Handle(Geom2d_Curve) pc2 = CDS.Curve2();
360 TopTools_ListIteratorOfListOfShape itLE = TopB.NewEdges(ic);
361 while (itLE.More()) {
362 TopoDS_Edge E = TopoDS::Edge(itLE.Value());
364 PutInBounds (F1,E,pc1);
365 PutInBounds (F2,E,pc2);
367 B.UpdateEdge (E,pc1,F1,0.);
368 B.UpdateEdge (E,pc2,F2,0.);
374 pc1 = Handle(Geom2d_Curve)::DownCast(pc1->Copy());
375 pc2 = Handle(Geom2d_Curve)::DownCast(pc2->Copy());
380 // ========================
381 // store same domain faces
382 // ========================
385 if ( DatStr->HasSameDomain( F1 ))
387 TopTools_ListOfShape emptyList;
388 if (!mySameDomainFM.IsBound(F1))
389 mySameDomainFM.Bind(F1,emptyList);
390 if (!mySameDomainFM.IsBound(F2))
391 mySameDomainFM.Bind(F2,emptyList);
392 mySameDomainFM(F1).Append(F2);
393 mySameDomainFM(F2).Append(F1);
396 // ====================
397 // Store section edges
398 // ====================
400 const TopOpeBRepDS_DataStructure& DS = DatStr->DS();
401 Standard_Integer j,i,nse = DS.NbSectionEdges();
402 if (nse == 0) return;
405 TopoDS_Vertex V, sdeV1, sdeV2;
406 TopTools_MapOfShape MV;
407 TopTools_ListOfShape LSE; // list of section edges
410 for (i = 1; i <= nse; i++)
412 const TopoDS_Edge & se = DS.SectionEdge(i);
413 if (! TopB.IsSplit(se,TopAbs_ON))
417 // add vertices where section edges interferes with other
418 // edges as its descendant in myAsDes
420 TopoDS_Edge sde, oe; // same domain, other edge
421 if (DatStr->HasSameDomain(se)) {
422 sde = TopoDS::Edge( DatStr->SameDomain(se).Value() );
423 TopExp::Vertices( sde, sdeV1, sdeV2);
425 TColStd_MapOfInteger MIV; // indices of added edges
426 TopOpeBRepDS_PointIterator itP (DS.ShapeInterferences( se ));
427 itP.SupportKind( TopOpeBRepDS_EDGE );
428 // loop on intersections of se
429 for (; itP.More(); itP.Next()) {
430 oe = TopoDS::Edge( DS.Shape( itP.Support()));
431 if (itP.IsVertex()) {
432 // there is a vertex at intersection
433 if ( !MIV.Add( itP.Current() ))
435 V = TopoDS::Vertex( DS.Shape( itP.Current()));
436 if ( !sde.IsNull() && (V.IsSame(sdeV1) || V.IsSame(sdeV2)) )
438 V = ReplaceSameDomainV( V , oe );
439 V.Orientation( TopAbs_INTERNAL);
440 B.UpdateVertex( V, itP.Parameter(), se, 0.); // AddVonE() sets real U
443 // create a new vertex at the intersection point
444 const TopOpeBRepDS_Point& DSP = DS.Point( itP.Current());
445 V = BRepLib_MakeVertex( DSP.Point() );
446 V.Orientation( TopAbs_INTERNAL);
447 B.UpdateVertex( V, itP.Parameter(), se, DSP.Tolerance());
448 // make V be on the other edge
449 TopOpeBRepDS_PointIterator itOP (DS.ShapeInterferences( oe ));
450 for (; itOP.More(); itOP.Next()) {
451 const TopOpeBRepDS_Point& ODSP = DS.Point( itOP.Current());
452 if ( DSP.IsEqual (ODSP)) {
453 B.UpdateVertex( V, itOP.Parameter(), TopoDS::Edge(oe), ODSP.Tolerance());
458 // add V on the both intersecting edges
459 TopoDS_Vertex addedV = Partition_Inter2d::AddVonE( V,se,oe,myAsDes,dummyF);
460 if (!addedV.IsSame( V ))
461 mySameDomainVM.Bind (V, addedV); // equal vertex is already there
463 MV.Add( addedV ); // to ease storage of vertices of ON splits
467 // add section edge to the face it intersects and find
468 // splits ON that do not have same domain pair
470 TopB.SplitSectionEdges(); // let TopB find ON splits
472 TopTools_MapOfShape SPM; // map of ON splits
473 TopTools_IndexedMapOfShape ME[2];
474 TopExp::MapShapes( F1, TopAbs_EDGE, ME[1]);
475 TopExp::MapShapes( F2, TopAbs_EDGE, ME[0]);
477 TopTools_ListIteratorOfListOfShape itSP, itLSE (LSE);
478 while ( itLSE.More() ) {
480 TopoDS_Edge se = TopoDS::Edge( itLSE.Value() );
482 // move itLSE to the next se
483 Standard_Integer ancRank = DS.AncestorRank(se);
484 if (ME[ancRank-1].Contains( se ))
486 LSE.Remove( itLSE ); // se is an edge of face it intersects
494 const TopoDS_Face& F = (ancRank == 1) ? F2 : F1;
496 // add se to face but dont add twice
497 TopTools_ListIteratorOfListOfShape itE( myAsDes->Descendant( F ));
498 if (myAsDes->HasDescendant( F )) {
499 for ( ; itE.More(); itE.Next())
500 if (se.IsSame( itE.Value() ))
505 myAsDes->Add( F, se );
507 // check se pcurve on F
508 Standard_Real tol, f,l, umin=1e100, umax=-1e100;
509 Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( se, F, f,l);
511 itSP.Initialize( TopB.Splits(se,TopAbs_ON) );
512 for ( ; itSP.More(); itSP.Next()) {
513 const TopoDS_Edge& E = TopoDS::Edge ( itSP.Value());
514 BRep_Tool::Range(E, f, l);
515 umin = Min( umin, f);
516 umax = Max( umax, l);
518 Handle(Geom_Curve) C3d = BRep_Tool::Curve( se, f, l);
519 if (umin < umax) // sometimes umin == umax for closed edge
520 C3d = new Geom_TrimmedCurve( C3d, umin, umax);
521 pc = TopOpeBRepTool_CurveTool::MakePCurveOnFace (F,C3d,tol);
523 MESSAGE (" CANT BUILD PCURVE ");
525 B.UpdateEdge( se, pc, F, tol);
529 // to detect splits that do not have same domain pair
530 // ie which split a face into parts and not pass by its boundary
531 itSP.Initialize( TopB.Splits(se,TopAbs_ON) );
532 for ( ; itSP.More(); itSP.Next()) {
533 const TopoDS_Shape& SP = itSP.Value();
539 // store vertices of ON splits and bind section edges to faces
541 for (itLSE.Initialize (LSE); itLSE.More(); itLSE.Next())
543 const TopoDS_Shape& se = itLSE.Value();
545 Standard_Integer ancRank = DS.AncestorRank(se);
546 TopoDS_Face F = (ancRank == 1) ? F2 : F1;
548 // add vertices of ON splits which have no same domain pair
549 Standard_Boolean added = Standard_False;
550 itSP.Initialize( TopB.Splits(se,TopAbs_ON) );
551 for ( ; itSP.More(); itSP.Next())
553 if (!SPM.Contains( itSP.Value() ))
556 const TopoDS_Edge& S = TopoDS::Edge ( itSP.Value());
558 added = Standard_True;
559 mySectionEdgesAD->Add( F, se );
562 TopExp::Vertices (S, VS[0], VS[1]);
565 if (mySameDomainVM.IsBound( VS[j] ))
566 VS[j] = TopoDS::Vertex( mySameDomainVM( VS[j] ));
567 if ( !MV.Contains( VS[j] )) {
568 // find equal vertex on se - point interference
569 gp_Pnt P1 = BRep_Tool::Pnt( VS[j] );
570 TopTools_ListIteratorOfListOfShape itV( myAsDes->Descendant(se) );
571 for (; itV.More(); itV.Next()) {
572 V = TopoDS::Vertex( itV.Value() );
573 if ( V.IsSame( VS[j] ))
575 gp_Pnt P2 = BRep_Tool::Pnt( V );
576 if (P1.IsEqual( P2, Precision::Confusion())) {
577 mySameDomainVM.Bind (VS[j], V);
582 if (!itV.More()) // no interferences with edges
583 myAsDes->Add( se, VS[j]);
586 // add ends of ON splits to F in order to detect later
587 // if a split is on face in IsSplitOn()
588 mySectionEdgesAD->Add( F, VS[j]);
590 // in the descendants of F, first go ends of an ON split and
591 // then a split itself
592 mySectionEdgesAD->Add( F, S );
595 mySectionEdgesAD->Add( F, se );
597 myNewEdges.Add( se );
601 //=======================================================================
602 //function : FacesPartition
604 //=======================================================================
606 void Partition_Inter3d::FacesPartition(const TopoDS_Face& F1,
607 const TopoDS_Face& F2)
608 //(const TopTools_DataMapOfShapeListOfShape& /*SetOfFaces2*/)
610 TopTools_ListOfShape LInt;
612 Inter3D (F1,F2,LInt);
614 StorePart3d (F1,F2,LInt);
617 //=======================================================================
620 //=======================================================================
622 void Partition_Inter3d::SetDone(const TopoDS_Face& F1,
623 const TopoDS_Face& F2)
625 if (!myDone.IsBound(F1)) {
626 TopTools_ListOfShape emptyList;
627 myDone.Bind(F1,emptyList);
629 myDone(F1).Append(F2);
630 if (!myDone.IsBound(F2)) {
631 TopTools_ListOfShape emptyList;
632 myDone.Bind(F2,emptyList);
634 myDone(F2).Append(F1);
637 //=======================================================================
640 //=======================================================================
642 Standard_Boolean Partition_Inter3d::IsDone(const TopoDS_Face& F1,
643 const TopoDS_Face& F2)
647 if (myDone.IsBound(F1)) {
648 TopTools_ListIteratorOfListOfShape it (myDone(F1));
649 for (; it.More(); it.Next()) {
650 if (it.Value().IsSame(F2)) return Standard_True;
653 return Standard_False;
656 //=======================================================================
657 //function : StorePart3d
659 //=======================================================================
661 void Partition_Inter3d::StorePart3d(const TopoDS_Face& F1,
662 const TopoDS_Face& F2,
663 const TopTools_ListOfShape& LInt)
665 if (!LInt.IsEmpty()) {
666 myAsDes->Add( F1,LInt);
667 myAsDes->Add( F2,LInt);
669 TopTools_ListIteratorOfListOfShape it(LInt);
670 for (; it.More(); it.Next()) {
672 TopoDS_Edge E = TopoDS::Edge(it.Value());
675 B.SameParameter(E,Standard_False);
676 BRepLib::SameParameter(E,1.0e-7);
684 //=======================================================================
685 //function : TouchedFaces
687 //=======================================================================
689 TopTools_MapOfShape& Partition_Inter3d::TouchedFaces()
694 //=======================================================================
697 //=======================================================================
699 Handle(BRepAlgo_AsDes) Partition_Inter3d::AsDes() const
704 //=======================================================================
705 //function : NewEdges
707 //=======================================================================
709 TopTools_MapOfShape& Partition_Inter3d::NewEdges()
714 //=======================================================================
717 //=======================================================================
719 void Partition_Inter3d::Affiche(const TopTools_ListOfShape& SetOfFaces) const
723 char *section=PSection;
724 Standard_Integer i = 0;
726 TopTools_ListOfShape aList;
727 TopTools_ListIteratorOfListOfShape it;
728 for (it.Initialize(SetOfFaces); it.More(); it.Next()) {
729 const TopoDS_Shape& OS = it.Value();
730 aList=myAsDes->Descendant(OS);
731 MESSAGE ( " the number of items stored in the list " << j << " : " << aList.Extent() )
733 TopTools_ListIteratorOfListOfShape itaList;
734 for (itaList.Initialize(aList); itaList.More(); itaList.Next()) {
735 const TopoDS_Shape& SS = itaList.Value();
737 sprintf(PSection,"section_%d",i);
738 DBRep::Set(section,SS);
744 //=======================================================================
745 //function : SameDomain
747 //=======================================================================
749 const TopTools_ListOfShape& Partition_Inter3d::SameDomain(const TopoDS_Face& F) const
751 if (mySameDomainFM.IsBound( F ))
752 return mySameDomainFM (F);
754 static TopTools_ListOfShape emptyList;
758 //=======================================================================
759 //function : HasSameDomainF
760 //purpose : Return true if F has same domain faces
761 //=======================================================================
763 Standard_Boolean Partition_Inter3d::HasSameDomainF(const TopoDS_Shape& F) const
765 return mySameDomainFM.IsBound( F );
768 //=======================================================================
769 //function : IsSameDomain
770 //purpose : Return true if F1 and F2 are same domain faces
771 //=======================================================================
773 Standard_Boolean Partition_Inter3d::IsSameDomainF(const TopoDS_Shape& F1,
774 const TopoDS_Shape& F2) const
776 if (mySameDomainFM.IsBound( F1 )) {
777 TopTools_ListIteratorOfListOfShape it (mySameDomainFM( F1 ));
778 for (; it.More(); it.Next())
779 if (F2.IsSame( it.Value()))
780 return Standard_True;
782 return F1.IsSame( F2 );
785 //=======================================================================
786 //function : ReplaceSameDomainV
787 //purpose : return same domain vertex of V if it was replaced
788 // and make this vertex to be on E too, else return V
789 //=======================================================================
791 TopoDS_Vertex Partition_Inter3d::ReplaceSameDomainV(const TopoDS_Vertex& V,
792 const TopoDS_Edge& E) const
794 TopoDS_Vertex SDV = V;
795 if (mySameDomainVM.IsBound( V )) {
798 TopExp::Vertices(E,V1,V2);
799 Standard_Boolean isClosed = V1.IsSame( V2 ) && V.IsSame(V1);
801 SDV = TopoDS::Vertex( mySameDomainVM(V) );
802 Standard_Real tol = BRep_Tool::Tolerance( V );
804 SDV.Orientation( V.Orientation());
808 BRep_Tool::Range (E, f, l);
809 Standard_Boolean isFirst = IsEqual( BRep_Tool::Parameter(V,E), f );
810 B.UpdateVertex(SDV, (isFirst ? f : l), E, tol);
812 B.UpdateVertex(SDV, (isFirst ? l : f), E, tol);
815 B.UpdateVertex (SDV, BRep_Tool::Parameter(V,E), E, tol);
821 //=======================================================================
822 //function : SectionEdgesAD
824 //=======================================================================
826 Handle(BRepAlgo_AsDes) Partition_Inter3d::SectionEdgesAD() const
828 return mySectionEdgesAD;
831 //=======================================================================
832 //function : IsSectionEdge
833 //purpose : return True if E is an edge of a face and it
834 // intersects an other face
835 //=======================================================================
838 Partition_Inter3d::IsSectionEdge(const TopoDS_Edge& E) const
840 return mySectionEdgesAD->HasAscendant(E);
843 //=======================================================================
844 //function : HasSectionEdge
845 //purpose : return True if an edge of F intersects an other
846 // face or F is intersected by edge of an other face
847 //=======================================================================
850 Partition_Inter3d::HasSectionEdge(const TopoDS_Face& F) const
852 return mySectionEdgesAD->HasDescendant(F);
855 //=======================================================================
856 //function : IsSplitOn
857 //purpose : return True if NewE is split of OldE on F
858 //=======================================================================
861 Partition_Inter3d::IsSplitOn(const TopoDS_Edge& NewE,
862 const TopoDS_Edge& OldE,
863 const TopoDS_Face& F) const
865 if (! mySectionEdgesAD->HasDescendant(F))
866 return Standard_False;
868 TopTools_ListIteratorOfListOfShape itE ( mySectionEdgesAD->Descendant(F) );
869 for ( ; itE.More(); itE.Next()) {
870 if ( itE.Value().ShapeType() != TopAbs_EDGE ||
871 ! OldE.IsSame ( itE.Value() ))
873 // an edge encountered, its vertices and a split come next
875 if (!itE.More()) break;
876 const TopoDS_Shape& V3 = itE.Value();
877 if (V3.ShapeType() != TopAbs_VERTEX) continue;
879 if (!itE.More()) break;
880 const TopoDS_Shape& V4 = itE.Value();
881 if (V4.ShapeType() != TopAbs_VERTEX) continue;
883 TopoDS_Vertex V1, V2;
884 TopExp::Vertices( OldE, V1, V2);
886 if ( V1.IsSame(V2) &&
887 (V1.IsSame(V3) || V1.IsSame(V4)) ) {
888 // closed old edge; use the split for the test
890 if (!itE.More()) break;
891 const TopoDS_Edge& split = TopoDS::Edge( itE.Value() );
892 // check distance at middle point of NewE
893 Standard_Real f1,l1, f2,l2;
894 Handle(Geom2d_Curve) PC1 = BRep_Tool::CurveOnSurface( split, F ,f1,l1);
896 Handle(Geom2d_Curve) PC2 = BRep_Tool::CurveOnSurface(NewE, F ,f2,l2);
897 gp_Pnt2d P = PC2->Value( 0.5*(f2+l2) );
898 Geom2dAPI_ProjectPointOnCurve proj (P, PC1, f1, l1);
899 if (proj.NbPoints() &&
900 proj.LowerDistance() <= Precision::Confusion())
901 return Standard_True;
904 Handle(Geom_Curve) C1 = BRep_Tool::Curve( split ,f1,l1);
905 Handle(Geom_Curve) C2 = BRep_Tool::Curve( NewE ,f2,l2);
906 gp_Pnt P = C2->Value( 0.5*(f2+l2) );
907 GeomAPI_ProjectPointOnCurve proj (P, C1, f1, l1);
908 if (proj.NbPoints() &&
909 proj.LowerDistance() <= Precision::Confusion())
910 return Standard_True;
914 Standard_Real u3 = BRep_Tool::Parameter( TopoDS::Vertex(V3), OldE);
915 Standard_Real u4 = BRep_Tool::Parameter( TopoDS::Vertex(V4), OldE);
917 Standard_Real f,l, u;
918 BRep_Tool::Range( NewE, f,l);
923 if (u <= l && u >= f)
924 return Standard_True;
927 return Standard_False;
930 //=======================================================================
931 //function : SectionEdgeFaces
932 //purpose : return faces cut by section edge
933 //=======================================================================
935 const TopTools_ListOfShape&
936 Partition_Inter3d::SectionEdgeFaces(const TopoDS_Edge& SecE) const
938 return mySectionEdgesAD->Ascendant( SecE );