0027067: Avoid use of virtual methods for implementation of destructors in legacy...
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_CorrectFace2d.cxx
CommitLineData
b311480e 1// Created on: 2000-01-26
2// Created by: Peter KURNEV
973c2be1 3// Copyright (c) 2000-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 15
7fd59977 16
42cf5bc1 17#include <Bnd_Box2d.hxx>
18#include <BndLib_Add2dCurve.hxx>
19#include <BRep_Builder.hxx>
20#include <BRep_Tool.hxx>
21#include <BRepAdaptor_Curve2d.hxx>
22#include <BRepAdaptor_Surface.hxx>
23#include <BRepTopAdaptor_FClass2d.hxx>
24#include <Geom2d_Curve.hxx>
25#include <Geom2d_TrimmedCurve.hxx>
26#include <Geom_Surface.hxx>
27#include <gp_Pnt.hxx>
28#include <gp_Pnt2d.hxx>
29#include <gp_Vec2d.hxx>
30#include <Precision.hxx>
31#include <TopExp.hxx>
32#include <TopExp_Explorer.hxx>
33#include <TopLoc_Location.hxx>
7fd59977 34#include <TopoDS.hxx>
42cf5bc1 35#include <TopoDS_Edge.hxx>
36#include <TopoDS_Face.hxx>
7fd59977 37#include <TopoDS_Shape.hxx>
7fd59977 38#include <TopoDS_Vertex.hxx>
39#include <TopoDS_Wire.hxx>
42cf5bc1 40#include <TopOpeBRepBuild_CorrectFace2d.hxx>
7fd59977 41#include <TopOpeBRepBuild_Tools2d.hxx>
42cf5bc1 42#include <TopTools_IndexedDataMapOfShapeShape.hxx>
7fd59977 43#include <TopTools_IndexedMapOfShape.hxx>
42cf5bc1 44#include <TopTools_ListIteratorOfListOfShape.hxx>
45#include <TopTools_ListOfShape.hxx>
7fd59977 46#include <TopTools_SequenceOfShape.hxx>
7fd59977 47
48//=======================================================================
49// function :TopOpeBRepBuild_CorrectFace2d::TopOpeBRepBuild_CorrectFace2d
50// purpose:
51//=======================================================================
b311480e 52TopOpeBRepBuild_CorrectFace2d::TopOpeBRepBuild_CorrectFace2d()
7fd59977 53{
54 myIsDone=Standard_False;
55 myErrorStatus=1;
56
57}
58//=======================================================================
59// function :TopOpeBRepBuild_CorrectFace2d::TopOpeBRepBuild_CorrectFace2d
60// purpose:
61//=======================================================================
62 TopOpeBRepBuild_CorrectFace2d::TopOpeBRepBuild_CorrectFace2d(const TopoDS_Face& aFace,
63 const TopTools_IndexedMapOfOrientedShape& anAvoidMap,
64 TopTools_IndexedDataMapOfShapeShape& aMap)
65{
66 myFace=aFace;
67 myAvoidMap=anAvoidMap;
68 myIsDone=Standard_False;
69 myErrorStatus=1;
70 myMap=(Standard_Address) &aMap;
71
72}
73//=======================================================================
74// function : TopOpeBRepBuild_CorrectFace2d::SetMapOfTrans2dInfo
75// purpose:
76//=======================================================================
77 void TopOpeBRepBuild_CorrectFace2d::SetMapOfTrans2dInfo (TopTools_IndexedDataMapOfShapeShape& aMap)
78{
79 myMap=(Standard_Address) &aMap;
80}
81
82//=======================================================================
83// function : TopOpeBRepBuild_CorrectFace2d::MapOfTrans2dInfo
84// purpose:
85//=======================================================================
86 TopTools_IndexedDataMapOfShapeShape& TopOpeBRepBuild_CorrectFace2d::MapOfTrans2dInfo ()
87{
88 return *(TopTools_IndexedDataMapOfShapeShape*) myMap;
89}
90//=======================================================================
91// function :TopOpeBRepBuild_CorrectFace2d::Face
92// purpose:
93//=======================================================================
94 const TopoDS_Face& TopOpeBRepBuild_CorrectFace2d::Face() const
95{
96 return myFace;
97}
98
99//=======================================================================
100// function :TopOpeBRepBuild_CorrectFace2d::IsDone
101// purpose:
102//=======================================================================
103 Standard_Boolean TopOpeBRepBuild_CorrectFace2d::IsDone() const
104{
105 return myIsDone;
106}
107//=======================================================================
108// function :TopOpeBRepBuild_CorrectFace2d::ErrorStatus
109// purpose:
110//=======================================================================
111 Standard_Integer TopOpeBRepBuild_CorrectFace2d::ErrorStatus() const
112{
113 return myErrorStatus;
114}
115//=======================================================================
116// function :TopOpeBRepBuild_CorrectFace2d::CorrectedFace
117// purpose:
118//=======================================================================
119 const TopoDS_Face& TopOpeBRepBuild_CorrectFace2d::CorrectedFace() const
120{
121 return myCorrectedFace;
122}
123//=======================================================================
124// function :TopOpeBRepBuild_CorrectFace2d::BuildCopyData
125// purpose:
126//=======================================================================
127 void TopOpeBRepBuild_CorrectFace2d::BuildCopyData(const TopoDS_Face& aFace,
128 const TopTools_IndexedMapOfOrientedShape& anAvoidMap,
129 TopoDS_Face& aCopyFace,
130 TopTools_IndexedMapOfOrientedShape& aCopyAvoidMap,
131 const Standard_Boolean aNeedToUsePMap)
132{
133 TopTools_IndexedDataMapOfShapeShape EdMap;
134
135 BRep_Builder BB;
136
137 TopTools_IndexedDataMapOfShapeShape* pMap=
138 (TopTools_IndexedDataMapOfShapeShape*) myMap;
139 //
140 // 1. Copy myFace =>> myCopyFace
141 TopoDS_Shape aLocalShape = aFace.EmptyCopied();
142 aCopyFace=TopoDS::Face(aLocalShape);
143 // aCopyFace=TopoDS::Face(aFace.EmptyCopied());
144
145 TopExp_Explorer anExpWires(aFace, TopAbs_WIRE);
146 for (; anExpWires.More(); anExpWires.Next()) {
147 const TopoDS_Wire& W=TopoDS::Wire(anExpWires.Current());
148
149 aLocalShape = W.EmptyCopied();
150 TopoDS_Wire aWire = TopoDS::Wire(aLocalShape);
151 // TopoDS_Wire aWire = TopoDS::Wire(W.EmptyCopied());
152
153 TopExp_Explorer anExpEdges(W, TopAbs_EDGE);
154 for (; anExpEdges.More(); anExpEdges.Next()) {
155 const TopoDS_Edge& E = TopoDS::Edge(anExpEdges.Current());
156
157 if (EdMap.Contains(E)) {
158 TopoDS_Shape anEdge = EdMap.ChangeFromKey(E);
159 anEdge.Orientation(E.Orientation());
160 BB.Add (aWire, anEdge);
161 continue;
162 }
163
164 if (aNeedToUsePMap) {
165 if (pMap->Contains(E)) {
166 TopoDS_Shape& anEdge=pMap->ChangeFromKey(E);
167 anEdge.Orientation(E.Orientation());
168 EdMap.Add(E, anEdge);
169 BB.Add (aWire, anEdge);
170 continue;
171 }
172 }
173
174 // add edges
175 aLocalShape = E.EmptyCopied();
176 TopoDS_Shape anEdge = TopoDS::Edge(aLocalShape);
177 // TopoDS_Shape anEdge = TopoDS::Edge(E.EmptyCopied());
178
179 EdMap.Add(E, anEdge);
180
181 TopExp_Explorer anExpVertices(E, TopAbs_VERTEX);
182 for (; anExpVertices.More(); anExpVertices.Next()) {
183 const TopoDS_Shape& aV=anExpVertices.Current();
184 BB.Add(anEdge, aV);
185 }
186
187 anEdge.Orientation(E.Orientation());
188 BB.Add (aWire, anEdge);
189 }
190 // Add wires
191 aWire.Orientation(W.Orientation());
192 EdMap.Add(W, aWire);
193
194 BB.Add (aCopyFace, aWire);
195 }
196
197 //
198 // 2. Copy myAvoidMap =>> myCopyAvoidMap
199 Standard_Integer i, aNb;
200 aNb=anAvoidMap.Extent();
201
202 for (i=1; i<=aNb; i++) {
203 const TopoDS_Shape& aSh=anAvoidMap(i);
204
205 if (EdMap.Contains (aSh)) {
206 TopoDS_Shape& aCopyShape=EdMap.ChangeFromKey(aSh);
207 aCopyShape.Orientation(aSh.Orientation());
208 aCopyAvoidMap.Add(aCopyShape);
209 }
210 }
211
212 //
213 // 3. Inversed EdMap
214 if (aNeedToUsePMap) {
215 aNb=EdMap.Extent();
216 myEdMapInversed.Clear();
217 for (i=1; i<=aNb; i++) {
218 const TopoDS_Shape& aSh =EdMap.FindKey(i);
219 const TopoDS_Shape& aShCopy=EdMap.FindFromIndex(i);
220 myEdMapInversed.Add (aShCopy, aSh);
221 }
222 }
223}
224//=======================================================================
225// function :TopOpeBRepBuild_CorrectFace2d::CheckFace
226// purpose:
227//=======================================================================
228 void TopOpeBRepBuild_CorrectFace2d::CheckFace()
229{
230 //
231 // I. Is the surface periodic
232 TopLoc_Location aLocF;
233 Handle(Geom_Surface) Surf = BRep_Tool::Surface(myCopyFace, aLocF);
234 if (!(Surf->IsUPeriodic() || Surf->IsVPeriodic())) {
235 myIsDone=Standard_True;
236 myErrorStatus=4;
237 return;
238 }
239
240 //modified by NIZHNY-MZV Mon Apr 24 11:29:56 2000
241 //don't treat torus surfaces
242 if(Surf->IsUPeriodic() && Surf->IsVPeriodic()) {
243 myIsDone=Standard_True;
244 myErrorStatus=4;
245 return;
246 }
247
248 //
249 // II. Has each wire at least one "licit" edge
250 TopTools_IndexedMapOfOrientedShape aVoidWires;
251 Standard_Integer i, aNbVoidWires, anEdgeExists=0, priz;
252 TopExp_Explorer aFExp,aWExp;
253 aFExp.Init (myCopyFace, TopAbs_WIRE);
254 for (; aFExp.More(); aFExp.Next()) {
255 const TopoDS_Shape& aWire=aFExp.Current();
256 if (myCopyAvoidMap.Contains(aWire)) {
257 anEdgeExists=1;
258 continue;
259 }
260
261 anEdgeExists=0;
262 aWExp.Init(aWire, TopAbs_EDGE);
263 for (; aWExp.More(); aWExp.Next()) {
264 TopoDS_Shape anEdge=aWExp.Current();
265 if (myCopyAvoidMap.Contains(anEdge)) {
266 anEdgeExists=1;
267 break;
268 }
269 }
270
271 if (!anEdgeExists) {
272 // This is the wire without any "Right" information
273 aVoidWires.Add(aWire);
274 }
275 }
276
277 // For Void Wires .
278 // We assume the first edge from the wire is non-movable edge
279 // PKV 24-Feb-2000
280 aNbVoidWires=aVoidWires.Extent();
281 for (i=1; i<=aNbVoidWires; i++) {
282 TopTools_IndexedMapOfShape aEM;
283 TopExp::MapShapes(aVoidWires(i), TopAbs_EDGE, aEM);
284 if (aEM.Extent())
285 myCopyAvoidMap.Add (aEM(1));
286 }
287
288 // III. Check all wires to know whether they are closed or not
289 aFExp.Init (myCopyFace, TopAbs_WIRE);
290 for (; aFExp.More(); aFExp.Next()) {
291 myCurrentWire = TopoDS::Wire(aFExp.Current());
292 priz=MakeRightWire ();
293 if (priz) {
294 // This myFace contais a wire (myCurrentWire) that is not closed.
295 myIsDone=Standard_True;
296 myErrorStatus=3;
297 return;
298 }
299 }
300
301 //
302 // VI. Check connectability wires in 2d
303 TopoDS_Face aCopyFace;
304 TopTools_IndexedMapOfOrientedShape aCopyAvoidMap;
305
306 // Coping data
307 BuildCopyData(myCopyFace, myCopyAvoidMap, aCopyFace, aCopyAvoidMap, Standard_False);
308
309 aFExp.Init (aCopyFace, TopAbs_WIRE);
310 for (; aFExp.More(); aFExp.Next()) {
311 myCurrentWire = TopoDS::Wire(aFExp.Current());
312 if (!aCopyAvoidMap.Contains(myCurrentWire)) {
313 priz=ConnectWire (aCopyFace, aCopyAvoidMap, Standard_True);
314 if (priz) {
315 myIsDone=Standard_True;
316 myErrorStatus=6;
317 return;
318 }
319 }
320 }
321
322 // Face seems to be OK
323}
324//=======================================================================
325// function : TopOpeBRepBuild_CorrectFace2d::ConnectWire
326// purpose:
327//=======================================================================
328 Standard_Integer TopOpeBRepBuild_CorrectFace2d::ConnectWire (TopoDS_Face& aCopyFace,
329 const TopTools_IndexedMapOfOrientedShape& aCopyAvoidMap,
330 const Standard_Boolean aTryFlag)
331{
332 BRep_Builder BB;
333 //
334 // 1.Make right order
335 Standard_Integer priz;
336 priz=MakeRightWire ();
337 if (priz) return priz;
338 //
339 // 2. Define the First Edge on the Wire from aCopyAvoidMap
340 Standard_Integer i, aNbEdges=0, aNbAvoidEdgesOnWire;
7fd59977 341 Standard_Real aDMax=0, aR;
342
343 TopExp_Explorer aWExp;
344 TopoDS_Edge aFEdge;
345 TopoDS_Shape aFirstEdge;
346 TopTools_IndexedMapOfOrientedShape anAvoidMap;
347
348 aWExp.Init(myCurrentWire, TopAbs_EDGE);
349 for (; aWExp.More(); aWExp.Next(), aNbEdges++) {
350 TopoDS_Shape anEdge=aWExp.Current();
351 if (aCopyAvoidMap.Contains(anEdge))
352 anAvoidMap.Add(anEdge);
353 }
354
355 if (aNbEdges==1) // nothing to do with this wire.
356 return 0;
357
358 aNbAvoidEdgesOnWire=anAvoidMap.Extent();
359 if (aNbAvoidEdgesOnWire==aNbEdges) // nothing to do. all edges on wire are good.
360 return 0;
361
362 // if at least one non-degenerated edge exists
363 // among anAvoidMap set it as aFirstEdge
364 priz=0;
365 for (i=1; i<=aNbAvoidEdgesOnWire; i++) {
366 const TopoDS_Edge& anEdge=TopoDS::Edge(anAvoidMap(i));
367 if (!BRep_Tool::Degenerated(anEdge)) {
368 aFirstEdge=anEdge;
369 priz=1;
370 break;
371 }
372 }
373
374
375 if (!priz) {
376 // All of anAvoidMap edges are degenerated
377 // So take the edge with max dist. between
378 //First and Last 2d points as the First edge
7fd59977 379 //if(aNbAvoidEdgesOnWire != 1)
380 // return 1; //in case of several degenerated edges we cannot connect wire by right way
381 for (i=1; i<=aNbAvoidEdgesOnWire; i++) {
382 gp_Pnt2d PF, PL;
383 const TopoDS_Edge& aDegenEdge=TopoDS::Edge(anAvoidMap(i));
384 GetP2dFL(aCopyFace, aDegenEdge, PF, PL);
385 aR=PF.Distance(PL);
386 if ((aR - aDMax) > 1e-7) {
387 aDMax=aR;
388 aFirstEdge=anAvoidMap(i);
389 }
390 }
391 }
392
393
394
395 //
396 // 3. Build HeadList (from myOrderedWireList), where aFirstEdge will be the first
397 TopTools_ListOfShape HeadList;
398 MakeHeadList(aFirstEdge, HeadList);
399 //
400 // 4. Check HeadList to provide toward point-arrow direction
401//modified by NIZNHY-PKV Mon Apr 24 14:43:20 2000 f
402 //CheckList (HeadList);
403 //modified by NIZNHY-PKV Tue Apr 25 12:08:29 2000CheckList (aCopyFace, HeadList);
404//modified by NIZNHY-PKV Mon Apr 24 14:43:24 2000t
405 //
406 // 5. Connect Edges
407 TopTools_IndexedMapOfShape anEdMap;
408 gp_Pnt2d PF, PL, PA, PB, PA1, PB1;
409 Handle(Geom2d_Curve) aTrCF, aTrCR, aTrC;
410 Standard_Real aD, aDTolerance=Precision::Confusion();
411
412 TopTools_SequenceOfShape aSeqEdges;
413
414 TopTools_ListIteratorOfListOfShape anIt;
415 anIt.Initialize(HeadList);
416 for (; anIt.More(); anIt.Next())
417 aSeqEdges.Append(anIt.Value());
418 aNbEdges=aSeqEdges.Length();
419
420 //
421 // First Edge
422 TopoDS_Edge aFstEdge=TopoDS::Edge(aSeqEdges(1));
423 GetP2dFL(aCopyFace, aFstEdge, PA, PB);
424 PA1=PA;
425 PB1=PB;
426
427 for (i=2; i<=aNbEdges; i++) {
428 TopoDS_Edge anEdge= TopoDS::Edge(aSeqEdges(i));
429 GetP2dFL(aCopyFace, anEdge, PF, PL);
430
431 aD=PF.Distance(PB);
432 if (aD<aDTolerance) {
433 PA=PF; PB=PL;
434 continue; // nothing to do with the edge cose it already connected
435 }
436
437 // tralslation's vector
438 gp_Vec2d aTrV(PF, PB);
439
440 //Begin modified by NIZHNY-MZV Mon Mar 27 16:04:04 2000
441 //translation vector must be equal to 2PI*n or it is wrong wire
442 Standard_Real U = aTrV.X();
443 Standard_Real V = aTrV.Y();
444
445 BRepAdaptor_Surface BAS(aCopyFace);
446 Standard_Boolean UP = BAS.IsUPeriodic();
447 Standard_Boolean VP = BAS.IsVPeriodic();
448
449 Standard_Boolean nonPU = (fabs(U) < 1e-7) ? Standard_True : Standard_False;
450 Standard_Boolean nonPV = (fabs(V) < 1e-7) ? Standard_True : Standard_False;
451
452 if(!nonPU && UP) {
c6541a0c
D
453 Standard_Real dU = fmod(fabs(U), 2*M_PI);
454 nonPU = (dU > 1e-7 && (2*M_PI - dU > 1e-7)) ? Standard_True : Standard_False;
7fd59977 455 }
456
457 if(!nonPV && VP) {
c6541a0c
D
458 Standard_Real dV = fmod(fabs(V), 2*M_PI);
459 nonPV = (dV > 1e-7 && (2*M_PI - dV > 1e-7)) ? Standard_True : Standard_False;
7fd59977 460 }
461
c6541a0c
D
462// printf("(fmod(fabs(U), 2*M_PI) =%lf\n", (fmod(fabs(U), 2*M_PI)));
463// printf(" (fmod(fabs(V), 2*M_PI) > 1e-7)=%lf\n", (fmod(fabs(V), 2*M_PI)));
7fd59977 464
465 if(nonPU && nonPV && !BRep_Tool::Degenerated(anEdge))
466 return 1;
467 //End modified by NIZHNY-MZV Mon Mar 27 16:04:11 2000
468
469 if (BRep_Tool::IsClosed(anEdge, aCopyFace)) {
470 // a. Closed edge <--->
471 if (anEdMap.Contains(anEdge)) continue;
472 anEdMap.Add(anEdge);
473
474 TopAbs_Orientation anOri = anEdge.Orientation();
475
476 TopoDS_Edge anEF, anER;
477 if (anOri==TopAbs_FORWARD) {
478 anEF=anEdge;
479 TopoDS_Shape aLocalShape = anEdge.Reversed();
480 anER=TopoDS::Edge(aLocalShape);
481 // anER=TopoDS::Edge(anEdge.Reversed());
482 }
483
484 else {
485 anER=anEdge;
486 TopoDS_Shape aLocalShape = anEdge.Reversed();
487 anEF=TopoDS::Edge(aLocalShape);
488 // anEF=TopoDS::Edge(anEdge.Reversed());
489 }
490
491 TranslateCurve2d (anEF, aCopyFace, aTrV, aTrCF);
492 TranslateCurve2d (anER, aCopyFace, aTrV, aTrCR);
493
494 if (aTryFlag) // Use Builder in a trying case
495 BB.UpdateEdge(anEdge, aTrCF, aTrCR, aCopyFace, myFaceTolerance);
496
497 else // Use "False-Builder" otherwise
498 UpdateEdge(anEdge, aTrCF, aTrCR, aCopyFace, myFaceTolerance);
499
500 }
501
502 else {
503 // b. Usual Edge
504 TranslateCurve2d (anEdge, aCopyFace, aTrV, aTrC);
505
506 if (aTryFlag)
507 BB.UpdateEdge(anEdge, aTrC, aCopyFace, myFaceTolerance);
508 else
509 UpdateEdge(anEdge, aTrC, aCopyFace, myFaceTolerance);
510 }
511
512 GetP2dFL(aCopyFace, anEdge, PF, PL);
513
514 PA=PF;
515 PB=PL;
516
517 ////////////////////////////////////////////
518 // In case of a trying we check the first
519 // and last 2d point of the contour
520 if (aTryFlag) {
521 if (i==aNbEdges) {
522 aD=PA1.Distance(PB);
523 if (aD>aDTolerance)
524 return 1;
525 }
526 }
527 ////////////////////////////////////////////
528
529 } //end of for (i=2; i<=aNbEdges; i++)
530
531 return 0;
532}
533
534
535//=======================================================================
536// function :TopOpeBRepBuild_CorrectFace2d::Perform
537// purpose:
538//=======================================================================
539 void TopOpeBRepBuild_CorrectFace2d::Perform()
540{
541 /////////////
542 // 0.
543 myCopyAvoidMap.Clear();
544 BuildCopyData(myFace, myAvoidMap, myCopyFace, myCopyAvoidMap, Standard_True);
545 /////////////
546
547 myCorrectedFace=myCopyFace;
548 myCorrectedFace.Orientation(myCopyFace.Orientation());
549 myFaceTolerance=BRep_Tool::Tolerance(myCopyFace);
550 //
551 // 1. Check the input face first
552 CheckFace ();
553 if (myIsDone)
554 return ;
555
556 //
557 // 2. Make all wires connected
558 Standard_Integer priz;
559 TopExp_Explorer aFExp;
560
561 aFExp.Init (myCopyFace, TopAbs_WIRE);
562 for (; aFExp.More(); aFExp.Next()) {
563 myCurrentWire = TopoDS::Wire(aFExp.Current());
564 if (!myCopyAvoidMap.Contains(myCurrentWire)) {
565 priz=ConnectWire (myCopyFace, myCopyAvoidMap, Standard_False);
566 if (priz) {
567 // This myFace contais a wire (myCurrentWire) that is not closed.
568 myIsDone=Standard_False;
569 myErrorStatus=3;
570 return;
571 }
572 }
573 }
574 //
575 // 3. Define Outer Wire
576 TopoDS_Wire anOuterWire;
577 priz=OuterWire (anOuterWire);
578 if (priz) {
579 myIsDone=Standard_False;
580 myErrorStatus=5; // can't find outer wire
581 return;
582 }
583 //
584 // 4. Moving the anOuterWire and other wires in 2d space
585 MoveWires2d(anOuterWire);
586
587 myIsDone=Standard_True;
588 myErrorStatus=0;
589}
590
591//=======================================================================
592// function : TopOpeBRepBuild_CorrectFace2d::MakeRightWire
593// purpose:
594//=======================================================================
595 Standard_Integer TopOpeBRepBuild_CorrectFace2d::MakeRightWire ()
596{
597 Standard_Integer aNbEdgesReally=0;
598 myOrderedWireList.Clear();
599
600 //1. Real amount of the edges on aWire
601 TopExp_Explorer aWExp;
602 aWExp.Init(myCurrentWire, TopAbs_EDGE);
603 for (; aWExp.More(); aWExp.Next()) aNbEdgesReally++;
604
605 //2. We'll use TopOpeBRepBuild_Tools::Path
606 TopTools_ListOfShape aL;
607 TopOpeBRepBuild_Tools2d::Path (myCurrentWire, aL);
608 if (aL.Extent()!=aNbEdgesReally) {
609 myErrorStatus=4;
610 return 1;
611 }
612
613 //Begin modified by NIZNHY-PKV Tue Apr 25 12:04:45 2000
614 //from path we obtained list in reverse order, so to have right wire
615 //we need to reverse it
616 TopTools_ListOfShape aFL;
617 TopTools_ListIteratorOfListOfShape lit(aL);
618 for(; lit.More(); lit.Next())
619 aFL.Prepend(lit.Value());
620
621 myOrderedWireList=aFL;
622 //End modified by NIZNHY-PKV Tue Apr 25 12:06:45 2000
623 return 0;
624}
625
626//=======================================================================
627// function : TopOpeBRepBuild_CorrectFace2d::GetP2dFL
628// purpose:
629//=======================================================================
630 void TopOpeBRepBuild_CorrectFace2d::GetP2dFL (const TopoDS_Face& aF, const TopoDS_Edge& anEdge,
631 gp_Pnt2d& P2dF, gp_Pnt2d& P2dL)
632{
633 Standard_Real aFirst, aLast;
634 const Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (anEdge, aF, aFirst, aLast);
635 C2d->D0 (aFirst, P2dF);
636 C2d->D0 (aLast , P2dL);
637 if (anEdge.Orientation()==TopAbs_REVERSED) {
638 gp_Pnt2d P2dTmp;
639 P2dTmp=P2dF; P2dF=P2dL; P2dL=P2dTmp;
640 }
641}
642
643
644//=======================================================================
645// function :TopOpeBRepBuild_CorrectFace2d::MakeHeadList
646// purpose:
647//=======================================================================
648 void TopOpeBRepBuild_CorrectFace2d::MakeHeadList(const TopoDS_Shape& aFirstEdge,
649 TopTools_ListOfShape& HeadList) const
650{
651 TopoDS_Shape aFE = aFirstEdge;
652 TopTools_ListOfShape aTailList;
653 TopTools_ListIteratorOfListOfShape anIt;
654 Standard_Integer aFlag=0;
655
656 anIt.Initialize(myOrderedWireList);
657 for (; anIt.More(); anIt.Next()) {
658 const TopoDS_Shape& anEdge=anIt.Value();
659 //modified by NIZHNY-MZV Mon Mar 27 11:40:00 2000
660 if(aFE.IsNull() && !BRep_Tool::Degenerated(TopoDS::Edge(anEdge)))
661 aFE = anEdge;
662 if (anEdge==aFE) aFlag=1; //turn the switch ON
663 if (aFlag) HeadList.Append(anEdge);
664 }
665
666 anIt.Initialize(myOrderedWireList);
667 for (; anIt.More(); anIt.Next()) {
668 const TopoDS_Shape& anEdge=anIt.Value();
669 if (anEdge==aFE) break;
670 aTailList.Append(anEdge);
671 }
672 HeadList.Append(aTailList);
673}
674//=======================================================================
675// function :TopOpeBRepBuild_CorrectFace2d::CheckList
676// purpose:
677//=======================================================================
678 void TopOpeBRepBuild_CorrectFace2d::CheckList (const TopoDS_Face& aFace,
679 TopTools_ListOfShape& HeadList)
680{
96a95605 681 TopAbs_Orientation r1;
7fd59977 682 Standard_Real aDTolerance=Precision::Confusion();
683 TopTools_SequenceOfShape aSeq;
684 TopTools_ListIteratorOfListOfShape anIt(HeadList);
685 for (; anIt.More(); anIt.Next()) {
686 aSeq.Append(anIt.Value());
687 }
688
689 r1=aSeq(1).Orientation();
7fd59977 690 Standard_Integer i, aNb=aSeq.Length();
691//modified by NIZNHY-PKV Mon Apr 24 14:43:57 2000f
692 Standard_Boolean aFirstCheck=Standard_False;
693 if (r1==TopAbs_REVERSED ) {
694 // when the orientation of the first edge is Revesed,
695 // and when everything in 2d is Ok :
696 // if at least one Forward edge exists in the List
697 // we consider that no necessity to reverse
698 // the list (aFirstCheck=Standard_True) .
699
700 Standard_Real aD;
701 gp_Pnt2d PF, PL, PA, PB;
702
703
704 TopoDS_Edge aFstEdge=TopoDS::Edge(aSeq(1));
705 GetP2dFL(aFace, aFstEdge, PA, PB);
706 for (i=2; i<=aNb; i++) {
707 TopoDS_Edge anEdge= TopoDS::Edge(aSeq(i));
708 GetP2dFL(aFace, anEdge, PF, PL);
709
710 aD=PF.Distance(PB);
711 if (aD<aDTolerance) {
712 PA=PF; PB=PL;
713 if (anEdge.Orientation()==TopAbs_FORWARD) {
714 aFirstCheck=Standard_True;
715 break;
716 }
717 }
718 }
719 }
720//modified by NIZNHY-PKV Mon Apr 24 14:43:59 2000t
721
722 r1=aSeq(1).Orientation();
7fd59977 723
724 TopoDS_Vertex aV1R, aV2F;
725
726 TopoDS_Edge aFirstEdge=TopoDS::Edge(aSeq(1));
727 TopExp_Explorer anExp;
728 anExp.Init (aFirstEdge, TopAbs_VERTEX);
729 for (; anExp.More(); anExp.Next()) {
730 const TopoDS_Shape& aV1=anExp.Current();
731 if (aV1.Orientation()==TopAbs_REVERSED){
732 aV1R=TopoDS::Vertex(aV1);
733 break;
734 }
735 }
736
737 TopoDS_Edge aSecondEdge=TopoDS::Edge(aSeq(2));
738 anExp.Init (aSecondEdge, TopAbs_VERTEX);
739 for (; anExp.More(); anExp.Next()) {
740 const TopoDS_Shape& aV1=anExp.Current();
741 if (aV1.Orientation()==TopAbs_FORWARD){
742 aV2F=TopoDS::Vertex(aV1);
743 break;
744 }
745 }
746
747 gp_Pnt P1, P2;
748 P1=BRep_Tool::Pnt(aV1R);
749 P2=BRep_Tool::Pnt(aV2F);
750
751
752 //modified by NIZNHY-PKV Mon Apr 24 13:24:06 2000 f
753 Standard_Real dist=P1.Distance(P2);
754 if (
755 (!(dist < aDTolerance) && r1==TopAbs_FORWARD)||
756 //(r1==TopAbs_REVERSED)) {
757 (!aFirstCheck && r1==TopAbs_REVERSED)
758 ) {
759 //modified by NIZNHY-PKV Mon Apr 24 14:28:06 2000 t
760 // We have to reverse the order in list
761 aSeq.Append(aFirstEdge);
762 HeadList.Clear();
763 aNb=aSeq.Length();
764 for (i=aNb; i>1; i--) {
765 HeadList.Append(aSeq(i));
766 }
767 }
768}
769
770//=======================================================================
771// function :TopOpeBRepBuild_CorrectFace2d::TranslateCurve2d
772// purpose:
773//=======================================================================
774 void TopOpeBRepBuild_CorrectFace2d::TranslateCurve2d(const TopoDS_Edge& anE,
775 const TopoDS_Face& aFace,
776 const gp_Vec2d& aTrV,
777 Handle(Geom2d_Curve)& aC2DOut)
778{
779 Standard_Real aFirst, aLast;
780 Handle(Geom2d_Curve) C2d=BRep_Tool::CurveOnSurface (anE, aFace, aFirst, aLast);
781 Handle(Geom2d_Curve) aTrC;
782 aTrC = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
783 Handle(Geom2d_TrimmedCurve) newC2D = new Geom2d_TrimmedCurve(aTrC, aFirst, aLast);
784 newC2D -> Translate(aTrV);
785 aC2DOut=newC2D;
786}
787//=======================================================================
788// function :TopOpeBRepBuild_CorrectFace2d::OuterWire
789// purpose:
790//=======================================================================
791 Standard_Integer TopOpeBRepBuild_CorrectFace2d::OuterWire(TopoDS_Wire& anOuterWire) const
792{
793 TopLoc_Location Loc;
794 Handle(Geom_Surface) Surf = BRep_Tool::Surface(TopoDS::Face(myCorrectedFace), Loc);
795
796 TopExp_Explorer ex(myCorrectedFace, TopAbs_WIRE);
797 for (; ex.More(); ex.Next()) {
798 const TopoDS_Wire& aWire=TopoDS::Wire(ex.Current());
799
800 TopoDS_Face newFace;
801 BRep_Builder BB;
802 BB.MakeFace(newFace, Surf, Loc, myFaceTolerance);
803 BB.Add(newFace, aWire);
804
805 BRepTopAdaptor_FClass2d aClass2d(newFace, myFaceTolerance);
806 TopAbs_State aState=aClass2d.PerformInfinitePoint();
807 if (aState==TopAbs_OUT) {
808 anOuterWire=aWire;
809 return 0;
810 }
811 }
812 return 1; // such wire is not found
813}
814
815//=======================================================================
816// function :TopOpeBRepBuild_CorrectFace2d::BndBoxWire
817// purpose:
818//=======================================================================
819 void TopOpeBRepBuild_CorrectFace2d::BndBoxWire(const TopoDS_Wire& aWire,
820 Bnd_Box2d& B2d) const
821{
822 Bnd_Box2d aB2d;
823 TopExp_Explorer aWEx (aWire, TopAbs_EDGE);
824 for (; aWEx.More(); aWEx.Next()) {
825 const TopoDS_Edge& anEdge = TopoDS::Edge(aWEx.Current());
826 Standard_Real aTolE = BRep_Tool::Tolerance(anEdge);
827 BRepAdaptor_Curve2d aBAC2d (anEdge,myCorrectedFace);
828 BndLib_Add2dCurve::Add(aBAC2d, aTolE, aB2d);
829 }
830 B2d=aB2d;
831}
832
833//=======================================================================
834// function : TopOpeBRepBuild_CorrectFace2d::MoveWire2d
835// purpose:
836//=======================================================================
837 void TopOpeBRepBuild_CorrectFace2d::MoveWire2d (TopoDS_Wire& aWire,
838 const gp_Vec2d& aTrV)
839{
840 if (aTrV.Magnitude()<Precision::Confusion())
841 return;
842
843 Standard_Integer i, aNbEdges;
844 TopTools_SequenceOfShape aSeqEdges;
845 TopTools_IndexedMapOfShape anEdMap;
846 Handle(Geom2d_Curve) aTrCF, aTrCR, aTrC;
847
848 TopExp_Explorer aWExp;
849
850 aWExp.Init(aWire, TopAbs_EDGE);
851 for (; aWExp.More(); aWExp.Next()) {
852 aSeqEdges.Append(aWExp.Current());
853 }
854 aNbEdges=aSeqEdges.Length();
855
856 //
857 // First Edge
858 for (i=1; i<=aNbEdges; i++) {
859 TopoDS_Edge anEdge= TopoDS::Edge(aSeqEdges(i));
860 if (BRep_Tool::IsClosed(anEdge, myCorrectedFace)) {
861 // a. Closed edge <--->
862 if (anEdMap.Contains(anEdge)) continue;
863 anEdMap.Add(anEdge);
864
865 TopAbs_Orientation anOri = anEdge.Orientation();
866
867 TopoDS_Edge anEF, anER;
868
869 if (anOri==TopAbs_FORWARD) {
870 anEF=anEdge;
871 TopoDS_Shape aLocalShape = anEdge.Reversed();
872 anER=TopoDS::Edge(aLocalShape);
873 // anER=TopoDS::Edge(anEdge.Reversed());
874 }
875
876 else {
877 anER=anEdge;
878 TopoDS_Shape aLocalShape = anEdge.Reversed();
879 anEF=TopoDS::Edge(aLocalShape);
880 // anEF=TopoDS::Edge(anEdge.Reversed());
881 }
882
883 TranslateCurve2d (anEF, myCorrectedFace, aTrV, aTrCF);
884 TranslateCurve2d (anER, myCorrectedFace, aTrV, aTrCR);
885 UpdateEdge(anEdge, aTrCF, aTrCR, myCorrectedFace, myFaceTolerance);
886 }
887
888 else {
889 // b. Usual Edge
890 TranslateCurve2d (anEdge, myCorrectedFace, aTrV, aTrC);
891 UpdateEdge(anEdge, aTrC, myCorrectedFace, myFaceTolerance);
892 }
893 } //end of for (i=1; i<=aNbEdges; i++)
894}
895//=======================================================================
896// function : TopOpeBRepBuild_CorrectFace2d::MoveWires2d
897// purpose:
898//=======================================================================
899 void TopOpeBRepBuild_CorrectFace2d::MoveWires2d (TopoDS_Wire& anOuterWire)
900{
901 Bnd_Box2d B2d, B2dOuterWire;
902 Standard_Real OuterU1,OuterV1,OuterU2,OuterV2, x, a, TwoPI;
903 Standard_Integer b, k;
904 gp_Vec2d aTrV;
905
c6541a0c 906 TwoPI=2.*M_PI;
7fd59977 907
908 BndBoxWire(anOuterWire, B2dOuterWire);
909 B2dOuterWire.Get(OuterU1,OuterV1,OuterU2,OuterV2);
910
911 a=.5*(OuterU1+OuterU2);
912 b=Standard_Integer(-a/TwoPI);
913 k=(a<0.)? 1 : 0;
914 x=(b+k)*TwoPI;
915 //
916 // 1. Move the Outer Wire to [0, 2*PI]
917 aTrV.SetCoord (x, 0.);
918 MoveWire2d (anOuterWire, aTrV);
919
920 BndBoxWire(anOuterWire, B2dOuterWire);
921 B2dOuterWire.Get(OuterU1,OuterV1,OuterU2,OuterV2);
922 //
923 // 2. Move all other wires into bounding box of the Outer Wire
924 TopExp_Explorer aFExp;
925 aFExp.Init (myCorrectedFace, TopAbs_WIRE);
926 for (; aFExp.More(); aFExp.Next()) {
927 myCurrentWire = TopoDS::Wire(aFExp.Current());
928 if (myCurrentWire!=anOuterWire) {
929 BndBoxWire(myCurrentWire, B2d);
930 Standard_Real u1,v1,u2,v2;
931 B2d.Get(u1,v1,u2,v2);
932
933 if (B2d.IsOut(B2dOuterWire)) {
934 //printf(" Need to Move\n" );
935 a=u1-OuterU1;
936 b=Standard_Integer(-a/TwoPI);
937 k= (a<0.) ? 1 : 0;
938 x=(b+k)*TwoPI;
939 aTrV.SetCoord (x, 0.);
940 MoveWire2d (myCurrentWire, aTrV);
941 }
942 }
943 }
944}
945//=======================================================================
946// function : TopOpeBRepBuild_CorrectFace2d::UpdateEdge
947// purpose:
948//=======================================================================
949 void TopOpeBRepBuild_CorrectFace2d::UpdateEdge (const TopoDS_Edge& ECopy,
950 const Handle(Geom2d_Curve)& C,
951 const TopoDS_Face& F,
952 const Standard_Real Tol)
953{
954 BRep_Builder BB;
955
956 TopTools_IndexedDataMapOfShapeShape* pMap=
957 (TopTools_IndexedDataMapOfShapeShape*) myMap;
958
959 // E is the Original Edge from Original Face.
960 if (myEdMapInversed.Contains(ECopy)) {
961 const TopoDS_Shape& E=myEdMapInversed.FindFromKey(ECopy);
962
963 if (!pMap->Contains(E)) {
964 TopExp_Explorer anExp;
965
966 TopoDS_Shape anEdge=E.EmptyCopied();
967
968 anExp.Init(E, TopAbs_VERTEX);
969 for (; anExp.More(); anExp.Next()) {
970 const TopoDS_Shape& aV=anExp.Current();
971 BB.Add(anEdge, aV);
972 }
973
974 BB.UpdateEdge(TopoDS::Edge(anEdge), C, F, Tol);
975 pMap->Add(E, anEdge);
976 //printf("pMap->Extent()=%d\n", pMap->Extent());
977 }
978
979 else {
980 TopoDS_Shape& anEdge=pMap->ChangeFromKey(E);
981 BB.UpdateEdge(TopoDS::Edge(anEdge), C, F, Tol);
982 }
983 }
984
985 BB.UpdateEdge (ECopy, C, F, Tol);
986}
987
988
989//=======================================================================
990// function : TopOpeBRepBuild_CorrectFace2d::UpdateEdge
991// purpose:
992//=======================================================================
993 void TopOpeBRepBuild_CorrectFace2d::UpdateEdge (const TopoDS_Edge& ECopy,
994 const Handle(Geom2d_Curve)& C1,
995 const Handle(Geom2d_Curve)& C2,
996 const TopoDS_Face& F,
997 const Standard_Real Tol)
998{
999 BRep_Builder BB;
1000
1001 TopTools_IndexedDataMapOfShapeShape* pMap=
1002 (TopTools_IndexedDataMapOfShapeShape*) myMap;
1003
1004 // E is the Original Edge from Original Face.
1005 if (myEdMapInversed.Contains(ECopy)) {
1006 const TopoDS_Shape& E=myEdMapInversed.FindFromKey(ECopy);
1007
1008 if (!pMap->Contains(E)) {
1009 TopoDS_Shape anEdge=E.EmptyCopied();
1010 TopExp_Explorer anExp;
1011 anExp.Init(E, TopAbs_VERTEX);
1012 for (; anExp.More(); anExp.Next()) {
1013 const TopoDS_Shape& aV=anExp.Current();
1014 BB.Add(anEdge, aV);
1015 }
1016 BB.UpdateEdge(TopoDS::Edge(anEdge), C1, C2, F, Tol);
1017 pMap->Add(E, anEdge);
1018 //printf("pMap->Extent()=%d\n", pMap->Extent());
1019 }
1020
1021 else {
1022 TopoDS_Shape& anEdge=pMap->ChangeFromKey(E);
1023 BB.UpdateEdge(TopoDS::Edge(anEdge), C1, C2, F, Tol);
1024 }
1025 }
1026
1027 BB.UpdateEdge (ECopy, C1, C2, F, Tol);
1028}
1029
1030//
1031// Description for ErrorStatus
1032// ErrorStatus=0 : All is done;
1033// ErrorStatus=1 : Nothing is done;
1034// ErrorStatus=2 : The wire doesn't contain any licit edges and the wire is not closed;
1035// ErrorStatus=3 : The face contains a wire that is not connectable
1036// ErrorStatus=4 : The base surface is not periodic;
1037// ErrorStatus=5 : an outer wir can not be found;
1038// ErrorStatus=6 : Wrong connectability of a wire in 2d
1039