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