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