0024511: Remove obsolete Image_PixelAddress.cxx
[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;
347 Standard_Boolean IsAllAvoidEdgesDegenerated=Standard_False;
348 Standard_Real aDMax=0, aR;
349
350 TopExp_Explorer aWExp;
351 TopoDS_Edge aFEdge;
352 TopoDS_Shape aFirstEdge;
353 TopTools_IndexedMapOfOrientedShape anAvoidMap;
354
355 aWExp.Init(myCurrentWire, TopAbs_EDGE);
356 for (; aWExp.More(); aWExp.Next(), aNbEdges++) {
357 TopoDS_Shape anEdge=aWExp.Current();
358 if (aCopyAvoidMap.Contains(anEdge))
359 anAvoidMap.Add(anEdge);
360 }
361
362 if (aNbEdges==1) // nothing to do with this wire.
363 return 0;
364
365 aNbAvoidEdgesOnWire=anAvoidMap.Extent();
366 if (aNbAvoidEdgesOnWire==aNbEdges) // nothing to do. all edges on wire are good.
367 return 0;
368
369 // if at least one non-degenerated edge exists
370 // among anAvoidMap set it as aFirstEdge
371 priz=0;
372 for (i=1; i<=aNbAvoidEdgesOnWire; i++) {
373 const TopoDS_Edge& anEdge=TopoDS::Edge(anAvoidMap(i));
374 if (!BRep_Tool::Degenerated(anEdge)) {
375 aFirstEdge=anEdge;
376 priz=1;
377 break;
378 }
379 }
380
381
382 if (!priz) {
383 // All of anAvoidMap edges are degenerated
384 // So take the edge with max dist. between
385 //First and Last 2d points as the First edge
386 IsAllAvoidEdgesDegenerated=Standard_True;
387 //if(aNbAvoidEdgesOnWire != 1)
388 // return 1; //in case of several degenerated edges we cannot connect wire by right way
389 for (i=1; i<=aNbAvoidEdgesOnWire; i++) {
390 gp_Pnt2d PF, PL;
391 const TopoDS_Edge& aDegenEdge=TopoDS::Edge(anAvoidMap(i));
392 GetP2dFL(aCopyFace, aDegenEdge, PF, PL);
393 aR=PF.Distance(PL);
394 if ((aR - aDMax) > 1e-7) {
395 aDMax=aR;
396 aFirstEdge=anAvoidMap(i);
397 }
398 }
399 }
400
401
402
403 //
404 // 3. Build HeadList (from myOrderedWireList), where aFirstEdge will be the first
405 TopTools_ListOfShape HeadList;
406 MakeHeadList(aFirstEdge, HeadList);
407 //
408 // 4. Check HeadList to provide toward point-arrow direction
409//modified by NIZNHY-PKV Mon Apr 24 14:43:20 2000 f
410 //CheckList (HeadList);
411 //modified by NIZNHY-PKV Tue Apr 25 12:08:29 2000CheckList (aCopyFace, HeadList);
412//modified by NIZNHY-PKV Mon Apr 24 14:43:24 2000t
413 //
414 // 5. Connect Edges
415 TopTools_IndexedMapOfShape anEdMap;
416 gp_Pnt2d PF, PL, PA, PB, PA1, PB1;
417 Handle(Geom2d_Curve) aTrCF, aTrCR, aTrC;
418 Standard_Real aD, aDTolerance=Precision::Confusion();
419
420 TopTools_SequenceOfShape aSeqEdges;
421
422 TopTools_ListIteratorOfListOfShape anIt;
423 anIt.Initialize(HeadList);
424 for (; anIt.More(); anIt.Next())
425 aSeqEdges.Append(anIt.Value());
426 aNbEdges=aSeqEdges.Length();
427
428 //
429 // First Edge
430 TopoDS_Edge aFstEdge=TopoDS::Edge(aSeqEdges(1));
431 GetP2dFL(aCopyFace, aFstEdge, PA, PB);
432 PA1=PA;
433 PB1=PB;
434
435 for (i=2; i<=aNbEdges; i++) {
436 TopoDS_Edge anEdge= TopoDS::Edge(aSeqEdges(i));
437 GetP2dFL(aCopyFace, anEdge, PF, PL);
438
439 aD=PF.Distance(PB);
440 if (aD<aDTolerance) {
441 PA=PF; PB=PL;
442 continue; // nothing to do with the edge cose it already connected
443 }
444
445 // tralslation's vector
446 gp_Vec2d aTrV(PF, PB);
447
448 //Begin modified by NIZHNY-MZV Mon Mar 27 16:04:04 2000
449 //translation vector must be equal to 2PI*n or it is wrong wire
450 Standard_Real U = aTrV.X();
451 Standard_Real V = aTrV.Y();
452
453 BRepAdaptor_Surface BAS(aCopyFace);
454 Standard_Boolean UP = BAS.IsUPeriodic();
455 Standard_Boolean VP = BAS.IsVPeriodic();
456
457 Standard_Boolean nonPU = (fabs(U) < 1e-7) ? Standard_True : Standard_False;
458 Standard_Boolean nonPV = (fabs(V) < 1e-7) ? Standard_True : Standard_False;
459
460 if(!nonPU && UP) {
c6541a0c
D
461 Standard_Real dU = fmod(fabs(U), 2*M_PI);
462 nonPU = (dU > 1e-7 && (2*M_PI - dU > 1e-7)) ? Standard_True : Standard_False;
7fd59977 463 }
464
465 if(!nonPV && VP) {
c6541a0c
D
466 Standard_Real dV = fmod(fabs(V), 2*M_PI);
467 nonPV = (dV > 1e-7 && (2*M_PI - dV > 1e-7)) ? Standard_True : Standard_False;
7fd59977 468 }
469
c6541a0c
D
470// printf("(fmod(fabs(U), 2*M_PI) =%lf\n", (fmod(fabs(U), 2*M_PI)));
471// printf(" (fmod(fabs(V), 2*M_PI) > 1e-7)=%lf\n", (fmod(fabs(V), 2*M_PI)));
7fd59977 472
473 if(nonPU && nonPV && !BRep_Tool::Degenerated(anEdge))
474 return 1;
475 //End modified by NIZHNY-MZV Mon Mar 27 16:04:11 2000
476
477 if (BRep_Tool::IsClosed(anEdge, aCopyFace)) {
478 // a. Closed edge <--->
479 if (anEdMap.Contains(anEdge)) continue;
480 anEdMap.Add(anEdge);
481
482 TopAbs_Orientation anOri = anEdge.Orientation();
483
484 TopoDS_Edge anEF, anER;
485 if (anOri==TopAbs_FORWARD) {
486 anEF=anEdge;
487 TopoDS_Shape aLocalShape = anEdge.Reversed();
488 anER=TopoDS::Edge(aLocalShape);
489 // anER=TopoDS::Edge(anEdge.Reversed());
490 }
491
492 else {
493 anER=anEdge;
494 TopoDS_Shape aLocalShape = anEdge.Reversed();
495 anEF=TopoDS::Edge(aLocalShape);
496 // anEF=TopoDS::Edge(anEdge.Reversed());
497 }
498
499 TranslateCurve2d (anEF, aCopyFace, aTrV, aTrCF);
500 TranslateCurve2d (anER, aCopyFace, aTrV, aTrCR);
501
502 if (aTryFlag) // Use Builder in a trying case
503 BB.UpdateEdge(anEdge, aTrCF, aTrCR, aCopyFace, myFaceTolerance);
504
505 else // Use "False-Builder" otherwise
506 UpdateEdge(anEdge, aTrCF, aTrCR, aCopyFace, myFaceTolerance);
507
508 }
509
510 else {
511 // b. Usual Edge
512 TranslateCurve2d (anEdge, aCopyFace, aTrV, aTrC);
513
514 if (aTryFlag)
515 BB.UpdateEdge(anEdge, aTrC, aCopyFace, myFaceTolerance);
516 else
517 UpdateEdge(anEdge, aTrC, aCopyFace, myFaceTolerance);
518 }
519
520 GetP2dFL(aCopyFace, anEdge, PF, PL);
521
522 PA=PF;
523 PB=PL;
524
525 ////////////////////////////////////////////
526 // In case of a trying we check the first
527 // and last 2d point of the contour
528 if (aTryFlag) {
529 if (i==aNbEdges) {
530 aD=PA1.Distance(PB);
531 if (aD>aDTolerance)
532 return 1;
533 }
534 }
535 ////////////////////////////////////////////
536
537 } //end of for (i=2; i<=aNbEdges; i++)
538
539 return 0;
540}
541
542
543//=======================================================================
544// function :TopOpeBRepBuild_CorrectFace2d::Perform
545// purpose:
546//=======================================================================
547 void TopOpeBRepBuild_CorrectFace2d::Perform()
548{
549 /////////////
550 // 0.
551 myCopyAvoidMap.Clear();
552 BuildCopyData(myFace, myAvoidMap, myCopyFace, myCopyAvoidMap, Standard_True);
553 /////////////
554
555 myCorrectedFace=myCopyFace;
556 myCorrectedFace.Orientation(myCopyFace.Orientation());
557 myFaceTolerance=BRep_Tool::Tolerance(myCopyFace);
558 //
559 // 1. Check the input face first
560 CheckFace ();
561 if (myIsDone)
562 return ;
563
564 //
565 // 2. Make all wires connected
566 Standard_Integer priz;
567 TopExp_Explorer aFExp;
568
569 aFExp.Init (myCopyFace, TopAbs_WIRE);
570 for (; aFExp.More(); aFExp.Next()) {
571 myCurrentWire = TopoDS::Wire(aFExp.Current());
572 if (!myCopyAvoidMap.Contains(myCurrentWire)) {
573 priz=ConnectWire (myCopyFace, myCopyAvoidMap, Standard_False);
574 if (priz) {
575 // This myFace contais a wire (myCurrentWire) that is not closed.
576 myIsDone=Standard_False;
577 myErrorStatus=3;
578 return;
579 }
580 }
581 }
582 //
583 // 3. Define Outer Wire
584 TopoDS_Wire anOuterWire;
585 priz=OuterWire (anOuterWire);
586 if (priz) {
587 myIsDone=Standard_False;
588 myErrorStatus=5; // can't find outer wire
589 return;
590 }
591 //
592 // 4. Moving the anOuterWire and other wires in 2d space
593 MoveWires2d(anOuterWire);
594
595 myIsDone=Standard_True;
596 myErrorStatus=0;
597}
598
599//=======================================================================
600// function : TopOpeBRepBuild_CorrectFace2d::MakeRightWire
601// purpose:
602//=======================================================================
603 Standard_Integer TopOpeBRepBuild_CorrectFace2d::MakeRightWire ()
604{
605 Standard_Integer aNbEdgesReally=0;
606 myOrderedWireList.Clear();
607
608 //1. Real amount of the edges on aWire
609 TopExp_Explorer aWExp;
610 aWExp.Init(myCurrentWire, TopAbs_EDGE);
611 for (; aWExp.More(); aWExp.Next()) aNbEdgesReally++;
612
613 //2. We'll use TopOpeBRepBuild_Tools::Path
614 TopTools_ListOfShape aL;
615 TopOpeBRepBuild_Tools2d::Path (myCurrentWire, aL);
616 if (aL.Extent()!=aNbEdgesReally) {
617 myErrorStatus=4;
618 return 1;
619 }
620
621 //Begin modified by NIZNHY-PKV Tue Apr 25 12:04:45 2000
622 //from path we obtained list in reverse order, so to have right wire
623 //we need to reverse it
624 TopTools_ListOfShape aFL;
625 TopTools_ListIteratorOfListOfShape lit(aL);
626 for(; lit.More(); lit.Next())
627 aFL.Prepend(lit.Value());
628
629 myOrderedWireList=aFL;
630 //End modified by NIZNHY-PKV Tue Apr 25 12:06:45 2000
631 return 0;
632}
633
634//=======================================================================
635// function : TopOpeBRepBuild_CorrectFace2d::GetP2dFL
636// purpose:
637//=======================================================================
638 void TopOpeBRepBuild_CorrectFace2d::GetP2dFL (const TopoDS_Face& aF, const TopoDS_Edge& anEdge,
639 gp_Pnt2d& P2dF, gp_Pnt2d& P2dL)
640{
641 Standard_Real aFirst, aLast;
642 const Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (anEdge, aF, aFirst, aLast);
643 C2d->D0 (aFirst, P2dF);
644 C2d->D0 (aLast , P2dL);
645 if (anEdge.Orientation()==TopAbs_REVERSED) {
646 gp_Pnt2d P2dTmp;
647 P2dTmp=P2dF; P2dF=P2dL; P2dL=P2dTmp;
648 }
649}
650
651
652//=======================================================================
653// function :TopOpeBRepBuild_CorrectFace2d::MakeHeadList
654// purpose:
655//=======================================================================
656 void TopOpeBRepBuild_CorrectFace2d::MakeHeadList(const TopoDS_Shape& aFirstEdge,
657 TopTools_ListOfShape& HeadList) const
658{
659 TopoDS_Shape aFE = aFirstEdge;
660 TopTools_ListOfShape aTailList;
661 TopTools_ListIteratorOfListOfShape anIt;
662 Standard_Integer aFlag=0;
663
664 anIt.Initialize(myOrderedWireList);
665 for (; anIt.More(); anIt.Next()) {
666 const TopoDS_Shape& anEdge=anIt.Value();
667 //modified by NIZHNY-MZV Mon Mar 27 11:40:00 2000
668 if(aFE.IsNull() && !BRep_Tool::Degenerated(TopoDS::Edge(anEdge)))
669 aFE = anEdge;
670 if (anEdge==aFE) aFlag=1; //turn the switch ON
671 if (aFlag) HeadList.Append(anEdge);
672 }
673
674 anIt.Initialize(myOrderedWireList);
675 for (; anIt.More(); anIt.Next()) {
676 const TopoDS_Shape& anEdge=anIt.Value();
677 if (anEdge==aFE) break;
678 aTailList.Append(anEdge);
679 }
680 HeadList.Append(aTailList);
681}
682//=======================================================================
683// function :TopOpeBRepBuild_CorrectFace2d::CheckList
684// purpose:
685//=======================================================================
686 void TopOpeBRepBuild_CorrectFace2d::CheckList (const TopoDS_Face& aFace,
687 TopTools_ListOfShape& HeadList)
688{
689 TopAbs_Orientation r1, r2;
690 Standard_Real aDTolerance=Precision::Confusion();
691 TopTools_SequenceOfShape aSeq;
692 TopTools_ListIteratorOfListOfShape anIt(HeadList);
693 for (; anIt.More(); anIt.Next()) {
694 aSeq.Append(anIt.Value());
695 }
696
697 r1=aSeq(1).Orientation();
698 r2=aSeq(2).Orientation();
699 Standard_Integer i, aNb=aSeq.Length();
700//modified by NIZNHY-PKV Mon Apr 24 14:43:57 2000f
701 Standard_Boolean aFirstCheck=Standard_False;
702 if (r1==TopAbs_REVERSED ) {
703 // when the orientation of the first edge is Revesed,
704 // and when everything in 2d is Ok :
705 // if at least one Forward edge exists in the List
706 // we consider that no necessity to reverse
707 // the list (aFirstCheck=Standard_True) .
708
709 Standard_Real aD;
710 gp_Pnt2d PF, PL, PA, PB;
711
712
713 TopoDS_Edge aFstEdge=TopoDS::Edge(aSeq(1));
714 GetP2dFL(aFace, aFstEdge, PA, PB);
715 for (i=2; i<=aNb; i++) {
716 TopoDS_Edge anEdge= TopoDS::Edge(aSeq(i));
717 GetP2dFL(aFace, anEdge, PF, PL);
718
719 aD=PF.Distance(PB);
720 if (aD<aDTolerance) {
721 PA=PF; PB=PL;
722 if (anEdge.Orientation()==TopAbs_FORWARD) {
723 aFirstCheck=Standard_True;
724 break;
725 }
726 }
727 }
728 }
729//modified by NIZNHY-PKV Mon Apr 24 14:43:59 2000t
730
731 r1=aSeq(1).Orientation();
732 r2=aSeq(2).Orientation();
733
734 TopoDS_Vertex aV1R, aV2F;
735
736 TopoDS_Edge aFirstEdge=TopoDS::Edge(aSeq(1));
737 TopExp_Explorer anExp;
738 anExp.Init (aFirstEdge, TopAbs_VERTEX);
739 for (; anExp.More(); anExp.Next()) {
740 const TopoDS_Shape& aV1=anExp.Current();
741 if (aV1.Orientation()==TopAbs_REVERSED){
742 aV1R=TopoDS::Vertex(aV1);
743 break;
744 }
745 }
746
747 TopoDS_Edge aSecondEdge=TopoDS::Edge(aSeq(2));
748 anExp.Init (aSecondEdge, TopAbs_VERTEX);
749 for (; anExp.More(); anExp.Next()) {
750 const TopoDS_Shape& aV1=anExp.Current();
751 if (aV1.Orientation()==TopAbs_FORWARD){
752 aV2F=TopoDS::Vertex(aV1);
753 break;
754 }
755 }
756
757 gp_Pnt P1, P2;
758 P1=BRep_Tool::Pnt(aV1R);
759 P2=BRep_Tool::Pnt(aV2F);
760
761
762 //modified by NIZNHY-PKV Mon Apr 24 13:24:06 2000 f
763 Standard_Real dist=P1.Distance(P2);
764 if (
765 (!(dist < aDTolerance) && r1==TopAbs_FORWARD)||
766 //(r1==TopAbs_REVERSED)) {
767 (!aFirstCheck && r1==TopAbs_REVERSED)
768 ) {
769 //modified by NIZNHY-PKV Mon Apr 24 14:28:06 2000 t
770 // We have to reverse the order in list
771 aSeq.Append(aFirstEdge);
772 HeadList.Clear();
773 aNb=aSeq.Length();
774 for (i=aNb; i>1; i--) {
775 HeadList.Append(aSeq(i));
776 }
777 }
778}
779
780//=======================================================================
781// function :TopOpeBRepBuild_CorrectFace2d::TranslateCurve2d
782// purpose:
783//=======================================================================
784 void TopOpeBRepBuild_CorrectFace2d::TranslateCurve2d(const TopoDS_Edge& anE,
785 const TopoDS_Face& aFace,
786 const gp_Vec2d& aTrV,
787 Handle(Geom2d_Curve)& aC2DOut)
788{
789 Standard_Real aFirst, aLast;
790 Handle(Geom2d_Curve) C2d=BRep_Tool::CurveOnSurface (anE, aFace, aFirst, aLast);
791 Handle(Geom2d_Curve) aTrC;
792 aTrC = Handle(Geom2d_Curve)::DownCast(C2d->Copy());
793 Handle(Geom2d_TrimmedCurve) newC2D = new Geom2d_TrimmedCurve(aTrC, aFirst, aLast);
794 newC2D -> Translate(aTrV);
795 aC2DOut=newC2D;
796}
797//=======================================================================
798// function :TopOpeBRepBuild_CorrectFace2d::OuterWire
799// purpose:
800//=======================================================================
801 Standard_Integer TopOpeBRepBuild_CorrectFace2d::OuterWire(TopoDS_Wire& anOuterWire) const
802{
803 TopLoc_Location Loc;
804 Handle(Geom_Surface) Surf = BRep_Tool::Surface(TopoDS::Face(myCorrectedFace), Loc);
805
806 TopExp_Explorer ex(myCorrectedFace, TopAbs_WIRE);
807 for (; ex.More(); ex.Next()) {
808 const TopoDS_Wire& aWire=TopoDS::Wire(ex.Current());
809
810 TopoDS_Face newFace;
811 BRep_Builder BB;
812 BB.MakeFace(newFace, Surf, Loc, myFaceTolerance);
813 BB.Add(newFace, aWire);
814
815 BRepTopAdaptor_FClass2d aClass2d(newFace, myFaceTolerance);
816 TopAbs_State aState=aClass2d.PerformInfinitePoint();
817 if (aState==TopAbs_OUT) {
818 anOuterWire=aWire;
819 return 0;
820 }
821 }
822 return 1; // such wire is not found
823}
824
825//=======================================================================
826// function :TopOpeBRepBuild_CorrectFace2d::BndBoxWire
827// purpose:
828//=======================================================================
829 void TopOpeBRepBuild_CorrectFace2d::BndBoxWire(const TopoDS_Wire& aWire,
830 Bnd_Box2d& B2d) const
831{
832 Bnd_Box2d aB2d;
833 TopExp_Explorer aWEx (aWire, TopAbs_EDGE);
834 for (; aWEx.More(); aWEx.Next()) {
835 const TopoDS_Edge& anEdge = TopoDS::Edge(aWEx.Current());
836 Standard_Real aTolE = BRep_Tool::Tolerance(anEdge);
837 BRepAdaptor_Curve2d aBAC2d (anEdge,myCorrectedFace);
838 BndLib_Add2dCurve::Add(aBAC2d, aTolE, aB2d);
839 }
840 B2d=aB2d;
841}
842
843//=======================================================================
844// function : TopOpeBRepBuild_CorrectFace2d::MoveWire2d
845// purpose:
846//=======================================================================
847 void TopOpeBRepBuild_CorrectFace2d::MoveWire2d (TopoDS_Wire& aWire,
848 const gp_Vec2d& aTrV)
849{
850 if (aTrV.Magnitude()<Precision::Confusion())
851 return;
852
853 Standard_Integer i, aNbEdges;
854 TopTools_SequenceOfShape aSeqEdges;
855 TopTools_IndexedMapOfShape anEdMap;
856 Handle(Geom2d_Curve) aTrCF, aTrCR, aTrC;
857
858 TopExp_Explorer aWExp;
859
860 aWExp.Init(aWire, TopAbs_EDGE);
861 for (; aWExp.More(); aWExp.Next()) {
862 aSeqEdges.Append(aWExp.Current());
863 }
864 aNbEdges=aSeqEdges.Length();
865
866 //
867 // First Edge
868 for (i=1; i<=aNbEdges; i++) {
869 TopoDS_Edge anEdge= TopoDS::Edge(aSeqEdges(i));
870 if (BRep_Tool::IsClosed(anEdge, myCorrectedFace)) {
871 // a. Closed edge <--->
872 if (anEdMap.Contains(anEdge)) continue;
873 anEdMap.Add(anEdge);
874
875 TopAbs_Orientation anOri = anEdge.Orientation();
876
877 TopoDS_Edge anEF, anER;
878
879 if (anOri==TopAbs_FORWARD) {
880 anEF=anEdge;
881 TopoDS_Shape aLocalShape = anEdge.Reversed();
882 anER=TopoDS::Edge(aLocalShape);
883 // anER=TopoDS::Edge(anEdge.Reversed());
884 }
885
886 else {
887 anER=anEdge;
888 TopoDS_Shape aLocalShape = anEdge.Reversed();
889 anEF=TopoDS::Edge(aLocalShape);
890 // anEF=TopoDS::Edge(anEdge.Reversed());
891 }
892
893 TranslateCurve2d (anEF, myCorrectedFace, aTrV, aTrCF);
894 TranslateCurve2d (anER, myCorrectedFace, aTrV, aTrCR);
895 UpdateEdge(anEdge, aTrCF, aTrCR, myCorrectedFace, myFaceTolerance);
896 }
897
898 else {
899 // b. Usual Edge
900 TranslateCurve2d (anEdge, myCorrectedFace, aTrV, aTrC);
901 UpdateEdge(anEdge, aTrC, myCorrectedFace, myFaceTolerance);
902 }
903 } //end of for (i=1; i<=aNbEdges; i++)
904}
905//=======================================================================
906// function : TopOpeBRepBuild_CorrectFace2d::MoveWires2d
907// purpose:
908//=======================================================================
909 void TopOpeBRepBuild_CorrectFace2d::MoveWires2d (TopoDS_Wire& anOuterWire)
910{
911 Bnd_Box2d B2d, B2dOuterWire;
912 Standard_Real OuterU1,OuterV1,OuterU2,OuterV2, x, a, TwoPI;
913 Standard_Integer b, k;
914 gp_Vec2d aTrV;
915
c6541a0c 916 TwoPI=2.*M_PI;
7fd59977 917
918 BndBoxWire(anOuterWire, B2dOuterWire);
919 B2dOuterWire.Get(OuterU1,OuterV1,OuterU2,OuterV2);
920
921 a=.5*(OuterU1+OuterU2);
922 b=Standard_Integer(-a/TwoPI);
923 k=(a<0.)? 1 : 0;
924 x=(b+k)*TwoPI;
925 //
926 // 1. Move the Outer Wire to [0, 2*PI]
927 aTrV.SetCoord (x, 0.);
928 MoveWire2d (anOuterWire, aTrV);
929
930 BndBoxWire(anOuterWire, B2dOuterWire);
931 B2dOuterWire.Get(OuterU1,OuterV1,OuterU2,OuterV2);
932 //
933 // 2. Move all other wires into bounding box of the Outer Wire
934 TopExp_Explorer aFExp;
935 aFExp.Init (myCorrectedFace, TopAbs_WIRE);
936 for (; aFExp.More(); aFExp.Next()) {
937 myCurrentWire = TopoDS::Wire(aFExp.Current());
938 if (myCurrentWire!=anOuterWire) {
939 BndBoxWire(myCurrentWire, B2d);
940 Standard_Real u1,v1,u2,v2;
941 B2d.Get(u1,v1,u2,v2);
942
943 if (B2d.IsOut(B2dOuterWire)) {
944 //printf(" Need to Move\n" );
945 a=u1-OuterU1;
946 b=Standard_Integer(-a/TwoPI);
947 k= (a<0.) ? 1 : 0;
948 x=(b+k)*TwoPI;
949 aTrV.SetCoord (x, 0.);
950 MoveWire2d (myCurrentWire, aTrV);
951 }
952 }
953 }
954}
955//=======================================================================
956// function : TopOpeBRepBuild_CorrectFace2d::UpdateEdge
957// purpose:
958//=======================================================================
959 void TopOpeBRepBuild_CorrectFace2d::UpdateEdge (const TopoDS_Edge& ECopy,
960 const Handle(Geom2d_Curve)& C,
961 const TopoDS_Face& F,
962 const Standard_Real Tol)
963{
964 BRep_Builder BB;
965
966 TopTools_IndexedDataMapOfShapeShape* pMap=
967 (TopTools_IndexedDataMapOfShapeShape*) myMap;
968
969 // E is the Original Edge from Original Face.
970 if (myEdMapInversed.Contains(ECopy)) {
971 const TopoDS_Shape& E=myEdMapInversed.FindFromKey(ECopy);
972
973 if (!pMap->Contains(E)) {
974 TopExp_Explorer anExp;
975
976 TopoDS_Shape anEdge=E.EmptyCopied();
977
978 anExp.Init(E, TopAbs_VERTEX);
979 for (; anExp.More(); anExp.Next()) {
980 const TopoDS_Shape& aV=anExp.Current();
981 BB.Add(anEdge, aV);
982 }
983
984 BB.UpdateEdge(TopoDS::Edge(anEdge), C, F, Tol);
985 pMap->Add(E, anEdge);
986 //printf("pMap->Extent()=%d\n", pMap->Extent());
987 }
988
989 else {
990 TopoDS_Shape& anEdge=pMap->ChangeFromKey(E);
991 BB.UpdateEdge(TopoDS::Edge(anEdge), C, F, Tol);
992 }
993 }
994
995 BB.UpdateEdge (ECopy, C, F, Tol);
996}
997
998
999//=======================================================================
1000// function : TopOpeBRepBuild_CorrectFace2d::UpdateEdge
1001// purpose:
1002//=======================================================================
1003 void TopOpeBRepBuild_CorrectFace2d::UpdateEdge (const TopoDS_Edge& ECopy,
1004 const Handle(Geom2d_Curve)& C1,
1005 const Handle(Geom2d_Curve)& C2,
1006 const TopoDS_Face& F,
1007 const Standard_Real Tol)
1008{
1009 BRep_Builder BB;
1010
1011 TopTools_IndexedDataMapOfShapeShape* pMap=
1012 (TopTools_IndexedDataMapOfShapeShape*) myMap;
1013
1014 // E is the Original Edge from Original Face.
1015 if (myEdMapInversed.Contains(ECopy)) {
1016 const TopoDS_Shape& E=myEdMapInversed.FindFromKey(ECopy);
1017
1018 if (!pMap->Contains(E)) {
1019 TopoDS_Shape anEdge=E.EmptyCopied();
1020 TopExp_Explorer anExp;
1021 anExp.Init(E, TopAbs_VERTEX);
1022 for (; anExp.More(); anExp.Next()) {
1023 const TopoDS_Shape& aV=anExp.Current();
1024 BB.Add(anEdge, aV);
1025 }
1026 BB.UpdateEdge(TopoDS::Edge(anEdge), C1, C2, F, Tol);
1027 pMap->Add(E, anEdge);
1028 //printf("pMap->Extent()=%d\n", pMap->Extent());
1029 }
1030
1031 else {
1032 TopoDS_Shape& anEdge=pMap->ChangeFromKey(E);
1033 BB.UpdateEdge(TopoDS::Edge(anEdge), C1, C2, F, Tol);
1034 }
1035 }
1036
1037 BB.UpdateEdge (ECopy, C1, C2, F, Tol);
1038}
1039
1040//
1041// Description for ErrorStatus
1042// ErrorStatus=0 : All is done;
1043// ErrorStatus=1 : Nothing is done;
1044// ErrorStatus=2 : The wire doesn't contain any licit edges and the wire is not closed;
1045// ErrorStatus=3 : The face contains a wire that is not connectable
1046// ErrorStatus=4 : The base surface is not periodic;
1047// ErrorStatus=5 : an outer wir can not be found;
1048// ErrorStatus=6 : Wrong connectability of a wire in 2d
1049