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