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