0026173: Wrong result of ChFi3d_ChBuilder algorithm: incorrect processing of G1 junct...
[occt.git] / src / ChFi3d / ChFi3d_Builder_1.cxx
... / ...
CommitLineData
1// Created on: 1993-12-15
2// Created by: Isabelle GRIGNON
3// Copyright (c) 1993-1999 Matra Datavision
4// Copyright (c) 1999-2014 OPEN CASCADE SAS
5//
6// This file is part of Open CASCADE Technology software library.
7//
8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
13//
14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
16
17
18#include <Adaptor2d_HCurve2d.hxx>
19#include <Adaptor3d_HSurface.hxx>
20#include <Adaptor3d_TopolTool.hxx>
21#include <AppBlend_Approx.hxx>
22#include <Blend_CurvPointFuncInv.hxx>
23#include <Blend_FuncInv.hxx>
24#include <Blend_Function.hxx>
25#include <Blend_RstRstFunction.hxx>
26#include <Blend_SurfCurvFuncInv.hxx>
27#include <Blend_SurfPointFuncInv.hxx>
28#include <Blend_SurfRstFunction.hxx>
29#include <BRep_Tool.hxx>
30#include <BRepAdaptor_Curve.hxx>
31#include <BRepAdaptor_HCurve2d.hxx>
32#include <BRepAdaptor_HSurface.hxx>
33#include <BRepAdaptor_Surface.hxx>
34#include <BRepBlend_Line.hxx>
35#include <BRepLProp_SLProps.hxx>
36#include <BRepTopAdaptor_TopolTool.hxx>
37#include <ChFi3d.hxx>
38#include <ChFi3d_Builder.hxx>
39#include <ChFi3d_Builder_0.hxx>
40#include <ChFiDS_CommonPoint.hxx>
41#include <ChFiDS_ErrorStatus.hxx>
42#include <ChFiDS_FilSpine.hxx>
43#include <ChFiDS_HData.hxx>
44#include <ChFiDS_HElSpine.hxx>
45#include <ChFiDS_ListIteratorOfListOfStripe.hxx>
46#include <ChFiDS_ListIteratorOfRegularities.hxx>
47#include <ChFiDS_Regul.hxx>
48#include <ChFiDS_Spine.hxx>
49#include <ChFiDS_State.hxx>
50#include <ChFiDS_Stripe.hxx>
51#include <ChFiDS_SurfData.hxx>
52#include <Geom2d_Curve.hxx>
53#include <Geom_Surface.hxx>
54#include <gp_Pnt.hxx>
55#include <gp_Pnt2d.hxx>
56#include <gp_Vec.hxx>
57#include <LocalAnalysis_SurfaceContinuity.hxx>
58#include <Precision.hxx>
59#include <Standard_ConstructionError.hxx>
60#include <Standard_NoSuchObject.hxx>
61#include <Standard_OutOfRange.hxx>
62#include <TopAbs.hxx>
63#include <TopAbs_Orientation.hxx>
64#include <TopAbs_ShapeEnum.hxx>
65#include <TopExp.hxx>
66#include <TopoDS.hxx>
67#include <TopoDS_Edge.hxx>
68#include <TopoDS_Face.hxx>
69#include <TopoDS_Shape.hxx>
70#include <TopoDS_Vertex.hxx>
71#include <TopOpeBRepBuild_HBuilder.hxx>
72#include <TopOpeBRepDS_HDataStructure.hxx>
73#include <TopOpeBRepDS_Surface.hxx>
74#include <TopOpeBRepTool_TOOL.hxx>
75#include <TopTools_ListIteratorOfListOfShape.hxx>
76
77#ifdef OCCT_DEBUG
78extern Standard_Boolean ChFi3d_GetcontextFORCEBLEND();
79#endif
80
81static TopOpeBRepDS_BuildTool mkbuildtool()
82{
83 TopOpeBRepTool_GeomTool GT2(TopOpeBRepTool_BSPLINE1,
84 Standard_True,
85 Standard_False,
86 Standard_False);
87 TopOpeBRepDS_BuildTool BT(GT2);
88 BT.OverWrite(Standard_False);
89 BT.Translate(Standard_False);
90 return BT;
91}
92
93//=======================================================================
94//function : ChFi3d_Builder
95//purpose :
96//=======================================================================
97ChFi3d_Builder::ChFi3d_Builder(const TopoDS_Shape& S,
98 const Standard_Real Ta) :
99 done(Standard_False), myShape(S)
100{
101 myDS = new TopOpeBRepDS_HDataStructure();
102 myCoup = new TopOpeBRepBuild_HBuilder(mkbuildtool());
103 myEFMap.Fill(S,TopAbs_EDGE,TopAbs_FACE);
104 myESoMap.Fill(S,TopAbs_EDGE,TopAbs_SOLID);
105 myEShMap.Fill(S,TopAbs_EDGE,TopAbs_SHELL);
106 myVFMap.Fill(S,TopAbs_VERTEX,TopAbs_FACE);
107 myVEMap.Fill(S,TopAbs_VERTEX,TopAbs_EDGE);
108 SetParams(Ta,1.e-4,1.e-5,1.e-4,1.e-5,1.e-3);
109 SetContinuity(GeomAbs_C1, Ta);
110}
111
112//=======================================================================
113//function : SetParams
114//purpose :
115//=======================================================================
116
117void ChFi3d_Builder::SetParams(const Standard_Real Tang,
118 const Standard_Real Tesp,
119 const Standard_Real T2d,
120 const Standard_Real TApp3d,
121 const Standard_Real TolApp2d,
122 const Standard_Real Fleche)
123{
124 angular = Tang;
125 tolesp = Tesp;
126 tol2d = T2d;
127 tolapp3d = TApp3d;
128 tolapp2d = TolApp2d;
129 fleche = Fleche;
130}
131
132//=======================================================================
133//function : SetContinuity
134//purpose :
135//=======================================================================
136
137void ChFi3d_Builder::SetContinuity(const GeomAbs_Shape InternalContinuity,
138 const Standard_Real AngularTolerance)
139{
140 myConti = InternalContinuity;
141 tolappangle = AngularTolerance;
142}
143
144//=======================================================================
145//function : IsDone
146//purpose :
147//=======================================================================
148
149Standard_Boolean ChFi3d_Builder::IsDone() const
150{
151 return done;
152}
153
154//=======================================================================
155//function : Shape
156//purpose :
157//=======================================================================
158
159TopoDS_Shape ChFi3d_Builder::Shape()const
160{
161 Standard_NoSuchObject_Raise_if(!done,"");
162 return myShapeResult;
163}
164
165//=======================================================================
166//function : NbFaultyContours
167//purpose :
168//=======================================================================
169
170Standard_Integer ChFi3d_Builder::NbFaultyContours() const
171{
172 return badstripes.Extent();
173}
174
175//=======================================================================
176//function : FaultyContour
177//purpose :
178//=======================================================================
179
180Standard_Integer ChFi3d_Builder::FaultyContour(const Standard_Integer I) const
181{
182 ChFiDS_ListIteratorOfListOfStripe itel;
183 Standard_Integer k = 0;
184 Handle(ChFiDS_Stripe) st;
185 for (itel.Initialize(badstripes);itel.More(); itel.Next()) {
186 k += 1;
187 if(k == I) {
188 st = itel.Value();
189 break;
190 }
191 }
192 if(st.IsNull()) return 0;
193 k = 0;
194 for (itel.Initialize(myListStripe);itel.More(); itel.Next()) {
195 k += 1;
196 if(st == itel.Value()) return k;
197 }
198 return 0;
199}
200
201//=======================================================================
202//function : NbComputedSurfaces
203//purpose :
204//=======================================================================
205
206Standard_Integer ChFi3d_Builder::NbComputedSurfaces(const Standard_Integer IC) const
207{
208 ChFiDS_ListIteratorOfListOfStripe itel;
209 Standard_Integer k = 0;
210 Handle(ChFiDS_Stripe) st;
211 for (itel.Initialize(myListStripe);itel.More(); itel.Next()) {
212 k += 1;
213 if(k == IC) {
214 st = itel.Value();
215 break;
216 }
217 }
218 if(st.IsNull()) return 0;
219 if(st->Spine().IsNull()) return 0;
220 Handle(ChFiDS_HData) hd = st->SetOfSurfData();
221 if(hd.IsNull()) return 0;
222 return hd->Length();
223}
224
225//=======================================================================
226//function : ComputedSurface
227//purpose :
228//=======================================================================
229
230Handle(Geom_Surface) ChFi3d_Builder::ComputedSurface(const Standard_Integer IC,
231 const Standard_Integer IS) const
232{
233 ChFiDS_ListIteratorOfListOfStripe itel;
234 Standard_Integer k = 0;
235 Handle(ChFiDS_Stripe) st;
236 for (itel.Initialize(myListStripe);itel.More(); itel.Next()) {
237 k += 1;
238 if(k == IC) {
239 st = itel.Value();
240 break;
241 }
242 }
243 Handle(ChFiDS_HData) hd = st->SetOfSurfData();
244 Standard_Integer isurf=hd->Value(IS)->Surf();
245 return myDS->Surface(isurf).Surface();
246}
247
248//=======================================================================
249//function : NbFaultyVertices
250//purpose :
251//=======================================================================
252
253Standard_Integer ChFi3d_Builder::NbFaultyVertices() const
254{
255 return badvertices.Extent();
256}
257
258//=======================================================================
259//function : FaultyVertex
260//purpose :
261//=======================================================================
262
263TopoDS_Vertex ChFi3d_Builder::FaultyVertex(const Standard_Integer IV) const
264{
265 TopTools_ListIteratorOfListOfShape it;
266 TopoDS_Vertex V;
267 Standard_Integer k = 0;
268 for(it.Initialize(badvertices);it.More(); it.Next()) {
269 k += 1;
270 if(k == IV) {
271 V = TopoDS::Vertex(it.Value());
272 break;
273 }
274 }
275 return V;
276}
277
278//=======================================================================
279//function : HasResult
280//purpose :
281//=======================================================================
282
283Standard_Boolean ChFi3d_Builder::HasResult() const
284{
285 return hasresult;
286}
287
288//=======================================================================
289//function : BadShape
290//purpose :
291//=======================================================================
292
293TopoDS_Shape ChFi3d_Builder::BadShape()const
294{
295 Standard_NoSuchObject_Raise_if(!hasresult,"");
296 return badShape;
297}
298
299//=======================================================================
300//function : StripeStatus
301//purpose :
302//=======================================================================
303
304ChFiDS_ErrorStatus ChFi3d_Builder::StripeStatus(const Standard_Integer IC)const
305{
306 ChFiDS_ListIteratorOfListOfStripe itel;
307 Standard_Integer k =0;
308 Handle(ChFiDS_Stripe) st;
309 for (itel.Initialize(myListStripe);itel.More(); itel.Next()) {
310 k += 1;
311 if(k == IC) {
312 st = itel.Value();
313 break;
314 }
315 }
316 ChFiDS_ErrorStatus stat=st->Spine()->ErrorStatus();
317 return stat;
318}
319
320//=======================================================================
321//function : Builder
322//purpose :
323//=======================================================================
324
325Handle(TopOpeBRepBuild_HBuilder) ChFi3d_Builder::Builder()const
326{
327 return myCoup;
328}
329
330//=======================================================================
331//function : ChFi3d_FaceTangency
332//purpose : determine if the faces opposing to edges are tangent
333// to go from opposing faces on e0 to opposing faces
334// on e1, consider all faces starting at a common top.
335//=======================================================================
336
337Standard_Boolean ChFi3d_Builder::FaceTangency(const TopoDS_Edge& E0,
338 const TopoDS_Edge& E1,
339 const TopoDS_Vertex& V) const
340{
341 TopTools_ListIteratorOfListOfShape It,Jt;
342 TopoDS_Edge Ec;
343 Standard_Integer Nbf;
344 TopoDS_Face F[2];
345
346 //It is checked if the connection is not on a regular edge.
347 for (It.Initialize(myEFMap(E1)), Nbf= 0 ;It.More();It.Next(), Nbf++) {
348 if (Nbf>1)
349 Standard_ConstructionError::Raise("ChFi3d_Builder:only 2 faces");
350 F[Nbf] = TopoDS::Face(It.Value());
351 }
352 if(Nbf < 2) return Standard_False;
353// Modified by Sergey KHROMOV - Fri Dec 21 17:44:19 2001 Begin
354//if (BRep_Tool::Continuity(E1,F[0],F[1]) != GeomAbs_C0) {
355 if (ChFi3d_isTangentFaces(E1,F[0],F[1])) {
356// Modified by Sergey KHROMOV - Fri Dec 21 17:44:21 2001 End
357 return Standard_False;
358 }
359
360 for (Jt.Initialize(myVEMap(V));Jt.More();Jt.Next()) {
361 Ec = TopoDS::Edge(Jt.Value());
362 if (!Ec.IsSame(E0) && !Ec.IsSame(E1) &&
363 Ec.Orientation() != TopAbs_INTERNAL &&
364 Ec.Orientation() != TopAbs_EXTERNAL &&
365 !BRep_Tool::Degenerated(Ec)) {
366 for (It.Initialize(myEFMap(Ec)), Nbf= 0 ;It.More();It.Next(), Nbf++) {
367 if (Nbf>1)
368 Standard_ConstructionError::Raise("ChFi3d_Builder:only 2 faces");
369 F[Nbf] = TopoDS::Face(It.Value());
370 }
371 if(Nbf < 2) return Standard_False;
372// Modified by Sergey KHROMOV - Tue Dec 18 18:10:40 2001 Begin
373// if (BRep_Tool::Continuity(Ec,F[0],F[1]) < GeomAbs_G1) {
374 if (!ChFi3d_isTangentFaces(Ec,F[0],F[1])) {
375// Modified by Sergey KHROMOV - Tue Dec 18 18:10:41 2001 End
376 return Standard_False;
377 }
378 }
379 }
380 return Standard_True;
381
382}
383
384
385//=======================================================================
386//function : TangentExtremity
387//purpose : Test if 2 faces are tangent at the end of an edge
388//=======================================================================
389static Standard_Boolean TangentExtremity(const TopoDS_Vertex& V,
390 const TopoDS_Edge& E,
391 const Handle(BRepAdaptor_HSurface)& hs1,
392 const Handle(BRepAdaptor_HSurface)& hs2,
393// const Standard_Real t3d,
394 const Standard_Real tang)
395{
396 TopoDS_Face f1 = hs1->ChangeSurface().Face();
397 TopAbs_Orientation O1 = f1.Orientation();
398 f1.Orientation(TopAbs_FORWARD);
399 TopoDS_Face f2 = hs2->ChangeSurface().Face();
400 TopAbs_Orientation O2 = f2.Orientation();
401 f2.Orientation(TopAbs_FORWARD);
402 TopoDS_Edge e1 = E, e2 = E;
403 e1.Orientation(TopAbs_FORWARD);
404 e2.Orientation(TopAbs_FORWARD);
405 if(f1.IsSame(f2) && BRep_Tool::IsClosed(e1,f1))
406 e2.Orientation(TopAbs_REVERSED);
407 Standard_Real p1 = BRep_Tool::Parameter(V,e1,f1);
408 Standard_Real p2 = BRep_Tool::Parameter(V,e2,f2);
409 Standard_Real u,v,f,l, Eps = 1.e-9;
410 gp_Vec n1, n2;// gp_Pnt pt1,pt2;
411 Handle(Geom2d_Curve) pc1 = BRep_Tool::CurveOnSurface(e1,f1,f,l);
412 pc1->Value(p1).Coord(u,v);
413 BRepLProp_SLProps theProp1(hs1->ChangeSurface(), u, v, 1, Eps);
414 if (theProp1.IsNormalDefined()) {
415 n1.SetXYZ(theProp1.Normal().XYZ());
416 if (O1 == TopAbs_REVERSED) n1.Reverse();
417 }
418 else return Standard_False; // It is not known...
419
420
421 Handle(Geom2d_Curve) pc2 = BRep_Tool::CurveOnSurface(e2,f2,f,l);
422 pc2->Value(p2).Coord(u,v);
423 BRepLProp_SLProps theProp2(hs2->ChangeSurface(), u, v, 1, Eps);
424 if (theProp2.IsNormalDefined()) {
425 n2.SetXYZ(theProp2.Normal().XYZ());
426 if(O2 == TopAbs_REVERSED) n2.Reverse();
427 }
428 else return Standard_False; // It is not known...
429
430 return (n1.Angle(n2) < tang);
431}
432
433//=======================================================================
434//function : TangentOnVertex
435//purpose : Test if support faces of an edge are tangent at end.
436//=======================================================================
437static Standard_Boolean TangentOnVertex(const TopoDS_Vertex& V,
438 const TopoDS_Edge& E,
439 const ChFiDS_Map& EFMap,
440 const Standard_Real tang)
441{
442 TopoDS_Face ff1,ff2;
443 ChFi3d_conexfaces(E,ff1,ff2,EFMap);
444 if(ff1.IsNull() || ff2.IsNull()) return 0;
445 Handle(BRepAdaptor_HSurface) S1 = new (BRepAdaptor_HSurface)(ff1);
446 Handle(BRepAdaptor_HSurface) S2 = new (BRepAdaptor_HSurface)(ff2);
447 return TangentExtremity(V, E, S1, S2, tang);
448}
449
450//=======================================================================
451//function : PerformExtremity
452//purpose : In case if PerformElement returned BreakPoint at one or
453// another extremity, it is attempted to refine
454// depending on concavities between neighbour faces of the top.
455//=======================================================================
456
457void ChFi3d_Builder::PerformExtremity (const Handle(ChFiDS_Spine)& Spine)
458{
459 Standard_Integer NbG1Connections = 0;
460
461 for(Standard_Integer ii = 1; ii <= 2; ii++){
462 TopoDS_Edge E[3],Ec;
463 TopoDS_Vertex V;
464 ChFiDS_State sst;
465 Standard_Integer iedge;
466 Handle(BRepAdaptor_HSurface) hs1,hs2;
467 if(ii == 1){
468 sst = Spine->FirstStatus();
469 iedge = 1;
470 V = Spine->FirstVertex();
471 }
472 else{
473 sst = Spine->LastStatus();
474 iedge = Spine->NbEdges();
475 E[0] = Spine->Edges(iedge);
476 V = Spine->LastVertex();
477 }
478 //Before all it is checked if the tangency is not dead.
479 E[0] = Spine->Edges(iedge);
480 ConexFaces (Spine,iedge,0,hs1,hs2);
481 if(TangentExtremity(V,E[0],hs1,hs2,angular)){
482 Spine->SetTangencyExtremity(Standard_True, (ii == 1));
483 }
484
485 if(sst == ChFiDS_BreakPoint){
486 TopTools_ListIteratorOfListOfShape It;//,Jt;
487 Standard_Integer i = 0;
488 Standard_Boolean sommetpourri = Standard_False;
489 TopTools_IndexedMapOfShape EdgesOfV;
490 //to avoid repeating of edges
491 for (It.Initialize(myVEMap(V)); It.More(); It.Next())
492 EdgesOfV.Add(It.Value());
493 for (Standard_Integer ind = 1; ind <= EdgesOfV.Extent(); ind++) {
494 Ec = TopoDS::Edge(EdgesOfV(ind));
495 Standard_Boolean bonedge = !BRep_Tool::Degenerated(Ec);
496 if (bonedge)
497 {
498 TopoDS_Face F1, F2;
499 ChFi3d_conexfaces(Ec, F1, F2, myEFMap);
500 if (!F2.IsNull() && ChFi3d_isTangentFaces(Ec, F1, F2, GeomAbs_G2))
501 {
502 bonedge = Standard_False;
503 if (!F1.IsSame(F2))
504 NbG1Connections++;
505 }
506 }
507 if(bonedge){
508 if (!Ec.IsSame(E[0]))
509 {
510 if( i < 2 ){
511 i++;
512 E[i] = Ec;
513 }
514 else{
515#ifdef OCCT_DEBUG
516 cout<<"top has more than 3 edges"<<endl;
517#endif
518 sommetpourri = Standard_True;
519 break;
520 }
521 }
522 }
523 }
524 if(i != 2) sommetpourri = Standard_True;
525 if(!sommetpourri){
526 sst = ChFi3d_EdgeState(E,myEFMap);
527 }
528 if(ii==1)Spine->SetFirstStatus(sst);
529 else Spine->SetLastStatus(sst);
530 }
531 }
532
533 if (!Spine->IsPeriodic()) {
534 TopTools_ListIteratorOfListOfShape It,Jt;
535 Standard_Integer nbf = 0, jf = 0;
536 for (It.Initialize(myVFMap(Spine->FirstVertex())); It.More(); It.Next()){
537 jf++;
538 Standard_Integer kf = 1;
539 const TopoDS_Shape& cur = It.Value();
540 for (Jt.Initialize(myVFMap(Spine->FirstVertex())); Jt.More() && (kf < jf); Jt.Next(), kf++){
541 if(cur.IsSame(Jt.Value())) break;
542 }
543 if(kf == jf) nbf++;
544 }
545 nbf -= NbG1Connections;
546 if(nbf>3) {
547 Spine->SetFirstStatus(ChFiDS_BreakPoint);
548#ifdef OCCT_DEBUG
549 cout<<"top has : "<<nbf<<" faces."<<endl;
550#endif
551 }
552 nbf = 0, jf = 0;
553 for (It.Initialize(myVFMap(Spine->LastVertex())); It.More(); It.Next()){
554 jf++;
555 Standard_Integer kf = 1;
556 const TopoDS_Shape& cur = It.Value();
557 for (Jt.Initialize(myVFMap(Spine->LastVertex())); Jt.More() && (kf < jf); Jt.Next(), kf++){
558 if(cur.IsSame(Jt.Value())) break;
559 }
560 if(kf == jf) nbf++;
561 }
562 nbf -= NbG1Connections;
563 if(nbf>3) {
564 Spine->SetLastStatus(ChFiDS_BreakPoint);
565#ifdef OCCT_DEBUG
566 cout<<"top has : "<<nbf<<" faces."<<endl;
567#endif
568 }
569 }
570}
571
572//=======================================================================
573//function : PerformElement
574//purpose : find all mutually tangent edges ;
575// Each edge has 2 opposing faces. For 2 adjacent tangent edges it is required that
576// the opposing faces were tangent.
577//=======================================================================
578
579Standard_Boolean ChFi3d_Builder::PerformElement(const Handle(ChFiDS_Spine)& Spine)
580{
581 Standard_Real ta = angular;
582 TopTools_ListIteratorOfListOfShape It;
583 Standard_Integer Nbface;
584 TopTools_ListIteratorOfListOfShape Jt;
585 Standard_Real Wl,Wf;
586 Standard_Boolean degeneOnEc;
587 gp_Pnt P2;
588 gp_Vec V1,V2;
589 TopoDS_Vertex Ve1,VStart,FVEc,LVEc,FVEv,LVEv;
590 TopoDS_Edge Ev,Ec(Spine->Edges(1));
591 if(BRep_Tool::Degenerated(Ec)) return 0;
592 //it is checked if the edge is a cut edge
593 TopoDS_Face ff1,ff2;
594 ChFi3d_conexfaces(Ec,ff1,ff2,myEFMap);
595 if(ff1.IsNull() || ff2.IsNull()) return 0;
596// Modified by Sergey KHROMOV - Fri Dec 21 17:46:22 2001 End
597//if(BRep_Tool::Continuity(Ec,ff1,ff2) != GeomAbs_C0) return 0;
598 if (ChFi3d_isTangentFaces(Ec,ff1,ff2)) return 0;
599// Modified by Sergey KHROMOV - Fri Dec 21 17:46:24 2001 Begin
600
601 BRepAdaptor_Curve CEc,CEv;
602 TopAbs_Orientation curor = Ec.Orientation();
603 TopExp::Vertices(Ec,VStart,LVEc);
604
605
606 Standard_Boolean Fini = Standard_False;
607 Standard_Integer Nb;
608 ChFiDS_State CurSt = ChFiDS_Closed;
609 if (VStart.IsSame(LVEc)) {//case if only one edge is closed
610 CEc.Initialize(Ec);
611 Wl = BRep_Tool::Parameter(VStart,Ec);
612 CEc.D1(Wl,P2,V1);
613 Wl = BRep_Tool::Parameter(LVEc,Ec);
614 CEc.D1(Wl,P2,V2);
615 if (V1.IsParallel(V2,ta)) {
616 if (FaceTangency(Ec,Ec,VStart)) {
617 CurSt = ChFiDS_Closed;
618 }
619 else {
620 CurSt = ChFiDS_BreakPoint;
621 }
622 }
623 else {
624 CurSt = ChFiDS_BreakPoint;
625 }
626 Spine->SetLastStatus(CurSt);
627 Spine->SetFirstStatus(CurSt);
628 }
629 else { // Downstream progression
630 FVEc = VStart;
631 TopAbs_Orientation Or1;
632 while (!Fini) {
633 CurSt = ChFiDS_FreeBoundary;
634 Wl = BRep_Tool::Parameter(LVEc,Ec);
635 degeneOnEc = TangentOnVertex(LVEc, Ec, myEFMap, ta);
636 CEc.Initialize(Ec);
637 CEc.D1(Wl,P2,V1);
638 Nb = Spine->NbEdges();
639
640 for (It.Initialize(myVEMap(LVEc));It.More();It.Next()) {
641 Ev = TopoDS::Edge(It.Value());
642 if (!Ev.IsSame(Ec) && !BRep_Tool::Degenerated(Ev)){
643 TopExp::Vertices(Ev,FVEv,LVEv);
644 if (LVEc.IsSame(LVEv)) {
645 Ve1 = FVEv;
646 FVEv = LVEv;
647 LVEv = Ve1;
648 Or1 = TopAbs_REVERSED;
649 }
650 else Or1 = TopAbs_FORWARD;
651
652 Wf = BRep_Tool::Parameter(FVEv,Ev);
653 CEv.Initialize(Ev);
654 CEv.D1(Wf,P2,V2);
655 Standard_Real av1v2 = V1.Angle(V2);
656 Standard_Boolean rev = (Or1 != curor);
657 Standard_Boolean OnAjoute = Standard_False;
658 if (FaceTangency(Ec,Ev,FVEv)) {
659 // there is no need of tolerance
660 // to make a decision (PRO9486) the regularity is enough.
661 // However, the abcense of turn-back is checked (PRO9810)
662 OnAjoute = ((!rev && av1v2 < M_PI/2)
663 ||(rev && av1v2 > M_PI/2));
664 // mate attention to the single case (cf CTS21610_1)
665 if (OnAjoute && (degeneOnEc ||
666 TangentOnVertex(LVEc, Ev,myEFMap, ta)) )
667 OnAjoute=((!rev && av1v2 < ta) || (rev && (M_PI - av1v2) < ta));
668 }
669 if (OnAjoute) {
670 Fini = Standard_False; // If this can be useful (Cf PRO14713)
671 Ec = Ev;
672// Ec = TopoDS::Edge(Ev);
673 Ec.Orientation(Or1);
674 Wl = Wf; LVEc = LVEv;
675 Spine->SetEdges(Ec);
676 curor = Or1;
677 if (VStart.IsSame(LVEv)) {
678 if (FaceTangency(Ev,Spine->Edges(1),LVEv)) {
679 CurSt = ChFiDS_Closed; Fini = Standard_True;
680 }
681 else {
682 CurSt = ChFiDS_BreakPoint;Fini = Standard_True;
683 }
684 }
685 break;
686 }
687 else {
688 for (Jt.Initialize(myEFMap(Ev)), Nbface= 0 ;Jt.More();Jt.Next(),
689 Nbface++) {}
690 if (Nbface> 1) CurSt = ChFiDS_BreakPoint;
691 Fini = ((!rev && av1v2 < ta) || (rev && (M_PI - av1v2) < ta));
692 }
693 }
694 }
695 Fini = Fini || (Nb == Spine->NbEdges());
696 }
697 Spine->SetLastStatus(CurSt);
698 if (CurSt == ChFiDS_Closed) {
699 Spine->SetFirstStatus(CurSt);
700 }
701 else {// Upstream progression
702 Fini = Standard_False;
703 Ec = Spine->Edges(1);
704 curor = Ec.Orientation();
705 FVEc = VStart;
706 while (!Fini) {
707 CurSt = ChFiDS_FreeBoundary;
708 Wl = BRep_Tool::Parameter(FVEc,Ec);
709 degeneOnEc = TangentOnVertex(FVEc, Ec, myEFMap, ta);
710 CEc.Initialize(Ec);
711 CEc.D1(Wl,P2,V1);
712 Nb = Spine->NbEdges();
713
714 for (It.Initialize(myVEMap(FVEc));It.More();It.Next()) {
715 Ev = TopoDS::Edge(It.Value());
716 if (!Ev.IsSame(Ec) && !BRep_Tool::Degenerated(Ev)) {
717 TopExp::Vertices(Ev,FVEv,LVEv);
718 if (FVEc.IsSame(FVEv)) {
719 Ve1 = FVEv;
720 FVEv = LVEv;
721 LVEv = Ve1;
722 Or1 = TopAbs_REVERSED;
723 }
724 else {
725 Or1 = TopAbs_FORWARD;
726 }
727 Wf = BRep_Tool::Parameter(LVEv,Ev);
728 CEv.Initialize(Ev);
729 CEv.D1(Wf,P2,V2);
730 Standard_Real av1v2 = V1.Angle(V2);
731 Standard_Boolean rev = (Or1 != curor);
732 Standard_Boolean OnAjoute = Standard_False;
733 if (FaceTangency(Ec,Ev,LVEv)) {
734 OnAjoute = ((!rev && av1v2 < M_PI/2)
735 ||(rev && av1v2 > M_PI/2));
736 if (OnAjoute && (degeneOnEc ||
737 TangentOnVertex(FVEc, Ev,myEFMap, ta)) )
738 OnAjoute=((!rev && av1v2 < ta) || (rev && (M_PI-av1v2) < ta));
739 }
740 if (OnAjoute) {
741 Ec = Ev;
742// Ec = TopoDS::Edge(Ev);
743 Ec.Orientation(Or1);
744 Wl = Wf; FVEc = FVEv;
745 Spine->PutInFirst(Ec);
746 curor = Or1;
747 break;
748 }
749 else {
750 for(Jt.Initialize(myEFMap(Ev)),Nbface= 0 ;Jt.More();Jt.Next(),
751 Nbface++) {}
752 if (Nbface> 1) CurSt = ChFiDS_BreakPoint;
753 Fini = ((!rev && av1v2 < ta) || (rev && (M_PI - av1v2) < ta));
754 }
755 }
756 }
757 Fini = Fini || (Nb == Spine->NbEdges());
758 }
759 Spine->SetFirstStatus(CurSt);
760 }
761 }
762 return 1;
763}
764
765//=======================================================================
766//function : Remove
767//purpose :
768//=======================================================================
769
770void ChFi3d_Builder::Remove(const TopoDS_Edge& E)
771{
772 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
773
774 for ( ; itel.More(); itel.Next()) {
775 const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine();
776 for (Standard_Integer j = 1; j <= sp->NbEdges(); j++){
777 if (E.IsSame(sp->Edges(j))){
778 myListStripe.Remove(itel);
779 return;
780 }
781 }
782 }
783}
784
785
786//=======================================================================
787//function : Value
788//purpose :
789//=======================================================================
790
791Handle(ChFiDS_Spine) ChFi3d_Builder::Value
792(const Standard_Integer I)const
793{
794 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
795 for (Standard_Integer ic = 1; ic < I; ic++) {itel.Next();}
796 return itel.Value()->Spine();
797}
798
799//=======================================================================
800//function : NbElements
801//purpose :
802//=======================================================================
803
804Standard_Integer ChFi3d_Builder::NbElements()const
805{
806 Standard_Integer i = 0;
807 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
808 for ( ;itel.More(); itel.Next()){
809 const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine();
810 if(sp.IsNull()) break;
811 i++;
812 }
813 return i;
814}
815
816//=======================================================================
817//function : Contains
818//purpose :
819//=======================================================================
820
821Standard_Integer ChFi3d_Builder::Contains(const TopoDS_Edge& E)const
822{
823 Standard_Integer i = 1,j;
824 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
825 for ( ;itel.More(); itel.Next(), i++){
826 const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine();
827 if(sp.IsNull()) break;
828 for (j = 1; j <= sp->NbEdges(); j++){
829 if(E.IsSame(sp->Edges(j))) return i;
830 }
831 }
832 return 0;
833}
834
835//=======================================================================
836//function : Contains
837//purpose :
838//=======================================================================
839
840Standard_Integer ChFi3d_Builder::Contains(const TopoDS_Edge& E,
841 Standard_Integer& IndexInSpine)const
842{
843 Standard_Integer i = 1,j;
844 IndexInSpine = 0;
845 ChFiDS_ListIteratorOfListOfStripe itel(myListStripe);
846 for ( ;itel.More(); itel.Next(), i++){
847 const Handle(ChFiDS_Spine)& sp = itel.Value()->Spine();
848 if(sp.IsNull()) break;
849 for (j = 1; j <= sp->NbEdges(); j++){
850 if(E.IsSame(sp->Edges(j)))
851 {
852 IndexInSpine = j;
853 return i;
854 }
855 }
856 }
857 return 0;
858}
859
860//=======================================================================
861//function : Length
862//purpose :
863//=======================================================================
864
865Standard_Real ChFi3d_Builder::Length(const Standard_Integer IC)const
866{
867 if(IC <= NbElements()){
868 const Handle(ChFiDS_Spine)& sp = Value(IC);
869 return sp->LastParameter(sp->NbEdges());
870 }
871 return -1;
872}
873
874
875//=======================================================================
876//function : FirstVertex
877//purpose :
878//=======================================================================
879
880TopoDS_Vertex ChFi3d_Builder::FirstVertex(const Standard_Integer IC) const
881{
882 if(IC <= NbElements()){
883 return Value(IC)->FirstVertex();
884 }
885 return TopoDS_Vertex();
886}
887
888//=======================================================================
889//function : LastVertex
890//purpose :
891//=======================================================================
892
893TopoDS_Vertex ChFi3d_Builder::LastVertex(const Standard_Integer IC) const
894{
895 if(IC <= NbElements()){
896 return Value(IC)->LastVertex();
897 }
898 return TopoDS_Vertex();
899}
900
901//=======================================================================
902//function : Abscissa
903//purpose :
904//=======================================================================
905
906Standard_Real ChFi3d_Builder::Abscissa(const Standard_Integer IC,
907 const TopoDS_Vertex& V) const
908{
909 if(IC <= NbElements()){
910 return Value(IC)->Absc(V);
911 }
912 return -1;
913}
914
915//=======================================================================
916//function : RelativeAbscissa
917//purpose :
918//=======================================================================
919
920Standard_Real ChFi3d_Builder::RelativeAbscissa(const Standard_Integer IC,
921 const TopoDS_Vertex& V) const
922{
923 if(IC <= NbElements()){
924 return Abscissa(IC,V)/Length(IC);
925 }
926 return -1;
927}
928
929//=======================================================================
930//function : Closed
931//purpose :
932//=======================================================================
933
934Standard_Boolean ChFi3d_Builder::Closed(const Standard_Integer IC)const
935{
936 if(IC <= NbElements()){
937 return Value(IC)->IsClosed();
938 }
939 return Standard_False;
940}
941
942//=======================================================================
943//function : ClosedAndTangent
944//purpose :
945//=======================================================================
946
947Standard_Boolean ChFi3d_Builder::ClosedAndTangent
948(const Standard_Integer IC)const
949{
950 if(IC <= NbElements()){
951 return Value(IC)->IsPeriodic();
952 }
953 return Standard_False;
954}
955