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