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