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