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