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