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_Inter3d.ixx"
31 #include "Partition_Inter2d.hxx"
32 #include "utilities.h"
34 #include <BRepOffset_Tool.hxx>
35 #include <BRep_Builder.hxx>
36 #include <BRep_Tool.hxx>
37 #include <BRepAlgo_AsDes.hxx>
38 #include <BRepAlgo_Image.hxx>
39 #include <BRepLib.hxx>
42 #include <TopExp_Explorer.hxx>
45 #include <TopoDS_Vertex.hxx>
46 #include <TopoDS_Edge.hxx>
47 #include <TopoDS_Face.hxx>
48 #include <TopoDS_Compound.hxx>
49 #include <TopTools_ListOfShape.hxx>
50 #include <TopTools_ListIteratorOfListOfShape.hxx>
51 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
52 #include <TopOpeBRepTool_BoxSort.hxx>
59 #include <TopOpeBRepDS_HDataStructure.hxx>
60 #include <TopOpeBRep_DSFiller.hxx>
61 #include <TopOpeBRepTool_GeomTool.hxx>
62 #include <TopOpeBRepTool_OutCurveType.hxx>
63 #include <TopOpeBRepDS_BuildTool.hxx>
64 #include <TopOpeBRepBuild_Builder.hxx>
65 #include <TopOpeBRepDS_CurveExplorer.hxx>
66 #include <Geom2d_Curve.hxx>
67 #include <TopOpeBRepDS_PointIterator.hxx>
68 #include <TopOpeBRepDS_Transition.hxx>
69 #include <Geom_Curve.hxx>
70 #include <TopOpeBRepTool_CurveTool.hxx>
71 #include <TopOpeBRepDS_Interference.hxx>
72 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
73 #include <BRepLib_MakeVertex.hxx>
74 #include <Precision.hxx>
75 #include <TColStd_MapOfInteger.hxx>
76 #include <BRepTools.hxx>
77 #include <Geom_RectangularTrimmedSurface.hxx>
78 #include <Geom_Surface.hxx>
79 #include <Geom_TrimmedCurve.hxx>
80 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
81 #include <GeomAPI_ProjectPointOnCurve.hxx>
83 //=======================================================================
84 //function : Partition_Inter3d
86 //=======================================================================
88 Partition_Inter3d::Partition_Inter3d()
91 //=======================================================================
92 //function : Partition_Inter3d
94 //=======================================================================
96 Partition_Inter3d::Partition_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes)
99 mySectionEdgesAD = new BRepAlgo_AsDes;
102 //=======================================================================
103 //function : CompletPart3d
104 //purpose : FaceShapeMap is just to know the shape a face belongs to
105 //=======================================================================
107 void Partition_Inter3d::CompletPart3d(const TopTools_ListOfShape& SetOfFaces1,
108 const TopTools_DataMapOfShapeShape& FaceShapeMap)
110 if (myAsDes.IsNull())
111 myAsDes = new BRepAlgo_AsDes;
113 TopTools_ListIteratorOfListOfShape it;
115 //---------------------------------------------------------------
116 // Construction of bounding boxes.
117 //---------------------------------------------------------------
120 TopoDS_Compound CompOS;
121 B.MakeCompound(CompOS);
122 for (it.Initialize(SetOfFaces1); it.More(); it.Next())
123 B.Add(CompOS, it.Value());
125 TopOpeBRepTool_BoxSort BOS;
126 BOS.AddBoxesMakeCOB(CompOS,TopAbs_FACE);
128 for (it.Initialize(SetOfFaces1); it.More(); it.Next()) {
129 TopoDS_Face F1 = TopoDS::Face(it.Value());
131 // avoid intersecting faces of one shape
133 if (FaceShapeMap.IsBound(F1)) S1 = FaceShapeMap.Find(F1);
134 // avoid intersecting faces sharing vertices, suppose they belong to
135 // shapes sharing same faces
136 TopTools_IndexedMapOfShape VM;
137 TopExp::MapShapes( F1, TopAbs_VERTEX, VM);
139 TColStd_ListIteratorOfListOfInteger itLI = BOS.Compare(F1);
140 for (; itLI.More(); itLI.Next()) {
141 TopoDS_Face F2 = TopoDS::Face(BOS.TouchedShape(itLI));
142 if (F1.IsSame(F2) || IsDone(F1,F2))
146 if (FaceShapeMap.IsBound(F2)) S2 = FaceShapeMap.Find(F2);
147 if (!S1.IsNull() && S1.IsSame(S2))
148 continue; // descendants of one shape
150 TopExp_Explorer expV (F2, TopAbs_VERTEX);
151 for ( ; expV.More(); expV.Next())
152 if (VM.Contains( expV.Current() ))
155 continue; // faces have a common edge
157 F1.Orientation(TopAbs_FORWARD);
158 F2.Orientation(TopAbs_FORWARD);
159 FacesPartition(F1,F2);
162 // mark as modified a face which has at least one new edge
163 if (!myAsDes->HasDescendant( F1 ))
165 TopTools_ListIteratorOfListOfShape itE (myAsDes->Descendant( F1 ));
166 for ( ; itE.More(); itE.Next()) {
167 if (myNewEdges.Contains( itE.Value())) {
175 //=======================================================================
176 //function : PutInBounds
178 //=======================================================================
180 static void PutInBounds (const TopoDS_Face& F,
181 const TopoDS_Edge& E,
182 Handle(Geom2d_Curve)& C2d)
184 Standard_Real umin,umax,vmin,vmax;
186 BRep_Tool::Range(E,f,l);
188 TopLoc_Location L; // Recup S avec la location pour eviter la copie.
189 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
191 if (S->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
192 S = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
197 if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
199 BRepTools::UVBounds(F,umin,umax,vmin,vmax);
201 if (S->IsUPeriodic()) {
202 Standard_Real period = S->UPeriod();
203 Standard_Real eps = period*1.e-6;
204 gp_Pnt2d Pf = C2d->Value(f);
205 gp_Pnt2d Pl = C2d->Value(l);
206 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
207 Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
208 Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
209 Standard_Real du = 0.;
210 if (minC< umin - eps) {
211 du = (int((umin - minC)/period) + 1)*period;
213 if (minC > umax + eps) {
214 du = -(int((minC - umax)/period) + 1)*period;
219 minC += du; maxC += du;
221 // Ajuste au mieux la courbe dans le domaine.
222 if (maxC > umax +100*eps) {
223 Standard_Real d1 = maxC - umax;
224 Standard_Real d2 = umin - minC + period;
225 if (d2 < d1) du =-period;
235 if (S->IsVPeriodic()) {
236 Standard_Real period = S->VPeriod();
237 Standard_Real eps = period*1.e-6;
238 gp_Pnt2d Pf = C2d->Value(f);
239 gp_Pnt2d Pl = C2d->Value(l);
240 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
241 Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
242 Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
243 Standard_Real dv = 0.;
244 if (minC< vmin - eps) {
245 dv = (int((vmin - minC)/period) + 1)*period;
247 if (minC > vmax + eps) {
248 dv = -(int((minC - vmax)/period) + 1)*period;
253 minC += dv; maxC += dv;
255 // Ajuste au mieux la courbe dans le domaine.
256 if (maxC > vmax +100*eps) {
257 Standard_Real d1 = maxC - vmax;
258 Standard_Real d2 = vmin - minC + period;
259 if (d2 < d1) dv =-period;
268 //=======================================================================
271 //=======================================================================
273 void Partition_Inter3d::Inter3D(const TopoDS_Face& F1,
274 const TopoDS_Face& F2,
275 TopTools_ListOfShape& L)
279 // fill the data Structure
280 Handle(TopOpeBRepDS_HDataStructure) DatStr = new TopOpeBRepDS_HDataStructure();
281 TopOpeBRep_DSFiller DSFiller;
282 DSFiller.Insert(F1,F2,DatStr);
284 // define the GeomTool used by the DSFiller :
285 // compute BSpline of degree 1 on intersection curves.
286 Standard_Real tol3dAPPROX = 1e-7;
287 Standard_Real tol2dAPPROX = 1e-7;
288 TopOpeBRepTool_GeomTool GT2 (TopOpeBRepTool_APPROX);
289 GT2.SetTolerances(tol3dAPPROX,tol2dAPPROX);
290 TopOpeBRepDS_BuildTool BT(GT2);
293 TopOpeBRepBuild_Builder TopB(BT);
294 TopB.Perform(DatStr);
301 TopOpeBRepDS_CurveExplorer cex(DatStr->DS());
302 for (; cex.More(); cex.Next()) {
303 const TopOpeBRepDS_Curve& CDS = cex.Curve();
304 Standard_Integer ic = cex.Index();
305 Handle(Geom2d_Curve) pc1 = CDS.Curve1();
306 Handle(Geom2d_Curve) pc2 = CDS.Curve2();
308 TopTools_ListIteratorOfListOfShape itLE = TopB.NewEdges(ic);
309 while (itLE.More()) {
310 TopoDS_Edge E = TopoDS::Edge(itLE.Value());
312 // Standard_Real f,l;
313 // BRep_Tool::Range(E,f,l);
314 PutInBounds (F1,E,pc1);
315 PutInBounds (F2,E,pc2);
317 B.UpdateEdge (E,pc1,F1,0.);
318 B.UpdateEdge (E,pc2,F2,0.);
324 pc1 = Handle(Geom2d_Curve)::DownCast(pc1->Copy());
325 pc2 = Handle(Geom2d_Curve)::DownCast(pc2->Copy());
330 // ===================================================
331 // Store section edges, same domain faces and verives
332 // ===================================================
334 TopTools_ListOfShape empty, LSP, LSE;
336 if ( DatStr->HasSameDomain( F1 )) { // same domain faces
337 if (!mySameDomainFM.IsBound(F1))
338 mySameDomainFM.Bind(F1,empty);
339 if (!mySameDomainFM.IsBound(F2))
340 mySameDomainFM.Bind(F2,empty);
341 mySameDomainFM(F1).Append(F2);
342 mySameDomainFM(F2).Append(F1);
345 const TopOpeBRepDS_DataStructure& DS = DatStr->DS();
346 Standard_Integer j,i,nes = DS.NbSectionEdges();
350 TopoDS_Vertex V, sdeV1, sdeV2;
351 TopTools_MapOfShape MV;
353 // put vertices on section edges
354 for (i=1;i<=nes;i++) {
356 TopoDS_Edge se, sde, oe; // section, same domain, other edge
357 se = DS.SectionEdge(i);
358 if (! TopB.IsSplit(se,TopAbs_ON))
361 if (DatStr->HasSameDomain(se)) {
362 sde = TopoDS::Edge( DatStr->SameDomain(se).Value() );
363 TopExp::Vertices( sde, sdeV1, sdeV2);
366 TColStd_MapOfInteger MIV;
367 TopOpeBRepDS_PointIterator itP (DS.ShapeInterferences( se ));
368 itP.SupportKind( TopOpeBRepDS_EDGE );
369 for (; itP.More(); itP.Next()) {
370 oe = TopoDS::Edge( DS.Shape( itP.Support()));
371 if (itP.IsVertex()) {
372 if ( !MIV.Add( itP.Current() ))
374 V = TopoDS::Vertex( DS.Shape( itP.Current()));
375 if ( !sde.IsNull() && (V.IsSame(sdeV1) || V.IsSame(sdeV2)) )
377 V = ReplaceSameDomainV( V , oe );
378 V.Orientation( TopAbs_INTERNAL);
379 B.UpdateVertex( V, itP.Parameter(), se, 0.);
382 const TopOpeBRepDS_Point& DSP = DS.Point( itP.Current());
383 V = BRepLib_MakeVertex( DSP.Point() );
384 V.Orientation( TopAbs_INTERNAL);
385 B.UpdateVertex( V, itP.Parameter(), se, DSP.Tolerance());
386 // make V be on the other edge
387 TopOpeBRepDS_PointIterator itOP (DS.ShapeInterferences( oe ));
388 for (; itOP.More(); itOP.Next()) {
389 const TopOpeBRepDS_Point& ODSP = DS.Point( itOP.Current());
390 if ( DSP.IsEqual (ODSP)) {
391 B.UpdateVertex( V, itOP.Parameter(), TopoDS::Edge(oe), ODSP.Tolerance());
396 TopoDS_Vertex addedV = Partition_Inter2d::AddVonE( V,se,oe,myAsDes);
397 if (!addedV.IsSame( V ))
398 mySameDomainVM.Bind (V, addedV);
403 TopB.SplitSectionEdges();
405 TopTools_DataMapOfShapeShape SEM; // map split - section edge
406 TopTools_IndexedMapOfShape ME[2];
407 TopExp::MapShapes( F1, TopAbs_EDGE, ME[1]);
408 TopExp::MapShapes( F2, TopAbs_EDGE, ME[0]);
410 // add section edge to the face it intersects and find
411 // splits ON that do not have same domain pair
413 for (i=1;i<=nes;i++) {
415 const TopoDS_Edge& se = DS.SectionEdge(i);
416 if (! TopB.IsSplit(se,TopAbs_ON))
419 Standard_Integer ancRank = DS.AncestorRank(se);
420 if (ME[ancRank-1].Contains( se ))
421 continue; // se is an edge of face it intersects
423 const TopoDS_Face& F = (ancRank == 1) ? F2 : F1;
425 // add se to face but dont add twice
426 TopTools_ListIteratorOfListOfShape itE;
427 if (myAsDes->HasDescendant( F )) {
428 for (itE.Initialize( (myAsDes->Descendant( F )) ); itE.More(); itE.Next())
429 if (se.IsSame( itE.Value() ))
433 myAsDes->Add( F, se );
434 Standard_Real tol, f,l, umin=1e100, umax=-1e100;
435 Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( se, F, f,l);
437 TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) );
438 for ( ;it.More();it.Next()) {
439 const TopoDS_Edge& E = TopoDS::Edge ( it.Value());
440 BRep_Tool::Range(E, f, l);
441 umin = Min( umin, f);
442 umax = Max( umax, l);
444 Handle(Geom_Curve) C3d = BRep_Tool::Curve( se, f, l);
445 if (umin < umax) // sometimes umin == umax for closed edge
446 C3d = new Geom_TrimmedCurve( C3d, umin, umax);
447 pc = TopOpeBRepTool_CurveTool::MakePCurveOnFace (F,C3d,tol);
449 MESSAGE (" CANT BUILD PCURVE ");
451 B.UpdateEdge( se, pc, F, tol);
455 // to detect splits that do not have same domain pair
456 TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) );
457 for ( ;it.More();it.Next()) {
458 const TopoDS_Edge& S = TopoDS::Edge ( it.Value());
459 if (SEM.IsBound( S ))
466 // store vertices of ON splits and bind section edges to faces
467 for (i=1;i<=nes;i++) {
469 const TopoDS_Edge& se = DS.SectionEdge(i);
470 if (! TopB.IsSplit(se,TopAbs_ON))
473 Standard_Integer ancRank = DS.AncestorRank(se);
474 if (ME[ancRank-1].Contains( se ))
475 continue; // se is an edge of face it intersects
477 TopoDS_Face F = (ancRank == 1) ? F2 : F1;
479 // add vertices of splits
480 Standard_Boolean added = Standard_False;
481 TopTools_ListIteratorOfListOfShape it( TopB.Splits(se,TopAbs_ON) );
482 for ( ;it.More();it.Next()) {
483 const TopoDS_Edge& S = TopoDS::Edge ( it.Value());
484 if (!SEM.IsBound( S ))
487 added = Standard_True;
488 mySectionEdgesAD->Add( F, se );
491 TopExp::Vertices (S, VS[0], VS[1]);
492 for (j=0; j<2; ++j) {
493 if (mySameDomainVM.IsBound( VS[j] ))
494 VS[j] = TopoDS::Vertex( mySameDomainVM( VS[j] ));
495 if ( !MV.Contains( VS[j] )) {
496 // find equal vertex on se - point interference
497 gp_Pnt P1 = BRep_Tool::Pnt( VS[j] );
498 TopTools_ListIteratorOfListOfShape itV( myAsDes->Descendant(se) );
499 for (; itV.More(); itV.Next()) {
500 V = TopoDS::Vertex( itV.Value() );
501 gp_Pnt P2 = BRep_Tool::Pnt( V );
502 if (P1.IsEqual( P2, Precision::Confusion())) {
503 mySameDomainVM.Bind (VS[j], V);
508 if (!itV.More()) // no interferences with edges
509 myAsDes->Add( se, VS[j]);
511 mySectionEdgesAD->Add( F, VS[j]);
513 mySectionEdgesAD->Add( F, S );
516 mySectionEdgesAD->Add( F, se );
518 myNewEdges.Add( se );
522 //=======================================================================
523 //function : FacesPartition
525 //=======================================================================
527 void Partition_Inter3d::FacesPartition(const TopoDS_Face& F1,
528 const TopoDS_Face& F2)
529 //(const TopTools_DataMapOfShapeListOfShape& /*SetOfFaces2*/)
531 TopTools_ListOfShape LInt;
533 Inter3D (F1,F2,LInt);
535 StorePart3d (F1,F2,LInt);
538 //=======================================================================
541 //=======================================================================
543 void Partition_Inter3d::SetDone(const TopoDS_Face& F1,
544 const TopoDS_Face& F2)
546 if (!myDone.IsBound(F1)) {
547 TopTools_ListOfShape empty;
548 myDone.Bind(F1,empty);
550 myDone(F1).Append(F2);
551 if (!myDone.IsBound(F2)) {
552 TopTools_ListOfShape empty;
553 myDone.Bind(F2,empty);
555 myDone(F2).Append(F1);
558 //=======================================================================
561 //=======================================================================
563 Standard_Boolean Partition_Inter3d::IsDone(const TopoDS_Face& F1,
564 const TopoDS_Face& F2)
568 if (myDone.IsBound(F1)) {
569 TopTools_ListIteratorOfListOfShape it (myDone(F1));
570 for (; it.More(); it.Next()) {
571 if (it.Value().IsSame(F2)) return Standard_True;
574 return Standard_False;
577 //=======================================================================
578 //function : StorePart3d
580 //=======================================================================
582 void Partition_Inter3d::StorePart3d(const TopoDS_Face& F1,
583 const TopoDS_Face& F2,
584 const TopTools_ListOfShape& LInt)
587 if (!LInt.IsEmpty()) {
588 myAsDes->Add( F1,LInt);
589 myAsDes->Add( F2,LInt);
591 TopTools_ListIteratorOfListOfShape it(LInt);
592 for (; it.More(); it.Next()) {
594 TopoDS_Edge E = TopoDS::Edge(it.Value());
597 B.SameParameter(E,Standard_False);
598 BRepLib::SameParameter(E,1.0e-7);
606 //=======================================================================
607 //function : TouchedFaces
609 //=======================================================================
611 TopTools_MapOfShape& Partition_Inter3d::TouchedFaces()
616 //=======================================================================
619 //=======================================================================
621 Handle(BRepAlgo_AsDes) Partition_Inter3d::AsDes() const
626 //=======================================================================
627 //function : NewEdges
629 //=======================================================================
631 TopTools_MapOfShape& Partition_Inter3d::NewEdges()
636 //=======================================================================
639 //=======================================================================
641 void Partition_Inter3d::Affiche(const TopTools_ListOfShape& SetOfFaces) const
645 char *section=PSection;
646 Standard_Integer i = 0;
648 TopTools_ListOfShape aList;
649 TopTools_ListIteratorOfListOfShape it;
650 for (it.Initialize(SetOfFaces); it.More(); it.Next()) {
651 const TopoDS_Shape& OS = it.Value();
652 aList=myAsDes->Descendant(OS);
653 MESSAGE ( " the number of items stored in the list " << j << " : " << aList.Extent() )
655 TopTools_ListIteratorOfListOfShape itaList;
656 for (itaList.Initialize(aList); itaList.More(); itaList.Next()) {
657 const TopoDS_Shape& SS = itaList.Value();
659 sprintf(PSection,"section_%d",i);
660 DBRep::Set(section,SS);
666 //=======================================================================
667 //function : SameDomain
669 //=======================================================================
671 const TopTools_ListOfShape& Partition_Inter3d::SameDomain(const TopoDS_Face& F) const
673 if (mySameDomainFM.IsBound( F ))
674 return mySameDomainFM (F);
676 static TopTools_ListOfShape empty;
680 //=======================================================================
681 //function : HasSameDomainF
682 //purpose : Return true if F has same domain faces
683 //=======================================================================
685 Standard_Boolean Partition_Inter3d::HasSameDomainF(const TopoDS_Shape& F) const
687 return mySameDomainFM.IsBound( F );
690 //=======================================================================
691 //function : IsSameDomain
692 //purpose : Return true if F1 and F2 are same domain faces
693 //=======================================================================
695 Standard_Boolean Partition_Inter3d::IsSameDomainF(const TopoDS_Shape& F1,
696 const TopoDS_Shape& F2) const
698 if (mySameDomainFM.IsBound( F1 )) {
699 TopTools_ListIteratorOfListOfShape it (mySameDomainFM( F1 ));
700 for (; it.More(); it.Next())
701 if (F2.IsSame( it.Value()))
702 return Standard_True;
704 return F1.IsSame( F2 );
707 //=======================================================================
708 //function : ReplaceSameDomainV
709 //purpose : return same domain vertex of V if it was replaced
710 // and make this vertex to be on E too, else return V
711 //=======================================================================
713 TopoDS_Vertex Partition_Inter3d::ReplaceSameDomainV(const TopoDS_Vertex& V,
714 const TopoDS_Edge& E) const
716 TopoDS_Vertex SDV = V;
717 if (mySameDomainVM.IsBound( V )) {
720 TopExp::Vertices(E,V1,V2);
721 Standard_Boolean isClosed = V1.IsSame( V2 ) && V.IsSame(V1);
723 SDV = TopoDS::Vertex( mySameDomainVM(V) );
724 Standard_Real tol = BRep_Tool::Tolerance( V );
726 SDV.Orientation( V.Orientation());
730 BRep_Tool::Range (E, f, l);
731 Standard_Boolean isFirst = IsEqual( BRep_Tool::Parameter(V,E), f );
732 B.UpdateVertex(SDV, (isFirst ? f : l), E, tol);
734 B.UpdateVertex(SDV, (isFirst ? l : f), E, tol);
737 B.UpdateVertex (SDV, BRep_Tool::Parameter(V,E), E, tol);
743 //=======================================================================
744 //function : SectionEdgesAD
746 //=======================================================================
748 Handle(BRepAlgo_AsDes) Partition_Inter3d::SectionEdgesAD() const
750 return mySectionEdgesAD;
753 //=======================================================================
754 //function : IsSectionEdge
755 //purpose : return True if E is an edge of a face and it
756 // intersects an other face
757 //=======================================================================
760 Partition_Inter3d::IsSectionEdge(const TopoDS_Edge& E) const
762 return mySectionEdgesAD->HasAscendant(E);
765 //=======================================================================
766 //function : HasSectionEdge
767 //purpose : return True if an edge of F intersects an other
768 // face or F is intersected by edge of an other face
769 //=======================================================================
772 Partition_Inter3d::HasSectionEdge(const TopoDS_Face& F) const
774 return mySectionEdgesAD->HasDescendant(F);
777 //=======================================================================
778 //function : IsSplitOn
779 //purpose : return True if NewE is split of OldE on F
780 //=======================================================================
783 Partition_Inter3d::IsSplitOn(const TopoDS_Edge& NewE,
784 const TopoDS_Edge& OldE,
785 const TopoDS_Face& F) const
787 if (! mySectionEdgesAD->HasDescendant(F))
788 return Standard_False;
790 TopTools_ListIteratorOfListOfShape itE ( mySectionEdgesAD->Descendant(F) );
791 for ( ; itE.More(); itE.Next()) {
792 if ( itE.Value().ShapeType() != TopAbs_EDGE ||
793 ! OldE.IsSame ( itE.Value() ))
795 // an edge encountered, its vertices and a split come next
797 if (!itE.More()) break;
798 const TopoDS_Shape& V3 = itE.Value();
799 if (V3.ShapeType() != TopAbs_VERTEX) continue;
801 if (!itE.More()) break;
802 const TopoDS_Shape& V4 = itE.Value();
803 if (V4.ShapeType() != TopAbs_VERTEX) continue;
805 TopoDS_Vertex V1, V2;
806 TopExp::Vertices( OldE, V1, V2);
808 if ( V1.IsSame(V2) &&
809 (V1.IsSame(V3) || V1.IsSame(V4)) ) {
810 // closed old edge; use the split for the test
812 if (!itE.More()) break;
813 const TopoDS_Edge& split = TopoDS::Edge( itE.Value() );
814 // check distance at middle point of NewE
815 Standard_Real f1,l1, f2,l2;
816 Handle(Geom2d_Curve) PC1 = BRep_Tool::CurveOnSurface( split, F ,f1,l1);
818 Handle(Geom2d_Curve) PC2 = BRep_Tool::CurveOnSurface(NewE, F ,f2,l2);
819 gp_Pnt2d P = PC2->Value( 0.5*(f2+l2) );
820 Geom2dAPI_ProjectPointOnCurve proj (P, PC1, f1, l1);
821 if (proj.NbPoints() &&
822 proj.LowerDistance() <= Precision::Confusion())
823 return Standard_True;
826 Handle(Geom_Curve) C1 = BRep_Tool::Curve( split ,f1,l1);
827 Handle(Geom_Curve) C2 = BRep_Tool::Curve( NewE ,f2,l2);
828 gp_Pnt P = C2->Value( 0.5*(f2+l2) );
829 GeomAPI_ProjectPointOnCurve proj (P, C1, f1, l1);
830 if (proj.NbPoints() &&
831 proj.LowerDistance() <= Precision::Confusion())
832 return Standard_True;
836 Standard_Real u3 = BRep_Tool::Parameter( TopoDS::Vertex(V3), OldE);
837 Standard_Real u4 = BRep_Tool::Parameter( TopoDS::Vertex(V4), OldE);
839 Standard_Real f,l, u;
840 BRep_Tool::Range( NewE, f,l);
845 if (u <= l && u >= f)
846 return Standard_True;
849 return Standard_False;
852 //=======================================================================
853 //function : SectionEdgeFaces
854 //purpose : return faces cut by section edge
855 //=======================================================================
857 const TopTools_ListOfShape&
858 Partition_Inter3d::SectionEdgeFaces(const TopoDS_Edge& SecE) const
860 return mySectionEdgesAD->Ascendant( SecE );