1 // Created on: 1993-12-15
2 // Created by: Isabelle GRIGNON
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 #include <ChFi3d_Builder.jxx>
24 #include <Precision.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <TopoDS_Face.hxx>
32 #include <TopoDS_Edge.hxx>
33 #include <TopoDS_Vertex.hxx>
35 #include <BRepAdaptor_Curve.hxx>
36 #include <BRepAdaptor_Surface.hxx>
37 #include <BRepLProp_SLProps.hxx>
40 #include <TopAbs_ShapeEnum.hxx>
41 #include <TopAbs_Orientation.hxx>
43 #include <BRep_Tool.hxx>
45 #include <TopTools_ListIteratorOfListOfShape.hxx>
46 #include <TopOpeBRepDS_Surface.hxx>
48 #include <ChFiDS_ErrorStatus.hxx>
49 #include <ChFiDS_State.hxx>
50 #include <ChFiDS_Spine.hxx>
51 #include <ChFiDS_FilSpine.hxx>
52 #include <ChFiDS_HData.hxx>
53 #include <ChFiDS_SurfData.hxx>
54 #include <ChFiDS_Regul.hxx>
55 #include <ChFiDS_ListIteratorOfRegularities.hxx>
56 #include <ChFiDS_ListIteratorOfListOfStripe.hxx>
59 #include <ChFi3d_Builder_0.hxx>
61 #include <LocalAnalysis_SurfaceContinuity.hxx>
62 #include <TopOpeBRepTool_TOOL.hxx>
65 extern Standard_Boolean ChFi3d_GetcontextFORCEBLEND();
68 static TopOpeBRepDS_BuildTool mkbuildtool()
70 TopOpeBRepTool_GeomTool GT2(TopOpeBRepTool_BSPLINE1,
74 TopOpeBRepDS_BuildTool BT(GT2);
75 BT.OverWrite(Standard_False);
76 BT.Translate(Standard_False);
80 // Modified by Sergey KHROMOV - Tue Dec 18 18:02:55 2001 Begin
81 Standard_Boolean isTangentFaces(const TopoDS_Edge &theEdge,
82 const TopoDS_Face &theFace1,
83 const TopoDS_Face &theFace2)
85 if (BRep_Tool::Continuity( theEdge, theFace1, theFace2 ) != GeomAbs_C0)
91 // Obtaining of pcurves of edge on two faces.
92 const Handle(Geom2d_Curve) aC2d1 = BRep_Tool::CurveOnSurface
93 (theEdge, theFace1, aFirst, aLast);
94 const Handle(Geom2d_Curve) aC2d2 = BRep_Tool::CurveOnSurface
95 (theEdge, theFace2, aFirst, aLast);
96 if (aC2d1.IsNull() || aC2d2.IsNull())
97 return Standard_False;
99 // Obtaining of two surfaces from adjacent faces.
100 Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
101 Handle(Geom_Surface) aSurf2 = BRep_Tool::Surface(theFace2);
103 if (aSurf1.IsNull() || aSurf2.IsNull())
104 return Standard_False;
106 // Computation of the number of samples on the edge.
107 BRepAdaptor_Surface aBAS1(theFace1);
108 BRepAdaptor_Surface aBAS2(theFace2);
109 Handle(BRepAdaptor_HSurface) aBAHS1 = new BRepAdaptor_HSurface(aBAS1);
110 Handle(BRepAdaptor_HSurface) aBAHS2 = new BRepAdaptor_HSurface(aBAS2);
111 Handle(BRepTopAdaptor_TopolTool) aTool1 = new BRepTopAdaptor_TopolTool(aBAHS1);
112 Handle(BRepTopAdaptor_TopolTool) aTool2 = new BRepTopAdaptor_TopolTool(aBAHS2);
113 Standard_Integer aNbSamples1 = aTool1->NbSamples();
114 Standard_Integer aNbSamples2 = aTool2->NbSamples();
115 Standard_Integer aNbSamples = Max(aNbSamples1, aNbSamples2);
118 // Computation of the continuity.
120 Standard_Real aDelta = (aLast - aFirst)/(aNbSamples - 1);
121 Standard_Integer i, nbNotDone = 0;
123 for (i = 1, aPar = aFirst; i <= aNbSamples; i++, aPar += aDelta) {
124 if (i == aNbSamples) aPar = aLast;
126 LocalAnalysis_SurfaceContinuity aCont(aC2d1, aC2d2, aPar,
127 aSurf1, aSurf2, GeomAbs_G1,
128 0.001, 0.001, 0.1, 0.1, 0.1);
135 return Standard_False;
138 if (nbNotDone == aNbSamples)
139 return Standard_False;
141 //Compare normals of tangent faces in the middle point
142 Standard_Real MidPar = (aFirst + aLast)/2.;
143 gp_Pnt2d uv1 = aC2d1->Value(MidPar);
144 gp_Pnt2d uv2 = aC2d2->Value(MidPar);
145 gp_Dir normal1, normal2;
146 TopOpeBRepTool_TOOL::Nt( uv1, theFace1, normal1 );
147 TopOpeBRepTool_TOOL::Nt( uv2, theFace2, normal2 );
148 Standard_Real dot = normal1.Dot(normal2);
150 return Standard_False;
151 return Standard_True;
153 // Modified by Sergey KHROMOV - Tue Dec 18 18:02:56 2001 End
155 //=======================================================================
156 //function : ChFi3d_Builder
158 //=======================================================================
159 ChFi3d_Builder::ChFi3d_Builder(const TopoDS_Shape& S,
160 const Standard_Real Ta) :
161 done(Standard_False), myShape(S)
163 myDS = new TopOpeBRepDS_HDataStructure();
164 myCoup = new TopOpeBRepBuild_HBuilder(mkbuildtool());
165 myEFMap.Fill(S,TopAbs_EDGE,TopAbs_FACE);
166 myESoMap.Fill(S,TopAbs_EDGE,TopAbs_SOLID);
167 myEShMap.Fill(S,TopAbs_EDGE,TopAbs_SHELL);
168 myVFMap.Fill(S,TopAbs_VERTEX,TopAbs_FACE);
169 myVEMap.Fill(S,TopAbs_VERTEX,TopAbs_EDGE);
170 SetParams(Ta,1.e-4,1.e-5,1.e-4,1.e-5,1.e-3);
171 SetContinuity(GeomAbs_C1, Ta);
174 //=======================================================================
175 //function : SetParams
177 //=======================================================================
179 void ChFi3d_Builder::SetParams(const Standard_Real Tang,
180 const Standard_Real Tesp,
181 const Standard_Real T2d,
182 const Standard_Real TApp3d,
183 const Standard_Real TolApp2d,
184 const Standard_Real Fleche)
194 //=======================================================================
195 //function : SetContinuity
197 //=======================================================================
199 void ChFi3d_Builder::SetContinuity(const GeomAbs_Shape InternalContinuity,
200 const Standard_Real AngularTolerance)
202 myConti = InternalContinuity;
203 tolappangle = AngularTolerance;
206 //=======================================================================
209 //=======================================================================
211 Standard_Boolean ChFi3d_Builder::IsDone() const
216 //=======================================================================
219 //=======================================================================
221 TopoDS_Shape ChFi3d_Builder::Shape()const
223 Standard_NoSuchObject_Raise_if(!done,"");
224 return myShapeResult;
227 //=======================================================================
228 //function : NbFaultyContours
230 //=======================================================================
232 Standard_Integer ChFi3d_Builder::NbFaultyContours() const
234 return badstripes.Extent();
237 //=======================================================================
238 //function : FaultyContour
240 //=======================================================================
242 Standard_Integer ChFi3d_Builder::FaultyContour(const Standard_Integer I) const
244 ChFiDS_ListIteratorOfListOfStripe itel;
245 Standard_Integer k = 0;
246 Handle(ChFiDS_Stripe) st;
247 for (itel.Initialize(badstripes);itel.More(); itel.Next()) {
254 if(st.IsNull()) return 0;
256 for (itel.Initialize(myListStripe);itel.More(); itel.Next()) {
258 if(st == itel.Value()) return k;
263 //=======================================================================
264 //function : NbComputedSurfaces
266 //=======================================================================
268 Standard_Integer ChFi3d_Builder::NbComputedSurfaces(const Standard_Integer IC) const
270 ChFiDS_ListIteratorOfListOfStripe itel;
271 Standard_Integer k = 0;
272 Handle(ChFiDS_Stripe) st;
273 for (itel.Initialize(myListStripe);itel.More(); itel.Next()) {
280 if(st.IsNull()) return 0;
281 if(st->Spine().IsNull()) return 0;
282 Handle(ChFiDS_HData) hd = st->SetOfSurfData();
283 if(hd.IsNull()) return 0;
287 //=======================================================================
288 //function : ComputedSurface
290 //=======================================================================
292 Handle(Geom_Surface) ChFi3d_Builder::ComputedSurface(const Standard_Integer IC,
293 const Standard_Integer IS) const
295 ChFiDS_ListIteratorOfListOfStripe itel;
296 Standard_Integer k = 0;
297 Handle(ChFiDS_Stripe) st;
298 for (itel.Initialize(myListStripe);itel.More(); itel.Next()) {
305 Handle(ChFiDS_HData) hd = st->SetOfSurfData();
306 Standard_Integer isurf=hd->Value(IS)->Surf();
307 return myDS->Surface(isurf).Surface();
310 //=======================================================================
311 //function : NbFaultyVertices
313 //=======================================================================
315 Standard_Integer ChFi3d_Builder::NbFaultyVertices() const
317 return badvertices.Extent();
320 //=======================================================================
321 //function : FaultyVertex
323 //=======================================================================
325 TopoDS_Vertex ChFi3d_Builder::FaultyVertex(const Standard_Integer IV) const
327 TopTools_ListIteratorOfListOfShape it;
329 Standard_Integer k = 0;
330 for(it.Initialize(badvertices);it.More(); it.Next()) {
333 V = TopoDS::Vertex(it.Value());
340 //=======================================================================
341 //function : HasResult
343 //=======================================================================
345 Standard_Boolean ChFi3d_Builder::HasResult() const
350 //=======================================================================
351 //function : BadShape
353 //=======================================================================
355 TopoDS_Shape ChFi3d_Builder::BadShape()const
357 Standard_NoSuchObject_Raise_if(!hasresult,"");
361 //=======================================================================
362 //function : StripeStatus
364 //=======================================================================
366 ChFiDS_ErrorStatus ChFi3d_Builder::StripeStatus(const Standard_Integer IC)const
368 ChFiDS_ListIteratorOfListOfStripe itel;
369 Standard_Integer k =0;
370 Handle(ChFiDS_Stripe) st;
371 for (itel.Initialize(myListStripe);itel.More(); itel.Next()) {
378 ChFiDS_ErrorStatus stat=st->Spine()->ErrorStatus();
382 //=======================================================================
385 //=======================================================================
387 Handle(TopOpeBRepBuild_HBuilder) ChFi3d_Builder::Builder()const
392 //=======================================================================
393 //function : ChFi3d_FaceTangency
394 //purpose : determine if the faces opposing to edges are tangent
395 // to go from opposing faces on e0 to opposing faces
396 // on e1, consider all faces starting at a common top.
397 //=======================================================================
399 Standard_Boolean ChFi3d_Builder::FaceTangency(const TopoDS_Edge& E0,
400 const TopoDS_Edge& E1,
401 const TopoDS_Vertex& V) const
403 TopTools_ListIteratorOfListOfShape It,Jt;
405 Standard_Integer Nbf;
408 //It is checked if the connection is not on a regular edge.
409 for (It.Initialize(myEFMap(E1)), Nbf= 0 ;It.More();It.Next(), Nbf++) {
411 Standard_ConstructionError::Raise("ChFi3d_Builder:only 2 faces");
412 F[Nbf] = TopoDS::Face(It.Value());
414 if(Nbf < 2) return Standard_False;
415 // Modified by Sergey KHROMOV - Fri Dec 21 17:44:19 2001 Begin
416 //if (BRep_Tool::Continuity(E1,F[0],F[1]) != GeomAbs_C0) {
417 if (isTangentFaces(E1,F[0],F[1])) {
418 // Modified by Sergey KHROMOV - Fri Dec 21 17:44:21 2001 End
419 return Standard_False;
422 for (Jt.Initialize(myVEMap(V));Jt.More();Jt.Next()) {
423 Ec = TopoDS::Edge(Jt.Value());
424 if (!Ec.IsSame(E0) && !Ec.IsSame(E1) &&
425 Ec.Orientation() != TopAbs_INTERNAL &&
426 Ec.Orientation() != TopAbs_EXTERNAL &&
427 !BRep_Tool::Degenerated(Ec)) {
428 for (It.Initialize(myEFMap(Ec)), Nbf= 0 ;It.More();It.Next(), Nbf++) {
430 Standard_ConstructionError::Raise("ChFi3d_Builder:only 2 faces");
431 F[Nbf] = TopoDS::Face(It.Value());
433 if(Nbf < 2) return Standard_False;
434 // Modified by Sergey KHROMOV - Tue Dec 18 18:10:40 2001 Begin
435 // if (BRep_Tool::Continuity(Ec,F[0],F[1]) < GeomAbs_G1) {
436 if (!isTangentFaces(Ec,F[0],F[1])) {
437 // Modified by Sergey KHROMOV - Tue Dec 18 18:10:41 2001 End
438 return Standard_False;
442 return Standard_True;
447 //=======================================================================
448 //function : TangentExtremity
449 //purpose : Test if 2 faces are tangent at the end of an edge
450 //=======================================================================
451 static Standard_Boolean TangentExtremity(const TopoDS_Vertex& V,
452 const TopoDS_Edge& E,
453 const Handle(BRepAdaptor_HSurface)& hs1,
454 const Handle(BRepAdaptor_HSurface)& hs2,
455 // const Standard_Real t3d,
456 const Standard_Real tang)
458 TopoDS_Face f1 = hs1->ChangeSurface().Face();
459 TopAbs_Orientation O1 = f1.Orientation();
460 f1.Orientation(TopAbs_FORWARD);
461 TopoDS_Face f2 = hs2->ChangeSurface().Face();
462 TopAbs_Orientation O2 = f2.Orientation();
463 f2.Orientation(TopAbs_FORWARD);
464 TopoDS_Edge e1 = E, e2 = E;
465 e1.Orientation(TopAbs_FORWARD);
466 e2.Orientation(TopAbs_FORWARD);
467 if(f1.IsSame(f2) && BRep_Tool::IsClosed(e1,f1))
468 e2.Orientation(TopAbs_REVERSED);
469 Standard_Real p1 = BRep_Tool::Parameter(V,e1,f1);
470 Standard_Real p2 = BRep_Tool::Parameter(V,e2,f2);
471 Standard_Real u,v,f,l, Eps = 1.e-9;
472 gp_Vec n1, n2;// gp_Pnt pt1,pt2;
473 Handle(Geom2d_Curve) pc1 = BRep_Tool::CurveOnSurface(e1,f1,f,l);
474 pc1->Value(p1).Coord(u,v);
475 BRepLProp_SLProps theProp1(hs1->ChangeSurface(), u, v, 1, Eps);
476 if (theProp1.IsNormalDefined()) {
477 n1.SetXYZ(theProp1.Normal().XYZ());
478 if (O1 == TopAbs_REVERSED) n1.Reverse();
480 else return Standard_False; // It is not known...
483 Handle(Geom2d_Curve) pc2 = BRep_Tool::CurveOnSurface(e2,f2,f,l);
484 pc2->Value(p2).Coord(u,v);
485 BRepLProp_SLProps theProp2(hs2->ChangeSurface(), u, v, 1, Eps);
486 if (theProp2.IsNormalDefined()) {
487 n2.SetXYZ(theProp2.Normal().XYZ());
488 if(O2 == TopAbs_REVERSED) n2.Reverse();
490 else return Standard_False; // It is not known...
492 return (n1.Angle(n2) < tang);
495 //=======================================================================
496 //function : TangentOnVertex
497 //purpose : Test if support faces of an edge are tangent at end.
498 //=======================================================================
499 static Standard_Boolean TangentOnVertex(const TopoDS_Vertex& V,
500 const TopoDS_Edge& E,
501 const ChFiDS_Map& EFMap,
502 const Standard_Real tang)
505 ChFi3d_conexfaces(E,ff1,ff2,EFMap);
506 if(ff1.IsNull() || ff2.IsNull()) return 0;
507 Handle(BRepAdaptor_HSurface) S1 = new (BRepAdaptor_HSurface)(ff1);
508 Handle(BRepAdaptor_HSurface) S2 = new (BRepAdaptor_HSurface)(ff2);
509 return TangentExtremity(V, E, S1, S2, tang);
512 //=======================================================================
513 //function : PerformExtremity
514 //purpose : In case if PerformElement returned BreakPoint at one or
515 // another extremity, it is attempted to refine
516 // depending on concavities between neighbour faces of the top.
517 //=======================================================================
519 void ChFi3d_Builder::PerformExtremity (const Handle(ChFiDS_Spine)& Spine)
521 for(Standard_Integer ii = 1; ii <= 2; ii++){
525 Standard_Integer iedge;
526 Handle(BRepAdaptor_HSurface) hs1,hs2;
528 sst = Spine->FirstStatus();
530 V = Spine->FirstVertex();
533 sst = Spine->LastStatus();
534 iedge = Spine->NbEdges();
535 E[0] = Spine->Edges(iedge);
536 V = Spine->LastVertex();
538 //Before all it is checked if the tangency is not dead.
539 E[0] = Spine->Edges(iedge);
540 ConexFaces (Spine,iedge,0,hs1,hs2);
541 if(TangentExtremity(V,E[0],hs1,hs2,angular)){
542 Spine->SetTangencyExtremity(Standard_True, (ii == 1));
545 if(sst == ChFiDS_BreakPoint){
546 TopTools_ListIteratorOfListOfShape It;//,Jt;
547 Standard_Integer i = 0, j;
548 Standard_Boolean sommetpourri = Standard_False;
549 for (It.Initialize(myVEMap(V));It.More();It.Next()){
550 Ec = TopoDS::Edge(It.Value());
551 Standard_Boolean bonedge = !BRep_Tool::Degenerated(Ec);
554 TopExp::Vertices(Ec,v1,v2);
555 Standard_Boolean eclosed = v1.IsSame(v2);
556 Standard_Integer nboc = 0;
557 for(j = 0; j <= i && bonedge; j++){
558 if(!eclosed) bonedge = !Ec.IsSame(E[j]);
559 else if(Ec.IsSame(E[j])){
572 cout<<"top has more than 3 edges"<<endl;
574 sommetpourri = Standard_True;
579 if(i != 2) sommetpourri = Standard_True;
581 sst = ChFi3d_EdgeState(E,myEFMap);
583 if(ii==1)Spine->SetFirstStatus(sst);
584 else Spine->SetLastStatus(sst);
588 if (!Spine->IsPeriodic()) {
589 TopTools_ListIteratorOfListOfShape It,Jt;
590 Standard_Integer nbf = 0, jf = 0;
591 for (It.Initialize(myVFMap(Spine->FirstVertex())); It.More(); It.Next()){
593 Standard_Integer kf = 1;
594 const TopoDS_Shape& cur = It.Value();
595 for (Jt.Initialize(myVFMap(Spine->FirstVertex())); Jt.More() && (kf < jf); Jt.Next(), kf++){
596 if(cur.IsSame(Jt.Value())) break;
601 Spine->SetFirstStatus(ChFiDS_BreakPoint);
603 cout<<"top has : "<<nbf<<" faces."<<endl;
607 for (It.Initialize(myVFMap(Spine->LastVertex())); It.More(); It.Next()){
609 Standard_Integer kf = 1;
610 const TopoDS_Shape& cur = It.Value();
611 for (Jt.Initialize(myVFMap(Spine->LastVertex())); Jt.More() && (kf < jf); Jt.Next(), kf++){
612 if(cur.IsSame(Jt.Value())) break;
617 Spine->SetLastStatus(ChFiDS_BreakPoint);
619 cout<<"top has : "<<nbf<<" faces."<<endl;
625 //=======================================================================
626 //function : PerformElement
627 //purpose : find all mutually tangent edges ;
628 // Each edge has 2 opposing faces. For 2 adjacent tangent edges it is required that
629 // the opposing faces were tangent.
630 //=======================================================================
632 Standard_Boolean ChFi3d_Builder::PerformElement(const Handle(ChFiDS_Spine)& Spine)
634 Standard_Real ta = angular;
635 TopTools_ListIteratorOfListOfShape It;
636 Standard_Integer Nbface;
637 TopTools_ListIteratorOfListOfShape Jt;
639 Standard_Boolean degeneOnEc;
642 TopoDS_Vertex Ve1,VStart,FVEc,LVEc,FVEv,LVEv;
643 TopoDS_Edge Ev,Ec(Spine->Edges(1));
644 if(BRep_Tool::Degenerated(Ec)) return 0;
645 //it is checked if the edge is a cut edge
647 ChFi3d_conexfaces(Ec,ff1,ff2,myEFMap);
648 if(ff1.IsNull() || ff2.IsNull()) return 0;
649 // Modified by Sergey KHROMOV - Fri Dec 21 17:46:22 2001 End
650 //if(BRep_Tool::Continuity(Ec,ff1,ff2) != GeomAbs_C0) return 0;
651 if (isTangentFaces(Ec,ff1,ff2)) return 0;
652 // Modified by Sergey KHROMOV - Fri Dec 21 17:46:24 2001 Begin
654 BRepAdaptor_Curve CEc,CEv;
655 TopAbs_Orientation curor = Ec.Orientation();
656 TopExp::Vertices(Ec,VStart,LVEc);
659 Standard_Boolean Fini = Standard_False;
662 ChFiDS_State CurSt = ChFiDS_Closed;
666 if (VStart.IsSame(LVEc)) {//case if only one edge is closed
668 Wl = BRep_Tool::Parameter(VStart,Ec);
670 Wl = BRep_Tool::Parameter(LVEc,Ec);
672 if (V1.IsParallel(V2,ta)) {
673 if (FaceTangency(Ec,Ec,VStart)) {
674 CurSt = ChFiDS_Closed;
677 CurSt = ChFiDS_BreakPoint;
681 CurSt = ChFiDS_BreakPoint;
683 Spine->SetLastStatus(CurSt);
684 Spine->SetFirstStatus(CurSt);
686 else { // Downstream progression
688 TopAbs_Orientation Or1;
690 CurSt = ChFiDS_FreeBoundary;
691 Wl = BRep_Tool::Parameter(LVEc,Ec);
692 degeneOnEc = TangentOnVertex(LVEc, Ec, myEFMap, ta);
695 Nb = Spine->NbEdges();
697 for (It.Initialize(myVEMap(LVEc));It.More();It.Next()) {
698 Ev = TopoDS::Edge(It.Value());
699 if (!Ev.IsSame(Ec) && !BRep_Tool::Degenerated(Ev)){
700 TopExp::Vertices(Ev,FVEv,LVEv);
701 if (LVEc.IsSame(LVEv)) {
705 Or1 = TopAbs_REVERSED;
707 else Or1 = TopAbs_FORWARD;
709 Wf = BRep_Tool::Parameter(FVEv,Ev);
712 Standard_Real av1v2 = V1.Angle(V2);
713 Standard_Boolean rev = (Or1 != curor);
714 Standard_Boolean OnAjoute = Standard_False;
715 if (FaceTangency(Ec,Ev,FVEv)) {
716 // there is no need of tolerance
717 // to make a decision (PRO9486) the regularity is enough.
718 // However, the abcense of turn-back is checked (PRO9810)
719 OnAjoute = ((!rev && av1v2 < M_PI/2)
720 ||(rev && av1v2 > M_PI/2));
721 // mate attention to the single case (cf CTS21610_1)
722 if (OnAjoute && (degeneOnEc ||
723 TangentOnVertex(LVEc, Ev,myEFMap, ta)) )
724 OnAjoute=((!rev && av1v2 < ta) || (rev && (M_PI - av1v2) < ta));
727 Fini = Standard_False; // If this can be useful (Cf PRO14713)
729 // Ec = TopoDS::Edge(Ev);
731 Wl = Wf; LVEc = LVEv;
734 if (VStart.IsSame(LVEv)) {
735 if (FaceTangency(Ev,Spine->Edges(1),LVEv)) {
736 CurSt = ChFiDS_Closed; Fini = Standard_True;
739 CurSt = ChFiDS_BreakPoint;Fini = Standard_True;
745 for (Jt.Initialize(myEFMap(Ev)), Nbface= 0 ;Jt.More();Jt.Next(),
747 if (Nbface> 1) CurSt = ChFiDS_BreakPoint;
748 Fini = ((!rev && av1v2 < ta) || (rev && (M_PI - av1v2) < ta));
752 Fini = Fini || (Nb == Spine->NbEdges());
754 Spine->SetLastStatus(CurSt);
755 if (CurSt == ChFiDS_Closed) {
756 Spine->SetFirstStatus(CurSt);
758 else {// Upstream progression
759 Fini = Standard_False;
760 Ec = Spine->Edges(1);
761 curor = Ec.Orientation();
764 CurSt = ChFiDS_FreeBoundary;
765 Wl = BRep_Tool::Parameter(FVEc,Ec);
766 degeneOnEc = TangentOnVertex(FVEc, Ec, myEFMap, ta);
769 Nb = Spine->NbEdges();
771 for (It.Initialize(myVEMap(FVEc));It.More();It.Next()) {
772 Ev = TopoDS::Edge(It.Value());
773 if (!Ev.IsSame(Ec) && !BRep_Tool::Degenerated(Ev)) {
774 TopExp::Vertices(Ev,FVEv,LVEv);
775 if (FVEc.IsSame(FVEv)) {
779 Or1 = TopAbs_REVERSED;
782 Or1 = TopAbs_FORWARD;
784 Wf = BRep_Tool::Parameter(LVEv,Ev);
787 Standard_Real av1v2 = V1.Angle(V2);
788 Standard_Boolean rev = (Or1 != curor);
789 Standard_Boolean OnAjoute = Standard_False;
790 if (FaceTangency(Ec,Ev,LVEv)) {
791 OnAjoute = ((!rev && av1v2 < M_PI/2)
792 ||(rev && av1v2 > M_PI/2));
793 if (OnAjoute && (degeneOnEc ||
794 TangentOnVertex(FVEc, Ev,myEFMap, ta)) )
795 OnAjoute=((!rev && av1v2 < ta) || (rev && (M_PI-av1v2) < ta));
799 // Ec = TopoDS::Edge(Ev);
801 Wl = Wf; FVEc = FVEv;
802 Spine->PutInFirst(Ec);
807 for(Jt.Initialize(myEFMap(Ev)),Nbface= 0 ;Jt.More();Jt.Next(),
809 if (Nbface> 1) CurSt = ChFiDS_BreakPoint;
810 Fini = ((!rev && av1v2 < ta) || (rev && (M_PI - av1v2) < ta));
814 Fini = Fini || (Nb == Spine->NbEdges());
816 Spine->SetFirstStatus(CurSt);
822 //=======================================================================
825 //=======================================================================
827 void ChFi3d_Builder::Remove(const TopoDS_Edge& E)
829 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
831 for ( ; itel.More(); itel.Next()) {
832 const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine();
833 for (Standard_Integer j = 1; j <= sp->NbEdges(); j++){
834 if (E.IsSame(sp->Edges(j))){
835 myListStripe.Remove(itel);
843 //=======================================================================
846 //=======================================================================
848 Handle(ChFiDS_Spine) ChFi3d_Builder::Value
849 (const Standard_Integer I)const
851 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
852 for (Standard_Integer ic = 1; ic < I; ic++) {itel.Next();}
853 return itel.Value()->Spine();
856 //=======================================================================
857 //function : NbElements
859 //=======================================================================
861 Standard_Integer ChFi3d_Builder::NbElements()const
863 Standard_Integer i = 0;
864 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
865 for ( ;itel.More(); itel.Next()){
866 const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine();
867 if(sp.IsNull()) break;
873 //=======================================================================
874 //function : Contains
876 //=======================================================================
878 Standard_Integer ChFi3d_Builder::Contains(const TopoDS_Edge& E)const
880 Standard_Integer i = 1,j;
881 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
882 for ( ;itel.More(); itel.Next(), i++){
883 const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine();
884 if(sp.IsNull()) break;
885 for (j = 1; j <= sp->NbEdges(); j++){
886 if(E.IsSame(sp->Edges(j))) return i;
892 //=======================================================================
893 //function : Contains
895 //=======================================================================
897 Standard_Integer ChFi3d_Builder::Contains(const TopoDS_Edge& E,
898 Standard_Integer& IndexInSpine)const
900 Standard_Integer i = 1,j;
902 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
903 for ( ;itel.More(); itel.Next(), i++){
904 const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine();
905 if(sp.IsNull()) break;
906 for (j = 1; j <= sp->NbEdges(); j++){
907 if(E.IsSame(sp->Edges(j)))
917 //=======================================================================
920 //=======================================================================
922 Standard_Real ChFi3d_Builder::Length(const Standard_Integer IC)const
924 if(IC <= NbElements()){
925 const Handle(ChFiDS_Spine)& sp = Value(IC);
926 return sp->LastParameter(sp->NbEdges());
932 //=======================================================================
933 //function : FirstVertex
935 //=======================================================================
937 TopoDS_Vertex ChFi3d_Builder::FirstVertex(const Standard_Integer IC) const
939 if(IC <= NbElements()){
940 return Value(IC)->FirstVertex();
942 return TopoDS_Vertex();
945 //=======================================================================
946 //function : LastVertex
948 //=======================================================================
950 TopoDS_Vertex ChFi3d_Builder::LastVertex(const Standard_Integer IC) const
952 if(IC <= NbElements()){
953 return Value(IC)->LastVertex();
955 return TopoDS_Vertex();
958 //=======================================================================
959 //function : Abscissa
961 //=======================================================================
963 Standard_Real ChFi3d_Builder::Abscissa(const Standard_Integer IC,
964 const TopoDS_Vertex& V) const
966 if(IC <= NbElements()){
967 return Value(IC)->Absc(V);
972 //=======================================================================
973 //function : RelativeAbscissa
975 //=======================================================================
977 Standard_Real ChFi3d_Builder::RelativeAbscissa(const Standard_Integer IC,
978 const TopoDS_Vertex& V) const
980 if(IC <= NbElements()){
981 return Abscissa(IC,V)/Length(IC);
986 //=======================================================================
989 //=======================================================================
991 Standard_Boolean ChFi3d_Builder::Closed(const Standard_Integer IC)const
993 if(IC <= NbElements()){
994 return Value(IC)->IsClosed();
996 return Standard_False;
999 //=======================================================================
1000 //function : ClosedAndTangent
1002 //=======================================================================
1004 Standard_Boolean ChFi3d_Builder::ClosedAndTangent
1005 (const Standard_Integer IC)const
1007 if(IC <= NbElements()){
1008 return Value(IC)->IsPeriodic();
1010 return Standard_False;