0024510: Remove unused local variables
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_CorrectFace2d.cxx
1 // Created on: 2000-01-26
2 // Created by: Peter KURNEV
3 // Copyright (c) 2000-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
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 //=======================================================================
58 TopOpeBRepBuild_CorrectFace2d::TopOpeBRepBuild_CorrectFace2d()
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_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
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) {
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;
461     }
462     
463     if(!nonPV && VP) {
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;
466     }
467
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)));
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 {
687   TopAbs_Orientation r1;
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();
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();
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
912   TwoPI=2.*M_PI;
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