0030422: Random behaviour of BRepAdaptor_CompCurve
[occt.git] / src / BRepTools / BRepTools_WireExplorer.cxx
CommitLineData
b311480e 1// Created on: 1993-01-21
2// Created by: Remi LEQUETTE
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
42cf5bc1 17
7fd59977 18#include <BRep_Tool.hxx>
b6cf8ffa 19#include <BRepAdaptor_Surface.hxx>
7fd59977 20#include <BRepTools.hxx>
42cf5bc1 21#include <BRepTools_WireExplorer.hxx>
7fd59977 22#include <Geom2d_Curve.hxx>
42cf5bc1 23#include <Geom_Surface.hxx>
7fd59977 24#include <GeomAdaptor_Surface.hxx>
42cf5bc1 25#include <gp_Pnt2d.hxx>
26#include <Precision.hxx>
27#include <Standard_DomainError.hxx>
28#include <Standard_NoMoreObject.hxx>
29#include <Standard_NoSuchObject.hxx>
30#include <TopExp.hxx>
7fd59977 31#include <TopExp_Explorer.hxx>
42cf5bc1 32#include <TopoDS.hxx>
33#include <TopoDS_Edge.hxx>
34#include <TopoDS_Face.hxx>
35#include <TopoDS_Iterator.hxx>
36#include <TopoDS_Vertex.hxx>
37#include <TopoDS_Wire.hxx>
38#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
39#include <TopTools_ListIteratorOfListOfShape.hxx>
40#include <TopTools_ListOfShape.hxx>
41#include <TopTools_MapIteratorOfMapOfShape.hxx>
42#include <TopTools_MapOfShape.hxx>
7fd59977 43
44//=======================================================================
45// forward declarations of aux functions
46//=======================================================================
47static Standard_Boolean SelectDouble(TopTools_MapOfShape& Doubles,
48 TopTools_ListOfShape& L,
49 TopoDS_Edge& E);
50
51static Standard_Boolean SelectDegenerated(TopTools_ListOfShape& L,
52 TopoDS_Edge& E);
53
54static Standard_Real GetNextParamOnPC(const Handle(Geom2d_Curve)& aPC,
55 const gp_Pnt2d& aPRef,
56 const Standard_Real& fP,
57 const Standard_Real& lP,
58 const Standard_Real& tolU,
59 const Standard_Real& tolV,
60 const Standard_Boolean& reverse);
61
62//=======================================================================
63//function : BRepTools_WireExplorer
64//purpose :
65//=======================================================================
d533dafb 66BRepTools_WireExplorer::BRepTools_WireExplorer()
67: myReverse(Standard_False),
68 myTolU(0.0),
69 myTolV(0.0)
7fd59977 70{
71}
72
73//=======================================================================
74//function : BRepTools_WireExplorer
75//purpose :
76//=======================================================================
77BRepTools_WireExplorer::BRepTools_WireExplorer(const TopoDS_Wire& W)
78{
79 TopoDS_Face F = TopoDS_Face();
80 Init(W,F);
81}
82
83//=======================================================================
84//function : BRepTools_WireExplorer
85//purpose :
86//=======================================================================
87BRepTools_WireExplorer::BRepTools_WireExplorer(const TopoDS_Wire& W,
88 const TopoDS_Face& F)
89{
90 Init(W,F);
91}
92
93//=======================================================================
94//function : Init
95//purpose :
96//=======================================================================
97void BRepTools_WireExplorer::Init(const TopoDS_Wire& W)
98{
99 TopoDS_Face F = TopoDS_Face();
100 Init(W,F);
101}
102
103//=======================================================================
104//function : Init
105//purpose :
106//=======================================================================
107void BRepTools_WireExplorer::Init(const TopoDS_Wire& W,
b6cf8ffa 108 const TopoDS_Face& F)
7fd59977 109{
110 myEdge = TopoDS_Edge();
111 myVertex = TopoDS_Vertex();
112 myMap.Clear();
113 myDoubles.Clear();
114
b6cf8ffa 115 if (W.IsNull())
116 return;
117
118 Standard_Real UMin(0.0), UMax(0.0), VMin(0.0), VMax(0.0);
119 if (!F.IsNull())
120 {
121 // For the faces based on Cone, BSpline and Bezier compute the
122 // UV bounds to precise the UV tolerance values
123 const GeomAbs_SurfaceType aSurfType = BRepAdaptor_Surface(F, Standard_False).GetType();
124 if (aSurfType == GeomAbs_Cone ||
125 aSurfType == GeomAbs_BSplineSurface ||
126 aSurfType == GeomAbs_BezierSurface)
127 {
128 BRepTools::UVBounds(F, UMin, UMax, VMin, VMax);
129 }
130 }
131
132 Init(W, F, UMin, UMax, VMin, VMax);
133}
134
135//=======================================================================
136//function : Init
137//purpose :
138//=======================================================================
139void BRepTools_WireExplorer::Init(const TopoDS_Wire& W,
140 const TopoDS_Face& F,
141 const Standard_Real UMin,
142 const Standard_Real UMax,
143 const Standard_Real VMin,
144 const Standard_Real VMax)
145{
146 myEdge = TopoDS_Edge();
147 myVertex = TopoDS_Vertex();
148 myMap.Clear();
149 myDoubles.Clear();
150
151 if (W.IsNull())
7fd59977 152 return;
153
154 myFace = F;
155 Standard_Real dfVertToler = 0.;
156 myReverse = Standard_False;
157
158 if (!myFace.IsNull())
b6cf8ffa 159 {
b6cf8ffa 160 TopLoc_Location aL;
161 const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(myFace, aL);
162 GeomAdaptor_Surface aGAS(aSurf);
163 TopExp_Explorer anExp(W, TopAbs_VERTEX);
164 for (; anExp.More(); anExp.Next())
7fd59977 165 {
b6cf8ffa 166 const TopoDS_Vertex& aV = TopoDS::Vertex(anExp.Current());
167 dfVertToler = Max(BRep_Tool::Tolerance(aV), dfVertToler);
168 }
169 if (dfVertToler < Precision::Confusion())
170 {
171 // Use tolerance of edges
172 for (TopoDS_Iterator it(W); it.More(); it.Next())
173 dfVertToler = Max(BRep_Tool::Tolerance(TopoDS::Edge(it.Value())), dfVertToler);
7fd59977 174
b6cf8ffa 175 if (dfVertToler < Precision::Confusion())
176 // empty wire
177 return;
7fd59977 178 }
b6cf8ffa 179 myTolU = 2. * aGAS.UResolution(dfVertToler);
180 myTolV = 2. * aGAS.VResolution(dfVertToler);
181
182 // uresolution for cone with infinite vmin vmax is too small.
183 if (aGAS.GetType() == GeomAbs_Cone)
184 {
185 gp_Pnt aP;
186 gp_Vec aD1U, aD1V;
187 aGAS.D1(UMin, VMin, aP, aD1U, aD1V);
188 Standard_Real tol1, tol2, maxtol = .0005*(UMax - UMin);
189 Standard_Real a = aD1U.Magnitude();
190
191 if (a <= Precision::Confusion())
192 tol1 = maxtol;
193 else
194 tol1 = Min(maxtol, dfVertToler / a);
195
196 aGAS.D1(UMin, VMax, aP, aD1U, aD1V);
197 a = aD1U.Magnitude();
198 if (a <= Precision::Confusion())
199 tol2 = maxtol;
200 else
201 tol2 = Min(maxtol, dfVertToler / a);
202
203 myTolU = 2. * Max(tol1, tol2);
204 }
205
206 if (aGAS.GetType() == GeomAbs_BSplineSurface ||
207 aGAS.GetType() == GeomAbs_BezierSurface)
208 {
209 Standard_Real maxTol = Max(myTolU, myTolV);
210 gp_Pnt aP;
211 gp_Vec aDU, aDV;
212 aGAS.D1((UMax - UMin) / 2., (VMax - VMin) / 2., aP, aDU, aDV);
213 Standard_Real mod = Sqrt(aDU*aDU + aDV*aDV);
214 if (mod > gp::Resolution())
215 {
216 if (mod * maxTol / dfVertToler < 1.5)
217 {
218 maxTol = 1.5 * dfVertToler / mod;
219 }
220 myTolU = maxTol;
221 myTolV = maxTol;
222 }
223 }
224
225 myReverse = (myFace.Orientation() == TopAbs_REVERSED);
226 }
227
7fd59977 228 // map of vertices to know if the wire is open
e2421df5 229 TopTools_IndexedMapOfShape vmap;
7fd59977 230 // map of infinite edges
231 TopTools_MapOfShape anInfEmap;
7fd59977 232
233 // list the vertices
b6cf8ffa 234 TopoDS_Vertex V1, V2;
7fd59977 235 TopTools_ListOfShape empty;
236
237 TopoDS_Iterator it(W);
238 while (it.More())
b6cf8ffa 239 {
240 const TopoDS_Edge& E = TopoDS::Edge(it.Value());
241 TopAbs_Orientation Eori = E.Orientation();
242 if (Eori == TopAbs_INTERNAL || Eori == TopAbs_EXTERNAL)
7fd59977 243 {
7fd59977 244 it.Next();
b6cf8ffa 245 continue;
246 }
247 TopExp::Vertices(E, V1, V2, Standard_True);
248
249 if (!V1.IsNull())
250 {
251 if (!myMap.IsBound(V1))
252 myMap.Bind(V1, empty);
253 myMap(V1).Append(E);
254
255 // add or remove in the vertex map
256 V1.Orientation(TopAbs_FORWARD);
e2421df5 257 Standard_Integer currsize = vmap.Extent(),
258 ind = vmap.Add(V1);
259 if (currsize >= ind)
260 {
261 vmap.RemoveKey(V1);
262 }
7fd59977 263 }
264
b6cf8ffa 265 if (!V2.IsNull())
266 {
267 V2.Orientation(TopAbs_REVERSED);
e2421df5 268 Standard_Integer currsize = vmap.Extent(),
269 ind = vmap.Add(V2);
270 if (currsize >= ind)
271 {
272 vmap.RemoveKey(V2);
273 }
b6cf8ffa 274 }
275
276 if (V1.IsNull() || V2.IsNull())
277 {
278 Standard_Real aF = 0., aL = 0.;
279 BRep_Tool::Range(E, aF, aL);
280
281 if (Eori == TopAbs_FORWARD)
282 {
283 if (aF == -Precision::Infinite())
284 anInfEmap.Add(E);
285 }
286 else
287 { // Eori == TopAbs_REVERSED
288 if (aL == Precision::Infinite())
289 anInfEmap.Add(E);
290 }
291 }
292 it.Next();
293 }
294
0d969553 295 //Construction of the set of double edges.
b6cf8ffa 296 TopoDS_Iterator it2(W);
7fd59977 297 TopTools_MapOfShape emap;
298 while (it2.More()) {
b6cf8ffa 299 if (!emap.Add(it2.Value()))
7fd59977 300 myDoubles.Add(it2.Value());
301 it2.Next();
302 }
303
304 // if vmap is not empty the wire is open, let us find the first vertex
305 if (!vmap.IsEmpty()) {
e2421df5 306 //TopTools_MapIteratorOfMapOfShape itt(vmap);
307 //while (itt.Key().Orientation() != TopAbs_FORWARD) {
308 // itt.Next();
309 // if (!itt.More()) break;
310 //}
311 //if (itt.More()) V1 = TopoDS::Vertex(itt.Key());
312 Standard_Integer ind = 0;
313 for (ind = 1; ind <= vmap.Extent(); ++ind)
314 {
315 if (vmap(ind).Orientation() == TopAbs_FORWARD)
316 {
317 V1 = TopoDS::Vertex(vmap(ind));
318 break;
319 }
7fd59977 320 }
7fd59977 321 }
322 else {
b6cf8ffa 323 // The wire is infinite Try to find the first vertex. It may be NULL.
7fd59977 324 if (!anInfEmap.IsEmpty()) {
325 TopTools_MapIteratorOfMapOfShape itt(anInfEmap);
326
327 for (; itt.More(); itt.Next()) {
b6cf8ffa 328 TopoDS_Edge anEdge = TopoDS::Edge(itt.Key());
329 TopAbs_Orientation anOri = anEdge.Orientation();
330 Standard_Real aF;
331 Standard_Real aL;
332
333 BRep_Tool::Range(anEdge, aF, aL);
334 if ((anOri == TopAbs_FORWARD && aF == -Precision::Infinite()) ||
335 (anOri == TopAbs_REVERSED && aL == Precision::Infinite())) {
336 myEdge = anEdge;
337 myVertex = TopoDS_Vertex();
338
339 return;
340 }
7fd59977 341 }
342 }
7fd59977 343
344 // use the first vertex in iterator
345 it.Initialize(W);
346 while (it.More()) {
347 const TopoDS_Edge& E = TopoDS::Edge(it.Value());
348 TopAbs_Orientation Eori = E.Orientation();
349 if (Eori == TopAbs_INTERNAL || Eori == TopAbs_EXTERNAL) {
b6cf8ffa 350 // JYL 10-03-97 : waiting for correct processing
351 // of INTERNAL/EXTERNAL edges
352 it.Next();
353 continue;
7fd59977 354 }
b6cf8ffa 355 TopExp::Vertices(E, V1, V2, Standard_True);
7fd59977 356 break;
357 }
358 }
359
b6cf8ffa 360 if (V1.IsNull()) return;
7fd59977 361 if (!myMap.IsBound(V1)) return;
b6cf8ffa 362
7fd59977 363 TopTools_ListOfShape& l = myMap(V1);
364 myEdge = TopoDS::Edge(l.First());
365 l.RemoveFirst();
b6cf8ffa 366 myVertex = TopExp::FirstVertex(myEdge, Standard_True);
7fd59977 367
368}
369
370//=======================================================================
371//function : More
372//purpose :
373//=======================================================================
374Standard_Boolean BRepTools_WireExplorer::More()const
375{
376 return !myEdge.IsNull();
377}
378
379//=======================================================================
380//function : Next
381//purpose :
382//=======================================================================
383void BRepTools_WireExplorer::Next()
384{
385 myVertex = TopExp::LastVertex (myEdge, Standard_True);
386
387 if (myVertex.IsNull()) {
388 myEdge = TopoDS_Edge();
389 return;
390 }
391 if (!myMap.IsBound(myVertex)) {
392 myEdge = TopoDS_Edge();
393 return;
394 }
395
396 TopTools_ListOfShape& l = myMap(myVertex);
397
398 if (l.IsEmpty()) {
399 myEdge = TopoDS_Edge();
400 }
401 else if (l.Extent() == 1) {
402// Modified by Sergey KHROMOV - Fri Jun 21 10:28:01 2002 OCC325 Begin
403 TopoDS_Vertex aV1;
404 TopoDS_Vertex aV2;
405 TopoDS_Edge aNextEdge = TopoDS::Edge(l.First());
406
407 TopExp::Vertices(aNextEdge, aV1, aV2, Standard_True);
408
409 if (!aV1.IsSame(myVertex)) {
410 myEdge = TopoDS_Edge();
411 return;
412 }
413 if (!myFace.IsNull() && aV1.IsSame(aV2)) {
414 Handle(Geom2d_Curve) aPrevPC;
415 Handle(Geom2d_Curve) aNextPC;
416 Standard_Real aPar11, aPar12;
417 Standard_Real aPar21, aPar22;
418 Standard_Real aPrevPar;
419 Standard_Real aNextFPar;
420 Standard_Real aNextLPar;
421
422 aPrevPC = BRep_Tool::CurveOnSurface(myEdge, myFace, aPar11, aPar12);
423 aNextPC = BRep_Tool::CurveOnSurface(aNextEdge, myFace, aPar21, aPar22);
424
425 if (aPrevPC.IsNull() || aNextPC.IsNull()) {
a0f8845f 426 myEdge = TopoDS_Edge();
427 return;
7fd59977 428 }
429
430 if (myEdge.Orientation() == TopAbs_FORWARD)
a0f8845f 431 aPrevPar = aPar12;
7fd59977 432 else
a0f8845f 433 aPrevPar = aPar11;
7fd59977 434
435 if (aNextEdge.Orientation() == TopAbs_FORWARD) {
a0f8845f 436 aNextFPar = aPar21;
437 aNextLPar = aPar22;
7fd59977 438 } else {
a0f8845f 439 aNextFPar = aPar22;
440 aNextLPar = aPar21;
7fd59977 441 }
442
443 gp_Pnt2d aPPrev = aPrevPC->Value(aPrevPar);
444 gp_Pnt2d aPNextF = aNextPC->Value(aNextFPar);
445 gp_Pnt2d aPNextL = aNextPC->Value(aNextLPar);
446
447 if (aPPrev.SquareDistance(aPNextF) > aPPrev.SquareDistance(aPNextL)) {
a0f8845f 448 myEdge = TopoDS_Edge();
449 return;
7fd59977 450 }
451 }
452// Modified by Sergey KHROMOV - Fri Jun 21 11:08:16 2002 End
453 myEdge = TopoDS::Edge(l.First());
454 l.Clear();
455 }
456 else {
457 if (myFace.IsNull()) {
0d969553
Y
458 // Without Face - try to return edges
459 // as logically as possible
460 // At first degenerated edges.
7fd59977 461 TopoDS_Edge E = myEdge;
462 if (SelectDegenerated(l,E)) {
a0f8845f 463 myEdge = E;
464 return;
7fd59977 465 }
0d969553 466 // At second double edges.
7fd59977 467 E = myEdge;
468 if (SelectDouble(myDoubles,l,E)) {
a0f8845f 469 myEdge = E;
470 return;
7fd59977 471 }
472
473 TopTools_ListIteratorOfListOfShape it(l);
474 Standard_Boolean notfound = Standard_True;
475 while (it.More()) {
a0f8845f 476 if (!it.Value().IsSame(myEdge)) {
477 myEdge = TopoDS::Edge(it.Value());
478 l.Remove(it);
479 notfound = Standard_False;
480 break;
481 }
482 it.Next();
7fd59977 483 }
484
485 if(notfound) {
a0f8845f 486 myEdge = TopoDS_Edge();
487 return;
7fd59977 488 }
489
490 }
491 else
a0f8845f 492 {
493 // If we have more than one edge attached to the list
494 // probably wire that we explore contains a loop or loops.
495 Standard_Real dfFPar = 0., dfLPar = 0.;
496 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface (myEdge, myFace, dfFPar, dfLPar);
497 if(aPCurve.IsNull())
7fd59977 498 {
a0f8845f 499 myEdge = TopoDS_Edge();
500 return;
501 }
502 // Note: current < myVertex > which is last on < myEdge >
503 // equals in 2D to following 2D points:
504 // edge is FORWARD - point with MAX parameter on PCurve;
505 // edge is REVERSED - point with MIN parameter on PCurve.
506
507 // Get 2D point equals to < myVertex > in 2D for current edge.
508 gp_Pnt2d PRef;
509 if( myEdge.Orientation() == TopAbs_REVERSED )
510 aPCurve->D0(dfFPar, PRef);
511 else
512 aPCurve->D0(dfLPar, PRef);
513
514 // Get next 2D point from current edge's PCurve with parameter
515 // F + dP (REV) or L - dP (FOR)
516 Standard_Boolean isrevese = ( myEdge.Orientation() == TopAbs_REVERSED );
517 Standard_Real dfMPar = GetNextParamOnPC(aPCurve,PRef,dfFPar,dfLPar,myTolU,myTolV,isrevese);
518
519 gp_Pnt2d PRefm;
520 aPCurve->D0(dfMPar, PRefm);
521 // Get vector from PRef to PRefm
522 gp_Vec2d anERefDir(PRef,PRefm);
b6cf8ffa 523 if (anERefDir.SquareMagnitude() < gp::Resolution())
524 {
525 myEdge = TopoDS_Edge();
526 return;
527 }
528
a0f8845f 529 // Search the list of edges looking for the edge having hearest
530 // 2D point of connected vertex to current one and smallest angle.
531 // First process all degenerated edges, then - all others.
532
533 TopTools_ListIteratorOfListOfShape it;
534 Standard_Integer k = 1, kMin = 0, iDone = 0;
535 Standard_Boolean isDegenerated = Standard_True;
536 Standard_Real dmin = RealLast();
537 Standard_Real dfMinAngle = 3.0*M_PI, dfCurAngle = 3.0*M_PI;
538
539 for(iDone = 0; iDone < 2; iDone++)
540 {
541 it.Initialize(l);
542 while( it.More() )
543 {
544 const TopoDS_Edge& E = TopoDS::Edge(it.Value());
545 if( E.IsSame(myEdge) )
546 {
547 it.Next();
548 k++;
549 continue;
550 }
551
552 TopoDS_Vertex aVert1, aVert2;
553 TopExp::Vertices (E, aVert1, aVert2, Standard_True);
554 if( aVert1.IsNull() || aVert2.IsNull() )
555 {
556 it.Next();
557 k++;
558 continue;
559 }
560
561 aPCurve = BRep_Tool::CurveOnSurface (E, myFace, dfFPar, dfLPar);
562 if( aPCurve.IsNull() )
563 {
564 it.Next();
565 k++;
566 continue;
567 }
568
569 gp_Pnt2d aPEb, aPEe;
570 if( aVert1.IsSame(aVert2) == isDegenerated )
571 {
572 if( E.Orientation() == TopAbs_REVERSED )
573 aPCurve->D0(dfLPar, aPEb);
574 else
575 aPCurve->D0(dfFPar, aPEb);
576
577 if( Abs(dfLPar-dfFPar) > Precision::PConfusion() )
578 {
579 isrevese = ( E.Orientation() == TopAbs_REVERSED );
580 isrevese = !isrevese;
581 Standard_Real aEPm = GetNextParamOnPC(aPCurve,aPEb,dfFPar,dfLPar,myTolU,myTolV,isrevese);
582
583 aPCurve->D0 (aEPm, aPEe);
584 if(aPEb.SquareDistance(aPEe) <= gp::Resolution())
585 {
586 //seems to be very short curve
587 gp_Vec2d aD;
588 aPCurve->D1(aEPm, aPEe, aD);
589 if( E.Orientation() == TopAbs_REVERSED )
590 aPEe.SetXY(aPEb.XY()-aD.XY());
591 else
592 aPEe.SetXY(aPEb.XY()+aD.XY());
593
594 if(aPEb.SquareDistance(aPEe) <= gp::Resolution())
595 {
596 it.Next();
597 k++;
598 continue;
599 }
600 }
601 gp_Vec2d anEDir(aPEb, aPEe);
602 dfCurAngle = Abs( anEDir.Angle(anERefDir) );
603 }
604
605 if( dfCurAngle <= dfMinAngle )
606 {
607 Standard_Real d = PRef.SquareDistance(aPEb);
608 if( d <= Precision::PConfusion() )
609 d = 0.;
610 if( Abs(aPEb.X()-PRef.X()) < myTolU && Abs(aPEb.Y()-PRef.Y()) < myTolV )
611 {
612 if( d <= dmin )
613 {
614 dfMinAngle = dfCurAngle;
615 kMin = k;
616 dmin = d;
617 }
618 }
619 }
620 }
621 it.Next();
622 k++;
623 }// while it
624
625 if( kMin == 0 )
626 {
627 isDegenerated = Standard_False;
628 k = 1;
629 dmin = RealLast();
630 }
631 else
632 break;
633 }// for iDone
634
635 if(kMin == 0)
636 {
637 // probably unclosed in 2d space wire
638 myEdge = TopoDS_Edge();
639 return;
640 }
641
642 // Selection the edge.
643 it.Initialize(l);
644 k = 1;
645 while( it.More() )
646 {
647 if( k == kMin )
648 {
649 myEdge = TopoDS::Edge(it.Value());
650 l.Remove(it);
651 break;
652 }
653 it.Next();
654 k++;
655 }
656 }//else face != NULL && l > 1
7fd59977 657 }//else l > 1
658}
659
660//=======================================================================
661//function : Current
662//purpose :
663//=======================================================================
664const TopoDS_Edge& BRepTools_WireExplorer::Current()const
665{
666 return myEdge;
667}
668
669//=======================================================================
670//function : Orientation
671//purpose :
672//=======================================================================
673TopAbs_Orientation BRepTools_WireExplorer::Orientation() const
674{
c7ba4578 675 if (myVertex.IsNull()
676 && !myEdge.IsNull())
677 {
678 // infinite edge
679 return TopAbs_FORWARD;
680 }
681
7fd59977 682 TopoDS_Iterator it(myEdge,Standard_False);
683 while (it.More()) {
684 if (myVertex.IsSame(it.Value()))
685 return it.Value().Orientation();
686 it.Next();
687 }
9775fa61 688 throw Standard_NoSuchObject("BRepTools_WireExplorer::Orientation");
7fd59977 689}
690
691//=======================================================================
692//function : CurrentVertex
693//purpose :
694//=======================================================================
695const TopoDS_Vertex& BRepTools_WireExplorer::CurrentVertex() const
696{
697 return myVertex;
698}
699
700//=======================================================================
701//function : Clear
702//purpose :
703//=======================================================================
704
705void BRepTools_WireExplorer::Clear()
706{
707 myMap.Clear();
708 myDoubles.Clear();
709 myEdge = TopoDS_Edge();
710 myFace = TopoDS_Face();
711 myVertex = TopoDS_Vertex();
712}
713
714
715//=======================================================================
716//function : SelectDouble
717//purpose :
718//=======================================================================
719
720Standard_Boolean SelectDouble(TopTools_MapOfShape& Doubles,
721 TopTools_ListOfShape& L,
722 TopoDS_Edge& E)
723{
724 TopTools_ListIteratorOfListOfShape it(L);
725
726 for (; it.More(); it.Next()) {
727 const TopoDS_Shape& CE = it.Value();
728 if (Doubles.Contains(CE) && (!E.IsSame(CE))) {
729 E = TopoDS::Edge(CE);
730 L.Remove(it);
731 return 1;
732 }
733 }
734 return 0;
735}
736
737//=======================================================================
738//function : SelectDegenerated
739//purpose :
740//=======================================================================
741
742Standard_Boolean SelectDegenerated(TopTools_ListOfShape& L,
743 TopoDS_Edge& E)
744{
745 TopTools_ListIteratorOfListOfShape it(L);
746 while (it.More()) {
747 if (!it.Value().IsSame(E)) {
748 E = TopoDS::Edge(it.Value());
749 if (BRep_Tool::Degenerated(E)) {
750 L.Remove(it);
751 return 1;
752 }
753 }
754 it.Next();
755 }
756 return 0;
757}
758
759//=======================================================================
760//function : GetNextParamOnPC
761//purpose :
762//=======================================================================
763Standard_Real GetNextParamOnPC(const Handle(Geom2d_Curve)& aPC,
764 const gp_Pnt2d& aPRef,
765 const Standard_Real& fP,
766 const Standard_Real& lP,
767 const Standard_Real& tolU,
768 const Standard_Real& tolV,
769 const Standard_Boolean& reverse)
770{
771 Standard_Real result = ( reverse ) ? fP : lP;
772 Standard_Real dP = Abs( lP - fP ) / 1000.; // was / 16.;
773 if( reverse )
774 {
775 Standard_Real startPar = fP;
776 Standard_Boolean nextPntOnEdge = Standard_False;
777 while( !nextPntOnEdge && startPar < lP )
778 {
779 gp_Pnt2d pnt;
780 startPar += dP;
781 aPC->D0(startPar, pnt);
782 if( Abs( aPRef.X() - pnt.X() ) < tolU && Abs( aPRef.Y() - pnt.Y() ) < tolV )
783 continue;
784 else
785 {
786 result = startPar;
787 nextPntOnEdge = Standard_True;
788 break;
789 }
790 }
791
792 if( !nextPntOnEdge )
793 result = lP;
794
795 if( result > lP )
796 result = lP;
797 }
798 else
799 {
800 Standard_Real startPar = lP;
801 Standard_Boolean nextPntOnEdge = Standard_False;
802 while( !nextPntOnEdge && startPar > fP )
803 {
804 gp_Pnt2d pnt;
805 startPar -= dP;
806 aPC->D0(startPar, pnt);
807 if( Abs( aPRef.X() - pnt.X() ) < tolU && Abs( aPRef.Y() - pnt.Y() ) < tolV )
808 continue;
809 else
810 {
811 result = startPar;
812 nextPntOnEdge = Standard_True;
813 break;
814 }
815 }
816
817 if( !nextPntOnEdge )
818 result = fP;
819
820 if( result < fP )
821 result = fP;
822 }
823
824 return result;
825}