0028643: Coding rules - eliminate GCC compiler warnings -Wmisleading-indentation
[occt.git] / src / BRepOffsetAPI / BRepOffsetAPI_DraftAngle.cxx
1 // Created on: 1995-02-22
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_Builder.hxx>
19 #include <BRep_GCurve.hxx>
20 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
21 #include <BRep_TEdge.hxx>
22 #include <BRep_Tool.hxx>
23 #include <BRepAdaptor_Curve.hxx>
24 #include <BRepAdaptor_Curve2d.hxx>
25 #include <BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal.hxx>
26 #include <BRepFill_DataMapOfShapeSequenceOfReal.hxx>
27 #include <BRepLib.hxx>
28 #include <BRepLib_MakeVertex.hxx>
29 #include <BRepOffsetAPI_DraftAngle.hxx>
30 #include <BRepOffsetAPI_SequenceOfSequenceOfReal.hxx>
31 #include <BRepOffsetAPI_SequenceOfSequenceOfShape.hxx>
32 #include <BRepTools.hxx>
33 #include <BRepTools_Substitution.hxx>
34 #include <Draft_Modification.hxx>
35 #include <Geom2d_Curve.hxx>
36 #include <Geom_Surface.hxx>
37 #include <gp_Dir.hxx>
38 #include <gp_Pln.hxx>
39 #include <Precision.hxx>
40 #include <Standard_ConstructionError.hxx>
41 #include <Standard_NoSuchObject.hxx>
42 #include <Standard_NullObject.hxx>
43 #include <StdFail_NotDone.hxx>
44 #include <TColgp_SequenceOfPnt.hxx>
45 #include <TColStd_SequenceOfReal.hxx>
46 #include <TopExp.hxx>
47 #include <TopExp_Explorer.hxx>
48 #include <TopLoc_Location.hxx>
49 #include <TopoDS.hxx>
50 #include <TopoDS_Face.hxx>
51 #include <TopoDS_Iterator.hxx>
52 #include <TopoDS_Shape.hxx>
53 #include <TopoDS_Wire.hxx>
54 #include <TopTools_DataMapOfShapeSequenceOfShape.hxx>
55 #include <TopTools_ListIteratorOfListOfShape.hxx>
56 #include <TopTools_SequenceOfShape.hxx>
57
58 #include <Geom2dInt_GInter.hxx>
59 #include <IntRes2d_IntersectionPoint.hxx>
60
61 //=======================================================================
62 //function : BRepOffsetAPI_DraftAngle
63 //purpose  : 
64 //=======================================================================
65 BRepOffsetAPI_DraftAngle::BRepOffsetAPI_DraftAngle () {}
66
67
68 //=======================================================================
69 //function : BRepOffsetAPI_DraftAngle
70 //purpose  : 
71 //=======================================================================
72
73 BRepOffsetAPI_DraftAngle::BRepOffsetAPI_DraftAngle (const TopoDS_Shape& S)
74 {
75   myInitialShape = S;
76   myModification = new Draft_Modification(S);
77 }
78
79
80 //=======================================================================
81 //function : Clear
82 //purpose  : 
83 //=======================================================================
84
85 void BRepOffsetAPI_DraftAngle::Clear ()
86 {
87   if (!myModification.IsNull()) {
88     Handle(Draft_Modification)::DownCast (myModification)->Clear();
89   }
90 }
91
92
93 //=======================================================================
94 //function : Init
95 //purpose  : 
96 //=======================================================================
97
98 void BRepOffsetAPI_DraftAngle::Init (const TopoDS_Shape& S)
99 {
100   myInitialShape = S;
101   NotDone();
102   if (!myModification.IsNull()) {
103     Handle(Draft_Modification)::DownCast (myModification)->Init(S);   
104   }
105   else {
106     myModification = new Draft_Modification(S);
107   }
108 }
109
110
111 //=======================================================================
112 //function : Add
113 //purpose  : 
114 //=======================================================================
115
116 void BRepOffsetAPI_DraftAngle::Add(const TopoDS_Face& F,
117                              const gp_Dir& D,
118                              const Standard_Real Angle,
119                              const gp_Pln& Plane,
120                              const Standard_Boolean Flag)
121 {
122 // POP-DPF : protection
123   if ( Abs(Angle) <= 1.e-04 ) 
124     return;
125   Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
126   Handle(Draft_Modification)::DownCast (myModification)->Add(F,D,Angle,Plane, Flag);
127 }
128
129
130 //=======================================================================
131 //function : AddDone
132 //purpose  : 
133 //=======================================================================
134
135 Standard_Boolean BRepOffsetAPI_DraftAngle::AddDone () const
136 {
137   Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
138   return Handle(Draft_Modification)::DownCast (myModification)
139     ->ProblematicShape().IsNull();
140 }
141
142
143 //=======================================================================
144 //function : Remove
145 //purpose  : 
146 //=======================================================================
147
148 void BRepOffsetAPI_DraftAngle::Remove(const TopoDS_Face& F)
149 {
150   Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
151   Handle(Draft_Modification)::DownCast (myModification)->Remove(F);
152 }
153
154
155 //=======================================================================
156 //function : ProblematicShape
157 //purpose  : 
158 //=======================================================================
159
160 const TopoDS_Shape& BRepOffsetAPI_DraftAngle::ProblematicShape () const
161 {
162   Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
163   return Handle(Draft_Modification)::DownCast (myModification)->ProblematicShape();
164 }
165
166
167 //=======================================================================
168 //function : ErrorStatus
169 //purpose  : 
170 //=======================================================================
171
172 Draft_ErrorStatus BRepOffsetAPI_DraftAngle::Status () const
173 {
174   Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
175   return Handle(Draft_Modification)::DownCast (myModification)->Error();
176 }
177
178
179 //=======================================================================
180 //function : ConnectedFaces
181 //purpose  : 
182 //=======================================================================
183
184 const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ConnectedFaces
185    (const TopoDS_Face& F) const
186 {
187   Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
188   return Handle(Draft_Modification)::DownCast (myModification)->ConnectedFaces(F);
189 }
190
191
192 //=======================================================================
193 //function : ModifiedFaces
194 //purpose  : 
195 //=======================================================================
196
197 const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::ModifiedFaces() const
198 {
199   Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
200   return Handle(Draft_Modification)::DownCast (myModification)->ModifiedFaces();
201 }
202
203 //=======================================================================
204 //function : Generated
205 //purpose  : 
206 //=======================================================================
207
208 const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Generated(const TopoDS_Shape& S) 
209 {
210   myGenerated.Clear();
211   Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
212   Handle(Draft_Modification) DMod = Handle(Draft_Modification)::DownCast (myModification);
213
214   if (S.ShapeType() == TopAbs_FACE) {
215     Handle(Geom_Surface) Surf;
216     TopLoc_Location      L;
217     Standard_Real        Tol;
218     Standard_Boolean     RW,RF;
219     if (DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) {
220       if(myVtxToReplace.IsEmpty())
221       {
222         myGenerated.Append(ModifiedShape (S));
223       }
224       else
225       {
226         myGenerated.Append(mySubs.Value(ModifiedShape (S)));
227       }
228     }
229   }
230   return myGenerated;
231 }
232
233 //=======================================================================
234 //function : Modified
235 //purpose  : 
236 //=======================================================================
237
238 const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Modified(const TopoDS_Shape& S) 
239 {
240   myGenerated.Clear();
241   Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
242   Handle(Draft_Modification) DMod = Handle(Draft_Modification)::DownCast (myModification);
243
244   if (S.ShapeType() == TopAbs_FACE) {
245     Handle(Geom_Surface) Surf;
246     TopLoc_Location      L;
247     Standard_Real        Tol;
248     Standard_Boolean     RW,RF;
249     
250     if (!DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) {
251       // Ce n est pas une generation => peut etre une  modif
252       if(myVtxToReplace.IsEmpty())
253       {
254         myGenerated.Append(ModifiedShape (S));
255       }
256       else
257       {
258         myGenerated.Append(mySubs.Value(ModifiedShape (S)));
259       }
260       if (myGenerated.Extent() == 1 && myGenerated.First().IsSame(S)) {
261               myGenerated.Clear();
262       }
263     }
264   }
265   return myGenerated;
266 }
267
268 //=======================================================================
269 //function : ModifiedShape
270 //purpose  : 
271 //=======================================================================
272
273 TopoDS_Shape BRepOffsetAPI_DraftAngle::ModifiedShape
274   (const TopoDS_Shape& S) const
275 {
276   if(S.ShapeType() == TopAbs_VERTEX)
277   {
278     if(myVtxToReplace.IsBound(S))
279     {
280       return myVtxToReplace(S);
281     }
282   }
283   if(myVtxToReplace.IsEmpty())
284   {
285     return myModifier.ModifiedShape(S);
286   }
287   else
288   {
289     const TopoDS_Shape& aNS = myModifier.ModifiedShape(S);
290     return mySubs.Value(aNS);
291   }
292 }
293
294 //=======================================================================
295 //function : Build
296 //purpose  : 
297 //=======================================================================
298
299 void BRepOffsetAPI_DraftAngle::Build()
300 {
301   Handle(Draft_Modification)::DownCast (myModification)->Perform();
302   if (!Handle(Draft_Modification)::DownCast (myModification)->IsDone()) {
303     NotDone();
304   }
305   else {
306     DoModif(myInitialShape);
307     CorrectWires();
308     CorrectVertexTol();
309   }
310 }
311
312 //=======================================================================
313 //function : CorrectWires
314 //purpose  :
315 //=======================================================================
316
317 void BRepOffsetAPI_DraftAngle::CorrectWires()
318 {
319   Standard_Real TolInter = 1.e-7;
320   Standard_Integer i, j, k;
321
322   TopTools_SequenceOfShape Eseq;
323   TopTools_SequenceOfShape Wseq;
324   TopTools_SequenceOfShape Fseq;
325   TopoDS_Shape CurEdge, CurWire, CurFace;
326   TopoDS_Iterator wit, eit;
327
328   TopExp_Explorer fexp( myShape, TopAbs_FACE );
329   for (; fexp.More(); fexp.Next())
330   {
331     CurFace = fexp.Current();
332     wit.Initialize( CurFace );
333     for (; wit.More(); wit.Next())
334     {
335       CurWire = wit.Value();
336       TopTools_MapOfShape emap;
337       eit.Initialize( CurWire );
338       for (; eit.More(); eit.Next())
339         emap.Add( eit.Value() );
340       TopTools_MapIteratorOfMapOfShape mapit( emap );
341       for (; mapit.More(); mapit.Next())
342       {
343         CurEdge = mapit.Key();
344         if (BRepTools::IsReallyClosed( TopoDS::Edge(CurEdge), TopoDS::Face(CurFace) ))
345         {
346           Eseq.Append( CurEdge );
347           Wseq.Append( CurWire );
348           Fseq.Append( CurFace );
349         }
350       }
351     }
352   }
353
354   BRepFill_DataMapOfShapeSequenceOfReal Emap;
355
356   TopTools_SequenceOfShape NonSeam;
357   TopTools_SequenceOfShape NonSeamWires;
358   BRepOffsetAPI_SequenceOfSequenceOfReal ParsNonSeam;
359   BRepOffsetAPI_SequenceOfSequenceOfShape Seam;
360   BRepOffsetAPI_SequenceOfSequenceOfReal ParsSeam;
361
362   TopTools_DataMapOfShapeShape WFmap;
363   TopTools_DataMapOfShapeListOfShape WWmap;
364   for (i = 1; i <= Eseq.Length(); i++)
365   {
366     CurEdge = Eseq(i);
367     CurWire = Wseq(i);
368     CurFace = Fseq(i);
369     //
370     const TopoDS_Face& aFace = TopoDS::Face(CurFace);
371     //
372     // Prepare 2D adaptors for intersection.
373     // The seam edge has two 2D curve, thus we have to create 2 adaptors
374     BRepAdaptor_Curve2d aBAC2D1(TopoDS::Edge(CurEdge), aFace);
375     BRepAdaptor_Curve2d aBAC2D1R(TopoDS::Edge(CurEdge.Reversed()), aFace);
376     // Get surface of the face to get 3D intersection point
377     TopLoc_Location aLoc;
378     const Handle(Geom_Surface)& aSurf = BRep_Tool::Surface(aFace, aLoc);
379     // Get the tolerance of the current edge to compare intersection points
380     Standard_Real aTolCurE = BRep_Tool::Tolerance(TopoDS::Edge(CurEdge));
381     //
382     wit.Initialize( CurFace );
383     for (; wit.More(); wit.Next())
384     {
385       TopoDS_Shape aWire = wit.Value();
386       if (! aWire.IsSame( CurWire ))
387       {
388         TColgp_SequenceOfPnt pts;
389         Standard_Boolean Wadd = Standard_False;
390         eit.Initialize( aWire );
391         for (; eit.More(); eit.Next())
392         {
393           const TopoDS_Edge& anEdge = TopoDS::Edge(eit.Value());
394           //
395           // Prepare 2D adaptor for intersection
396           BRepAdaptor_Curve2d aBAC2D2(anEdge, aFace);
397           // Perform intersection
398           Geom2dInt_GInter aGInter;
399           aGInter.Perform(aBAC2D1, aBAC2D2, TolInter, TolInter);
400           if (!aGInter.IsDone() || aGInter.IsEmpty()) {
401             // If first intersection is empty try intersection with reversed edge
402             aGInter.Perform(aBAC2D1R, aBAC2D2, TolInter, TolInter);
403             if (!aGInter.IsDone() || aGInter.IsEmpty()) {
404               continue;
405             }
406           }
407           //
408           Wadd = Standard_True;
409           if (! WFmap.IsBound( aWire ))
410             WFmap.Bind( aWire, CurFace );
411           Standard_Integer ind = 0;
412           for (j = 1; j <= NonSeam.Length(); j++) {
413             if (anEdge.IsSame(NonSeam(j)))
414             {
415               ind = j;
416               break;
417             }
418           }
419           if (ind == 0)
420           {
421             NonSeam.Append(anEdge);
422             NonSeamWires.Append(aWire);
423             ind = NonSeam.Length();
424             TColStd_SequenceOfReal emptyseq1, emptyseq2;
425             TopTools_SequenceOfShape emptyedgeseq;
426             ParsNonSeam.Append(emptyseq1);
427             Seam.Append(emptyedgeseq);
428             ParsSeam.Append(emptyseq2);
429           }
430           if (!Emap.IsBound(CurEdge))
431           {
432             TColStd_SequenceOfReal emptyseq;
433             Emap.Bind(CurEdge, emptyseq);
434           }
435           //
436           // Get the tolerance of edge to compare intersection points
437           Standard_Real aTolE = BRep_Tool::Tolerance(anEdge);
438           // Tolerance to compare the intersection points is the maximal
439           // tolerance of intersecting edges
440           Standard_Real aTolCmp = Max(aTolCurE, aTolE);
441           //
442           Standard_Integer aNbIntPnt = aGInter.NbPoints();
443           for (k = 1; k <= aNbIntPnt; ++k) {
444             const IntRes2d_IntersectionPoint& aP2DInt = aGInter.Point(k);
445             const gp_Pnt2d& aP2D = aP2DInt.Value();
446             gp_Pnt aP3D = aSurf->Value(aP2D.X(), aP2D.Y());
447             //
448             // Check if the intersection point is new
449             Standard_Integer ied = 0;
450             for (j = 1; j <= pts.Length(); j++) {
451               if (aP3D.IsEqual(pts(j), aTolCmp))
452               {
453                 ied = j;
454                 break;
455               }
456             }
457             if (ied == 0)
458             {
459               pts.Append(aP3D);
460               Emap(CurEdge).Append(aP2DInt.ParamOnFirst());
461               ParsNonSeam(ind).Append(aP2DInt.ParamOnSecond());
462               Seam(ind).Append(CurEdge);
463               ParsSeam(ind).Append(aP2DInt.ParamOnFirst());
464             }
465           }
466         } //for (; eit.More(); eit.Next())
467         if (Wadd)
468         {
469           if (! WWmap.IsBound( CurWire ))
470           {
471             TopTools_ListOfShape emptylist;
472             WWmap.Bind( CurWire, emptylist );
473           }
474           WWmap(CurWire).Append( aWire );
475         }
476       } //if (! aWire.IsSame( CurWire ))
477     } //for (; wit.More(); wit.Next())
478   } //for (i = 1; i <= Eseq.Length(); i++)
479
480   //Sorting
481   for (i = 1; i <= NonSeam.Length(); i++)
482   {
483     for (j = 1; j < ParsNonSeam(i).Length(); j++)
484     {
485       for (k = j+1; k <= ParsNonSeam(i).Length(); k++)
486       {
487         if (ParsNonSeam(i)(k) < ParsNonSeam(i)(j))
488         {
489           Standard_Real temp = ParsNonSeam(i)(j);
490           ParsNonSeam(i)(j) = ParsNonSeam(i)(k);
491           ParsNonSeam(i)(k) = temp;
492           TopoDS_Shape tmp = Seam(i)(j);
493           Seam(i)(j) = Seam(i)(k);
494           Seam(i)(k) = tmp;
495           temp = ParsSeam(i)(j);
496           ParsSeam(i)(j) = ParsSeam(i)(k);
497           ParsSeam(i)(k) = temp;
498         }
499       }
500     }
501   }
502   BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal iter (Emap);
503   for (; iter.More (); iter.Next ())
504   {
505     TColStd_SequenceOfReal Seq = iter.Value ();
506     for (i = 1; i < Seq.Length (); i++)
507     {
508       for (j = i + 1; j <= Seq.Length (); j++)
509       {
510         if (Seq (j) < Seq (i))
511         {
512           Standard_Real temp = Seq (i);
513           Seq (i) = Seq (j);
514           Seq (j) = temp;
515         }
516       }
517     }
518     Emap (iter.Key ()) = Seq;
519   }
520   BRepFill_DataMapOfShapeSequenceOfReal EPmap;
521   TopTools_DataMapOfShapeSequenceOfShape EVmap; //Seam
522   TopTools_DataMapOfShapeSequenceOfShape EWmap; //Seam and wires intersecting it
523   iter.Initialize (Emap);
524   for (; iter.More (); iter.Next ())
525   {
526     TColStd_SequenceOfReal parseq;
527     EPmap.Bind (iter.Key (), parseq);
528     TopTools_SequenceOfShape shapeseq;
529     EVmap.Bind (iter.Key (), shapeseq);
530     TopTools_SequenceOfShape shapeseq2;
531     EWmap.Bind (iter.Key (), shapeseq2);
532   }
533
534   //Reconstruction of non-seam edges
535   BRepTools_Substitution aSub;
536   BRep_Builder BB;
537   for (i = 1; i <= NonSeam.Length (); i++)
538   {
539     TopoDS_Edge anEdge = TopoDS::Edge (NonSeam (i));
540     TopTools_ListOfShape NewEdges;
541     TopoDS_Edge NewE;
542     TopoDS_Vertex Vfirst, Vlast;
543     TopExp::Vertices (anEdge, Vfirst, Vlast);
544     Standard_Real par, FirstPar, LastPar;
545     BRep_Tool::Range (anEdge, FirstPar, LastPar);
546     Standard_Integer firstind = 1;
547     par = ParsNonSeam (i)(1);
548     TopoDS_Edge SeamEdge = TopoDS::Edge (Seam (i)(1));
549     //Find the face
550     for (j = 1; j <= Eseq.Length (); j++)
551       if (SeamEdge.IsSame (Eseq (j)))
552         break;
553     TopoDS_Face theFace = TopoDS::Face (Fseq (j));
554     TopLoc_Location L;
555     Handle (Geom_Surface) theSurf = BRep_Tool::Surface (theFace, L);
556     if (Abs (par - FirstPar) <= Precision::Confusion ())
557     {
558       BB.UpdateVertex (Vfirst, ParsSeam (i)(1), SeamEdge, BRep_Tool::Tolerance (Vfirst));
559       EPmap (SeamEdge).Append (ParsSeam (i)(1));
560       EVmap (SeamEdge).Append (Vfirst);
561       EWmap (SeamEdge).Append (NonSeamWires (i));
562       firstind = 2;
563     }
564     Standard_Real prevpar = FirstPar;
565     TopoDS_Vertex PrevV = Vfirst;
566     for (j = firstind; j <= ParsNonSeam (i).Length (); j++)
567     {
568       TopoDS_Shape aLocalShape = anEdge.EmptyCopied ();
569       NewE = TopoDS::Edge (aLocalShape);
570       //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
571       TopoDS_Vertex NewV;
572       par = ParsNonSeam (i)(j);
573       BB.Range (NewE, prevpar, par);
574       SeamEdge = TopoDS::Edge (Seam (i)(j));
575       if (j == ParsNonSeam (i).Length () && Abs (par - LastPar) <= Precision::Confusion ())
576       {
577         NewV = Vlast;
578         if (firstind == 2 && j == 2)
579         {
580           BB.UpdateVertex (Vlast, ParsSeam (i)(j), SeamEdge, BRep_Tool::Tolerance (Vlast));
581           EPmap (SeamEdge).Append (ParsSeam (i)(j));
582           EVmap (SeamEdge).Append (Vlast);
583           EWmap (SeamEdge).Append (NonSeamWires (i));
584           break;
585         }
586       }
587       else
588       {
589         BRepAdaptor_Curve bcur (NewE);
590         gp_Pnt Point = bcur.Value (par);
591         NewV = BRepLib_MakeVertex (Point);
592         BB.UpdateVertex (NewV, par, NewE, 10.*Precision::Confusion ());
593       }
594       BB.UpdateVertex (NewV, ParsSeam (i)(j), SeamEdge, 10.*Precision::Confusion ());
595       NewE.Orientation (TopAbs_FORWARD);
596       BB.Add (NewE, PrevV.Oriented (TopAbs_FORWARD));
597       BB.Add (NewE, NewV.Oriented (TopAbs_REVERSED));
598
599       NewEdges.Append (NewE);
600       EPmap (SeamEdge).Append (ParsSeam (i)(j));
601       EVmap (SeamEdge).Append (NewV);
602       EWmap (SeamEdge).Append (NonSeamWires (i));
603
604       prevpar = par;
605       PrevV = NewV;
606     }
607     //The last edge
608     TopoDS_Shape aLocalShape = anEdge.EmptyCopied ();
609     NewE = TopoDS::Edge (aLocalShape);
610     //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
611     par = LastPar;
612     if (Abs (prevpar - par) > Precision::Confusion ())
613     {
614       BB.Range (NewE, prevpar, par);
615       NewE.Orientation (TopAbs_FORWARD);
616       BB.Add (NewE, PrevV.Oriented (TopAbs_FORWARD));
617       BB.Add (NewE, Vlast.Oriented (TopAbs_REVERSED));
618       NewEdges.Append (NewE);
619     }
620
621     //Substitute anEdge by NewEdges
622     aSub.Substitute (anEdge, NewEdges);
623   }
624
625   //Sorting of EPmap and EVmap and removing repeating points from them
626   iter.Initialize (EPmap);
627   for (; iter.More (); iter.Next ())
628   {
629     TColStd_SequenceOfReal Seq;
630     Seq = iter.Value ();
631     TopTools_SequenceOfShape SeqShape;
632     SeqShape = EVmap (iter.Key ());
633     TopTools_SequenceOfShape SeqShape2;
634     SeqShape2 = EWmap (iter.Key ());
635     for (i = 1; i < Seq.Length (); i++)
636     {
637       for (j = i + 1; j <= Seq.Length (); j++)
638       {
639         if (Seq (j) < Seq (i))
640         {
641           Standard_Real temp = Seq (i);
642           Seq (i) = Seq (j);
643           Seq (j) = temp;
644           TopoDS_Shape tmp = SeqShape (i);
645           SeqShape (i) = SeqShape (j);
646           SeqShape (j) = tmp;
647           tmp = SeqShape2 (i);
648           SeqShape2 (i) = SeqShape2 (j);
649           SeqShape2 (j) = tmp;
650         }
651       }
652     }
653
654     EPmap (iter.Key ()) = Seq;
655     EVmap (iter.Key ()) = SeqShape;
656     EWmap (iter.Key ()) = SeqShape2;
657   }
658   iter.Initialize (EPmap);
659   for (; iter.More (); iter.Next ())
660   {
661     TColStd_SequenceOfReal Seq;
662     Seq = iter.Value ();
663     TopTools_SequenceOfShape SeqShape;
664     SeqShape = EVmap (iter.Key ());
665     TopTools_SequenceOfShape SeqShape2;
666     SeqShape2 = EWmap (iter.Key ());
667     Standard_Boolean remove = Standard_True;
668     while (remove)
669     {
670       remove = Standard_False;
671       for (i = 1; i < Seq.Length (); i++)
672       {
673         if (Abs (Seq (i) - Seq (i + 1)) <= Precision::Confusion ())
674         {
675           Seq.Remove (i + 1);
676           SeqShape.Remove (i + 1);
677           SeqShape2.Remove (i + 1);
678           remove = Standard_True;
679         }
680       }
681     }
682     EPmap (iter.Key ()) = Seq;
683     EVmap (iter.Key ()) = SeqShape;
684     EWmap (iter.Key ()) = SeqShape2;
685   }
686
687   //Reconstruction of seam edges
688   TopTools_DataMapOfShapeShape VEmap;
689   iter.Initialize (Emap);
690   for (; iter.More (); iter.Next ())
691   {
692     TopoDS_Edge anEdge = TopoDS::Edge (iter.Key ());
693     Standard_Boolean onepoint = Standard_False;
694     TopTools_ListOfShape NewEdges;
695     TColStd_SequenceOfReal Seq;
696     Seq = iter.Value ();
697     TColStd_SequenceOfReal Seq2;
698     Seq2 = EPmap (anEdge);
699     TopTools_SequenceOfShape SeqVer;
700     SeqVer = EVmap (anEdge);
701     TopTools_SequenceOfShape SeqWire;
702     SeqWire = EWmap (anEdge);
703     TopoDS_Vertex Vfirst, Vlast;
704     TopExp::Vertices (anEdge, Vfirst, Vlast);
705     Standard_Real fpar, lpar, FirstPar, LastPar;
706     BRep_Tool::Range (anEdge, FirstPar, LastPar);
707     fpar = FirstPar;
708     lpar = Seq (1);
709     TopoDS_Edge NewE;
710     Standard_Integer firstind = 1;
711     if (Abs (fpar - lpar) <= Precision::Confusion ())
712     {
713       firstind = 2;
714       fpar = Seq (1);
715       lpar = Seq (2);
716     }
717     else
718     {
719       if (Seq.Length () % 2 != 0)
720       {
721         VEmap.Bind (Vfirst, anEdge);
722         firstind = 2;
723         fpar = Seq (1);
724         if (Seq.Length () > 2)
725           lpar = Seq (2);
726         else
727           onepoint = Standard_True;
728       }
729     }
730     if (!onepoint)
731     {
732       TopoDS_Shape aLocalShape = anEdge.EmptyCopied ();
733       NewE = TopoDS::Edge (aLocalShape);
734       //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
735       BB.Range (NewE, fpar, lpar);
736       NewE.Orientation (TopAbs_FORWARD);
737       if (firstind == 1)
738       {
739         BB.Add (NewE, Vfirst.Oriented (TopAbs_FORWARD));
740         aLocalShape = SeqVer (1).Oriented (TopAbs_REVERSED);
741         BB.Add (NewE, TopoDS::Vertex (aLocalShape));
742         //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_REVERSED) ) );
743       }
744       else
745       {
746         aLocalShape = SeqVer (1).Oriented (TopAbs_FORWARD);
747         BB.Add (NewE, TopoDS::Vertex (aLocalShape));
748         aLocalShape = SeqVer (2).Oriented (TopAbs_REVERSED);
749         BB.Add (NewE, TopoDS::Vertex (aLocalShape));
750         //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_FORWARD) ) );
751         //BB.Add( NewE, TopoDS::Vertex( SeqVer(2).Oriented(TopAbs_REVERSED) ) );
752       }
753       NewEdges.Append (NewE);
754
755       firstind++;
756       for (i = firstind; i < Seq.Length (); i += 2)
757       {
758         aLocalShape = anEdge.EmptyCopied ();
759         NewE = TopoDS::Edge (aLocalShape);
760         //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
761         fpar = Seq (i);
762         lpar = Seq (i + 1);
763         BB.Range (NewE, fpar, lpar);
764         //Find vertices
765         for (j = 1; j <= Seq2.Length (); j++)
766         {
767           if (Abs (fpar - Seq2 (j)) <= Precision::Confusion ())
768           {
769             break;
770           }
771         }
772         NewE.Orientation (TopAbs_FORWARD);
773         TopoDS_Shape aLocalShapeCur = SeqVer (j).Oriented (TopAbs_FORWARD);
774         BB.Add (NewE, TopoDS::Vertex (aLocalShapeCur));
775         aLocalShapeCur = SeqVer (j + 1).Oriented (TopAbs_REVERSED);
776         BB.Add (NewE, TopoDS::Vertex (aLocalShapeCur));
777         //BB.Add( NewE, TopoDS::Vertex( SeqVer(j).Oriented(TopAbs_FORWARD) ) );
778         //BB.Add( NewE, TopoDS::Vertex( SeqVer(j+1).Oriented(TopAbs_REVERSED) ) );
779         NewEdges.Append (NewE);
780       }
781     }
782
783     i = Seq.Length ();
784     fpar = Seq (i);
785     lpar = LastPar;
786     if (Abs (fpar - lpar) <= Precision::Confusion ())
787       continue;
788     TopoDS_Shape aLocalShape = anEdge.EmptyCopied ();
789     NewE = TopoDS::Edge (aLocalShape);
790     //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
791     BB.Range (NewE, fpar, lpar);
792     NewE.Orientation (TopAbs_FORWARD);
793     aLocalShape = SeqVer (SeqVer.Length ()).Oriented (TopAbs_FORWARD);
794     BB.Add (NewE, TopoDS::Vertex (aLocalShape));
795     //BB.Add( NewE, TopoDS::Vertex( SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD) ) );
796     BB.Add (NewE, Vlast.Oriented (TopAbs_REVERSED));
797     NewEdges.Append (NewE);
798
799     //Substitute anEdge by NewEdges
800     aSub.Substitute (anEdge, NewEdges);
801   }
802
803   //Removing edges connected with missing extremities of seam edges
804   TopTools_DataMapIteratorOfDataMapOfShapeShape itve (VEmap);
805   for (; itve.More (); itve.Next ())
806   {
807     TopoDS_Shape V = itve.Key ();
808     TopoDS_Shape E = itve.Value ();
809     TopoDS_Shape W;
810     for (i = 1; i <= Eseq.Length (); i++)
811     {
812       if (E.IsSame (Eseq (i)))
813       {
814         W = Wseq (i);
815         break;
816       }
817     }
818     TopoDS_Shape Etoremove;
819     eit.Initialize (W);
820     for (; eit.More (); eit.Next ())
821     {
822       TopoDS_Edge CurE = TopoDS::Edge (eit.Value ());
823       if (CurE.IsSame (E))
824         continue;
825       TopoDS_Vertex Vfirst, Vlast;
826       TopExp::Vertices (CurE, Vfirst, Vlast);
827       if (Vfirst.IsSame (V) || Vlast.IsSame (V))
828       {
829         Etoremove = CurE;
830         break;
831       }
832     }
833     if (!Etoremove.IsNull ())
834     {
835       W.Free (Standard_True);
836       BB.Remove (W, Etoremove);
837     }
838   }
839
840   aSub.Build (myShape);
841   if (aSub.IsCopied (myShape))
842   {
843     const TopTools_ListOfShape& listSh = aSub.Copy (myShape);
844     if (!listSh.IsEmpty ())
845       myShape = listSh.First ();
846   }
847
848   //Reconstruction of wires
849   TopTools_ListOfShape theCopy;
850   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itww (WWmap);
851   for (; itww.More (); itww.Next ())
852   {
853     CurWire = itww.Key ();
854     theCopy = aSub.Copy (CurWire);
855     CurWire = theCopy.First ();
856     CurWire.Free (Standard_True);
857     TopTools_ListIteratorOfListOfShape itl (itww.Value ());
858     for (; itl.More (); itl.Next ())
859     {
860       TopoDS_Shape aWire = itl.Value ();
861       CurFace = WFmap (aWire);
862       theCopy = aSub.Copy (aWire);
863       aWire = theCopy.First ();
864       //Adjusting period
865       TopLoc_Location L;
866       Handle (Geom_Surface) theSurf = BRep_Tool::Surface (TopoDS::Face (CurFace), L);
867       eit.Initialize (aWire);
868       for (; eit.More (); eit.Next ())
869       {
870         TopoDS_Edge anEdge = TopoDS::Edge (eit.Value ());
871         gp_Pnt2d Pfirst, Plast, Pmid;
872         BRep_Tool::UVPoints (anEdge, TopoDS::Face (CurFace), Pfirst, Plast);
873         BRepAdaptor_Curve2d bc2d (anEdge, TopoDS::Face (CurFace));
874         Pmid = bc2d.Value ((bc2d.FirstParameter () + bc2d.LastParameter ()) / 2.);
875         gp_Vec2d offset;
876         Standard_Boolean translate = Standard_False;
877         if (Pfirst.X () - 2.*M_PI > Precision::Confusion () ||
878           Plast.X () - 2.*M_PI > Precision::Confusion () ||
879           Pmid.X () - 2.*M_PI > Precision::Confusion ())
880         {
881           offset.SetCoord (-2.*M_PI, 0);
882           translate = Standard_True;
883         }
884         if (Pfirst.X () < -Precision::Confusion () ||
885           Plast.X () < -Precision::Confusion () ||
886           Pmid.X () < -Precision::Confusion ())
887         {
888           offset.SetCoord (2.*M_PI, 0);
889           translate = Standard_True;
890         }
891         if (translate)
892         {
893           const Handle (BRep_TEdge)& TE = *((Handle (BRep_TEdge)*) &anEdge.TShape ());
894           BRep_ListIteratorOfListOfCurveRepresentation itcr (TE->ChangeCurves ());
895           Handle (BRep_GCurve) GC;
896
897           for (; itcr.More (); itcr.Next ())
898           {
899             GC = Handle (BRep_GCurve)::DownCast (itcr.Value ());
900             if (!GC.IsNull () && GC->IsCurveOnSurface (theSurf, L))
901             {
902               Handle (Geom2d_Curve) PC = GC->PCurve ();
903               PC = Handle (Geom2d_Curve)::DownCast (PC->Translated (offset));
904               GC->PCurve (PC);
905               TE->ChangeCurves ().Remove (itcr);
906               TE->ChangeCurves ().Append (GC);
907               break;
908             }
909           }
910         }
911       }
912       ///////////////////
913       eit.Initialize (aWire, Standard_False);
914       for (; eit.More (); eit.Next ())
915       {
916         TopoDS_Shape anEdge = eit.Value ();
917         BB.Add (CurWire, anEdge);
918       }
919       if (aSub.IsCopied (CurFace))
920       {
921         theCopy = aSub.Copy (CurFace);
922         CurFace = theCopy.First ();
923       }
924       CurFace.Free (Standard_True);
925       BB.Remove (CurFace, aWire);
926     }
927   }
928 }
929 //=======================================================================
930 //function : CorrectVertexTol
931 //purpose  : 
932 //=======================================================================
933
934 void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
935 {
936   TopTools_MapOfShape anInitVertices, anInitEdges, aNewEdges;
937   TopExp_Explorer anExp(myInitialShape, TopAbs_EDGE);
938   for(; anExp.More(); anExp.Next())
939   {
940     anInitEdges.Add(anExp.Current());
941     TopoDS_Iterator anIter(anExp.Current());
942     for(; anIter.More(); anIter.Next())
943     {
944       anInitVertices.Add(anIter.Value());
945     }
946   }
947   //
948
949   BRep_Builder aBB;
950   myVtxToReplace.Clear();
951   anExp.Init(myShape, TopAbs_EDGE);
952   for(; anExp.More(); anExp.Next())
953   {
954     const TopoDS_Shape& anE = anExp.Current();
955     //Skip old (not modified) edges
956     if(anInitEdges.Contains(anE))
957       continue;
958     //
959     //Skip processed edges
960     if(aNewEdges.Contains(anE))
961       continue;
962     //
963     aNewEdges.Add(anE);
964     //
965     Standard_Real anETol = BRep_Tool::Tolerance(TopoDS::Edge(anE));
966     TopoDS_Iterator anIter(anE);
967     for(; anIter.More(); anIter.Next())
968     {
969       const TopoDS_Vertex& aVtx = TopoDS::Vertex(anIter.Value());
970       if(anInitVertices.Contains(aVtx))
971       {
972         if(myVtxToReplace.IsBound(aVtx))
973         {
974           aBB.UpdateVertex(TopoDS::Vertex(myVtxToReplace(aVtx)), anETol + Epsilon(anETol));
975         }
976         else
977         {
978           Standard_Real aVTol = BRep_Tool::Tolerance(aVtx);
979           if(aVTol < anETol)
980           {
981             TopoDS_Vertex aNewVtx;
982             gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx);
983             aBB.MakeVertex(aNewVtx, aVPnt,anETol + Epsilon(anETol));
984             aNewVtx.Orientation(aVtx.Orientation());
985             myVtxToReplace.Bind(aVtx, aNewVtx);
986           }
987         }
988       }
989       else
990       {
991         aBB.UpdateVertex(aVtx, anETol + Epsilon(anETol));
992       }
993     }
994   }
995   //
996   if(myVtxToReplace.IsEmpty())
997   {
998     return;
999   }
1000   //
1001   mySubs.Clear();
1002   TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myVtxToReplace);
1003   for(; anIter.More(); anIter.Next())
1004   {
1005     mySubs.Replace(anIter.Key(), anIter.Value());
1006   }
1007   mySubs.Apply( myShape );
1008   myShape = mySubs.Value(myShape);
1009   //
1010 }