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