Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1995-11-10 |
2 | // Created by: Yves FRICAUD | |
3 | // Copyright (c) 1995-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 | |
18 | #include <BRep_Builder.hxx> | |
42cf5bc1 | 19 | #include <BRep_TEdge.hxx> |
7fd59977 | 20 | #include <BRep_Tool.hxx> |
42cf5bc1 | 21 | #include <BRep_TVertex.hxx> |
22 | #include <BRepAlgo_FaceRestrictor.hxx> | |
23 | #include <BRepAlgo_Loop.hxx> | |
7fd59977 | 24 | #include <Geom2d_Curve.hxx> |
25 | #include <Geom_Surface.hxx> | |
7fd59977 | 26 | #include <gp_Pnt.hxx> |
27 | #include <gp_Pnt2d.hxx> | |
28 | #include <Precision.hxx> | |
42cf5bc1 | 29 | #include <TopExp.hxx> |
7fd59977 | 30 | #include <TopExp_Explorer.hxx> |
42cf5bc1 | 31 | #include <TopoDS.hxx> |
32 | #include <TopoDS_Edge.hxx> | |
33 | #include <TopoDS_Face.hxx> | |
7fd59977 | 34 | #include <TopoDS_Iterator.hxx> |
42cf5bc1 | 35 | #include <TopoDS_Vertex.hxx> |
36 | #include <TopoDS_Wire.hxx> | |
37 | #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx> | |
7fd59977 | 38 | #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx> |
42cf5bc1 | 39 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
40 | #include <TopTools_ListIteratorOfListOfShape.hxx> | |
41 | #include <TopTools_MapOfShape.hxx> | |
42 | #include <TopTools_SequenceOfShape.hxx> | |
7fd59977 | 43 | |
42cf5bc1 | 44 | #include <stdio.h> |
7fd59977 | 45 | #ifdef DRAW |
46 | #include <DBRep.hxx> | |
457b01e2 | 47 | #pragma comment(lib,"TKDraw") |
7fd59977 | 48 | #endif |
0797d9d3 | 49 | #ifdef OCCT_DEBUG_ALGO |
7fd59977 | 50 | Standard_Boolean AffichLoop = Standard_False; |
51 | Standard_Integer NbLoops = 0; | |
52 | Standard_Integer NbWires = 1; | |
53 | static char* name = new char[100]; | |
54 | #endif | |
55 | ||
56 | //======================================================================= | |
57 | //function : BRepAlgo_Loop | |
58 | //purpose : | |
59 | //======================================================================= | |
60 | ||
61 | BRepAlgo_Loop::BRepAlgo_Loop() | |
62 | { | |
63 | } | |
64 | ||
65 | ||
66 | //======================================================================= | |
67 | //function : Init | |
68 | //purpose : | |
69 | //======================================================================= | |
70 | ||
71 | void BRepAlgo_Loop::Init(const TopoDS_Face& F) | |
72 | { | |
73 | myConstEdges.Clear(); | |
457b01e2 | 74 | myEdges .Clear(); |
7fd59977 | 75 | myVerOnEdges.Clear(); |
76 | myNewWires .Clear(); | |
77 | myNewFaces .Clear(); | |
457b01e2 | 78 | myCutEdges .Clear(); |
7fd59977 | 79 | myFace = F; |
80 | } | |
81 | ||
82 | ||
83 | //======================================================================= | |
84 | //function : Bubble | |
0d969553 | 85 | //purpose : Orders the sequence of vertices by increasing parameter. |
7fd59977 | 86 | //======================================================================= |
87 | ||
88 | static void Bubble(const TopoDS_Edge& E, | |
89 | TopTools_SequenceOfShape& Seq) | |
90 | { | |
91 | Standard_Boolean Invert = Standard_True; | |
92 | Standard_Integer NbPoints = Seq.Length(); | |
93 | Standard_Real U1,U2; | |
94 | TopoDS_Vertex V1,V2; | |
95 | ||
96 | while (Invert) { | |
97 | Invert = Standard_False; | |
98 | for ( Standard_Integer i = 1; i < NbPoints; i++) { | |
99 | TopoDS_Shape aLocalV = Seq.Value(i) .Oriented(TopAbs_INTERNAL); | |
100 | V1 = TopoDS::Vertex(aLocalV); | |
101 | aLocalV = Seq.Value(i+1).Oriented(TopAbs_INTERNAL); | |
102 | V2 = TopoDS::Vertex(aLocalV); | |
103 | // V1 = TopoDS::Vertex(Seq.Value(i) .Oriented(TopAbs_INTERNAL)); | |
104 | // V2 = TopoDS::Vertex(Seq.Value(i+1).Oriented(TopAbs_INTERNAL)); | |
105 | ||
106 | U1 = BRep_Tool::Parameter(V1,E); | |
107 | U2 = BRep_Tool::Parameter(V2,E); | |
108 | if (U2 < U1) { | |
109 | Seq.Exchange(i,i+1); | |
110 | Invert = Standard_True; | |
111 | } | |
112 | } | |
113 | } | |
114 | } | |
115 | ||
116 | ||
117 | ||
118 | //======================================================================= | |
119 | //function : AddEdges | |
120 | //purpose : | |
121 | //======================================================================= | |
122 | ||
123 | void BRepAlgo_Loop::AddEdge (TopoDS_Edge& E, | |
124 | const TopTools_ListOfShape& LV) | |
125 | { | |
457b01e2 | 126 | myEdges.Append(E); |
7fd59977 | 127 | myVerOnEdges.Bind(E,LV); |
128 | } | |
129 | ||
130 | ||
131 | //======================================================================= | |
132 | //function : AddConstEdges | |
133 | //purpose : | |
134 | //======================================================================= | |
135 | ||
136 | void BRepAlgo_Loop::AddConstEdge (const TopoDS_Edge& E) | |
137 | { | |
138 | myConstEdges.Append(E); | |
139 | } | |
140 | ||
141 | //======================================================================= | |
142 | //function : AddConstEdges | |
143 | //purpose : | |
144 | //======================================================================= | |
145 | ||
146 | void BRepAlgo_Loop::AddConstEdges(const TopTools_ListOfShape& LE) | |
147 | { | |
148 | TopTools_ListIteratorOfListOfShape itl(LE); | |
149 | for (; itl.More(); itl.Next()) { | |
150 | myConstEdges.Append(itl.Value()); | |
151 | } | |
152 | } | |
153 | ||
154 | ||
155 | //======================================================================= | |
156 | //function : UpdateClosedEdge | |
0d969553 Y |
157 | //purpose : If the first or the last vertex of intersection |
158 | // coincides with the closing vertex, it is removed from SV. | |
159 | // it will be added at the beginning and the end of SV by the caller. | |
7fd59977 | 160 | //======================================================================= |
161 | ||
162 | static TopoDS_Vertex UpdateClosedEdge(const TopoDS_Edge& E, | |
163 | TopTools_SequenceOfShape& SV) | |
164 | { | |
165 | TopoDS_Vertex VB [2], V1, V2, VRes; | |
166 | gp_Pnt P,PC; | |
167 | Standard_Boolean OnStart = 0, OnEnd = 0; | |
168 | //// modified by jgv, 13.04.04 for OCC5634 //// | |
169 | TopExp::Vertices (E,V1,V2); | |
170 | //Standard_Real Tol = Precision::Confusion(); | |
171 | Standard_Real Tol = BRep_Tool::Tolerance( V1 ); | |
172 | /////////////////////////////////////////////// | |
173 | ||
174 | if (SV.IsEmpty()) return VRes; | |
175 | ||
176 | VB[0] = TopoDS::Vertex(SV.First()); | |
177 | VB[1] = TopoDS::Vertex(SV.Last ()); | |
178 | PC = BRep_Tool::Pnt(V1); | |
179 | ||
180 | for ( Standard_Integer i = 0 ; i < 2 ; i++) { | |
181 | P = BRep_Tool::Pnt(VB [i]); | |
182 | if (P.IsEqual(PC,Tol)) { | |
183 | VRes = VB [i]; | |
184 | if (i == 0) OnStart = Standard_True; | |
185 | else OnEnd = Standard_True; | |
186 | } | |
187 | } | |
188 | if (OnStart && OnEnd) { | |
189 | if (!VB[0].IsSame(VB[1])) { | |
0797d9d3 | 190 | #ifdef OCCT_DEBUG_ALGO |
7fd59977 | 191 | if (AffichLoop) |
0d969553 | 192 | cout <<"Two different vertices on the closing vertex"<<endl; |
7fd59977 | 193 | #endif |
194 | } | |
195 | else { | |
196 | SV.Remove(1); | |
197 | if (!SV.IsEmpty()) SV.Remove(SV.Length()); | |
198 | } | |
199 | } | |
200 | else if (OnStart) SV.Remove(1); | |
201 | else if (OnEnd ) SV.Remove(SV.Length()); | |
202 | ||
203 | return VRes; | |
204 | } | |
205 | ||
457b01e2 | 206 | //======================================================================= |
207 | //function : RemoveFromMVE | |
208 | //purpose : | |
209 | //======================================================================= | |
7fd59977 | 210 | |
457b01e2 | 211 | static void RemoveFromMVE(TopTools_IndexedDataMapOfShapeListOfShape& MVE, |
212 | const TopoDS_Shape& theVertex) | |
213 | { | |
214 | // remove from the indexed data map by substituting last item instead of removed | |
215 | Standard_Integer iV = MVE.FindIndex(theVertex); | |
216 | if (iV > 0) | |
217 | { | |
218 | Standard_Integer iLast = MVE.Extent(); | |
219 | if (iV == iLast) | |
220 | MVE.RemoveLast(); | |
221 | else | |
222 | { | |
223 | TopoDS_Shape aVertex = MVE.FindKey(iLast); | |
224 | TopTools_ListOfShape anEdges = MVE(iLast); | |
225 | MVE.RemoveLast(); | |
226 | MVE.Substitute(iV, aVertex, anEdges); | |
227 | } | |
228 | } | |
229 | } | |
7fd59977 | 230 | |
231 | //======================================================================= | |
232 | //function : RemovePendingEdges | |
233 | //purpose : | |
234 | //======================================================================= | |
235 | ||
457b01e2 | 236 | static void RemovePendingEdges(TopTools_IndexedDataMapOfShapeListOfShape& MVE) |
7fd59977 | 237 | { |
238 | //-------------------------------- | |
0d969553 | 239 | // Remove hanging edges. |
7fd59977 | 240 | //-------------------------------- |
7fd59977 | 241 | TopTools_ListOfShape ToRemove; |
242 | TopTools_ListIteratorOfListOfShape itl; | |
243 | Standard_Boolean YaSupress = Standard_True; | |
244 | TopoDS_Vertex V1,V2; | |
245 | ||
246 | while (YaSupress) { | |
247 | YaSupress = Standard_False; | |
248 | TopTools_ListOfShape VToRemove; | |
249 | TopTools_MapOfShape EToRemove; | |
250 | ||
457b01e2 | 251 | for (Standard_Integer iV = 1; iV <= MVE.Extent(); iV++) { |
252 | const TopoDS_Shape& aVertex = MVE.FindKey(iV); | |
253 | const TopTools_ListOfShape& anEdges = MVE(iV); | |
254 | if (anEdges.IsEmpty()) { | |
255 | VToRemove.Append(aVertex); | |
7fd59977 | 256 | } |
457b01e2 | 257 | if (anEdges.Extent() == 1) { |
258 | const TopoDS_Edge& E = TopoDS::Edge(anEdges.First()); | |
7fd59977 | 259 | TopExp::Vertices(E,V1,V2) ; |
260 | if (!V1.IsSame(V2)) { | |
457b01e2 | 261 | VToRemove.Append(aVertex); |
262 | EToRemove.Add(anEdges.First()); | |
7fd59977 | 263 | } |
264 | } | |
265 | } | |
266 | ||
267 | if (!VToRemove.IsEmpty()) { | |
268 | YaSupress = Standard_True; | |
269 | for (itl.Initialize(VToRemove); itl.More(); itl.Next()) { | |
457b01e2 | 270 | RemoveFromMVE(MVE, itl.Value()); |
7fd59977 | 271 | } |
272 | if (!EToRemove.IsEmpty()) { | |
457b01e2 | 273 | for (Standard_Integer iV = 1; iV <= MVE.Extent(); iV++) { |
274 | TopTools_ListOfShape& LE = MVE.ChangeFromIndex(iV); | |
7fd59977 | 275 | itl.Initialize(LE); |
276 | while (itl.More()) { | |
277 | if (EToRemove.Contains(itl.Value())) { | |
278 | LE.Remove(itl); | |
279 | } | |
280 | else itl.Next(); | |
281 | } | |
282 | } | |
283 | } | |
284 | } | |
285 | } | |
286 | } | |
287 | //======================================================================= | |
288 | //function : SamePnt2d | |
289 | //purpose : | |
290 | //======================================================================= | |
291 | ||
292 | static Standard_Boolean SamePnt2d(TopoDS_Vertex V, | |
293 | TopoDS_Edge& E1, | |
294 | TopoDS_Edge& E2, | |
295 | TopoDS_Face& F) | |
296 | { | |
297 | Standard_Real f1,f2,l1,l2; | |
298 | gp_Pnt2d P1,P2; | |
299 | TopoDS_Shape aLocalF = F.Oriented(TopAbs_FORWARD); | |
300 | TopoDS_Face FF = TopoDS::Face(aLocalF); | |
301 | // TopoDS_Face FF = TopoDS::Face(F.Oriented(TopAbs_FORWARD)); | |
302 | Handle(Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E1,FF,f1,l1); | |
303 | Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E2,FF,f2,l2); | |
304 | if (E1.Orientation () == TopAbs_FORWARD) P1 = C1->Value(f1); | |
305 | else P1 = C1->Value(l1); | |
306 | ||
307 | if (E2.Orientation () == TopAbs_FORWARD) P2 = C2->Value(l2); | |
308 | else P2 = C2->Value(f2); | |
309 | Standard_Real Tol = 100*BRep_Tool::Tolerance(V); | |
310 | Standard_Real Dist = P1.Distance(P2); | |
311 | return Dist < Tol; | |
312 | } | |
313 | ||
314 | //======================================================================= | |
315 | //function : SelectEdge | |
0d969553 Y |
316 | //purpose : Find edge <NE> connected to <CE> by vertex <CV> in the |
317 | // list <LE>. <NE> is removed from the list. If <CE> is | |
318 | // also in the list <LE> with the same orientation, it is | |
319 | // removed from the list. | |
7fd59977 | 320 | //======================================================================= |
321 | ||
322 | static Standard_Boolean SelectEdge(const TopoDS_Face& F, | |
323 | const TopoDS_Edge& CE, | |
324 | const TopoDS_Vertex& CV, | |
325 | TopoDS_Edge& NE, | |
326 | TopTools_ListOfShape& LE) | |
327 | { | |
328 | TopTools_ListIteratorOfListOfShape itl; | |
329 | NE.Nullify(); | |
0797d9d3 | 330 | #ifdef OCCT_DEBUG_ALGO |
7fd59977 | 331 | if (AffichLoop) { |
332 | if ( LE.Extent() > 2) { | |
0d969553 | 333 | cout <<"vertex on more than 2 edges in a face."<<endl; |
7fd59977 | 334 | } |
335 | } | |
336 | #endif | |
337 | for ( itl.Initialize(LE); itl.More(); itl.Next()) { | |
338 | if (itl.Value().IsEqual(CE)) { | |
339 | LE.Remove(itl); | |
340 | break; | |
341 | } | |
342 | } | |
343 | if (LE.Extent() > 1) { | |
344 | //-------------------------------------------------------------- | |
0d969553 Y |
345 | // Several edges possible. |
346 | // - Test edges different from CE , Selection of edge | |
347 | // for which CV has U,V closer to the face | |
348 | // than corresponding to CE. | |
349 | // - If several edges give representation less than the tolerance. | |
350 | // discrimination on tangents. | |
7fd59977 | 351 | //-------------------------------------------------------------- |
352 | TopLoc_Location L; | |
353 | Standard_Real f,l; | |
354 | TopoDS_Face FForward = F; | |
355 | FForward.Orientation(TopAbs_FORWARD); | |
356 | ||
357 | Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(CE,FForward,f,l); | |
358 | Standard_Integer k = 1, kmin = 0; | |
359 | Standard_Real dist,distmin = 100*BRep_Tool::Tolerance(CV); | |
360 | Standard_Real u ; | |
361 | if (CE.Orientation () == TopAbs_FORWARD) u = l; | |
362 | else u = f; | |
363 | ||
364 | gp_Pnt2d P2,PV = C->Value(u); | |
365 | ||
366 | for ( itl.Initialize(LE); itl.More(); itl.Next()) { | |
367 | const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); | |
368 | if (!E.IsSame(CE)) { | |
369 | C = BRep_Tool::CurveOnSurface(E,FForward,f,l); | |
370 | if (E.Orientation () == TopAbs_FORWARD) u = f; | |
371 | else u = l; | |
372 | P2 = C->Value(u); | |
373 | dist = PV.Distance(P2); | |
374 | if ( dist <= distmin) { | |
375 | kmin = k; | |
376 | distmin = dist; | |
377 | } | |
378 | } | |
379 | k++; | |
380 | } | |
381 | if (kmin == 0) return Standard_False; | |
382 | ||
383 | k = 1; itl.Initialize(LE); | |
384 | while (k < kmin) {k++; itl.Next();} | |
385 | NE = TopoDS::Edge(itl.Value()); | |
386 | LE.Remove(itl); | |
387 | } | |
388 | else if (LE.Extent() == 1) { | |
389 | NE = TopoDS::Edge(LE.First()); | |
390 | LE.RemoveFirst(); | |
391 | } | |
392 | else { | |
393 | return Standard_False; | |
394 | } | |
395 | #ifdef DRAW | |
396 | if (AffichLoop) { | |
397 | DBRep::Set("Selected",NE); | |
398 | } | |
399 | ||
400 | #endif | |
401 | return Standard_True; | |
402 | } | |
403 | //======================================================================= | |
457b01e2 | 404 | //function : PurgeNewEdges |
7fd59977 | 405 | //purpose : |
406 | //======================================================================= | |
407 | ||
408 | static void PurgeNewEdges(TopTools_DataMapOfShapeListOfShape& NewEdges, | |
409 | const TopTools_MapOfShape& UsedEdges) | |
410 | { | |
411 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape it(NewEdges); | |
412 | for (; it.More(); it.Next()) { | |
413 | TopTools_ListOfShape& LNE = NewEdges.ChangeFind(it.Key()); | |
414 | TopTools_ListIteratorOfListOfShape itL(LNE); | |
415 | while (itL.More()) { | |
416 | const TopoDS_Shape& NE = itL.Value(); | |
417 | if (!UsedEdges.Contains(NE)) { | |
418 | LNE.Remove(itL); | |
419 | } | |
420 | else { | |
421 | itL.Next(); | |
422 | } | |
423 | } | |
424 | } | |
425 | ||
426 | } | |
427 | ||
428 | //======================================================================= | |
457b01e2 | 429 | //function : StoreInMVE |
7fd59977 | 430 | //purpose : |
431 | //======================================================================= | |
432 | ||
433 | static void StoreInMVE (const TopoDS_Face& F, | |
434 | TopoDS_Edge& E, | |
457b01e2 | 435 | TopTools_IndexedDataMapOfShapeListOfShape& MVE, |
7fd59977 | 436 | Standard_Boolean& YaCouture, |
437 | TopTools_DataMapOfShapeShape& VerticesForSubstitute ) | |
438 | { | |
439 | TopoDS_Vertex V1, V2, V; | |
440 | TopTools_ListOfShape Empty; | |
441 | ||
442 | Standard_Real Tol = 0.001; //5.e-05; //5.e-07; | |
443 | // gp_Pnt P1, P2, P; | |
444 | gp_Pnt P1, P; | |
7fd59977 | 445 | BRep_Builder BB; |
457b01e2 | 446 | for (Standard_Integer iV = 1; iV <= MVE.Extent(); iV++) |
7fd59977 | 447 | { |
457b01e2 | 448 | V = TopoDS::Vertex(MVE.FindKey(iV)); |
7fd59977 | 449 | P = BRep_Tool::Pnt( V ); |
450 | TopTools_ListOfShape VList; | |
451 | TopoDS_Iterator VerExp( E ); | |
452 | for (; VerExp.More(); VerExp.Next()) | |
453 | VList.Append( VerExp.Value() ); | |
454 | TopTools_ListIteratorOfListOfShape itl( VList ); | |
455 | for (; itl.More(); itl.Next()) | |
456 | { | |
457 | V1 = TopoDS::Vertex( itl.Value() ); | |
458 | P1 = BRep_Tool::Pnt( V1 ); | |
459 | if (P.IsEqual( P1, Tol ) && !V.IsSame(V1)) | |
460 | { | |
461 | V.Orientation( V1.Orientation() ); | |
462 | if (VerticesForSubstitute.IsBound( V1 )) | |
463 | { | |
464 | TopoDS_Shape OldNewV = VerticesForSubstitute( V1 ); | |
465 | if (! OldNewV.IsSame( V )) | |
466 | { | |
467 | VerticesForSubstitute.Bind( OldNewV, V ); | |
468 | VerticesForSubstitute( V1 ) = V; | |
469 | } | |
470 | } | |
471 | else | |
472 | { | |
473 | if (VerticesForSubstitute.IsBound( V )) | |
474 | { | |
475 | TopoDS_Shape NewNewV = VerticesForSubstitute( V ); | |
476 | if (! NewNewV.IsSame( V1 )) | |
477 | VerticesForSubstitute.Bind( V1, NewNewV ); | |
478 | } | |
479 | else | |
480 | { | |
481 | VerticesForSubstitute.Bind( V1, V ); | |
482 | TopTools_DataMapIteratorOfDataMapOfShapeShape mapit( VerticesForSubstitute ); | |
483 | for (; mapit.More(); mapit.Next()) | |
484 | if (mapit.Value().IsSame( V1 )) | |
485 | VerticesForSubstitute( mapit.Key() ) = V; | |
486 | } | |
487 | } | |
488 | E.Free( Standard_True ); | |
489 | BB.Remove( E, V1 ); | |
490 | BB.Add( E, V ); | |
491 | } | |
492 | } | |
493 | } | |
494 | ||
495 | TopExp::Vertices(E,V1,V2); | |
496 | if( V1.IsNull() && V2.IsNull() ){ YaCouture = Standard_False; return; } | |
457b01e2 | 497 | if (!MVE.Contains(V1)) { |
498 | MVE.Add(V1,Empty); | |
7fd59977 | 499 | } |
457b01e2 | 500 | MVE.ChangeFromKey(V1).Append(E); |
7fd59977 | 501 | if (!V1.IsSame(V2)) { |
457b01e2 | 502 | if (!MVE.Contains(V2)) { |
503 | MVE.Add(V2,Empty); | |
504 | } | |
505 | MVE.ChangeFromKey(V2).Append(E); | |
7fd59977 | 506 | } |
507 | TopLoc_Location L ; | |
508 | Handle(Geom_Surface) S = BRep_Tool::Surface(F,L); | |
509 | if (BRep_Tool::IsClosed(E,S,L)) { | |
457b01e2 | 510 | MVE.ChangeFromKey(V2).Append(E.Reversed()); |
7fd59977 | 511 | if (!V1.IsSame(V2)) { |
457b01e2 | 512 | MVE.ChangeFromKey(V1).Append(E.Reversed()); |
7fd59977 | 513 | } |
514 | YaCouture = Standard_True; | |
515 | } | |
516 | } | |
517 | ||
518 | //======================================================================= | |
519 | //function : Perform | |
520 | //purpose : | |
521 | //======================================================================= | |
522 | ||
523 | void BRepAlgo_Loop::Perform() | |
524 | { | |
457b01e2 | 525 | TopTools_ListIteratorOfListOfShape itl, itl1; |
7fd59977 | 526 | TopoDS_Vertex V1,V2; |
527 | Standard_Boolean YaCouture = Standard_False; | |
528 | ||
0797d9d3 | 529 | #ifdef OCCT_DEBUG_ALGO |
7fd59977 | 530 | if (AffichLoop) { |
531 | cout <<"NewLoop"<<endl; | |
7fd59977 | 532 | NbLoops++; |
533 | #ifdef DRAW | |
534 | sprintf(name,"FLoop_%d",NbLoops); | |
535 | DBRep::Set(name,myFace); | |
498ce76b | 536 | Standard_Integer NbEdges = 1; |
7fd59977 | 537 | #endif |
457b01e2 | 538 | for (itl.Initialize(myEdges); itl.More(); itl.Next()) { |
539 | const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); | |
7fd59977 | 540 | #ifdef DRAW |
541 | sprintf(name,"EEE_%d_%d",NbLoops,NbEdges++); | |
542 | DBRep::Set(name,E); | |
543 | #endif | |
544 | } | |
545 | for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) { | |
546 | const TopoDS_Edge& E = TopoDS::Edge(itl.Value()); | |
547 | #ifdef DRAW | |
548 | sprintf(name,"EEE_%d_%d",NbLoops,NbEdges++); | |
549 | DBRep::Set(name,E); | |
550 | #endif | |
551 | } | |
552 | } | |
553 | #endif | |
7fd59977 | 554 | //------------------------------------------------ |
0d969553 | 555 | // Cut edges |
7fd59977 | 556 | //------------------------------------------------ |
457b01e2 | 557 | for (itl.Initialize(myEdges); itl.More(); itl.Next()) |
558 | { | |
559 | const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value()); | |
7fd59977 | 560 | TopTools_ListOfShape LCE; |
b7c077b9 | 561 | const TopTools_ListOfShape* pVertices = myVerOnEdges.Seek (anEdge); |
457b01e2 | 562 | if (pVertices) |
563 | { | |
564 | CutEdge (anEdge, *pVertices, LCE); | |
565 | myCutEdges.Bind(anEdge, LCE); | |
566 | } | |
7fd59977 | 567 | } |
568 | //----------------------------------- | |
569 | // Construction map vertex => edges | |
570 | //----------------------------------- | |
457b01e2 | 571 | TopTools_IndexedDataMapOfShapeListOfShape MVE; |
7fd59977 | 572 | |
0d969553 | 573 | // add cut edges. |
457b01e2 | 574 | for (itl.Initialize(myEdges); itl.More(); itl.Next()) |
575 | { | |
b7c077b9 | 576 | const TopTools_ListOfShape* pLCE = myCutEdges.Seek (itl.Value()); |
457b01e2 | 577 | if (pLCE) |
578 | { | |
579 | for (itl1.Initialize(*pLCE); itl1.More(); itl1.Next()) { | |
580 | TopoDS_Edge& E = TopoDS::Edge(itl1.Value()); | |
581 | StoreInMVE(myFace,E,MVE,YaCouture,myVerticesForSubstitute); | |
582 | } | |
7fd59977 | 583 | } |
584 | } | |
585 | ||
0d969553 Y |
586 | // add const edges |
587 | // Sewn edges can be doubled or not in myConstEdges | |
588 | // => call only once StoreInMVE which should double them | |
7fd59977 | 589 | TopTools_MapOfShape DejaVu; |
590 | for (itl.Initialize(myConstEdges); itl.More(); itl.Next()) { | |
591 | TopoDS_Edge& E = TopoDS::Edge(itl.Value()); | |
592 | if (DejaVu.Add(E)) | |
593 | StoreInMVE(myFace,E,MVE,YaCouture,myVerticesForSubstitute); | |
594 | } | |
595 | ||
596 | #ifdef DRAW | |
597 | if (AffichLoop) { | |
598 | cout <<"NewLoop"<<endl; | |
599 | Standard_Integer NbEdges = 1; | |
600 | TopTools_MapOfShape Done; | |
457b01e2 | 601 | for (Standard_Integer iV = 1; iV <= MVE.Extent(); iV++) { |
602 | for (itl.Initialize(MVE(iV)); itl.More(); itl.Next()) { | |
302f96fb | 603 | TopoDS_Edge& E = TopoDS::Edge(itl.Value()); |
604 | if (Done.Add(E)) { | |
605 | sprintf(name,"EEC_%d_%d",NbLoops,NbEdges++); | |
606 | DBRep::Set(name,E); | |
607 | } | |
7fd59977 | 608 | } |
609 | } | |
610 | } | |
611 | #endif | |
612 | ||
613 | //----------------------------------------------- | |
0d969553 | 614 | // Construction of wires and new faces. |
7fd59977 | 615 | //---------------------------------------------- |
616 | TopoDS_Vertex VF,VL,CV; | |
617 | TopoDS_Edge CE,NE,EF; | |
618 | BRep_Builder B; | |
619 | TopoDS_Wire NW; | |
620 | Standard_Boolean End; | |
621 | ||
622 | TopTools_MapOfShape UsedEdges; | |
623 | ||
457b01e2 | 624 | while (MVE.Extent() > 0) { |
7fd59977 | 625 | B.MakeWire(NW); |
626 | //-------------------------------- | |
0d969553 | 627 | // Removal of hanging edges. |
7fd59977 | 628 | //-------------------------------- |
629 | RemovePendingEdges(MVE); | |
630 | ||
457b01e2 | 631 | if (MVE.Extent() == 0) break; |
7fd59977 | 632 | //-------------------------------- |
0d969553 | 633 | // Start edge. |
7fd59977 | 634 | //-------------------------------- |
457b01e2 | 635 | EF = CE = TopoDS::Edge(MVE(1).First()); |
7fd59977 | 636 | TopExp::Vertices(CE,V1,V2); |
637 | //-------------------------------- | |
0d969553 | 638 | // VF vertex start of new wire |
7fd59977 | 639 | //-------------------------------- |
640 | if (CE.Orientation() == TopAbs_FORWARD) { CV = VF = V1;} | |
641 | else { CV = VF = V2;} | |
457b01e2 | 642 | if (!MVE.Contains(CV)) continue; |
643 | TopTools_ListOfShape& aListEdges = MVE.ChangeFromKey(CV); | |
644 | for ( itl.Initialize(aListEdges); itl.More(); itl.Next()) { | |
7fd59977 | 645 | if (itl.Value().IsEqual(CE)) { |
457b01e2 | 646 | aListEdges.Remove(itl); |
7fd59977 | 647 | break; |
648 | } | |
649 | } | |
650 | End = Standard_False; | |
651 | ||
652 | while (!End) { | |
653 | //------------------------------- | |
0d969553 | 654 | // Construction of a wire. |
7fd59977 | 655 | //------------------------------- |
656 | TopExp::Vertices(CE,V1,V2); | |
657 | if (!CV.IsSame(V1)) CV = V1; else CV = V2; | |
658 | ||
659 | B.Add (NW,CE); | |
660 | UsedEdges.Add(CE); | |
661 | ||
457b01e2 | 662 | if (!MVE.Contains(CV) || MVE.FindFromKey(CV).IsEmpty()) { |
302f96fb | 663 | End = Standard_True; |
7fd59977 | 664 | } |
665 | else { | |
457b01e2 | 666 | End = !SelectEdge(myFace,CE,CV,NE,MVE.ChangeFromKey(CV)); |
302f96fb | 667 | if (!End) { |
668 | CE = NE; | |
457b01e2 | 669 | if (MVE.FindFromKey(CV).IsEmpty()) |
670 | RemoveFromMVE(MVE, CV); | |
302f96fb | 671 | } |
7fd59977 | 672 | } |
673 | } | |
674 | //-------------------------------------------------- | |
0d969553 | 675 | // Add new wire to the set of wires |
7fd59977 | 676 | //------------------------------------------------ |
677 | Standard_Real Tol = 0.001; //5.e-05; //5.e-07; | |
678 | TopExp_Explorer explo( NW, TopAbs_VERTEX ); | |
679 | for (; explo.More(); explo.Next()) | |
680 | { | |
302f96fb | 681 | const TopoDS_Vertex& aV = TopoDS::Vertex( explo.Current() ); |
682 | Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &(aV).TShape()); | |
683 | TV->Tolerance( Tol ); | |
684 | TV->Modified( Standard_True ); | |
7fd59977 | 685 | } |
686 | for (explo.Init( NW, TopAbs_EDGE ); explo.More(); explo.Next()) | |
687 | { | |
302f96fb | 688 | const TopoDS_Edge& aE = TopoDS::Edge( explo.Current() ); |
689 | Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &(aE).TShape()); | |
690 | TE->Tolerance( Tol ); | |
691 | TE->Modified( Standard_True ); | |
7fd59977 | 692 | } |
693 | ||
694 | if (VF.IsSame(CV) && SamePnt2d(VF,EF,CE,myFace)) | |
ab860031 | 695 | { |
696 | NW.Closed (Standard_True); | |
7fd59977 | 697 | myNewWires.Append (NW); |
ab860031 | 698 | } |
0797d9d3 | 699 | #ifdef OCCT_DEBUG_ALGO |
302f96fb | 700 | else { |
7fd59977 | 701 | cout <<"BRepAlgo_Loop: Open Wire"<<endl; |
702 | if (AffichLoop) | |
302f96fb | 703 | cout << "OpenWire is : NW_"<<NbLoops<<"_"<<NbWires<<endl; |
704 | } | |
7fd59977 | 705 | #endif |
7fd59977 | 706 | #ifdef DRAW |
707 | if (AffichLoop) { | |
708 | sprintf(name,"NW_%d_%d",NbLoops,NbWires++); | |
709 | DBRep::Set(name,NW); | |
710 | } | |
711 | #endif | |
712 | } | |
713 | ||
457b01e2 | 714 | PurgeNewEdges(myCutEdges,UsedEdges); |
7fd59977 | 715 | } |
716 | ||
717 | //======================================================================= | |
718 | //function : CutEdges | |
719 | //purpose : | |
720 | //======================================================================= | |
721 | ||
722 | void BRepAlgo_Loop::CutEdge (const TopoDS_Edge& E, | |
723 | const TopTools_ListOfShape& VOnE, | |
724 | TopTools_ListOfShape& NE ) const | |
725 | { | |
726 | TopoDS_Shape aLocalE = E.Oriented(TopAbs_FORWARD); | |
727 | TopoDS_Edge WE = TopoDS::Edge(aLocalE); | |
7fd59977 | 728 | |
729 | Standard_Real U1,U2; | |
730 | TopoDS_Vertex V1,V2; | |
731 | TopTools_SequenceOfShape SV; | |
732 | TopTools_ListIteratorOfListOfShape it(VOnE); | |
733 | BRep_Builder B; | |
734 | ||
735 | for ( ; it.More(); it.Next()) { | |
736 | SV.Append(it.Value()); | |
737 | } | |
738 | //-------------------------------- | |
0d969553 | 739 | // Parse vertices on the edge. |
7fd59977 | 740 | //-------------------------------- |
741 | Bubble (WE,SV); | |
742 | ||
743 | Standard_Integer NbVer = SV.Length(); | |
744 | //---------------------------------------------------------------- | |
0d969553 Y |
745 | // Construction of new edges. |
746 | // Note : vertices at the extremities of edges are not | |
747 | // onligatorily in the list of vertices | |
7fd59977 | 748 | //---------------------------------------------------------------- |
749 | if (SV.IsEmpty()) { | |
750 | NE.Append(E); | |
751 | return; | |
752 | } | |
753 | TopoDS_Vertex VF,VL; | |
754 | Standard_Real f,l; | |
755 | BRep_Tool::Range(WE,f,l); | |
756 | TopExp::Vertices(WE,VF,VL); | |
757 | ||
758 | if (NbVer == 2) { | |
759 | if (SV(1).IsEqual(VF) && SV(2).IsEqual(VL)) { | |
760 | NE.Append(E); | |
761 | #ifdef DRAW | |
762 | if (AffichLoop) { | |
763 | DBRep::Set("ECOpied",E); | |
764 | } | |
765 | #endif | |
766 | return; | |
767 | } | |
768 | } | |
769 | //---------------------------------------------------- | |
0d969553 Y |
770 | // Processing of closed edges |
771 | // If a vertex of intersection is on the common vertex | |
772 | // it should appear at the beginning and end of SV. | |
7fd59977 | 773 | //---------------------------------------------------- |
774 | TopoDS_Vertex VCEI; | |
775 | if (!VF.IsNull() && VF.IsSame(VL)) { | |
776 | VCEI = UpdateClosedEdge(WE,SV); | |
777 | if (!VCEI.IsNull()) { | |
778 | TopoDS_Shape aLocalV = VCEI.Oriented(TopAbs_FORWARD); | |
779 | VF = TopoDS::Vertex(aLocalV); | |
780 | aLocalV = VCEI.Oriented(TopAbs_REVERSED); | |
781 | VL = TopoDS::Vertex(aLocalV); | |
782 | // VF = TopoDS::Vertex(VCEI.Oriented(TopAbs_FORWARD)); | |
783 | // VL = TopoDS::Vertex(VCEI.Oriented(TopAbs_REVERSED)); | |
784 | } | |
785 | SV.Prepend(VF); | |
786 | SV.Append(VL); | |
787 | } | |
788 | else { | |
789 | //----------------------------------------- | |
0d969553 | 790 | // Eventually all extremities of the edge. |
7fd59977 | 791 | //----------------------------------------- |
792 | if (!VF.IsNull() && !VF.IsSame(SV.First())) SV.Prepend(VF); | |
793 | if (!VL.IsNull() && !VL.IsSame(SV.Last ())) SV.Append (VL); | |
794 | } | |
795 | ||
796 | while (!SV.IsEmpty()) { | |
797 | while (!SV.IsEmpty() && | |
798 | SV.First().Orientation() != TopAbs_FORWARD) { | |
799 | SV.Remove(1); | |
800 | } | |
801 | if (SV.IsEmpty()) | |
802 | break; | |
803 | V1 = TopoDS::Vertex(SV.First()); | |
804 | SV.Remove(1); | |
805 | if (SV.IsEmpty()) | |
806 | break; | |
807 | if (SV.First().Orientation() == TopAbs_REVERSED) { | |
808 | V2 = TopoDS::Vertex(SV.First()); | |
809 | SV.Remove(1); | |
810 | //------------------------------------------- | |
0d969553 | 811 | // Copy the edge and restriction by V1 V2. |
7fd59977 | 812 | //------------------------------------------- |
813 | TopoDS_Shape NewEdge = WE.EmptyCopied(); | |
814 | TopoDS_Shape aLocalEdge = V1.Oriented(TopAbs_FORWARD); | |
815 | B.Add (NewEdge,aLocalEdge); | |
816 | aLocalEdge = V2.Oriented(TopAbs_REVERSED); | |
817 | B.Add (TopoDS::Edge(NewEdge),aLocalEdge); | |
818 | // B.Add (NewEdge,V1.Oriented(TopAbs_FORWARD)); | |
819 | // B.Add (NewEdge,V2.Oriented(TopAbs_REVERSED)); | |
820 | if (V1.IsSame(VF)) | |
821 | U1 = f; | |
822 | else | |
823 | // U1=BRep_Tool::Parameter | |
824 | // (TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),WE); | |
825 | { | |
826 | TopoDS_Shape aLocalV = V1.Oriented(TopAbs_INTERNAL); | |
827 | U1=BRep_Tool::Parameter(TopoDS::Vertex(aLocalV),WE); | |
828 | } | |
829 | if (V2.IsSame(VL)) | |
830 | U2 = l; | |
831 | else | |
832 | { | |
833 | TopoDS_Shape aLocalV = V2.Oriented(TopAbs_INTERNAL); | |
834 | U2=BRep_Tool::Parameter(TopoDS::Vertex(aLocalV),WE); | |
835 | // U2=BRep_Tool::Parameter | |
836 | // (TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),WE); | |
837 | } | |
838 | B.Range (TopoDS::Edge(NewEdge),U1,U2); | |
839 | #ifdef DRAW | |
840 | if (AffichLoop) { | |
841 | DBRep::Set("Cut",NewEdge); | |
842 | } | |
843 | #endif | |
844 | NE.Append(NewEdge.Oriented(E.Orientation())); | |
845 | } | |
846 | } | |
847 | ||
848 | //Remove edges with size <= tolerance | |
849 | Standard_Real Tol = 0.001; //5.e-05; //5.e-07; | |
850 | it.Initialize(NE); | |
851 | while (it.More()) | |
852 | { | |
853 | // skl : I change "E" to "EE" | |
854 | TopoDS_Edge EE = TopoDS::Edge( it.Value() ); | |
855 | Standard_Real fpar, lpar; | |
856 | BRep_Tool::Range( EE, fpar, lpar ); | |
857 | if (lpar - fpar <= Precision::Confusion()) | |
858 | NE.Remove(it); | |
859 | else | |
860 | { | |
861 | gp_Pnt2d pf, pl; | |
862 | BRep_Tool::UVPoints( EE, myFace, pf, pl ); | |
da72a17c | 863 | if (pf.Distance(pl) <= Tol && !BRep_Tool::IsClosed(EE)) |
7fd59977 | 864 | NE.Remove(it); |
865 | else | |
866 | it.Next(); | |
867 | } | |
868 | } | |
869 | } | |
870 | ||
871 | //======================================================================= | |
872 | //function : NewWires | |
873 | //purpose : | |
874 | //======================================================================= | |
875 | ||
876 | const TopTools_ListOfShape& BRepAlgo_Loop::NewWires() const | |
877 | { | |
878 | return myNewWires; | |
879 | } | |
880 | ||
881 | //======================================================================= | |
882 | //function : NewFaces | |
883 | //purpose : | |
884 | //======================================================================= | |
885 | ||
886 | const TopTools_ListOfShape& BRepAlgo_Loop::NewFaces() const | |
887 | { | |
888 | return myNewFaces; | |
889 | } | |
890 | ||
891 | //======================================================================= | |
892 | //function : WiresToFaces | |
893 | //purpose : | |
894 | //======================================================================= | |
895 | ||
896 | void BRepAlgo_Loop::WiresToFaces() | |
897 | { | |
898 | if (!myNewWires.IsEmpty()) { | |
899 | BRepAlgo_FaceRestrictor FR; | |
900 | TopoDS_Shape aLocalS = myFace.Oriented(TopAbs_FORWARD); | |
901 | FR.Init (TopoDS::Face(aLocalS),Standard_False); | |
902 | // FR.Init (TopoDS::Face(myFace.Oriented(TopAbs_FORWARD)), | |
903 | // Standard_False); | |
904 | TopTools_ListIteratorOfListOfShape it(myNewWires); | |
905 | for (; it.More(); it.Next()) { | |
906 | FR.Add(TopoDS::Wire(it.Value())); | |
907 | } | |
908 | ||
909 | FR.Perform(); | |
910 | ||
911 | if (FR.IsDone()) { | |
912 | TopAbs_Orientation OriF = myFace.Orientation(); | |
913 | for (; FR.More(); FR.Next()) { | |
914 | myNewFaces.Append(FR.Current().Oriented(OriF)); | |
915 | } | |
916 | } | |
917 | } | |
918 | } | |
919 | ||
920 | ||
921 | //======================================================================= | |
922 | //function : NewEdges | |
923 | //purpose : | |
924 | //======================================================================= | |
925 | ||
926 | const TopTools_ListOfShape& BRepAlgo_Loop::NewEdges(const TopoDS_Edge& E) const | |
927 | { | |
457b01e2 | 928 | return myCutEdges(E); |
7fd59977 | 929 | } |
930 | ||
931 | //======================================================================= | |
932 | //function : GetVerticesForSubstitute | |
933 | //purpose : | |
934 | //======================================================================= | |
935 | ||
936 | void BRepAlgo_Loop::GetVerticesForSubstitute( TopTools_DataMapOfShapeShape& VerVerMap ) const | |
937 | { | |
938 | VerVerMap = myVerticesForSubstitute; | |
939 | } | |
940 | //======================================================================= | |
941 | //function : VerticesForSubstitute | |
942 | //purpose : | |
943 | //======================================================================= | |
944 | ||
945 | void BRepAlgo_Loop::VerticesForSubstitute( TopTools_DataMapOfShapeShape& VerVerMap ) | |
946 | { | |
947 | myVerticesForSubstitute = VerVerMap; | |
948 | } |