0024157: Parallelization of assembly part of BO
[occt.git] / src / BRepAlgo / BRepAlgo_Loop.cxx
CommitLineData
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 54Standard_Boolean AffichLoop = Standard_False;
55Standard_Integer NbLoops = 0;
56Standard_Integer NbWires = 1;
57static char* name = new char[100];
58#endif
59
60//=======================================================================
61//function : BRepAlgo_Loop
62//purpose :
63//=======================================================================
64
65BRepAlgo_Loop::BRepAlgo_Loop()
66{
67}
68
69
70//=======================================================================
71//function : Init
72//purpose :
73//=======================================================================
74
75void 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
91static 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
126void 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
138void BRepAlgo_Loop::AddConstEdge (const TopoDS_Edge& E)
139{
140 myConstEdges.Append(E);
141}
142
143//=======================================================================
144//function : AddConstEdges
145//purpose :
146//=======================================================================
147
148void 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
164static 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
215static 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
271static 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
301static 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
387static 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
412static 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
503void 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
690void 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
844const TopTools_ListOfShape& BRepAlgo_Loop::NewWires() const
845{
846 return myNewWires;
847}
848
849//=======================================================================
850//function : NewFaces
851//purpose :
852//=======================================================================
853
854const TopTools_ListOfShape& BRepAlgo_Loop::NewFaces() const
855{
856 return myNewFaces;
857}
858
859//=======================================================================
860//function : WiresToFaces
861//purpose :
862//=======================================================================
863
864void 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
894const 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
904void BRepAlgo_Loop::GetVerticesForSubstitute( TopTools_DataMapOfShapeShape& VerVerMap ) const
905{
906 VerVerMap = myVerticesForSubstitute;
907}
908//=======================================================================
909//function : VerticesForSubstitute
910//purpose :
911//=======================================================================
912
913void BRepAlgo_Loop::VerticesForSubstitute( TopTools_DataMapOfShapeShape& VerVerMap )
914{
915 myVerticesForSubstitute = VerVerMap;
916}