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