2 // File : Partition_Inter3d.cxx
3 // Created : Thu Aug 02 16:20:37 2001
4 // Author : Benedicte MARTIN
7 // Copyright : Open CASCADE
10 #include "Partition_Inter3d.ixx"
11 #include "Partition_Inter2d.hxx"
12 #include "utilities.h"
14 #include <BRepOffset_Tool.hxx>
15 #include <BRep_Builder.hxx>
16 #include <BRep_Tool.hxx>
17 #include <BRepAlgo_AsDes.hxx>
18 #include <BRepAlgo_Image.hxx>
19 #include <BRepLib.hxx>
22 #include <TopExp_Explorer.hxx>
25 #include <TopoDS_Vertex.hxx>
26 #include <TopoDS_Edge.hxx>
27 #include <TopoDS_Face.hxx>
28 #include <TopoDS_Compound.hxx>
29 #include <TopTools_ListOfShape.hxx>
30 #include <TopTools_ListIteratorOfListOfShape.hxx>
31 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
32 #include <TopOpeBRepTool_BoxSort.hxx>
39 #include <TopOpeBRepDS_HDataStructure.hxx>
40 #include <TopOpeBRep_DSFiller.hxx>
41 #include <TopOpeBRepTool_GeomTool.hxx>
42 #include <TopOpeBRepTool_OutCurveType.hxx>
43 #include <TopOpeBRepDS_BuildTool.hxx>
44 #include <TopOpeBRepBuild_Builder.hxx>
45 #include <TopOpeBRepDS_CurveExplorer.hxx>
46 #include <Geom2d_Curve.hxx>
47 #include <TopOpeBRepDS_PointIterator.hxx>
48 #include <TopOpeBRepDS_Transition.hxx>
49 #include <Geom_Curve.hxx>
50 #include <TopOpeBRepTool_CurveTool.hxx>
51 #include <TopOpeBRepDS_Interference.hxx>
52 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
53 #include <BRepLib_MakeVertex.hxx>
54 #include <Precision.hxx>
55 #include <TColStd_MapOfInteger.hxx>
56 #include <BRepTools.hxx>
57 #include <Geom_RectangularTrimmedSurface.hxx>
58 #include <Geom_Surface.hxx>
59 #include <Geom_TrimmedCurve.hxx>
60 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
61 #include <GeomAPI_ProjectPointOnCurve.hxx>
63 //=======================================================================
64 //function : Partition_Inter3d
66 //=======================================================================
68 Partition_Inter3d::Partition_Inter3d()
71 //=======================================================================
72 //function : Partition_Inter3d
74 //=======================================================================
76 Partition_Inter3d::Partition_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes)
79 mySectionEdgesAD = new BRepAlgo_AsDes;
82 //=======================================================================
83 //function : CompletPart3d
84 //purpose : FaceShapeMap is just to know the shape a face belongs to
85 //=======================================================================
87 void Partition_Inter3d::CompletPart3d(const TopTools_ListOfShape& SetOfFaces1,
88 const TopTools_DataMapOfShapeShape& FaceShapeMap)
91 myAsDes = new BRepAlgo_AsDes;
93 TopTools_ListIteratorOfListOfShape it;
95 //---------------------------------------------------------------
96 // Construction of bounding boxes.
97 //---------------------------------------------------------------
100 TopoDS_Compound CompOS;
101 B.MakeCompound(CompOS);
102 for (it.Initialize(SetOfFaces1); it.More(); it.Next())
103 B.Add(CompOS, it.Value());
105 TopOpeBRepTool_BoxSort BOS;
106 BOS.AddBoxesMakeCOB(CompOS,TopAbs_FACE);
108 for (it.Initialize(SetOfFaces1); it.More(); it.Next()) {
109 TopoDS_Face F1 = TopoDS::Face(it.Value());
111 // avoid intersecting faces of one shape
113 if (FaceShapeMap.IsBound(F1)) S1 = FaceShapeMap.Find(F1);
114 // avoid intersecting faces sharing vertices, suppose they belong to
115 // shapes sharing same faces
116 TopTools_IndexedMapOfShape VM;
117 TopExp::MapShapes( F1, TopAbs_VERTEX, VM);
119 TColStd_ListIteratorOfListOfInteger itLI = BOS.Compare(F1);
120 for (; itLI.More(); itLI.Next()) {
121 TopoDS_Face F2 = TopoDS::Face(BOS.TouchedShape(itLI));
122 if (F1.IsSame(F2) || IsDone(F1,F2))
126 if (FaceShapeMap.IsBound(F2)) S2 = FaceShapeMap.Find(F2);
127 if (!S1.IsNull() && S1.IsSame(S2))
128 continue; // descendants of one shape
130 TopExp_Explorer expV (F2, TopAbs_VERTEX);
131 for ( ; expV.More(); expV.Next())
132 if (VM.Contains( expV.Current() ))
135 continue; // faces have a common edge
137 F1.Orientation(TopAbs_FORWARD);
138 F2.Orientation(TopAbs_FORWARD);
139 FacesPartition(F1,F2);
142 // mark as modified a face which has at least one new edge
143 if (!myAsDes->HasDescendant( F1 ))
145 TopTools_ListIteratorOfListOfShape itE (myAsDes->Descendant( F1 ));
146 for ( ; itE.More(); itE.Next()) {
147 if (myNewEdges.Contains( itE.Value())) {
155 //=======================================================================
156 //function : PutInBounds
158 //=======================================================================
160 static void PutInBounds (const TopoDS_Face& F,
161 const TopoDS_Edge& E,
162 Handle(Geom2d_Curve)& C2d)
164 Standard_Real umin,umax,vmin,vmax;
166 BRep_Tool::Range(E,f,l);
168 TopLoc_Location L; // Recup S avec la location pour eviter la copie.
169 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
171 if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
172 S = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
177 if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
179 BRepTools::UVBounds(F,umin,umax,vmin,vmax);
181 if (S->IsUPeriodic()) {
182 Standard_Real period = S->UPeriod();
183 Standard_Real eps = period*1.e-6;
184 gp_Pnt2d Pf = C2d->Value(f);
185 gp_Pnt2d Pl = C2d->Value(l);
186 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
187 Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
188 Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
189 Standard_Real du = 0.;
190 if (minC< umin - eps) {
191 du = (int((umin - minC)/period) + 1)*period;
193 if (minC > umax + eps) {
194 du = -(int((minC - umax)/period) + 1)*period;
199 minC += du; maxC += du;
201 // Ajuste au mieux la courbe dans le domaine.
202 if (maxC > umax +100*eps) {
203 Standard_Real d1 = maxC - umax;
204 Standard_Real d2 = umin - minC + period;
205 if (d2 < d1) du =-period;
215 if (S->IsVPeriodic()) {
216 Standard_Real period = S->VPeriod();
217 Standard_Real eps = period*1.e-6;
218 gp_Pnt2d Pf = C2d->Value(f);
219 gp_Pnt2d Pl = C2d->Value(l);
220 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
221 Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
222 Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
223 Standard_Real dv = 0.;
224 if (minC< vmin - eps) {
225 dv = (int((vmin - minC)/period) + 1)*period;
227 if (minC > vmax + eps) {
228 dv = -(int((minC - vmax)/period) + 1)*period;
233 minC += dv; maxC += dv;
235 // Ajuste au mieux la courbe dans le domaine.
236 if (maxC > vmax +100*eps) {
237 Standard_Real d1 = maxC - vmax;
238 Standard_Real d2 = vmin - minC + period;
239 if (d2 < d1) dv =-period;
248 //=======================================================================
251 //=======================================================================
253 void Partition_Inter3d::Inter3D(const TopoDS_Face& F1,
254 const TopoDS_Face& F2,
255 TopTools_ListOfShape& L)
259 // fill the data Structure
260 Handle(TopOpeBRepDS_HDataStructure) DatStr = new TopOpeBRepDS_HDataStructure();
261 TopOpeBRep_DSFiller DSFiller;
262 DSFiller.Insert(F1,F2,DatStr);
264 // define the GeomTool used by the DSFiller :
265 // compute BSpline of degree 1 on intersection curves.
266 Standard_Real tol3dAPPROX = 1e-7;
267 Standard_Real tol2dAPPROX = 1e-7;
268 TopOpeBRepTool_GeomTool GT2 (TopOpeBRepTool_APPROX);
269 GT2.SetTolerances(tol3dAPPROX,tol2dAPPROX);
270 TopOpeBRepDS_BuildTool BT(GT2);
273 TopOpeBRepBuild_Builder TopB(BT);
274 TopB.Perform(DatStr);
281 TopOpeBRepDS_CurveExplorer cex(DatStr->DS());
282 for (; cex.More(); cex.Next()) {
283 const TopOpeBRepDS_Curve& CDS = cex.Curve();
284 Standard_Integer ic = cex.Index();
285 Handle(Geom2d_Curve) pc1 = CDS.Curve1();
286 Handle(Geom2d_Curve) pc2 = CDS.Curve2();
288 TopTools_ListIteratorOfListOfShape itLE = TopB.NewEdges(ic);
289 while (itLE.More()) {
290 TopoDS_Edge E = TopoDS::Edge(itLE.Value());
292 // Standard_Real f,l;
293 // BRep_Tool::Range(E,f,l);
294 PutInBounds (F1,E,pc1);
295 PutInBounds (F2,E,pc2);
297 B.UpdateEdge (E,pc1,F1,0.);
298 B.UpdateEdge (E,pc2,F2,0.);
304 pc1 = Handle(Geom2d_Curve)::DownCast(pc1->Copy());
305 pc2 = Handle(Geom2d_Curve)::DownCast(pc2->Copy());
310 // ===================================================
311 // Store section edges, same domain faces and verives
312 // ===================================================
314 TopTools_ListOfShape empty, LSP, LSE;
316 if ( DatStr->HasSameDomain( F1 )) { // same domain faces
317 if (!mySameDomainFM.IsBound(F1))
318 mySameDomainFM.Bind(F1,empty);
319 if (!mySameDomainFM.IsBound(F2))
320 mySameDomainFM.Bind(F2,empty);
321 mySameDomainFM(F1).Append(F2);
322 mySameDomainFM(F2).Append(F1);
325 const TopOpeBRepDS_DataStructure& DS = DatStr->DS();
326 Standard_Integer j,i,nes = DS.NbSectionEdges();
330 TopoDS_Vertex V, sdeV1, sdeV2;
331 TopTools_MapOfShape MV;
333 // put vertices on section edges
334 for (i=1;i<=nes;i++) {
336 TopoDS_Edge se, sde, oe; // section, same domain, other edge
337 se = DS.SectionEdge(i);
338 if (! TopB.IsSplit(se,TopAbs_ON))
341 if (DatStr->HasSameDomain(se)) {
342 sde = TopoDS::Edge( DatStr->SameDomain(se).Value() );
343 TopExp::Vertices( sde, sdeV1, sdeV2);
346 TColStd_MapOfInteger MIV;
347 TopOpeBRepDS_PointIterator itP (DS.ShapeInterferences( se ));
348 itP.SupportKind( TopOpeBRepDS_EDGE );
349 for (; itP.More(); itP.Next()) {
350 oe = TopoDS::Edge( DS.Shape( itP.Support()));
351 if (itP.IsVertex()) {
352 if ( !MIV.Add( itP.Current() ))
354 V = TopoDS::Vertex( DS.Shape( itP.Current()));
355 if ( !sde.IsNull() && (V.IsSame(sdeV1) || V.IsSame(sdeV2)) )
357 V = ReplaceSameDomainV( V , oe );
358 V.Orientation( TopAbs_INTERNAL);
359 B.UpdateVertex( V, itP.Parameter(), se, 0.);
362 const TopOpeBRepDS_Point& DSP = DS.Point( itP.Current());
363 V = BRepLib_MakeVertex( DSP.Point() );
364 V.Orientation( TopAbs_INTERNAL);
365 B.UpdateVertex( V, itP.Parameter(), se, DSP.Tolerance());
366 // make V be on the other edge
367 TopOpeBRepDS_PointIterator itOP (DS.ShapeInterferences( oe ));
368 for (; itOP.More(); itOP.Next()) {
369 const TopOpeBRepDS_Point& ODSP = DS.Point( itOP.Current());
370 if ( DSP.IsEqual (ODSP)) {
371 B.UpdateVertex( V, itOP.Parameter(), TopoDS::Edge(oe), ODSP.Tolerance());
376 TopoDS_Vertex addedV = Partition_Inter2d::AddVonE( V,se,oe,myAsDes);
377 if (!addedV.IsSame( V ))
378 mySameDomainVM.Bind (V, addedV);
383 TopB.SplitSectionEdges();
385 TopTools_DataMapOfShapeShape SEM; // map split - section edge
386 TopTools_IndexedMapOfShape ME[2];
387 TopExp::MapShapes( F1, TopAbs_EDGE, ME[1]);
388 TopExp::MapShapes( F2, TopAbs_EDGE, ME[0]);
390 // add section edge to the face it intersects and find
391 // splits ON that do not have same domain pair
393 for (i=1;i<=nes;i++) {
395 const TopoDS_Edge& se = DS.SectionEdge(i);
396 if (! TopB.IsSplit(se,TopAbs_ON))
399 Standard_Integer ancRank = DS.AncestorRank(se);
400 if (ME[ancRank-1].Contains( se ))
401 continue; // se is an edge of face it intersects
403 const TopoDS_Face& F = (ancRank == 1) ? F2 : F1;
405 // add se to face but dont add twice
406 TopTools_ListIteratorOfListOfShape itE;
407 if (myAsDes->HasDescendant( F )) {
408 for (itE.Initialize( (myAsDes->Descendant( F )) ); itE.More(); itE.Next())
409 if (se.IsSame( itE.Value() ))
413 myAsDes->Add( F, se );
414 Standard_Real tol, f,l, umin=1e100, umax=-1e100;
415 Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( se, F, f,l);
417 TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) );
418 for ( ;it.More();it.Next()) {
419 const TopoDS_Edge& E = TopoDS::Edge ( it.Value());
420 BRep_Tool::Range(E, f, l);
421 umin = Min( umin, f);
422 umax = Max( umax, l);
424 Handle(Geom_Curve) C3d = BRep_Tool::Curve( se, f, l);
425 if (umin < umax) // sometimes umin == umax for closed edge
426 C3d = new Geom_TrimmedCurve( C3d, umin, umax);
427 pc = TopOpeBRepTool_CurveTool::MakePCurveOnFace (F,C3d,tol);
429 MESSAGE (" CANT BUILD PCURVE ");
431 B.UpdateEdge( se, pc, F, tol);
435 // to detect splits that do not have same domain pair
436 TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) );
437 for ( ;it.More();it.Next()) {
438 const TopoDS_Edge& S = TopoDS::Edge ( it.Value());
439 if (SEM.IsBound( S ))
446 // store vertices of ON splits and bind section edges to faces
447 for (i=1;i<=nes;i++) {
449 const TopoDS_Edge& se = DS.SectionEdge(i);
450 if (! TopB.IsSplit(se,TopAbs_ON))
453 Standard_Integer ancRank = DS.AncestorRank(se);
454 if (ME[ancRank-1].Contains( se ))
455 continue; // se is an edge of face it intersects
457 TopoDS_Face F = (ancRank == 1) ? F2 : F1;
459 // add vertices of splits
460 Standard_Boolean added = Standard_False;
461 TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) );
462 for ( ;it.More();it.Next()) {
463 const TopoDS_Edge& S = TopoDS::Edge ( it.Value());
464 if (!SEM.IsBound( S ))
467 added = Standard_True;
468 mySectionEdgesAD->Add( F, se );
471 TopExp::Vertices (S, VS[0], VS[1]);
472 for (j=0; j<2; ++j) {
473 if (mySameDomainVM.IsBound( VS[j] ))
474 VS[j] = TopoDS::Vertex( mySameDomainVM( VS[j] ));
475 if ( !MV.Contains( VS[j] )) {
476 // find equal vertex on se - point interference
477 gp_Pnt P1 = BRep_Tool::Pnt( VS[j] );
478 TopTools_ListIteratorOfListOfShape itV( myAsDes->Descendant(se) );
479 for (; itV.More(); itV.Next()) {
480 V = TopoDS::Vertex( itV.Value() );
481 gp_Pnt P2 = BRep_Tool::Pnt( V );
482 if (P1.IsEqual( P2, Precision::Confusion())) {
483 mySameDomainVM.Bind (VS[j], V);
488 if (!itV.More()) // no interferences with edges
489 myAsDes->Add( se, VS[j]);
491 mySectionEdgesAD->Add( F, VS[j]);
493 mySectionEdgesAD->Add( F, S );
496 mySectionEdgesAD->Add( F, se );
498 myNewEdges.Add( se );
502 //=======================================================================
503 //function : FacesPartition
505 //=======================================================================
507 void Partition_Inter3d::FacesPartition(const TopoDS_Face& F1,
508 const TopoDS_Face& F2)
509 //(const TopTools_DataMapOfShapeListOfShape& /*SetOfFaces2*/)
511 TopTools_ListOfShape LInt;
513 Inter3D (F1,F2,LInt);
515 StorePart3d (F1,F2,LInt);
518 //=======================================================================
521 //=======================================================================
523 void Partition_Inter3d::SetDone(const TopoDS_Face& F1,
524 const TopoDS_Face& F2)
526 if (!myDone.IsBound(F1)) {
527 TopTools_ListOfShape empty;
528 myDone.Bind(F1,empty);
530 myDone(F1).Append(F2);
531 if (!myDone.IsBound(F2)) {
532 TopTools_ListOfShape empty;
533 myDone.Bind(F2,empty);
535 myDone(F2).Append(F1);
538 //=======================================================================
541 //=======================================================================
543 Standard_Boolean Partition_Inter3d::IsDone(const TopoDS_Face& F1,
544 const TopoDS_Face& F2)
548 if (myDone.IsBound(F1)) {
549 TopTools_ListIteratorOfListOfShape it (myDone(F1));
550 for (; it.More(); it.Next()) {
551 if (it.Value().IsSame(F2)) return Standard_True;
554 return Standard_False;
557 //=======================================================================
558 //function : StorePart3d
560 //=======================================================================
562 void Partition_Inter3d::StorePart3d(const TopoDS_Face& F1,
563 const TopoDS_Face& F2,
564 const TopTools_ListOfShape& LInt)
567 if (!LInt.IsEmpty()) {
568 myAsDes->Add( F1,LInt);
569 myAsDes->Add( F2,LInt);
571 TopTools_ListIteratorOfListOfShape it(LInt);
572 for (; it.More(); it.Next()) {
574 TopoDS_Edge E = TopoDS::Edge(it.Value());
577 B.SameParameter(E,Standard_False);
578 BRepLib::SameParameter(E,1.0e-7);
586 //=======================================================================
587 //function : TouchedFaces
589 //=======================================================================
591 TopTools_MapOfShape& Partition_Inter3d::TouchedFaces()
596 //=======================================================================
599 //=======================================================================
601 Handle(BRepAlgo_AsDes) Partition_Inter3d::AsDes() const
606 //=======================================================================
607 //function : NewEdges
609 //=======================================================================
611 TopTools_MapOfShape& Partition_Inter3d::NewEdges()
616 //=======================================================================
619 //=======================================================================
621 void Partition_Inter3d::Affiche(const TopTools_ListOfShape& SetOfFaces) const
625 char *section=PSection;
626 Standard_Integer i = 0;
628 TopTools_ListOfShape aList;
629 TopTools_ListIteratorOfListOfShape it;
630 for (it.Initialize(SetOfFaces); it.More(); it.Next()) {
631 const TopoDS_Shape& OS = it.Value();
632 aList=myAsDes->Descendant(OS);
633 MESSAGE ( " the number of items stored in the list " << j << " : " << aList.Extent() )
635 TopTools_ListIteratorOfListOfShape itaList;
636 for (itaList.Initialize(aList); itaList.More(); itaList.Next()) {
637 const TopoDS_Shape& SS = itaList.Value();
639 sprintf(PSection,"section_%d",i);
640 DBRep::Set(section,SS);
646 //=======================================================================
647 //function : SameDomain
649 //=======================================================================
651 const TopTools_ListOfShape& Partition_Inter3d::SameDomain(const TopoDS_Face& F) const
653 if (mySameDomainFM.IsBound( F ))
654 return mySameDomainFM (F);
656 static TopTools_ListOfShape empty;
660 //=======================================================================
661 //function : HasSameDomainF
662 //purpose : Return true if F has same domain faces
663 //=======================================================================
665 Standard_Boolean Partition_Inter3d::HasSameDomainF(const TopoDS_Shape& F) const
667 return mySameDomainFM.IsBound( F );
670 //=======================================================================
671 //function : IsSameDomain
672 //purpose : Return true if F1 and F2 are same domain faces
673 //=======================================================================
675 Standard_Boolean Partition_Inter3d::IsSameDomainF(const TopoDS_Shape& F1,
676 const TopoDS_Shape& F2) const
678 if (mySameDomainFM.IsBound( F1 )) {
679 TopTools_ListIteratorOfListOfShape it (mySameDomainFM( F1 ));
680 for (; it.More(); it.Next())
681 if (F2.IsSame( it.Value()))
682 return Standard_True;
684 return F1.IsSame( F2 );
687 //=======================================================================
688 //function : ReplaceSameDomainV
689 //purpose : return same domain vertex of V if it was replaced
690 // and make this vertex to be on E too, else return V
691 //=======================================================================
693 TopoDS_Vertex Partition_Inter3d::ReplaceSameDomainV(const TopoDS_Vertex& V,
694 const TopoDS_Edge& E) const
696 TopoDS_Vertex SDV = V;
697 if (mySameDomainVM.IsBound( V )) {
700 TopExp::Vertices(E,V1,V2);
701 Standard_Boolean isClosed = V1.IsSame( V2 ) && V.IsSame(V1);
703 SDV = TopoDS::Vertex( mySameDomainVM(V) );
704 Standard_Real tol = BRep_Tool::Tolerance( V );
706 SDV.Orientation( V.Orientation());
710 BRep_Tool::Range (E, f, l);
711 Standard_Boolean isFirst = IsEqual( BRep_Tool::Parameter(V,E), f );
712 B.UpdateVertex(SDV, (isFirst ? f : l), E, tol);
714 B.UpdateVertex(SDV, (isFirst ? l : f), E, tol);
717 B.UpdateVertex (SDV, BRep_Tool::Parameter(V,E), E, tol);
723 //=======================================================================
724 //function : SectionEdgesAD
726 //=======================================================================
728 Handle(BRepAlgo_AsDes) Partition_Inter3d::SectionEdgesAD() const
730 return mySectionEdgesAD;
733 //=======================================================================
734 //function : IsSectionEdge
735 //purpose : return True if E is an edge of a face and it
736 // intersects an other face
737 //=======================================================================
740 Partition_Inter3d::IsSectionEdge(const TopoDS_Edge& E) const
742 return mySectionEdgesAD->HasAscendant(E);
745 //=======================================================================
746 //function : HasSectionEdge
747 //purpose : return True if an edge of F intersects an other
748 // face or F is intersected by edge of an other face
749 //=======================================================================
752 Partition_Inter3d::HasSectionEdge(const TopoDS_Face& F) const
754 return mySectionEdgesAD->HasDescendant(F);
757 //=======================================================================
758 //function : IsSplitOn
759 //purpose : return True if NewE is split of OldE on F
760 //=======================================================================
763 Partition_Inter3d::IsSplitOn(const TopoDS_Edge& NewE,
764 const TopoDS_Edge& OldE,
765 const TopoDS_Face& F) const
767 if (! mySectionEdgesAD->HasDescendant(F))
768 return Standard_False;
770 TopTools_ListIteratorOfListOfShape itE ( mySectionEdgesAD->Descendant(F) );
771 for ( ; itE.More(); itE.Next()) {
772 if ( itE.Value().ShapeType() != TopAbs_EDGE ||
773 ! OldE.IsSame ( itE.Value() ))
775 // an edge encountered, its vertices and a split come next
777 if (!itE.More()) break;
778 const TopoDS_Shape& V3 = itE.Value();
779 if (V3.ShapeType() != TopAbs_VERTEX) continue;
781 if (!itE.More()) break;
782 const TopoDS_Shape& V4 = itE.Value();
783 if (V4.ShapeType() != TopAbs_VERTEX) continue;
785 TopoDS_Vertex V1, V2;
786 TopExp::Vertices( OldE, V1, V2);
788 if ( V1.IsSame(V2) &&
789 (V1.IsSame(V3) || V1.IsSame(V4)) ) {
790 // closed old edge; use the split for the test
792 if (!itE.More()) break;
793 const TopoDS_Edge& split = TopoDS::Edge( itE.Value() );
794 // check distance at middle point of NewE
795 Standard_Real f1,l1, f2,l2;
796 Handle(Geom2d_Curve) PC1 = BRep_Tool::CurveOnSurface( split, F ,f1,l1);
798 Handle(Geom2d_Curve) PC2 = BRep_Tool::CurveOnSurface(NewE, F ,f2,l2);
799 gp_Pnt2d P = PC2->Value( 0.5*(f2+l2) );
800 Geom2dAPI_ProjectPointOnCurve proj (P, PC1, f1, l1);
801 if (proj.NbPoints() &&
802 proj.LowerDistance() <= Precision::Confusion())
803 return Standard_True;
806 Handle(Geom_Curve) C1 = BRep_Tool::Curve( split ,f1,l1);
807 Handle(Geom_Curve) C2 = BRep_Tool::Curve( NewE ,f2,l2);
808 gp_Pnt P = C2->Value( 0.5*(f2+l2) );
809 GeomAPI_ProjectPointOnCurve proj (P, C1, f1, l1);
810 if (proj.NbPoints() &&
811 proj.LowerDistance() <= Precision::Confusion())
812 return Standard_True;
816 Standard_Real u3 = BRep_Tool::Parameter( TopoDS::Vertex(V3), OldE);
817 Standard_Real u4 = BRep_Tool::Parameter( TopoDS::Vertex(V4), OldE);
819 Standard_Real f,l, u;
820 BRep_Tool::Range( NewE, f,l);
825 if (u <= l && u >= f)
826 return Standard_True;
829 return Standard_False;
832 //=======================================================================
833 //function : SectionEdgeFaces
834 //purpose : return faces cut by section edge
835 //=======================================================================
837 const TopTools_ListOfShape&
838 Partition_Inter3d::SectionEdgeFaces(const TopoDS_Edge& SecE) const
840 return mySectionEdgesAD->Ascendant( SecE );