0028577: Get rid of the TopOpeBRep* algorithms in TKOffset toolkit
[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 k, 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     for (j = 1; j < ParsNonSeam(i).Length(); j++)
483       for (k = j+1; k <= ParsNonSeam(i).Length(); k++)
484         if (ParsNonSeam(i)(k) < ParsNonSeam(i)(j))
485         {
486           Standard_Real temp = ParsNonSeam(i)(j);
487           ParsNonSeam(i)(j) = ParsNonSeam(i)(k);
488           ParsNonSeam(i)(k) = temp;
489           TopoDS_Shape tmp = Seam(i)(j);
490           Seam(i)(j) = Seam(i)(k);
491           Seam(i)(k) = tmp;
492           temp = ParsSeam(i)(j);
493           ParsSeam(i)(j) = ParsSeam(i)(k);
494           ParsSeam(i)(k) = temp;
495         }
496         BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal iter( Emap );
497         for (; iter.More(); iter.Next())
498         {
499           TColStd_SequenceOfReal Seq;
500           Seq = iter.Value();
501           for (i = 1; i < Seq.Length(); i++)
502             for (j = i+1; j <= Seq.Length(); j++)
503               if (Seq(j) < Seq(i))
504               {
505                 Standard_Real temp = Seq(i);
506                 Seq(i) = Seq(j);
507                 Seq(j) = temp;
508               }
509               Emap( iter.Key() ) = Seq;
510         }
511         BRepFill_DataMapOfShapeSequenceOfReal EPmap;
512         TopTools_DataMapOfShapeSequenceOfShape EVmap; //Seam
513         TopTools_DataMapOfShapeSequenceOfShape EWmap; //Seam and wires intersecting it
514         iter.Initialize( Emap );
515         for (; iter.More(); iter.Next())
516         {
517           TColStd_SequenceOfReal parseq;
518           EPmap.Bind( iter.Key(), parseq );
519           TopTools_SequenceOfShape shapeseq;
520           EVmap.Bind( iter.Key(), shapeseq );
521           TopTools_SequenceOfShape shapeseq2;
522           EWmap.Bind( iter.Key(), shapeseq2 );
523         }
524
525         //Reconstruction of non-seam edges
526         BRepTools_Substitution aSub;
527         BRep_Builder BB;
528         for (i = 1; i <= NonSeam.Length(); i++)
529         {
530           TopoDS_Edge anEdge = TopoDS::Edge( NonSeam(i) );
531           TopTools_ListOfShape NewEdges;
532           TopoDS_Edge NewE;
533           TopoDS_Vertex Vfirst, Vlast;
534           TopExp::Vertices( anEdge, Vfirst, Vlast );
535           Standard_Real par, FirstPar, LastPar;
536           BRep_Tool::Range( anEdge, FirstPar, LastPar );
537           Standard_Integer firstind = 1;
538           par = ParsNonSeam(i)(1);
539           TopoDS_Edge SeamEdge = TopoDS::Edge( Seam(i)(1) );
540           //Find the face
541           for (j = 1; j <= Eseq.Length(); j++)
542             if (SeamEdge.IsSame( Eseq(j) ))
543               break;
544           TopoDS_Face theFace = TopoDS::Face( Fseq(j) );
545           TopLoc_Location L;
546           Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( theFace, L );
547           if (Abs(par-FirstPar) <= Precision::Confusion())
548           {
549             BB.UpdateVertex( Vfirst, ParsSeam(i)(1), SeamEdge, BRep_Tool::Tolerance(Vfirst) );
550             EPmap( SeamEdge ).Append( ParsSeam(i)(1) );
551             EVmap( SeamEdge ).Append( Vfirst );
552             EWmap( SeamEdge ).Append( NonSeamWires(i) );
553             firstind = 2;
554           }
555           Standard_Real prevpar = FirstPar;
556           TopoDS_Vertex PrevV = Vfirst;
557           for (j = firstind; j <= ParsNonSeam(i).Length(); j++)
558           {
559             TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
560             NewE = TopoDS::Edge( aLocalShape );
561             //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
562             TopoDS_Vertex NewV;
563             par = ParsNonSeam(i)(j);
564             BB.Range( NewE, prevpar, par );
565             SeamEdge = TopoDS::Edge( Seam(i)(j) );
566             if (j == ParsNonSeam(i).Length() && Abs(par-LastPar) <= Precision::Confusion())
567             {
568               NewV = Vlast;
569               if (firstind == 2 && j == 2)
570               {
571                 BB.UpdateVertex( Vlast, ParsSeam(i)(j), SeamEdge, BRep_Tool::Tolerance(Vlast) );
572                 EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
573                 EVmap( SeamEdge ).Append( Vlast );
574                 EWmap( SeamEdge ).Append( NonSeamWires(i) );
575                 break;
576               }
577             }
578             else
579             {
580               BRepAdaptor_Curve bcur( NewE );
581               gp_Pnt Point = bcur.Value( par );
582               NewV = BRepLib_MakeVertex( Point );
583               BB.UpdateVertex( NewV, par, NewE, 10.*Precision::Confusion() );
584             }
585             BB.UpdateVertex( NewV, ParsSeam(i)(j), SeamEdge, 10.*Precision::Confusion() );
586             NewE.Orientation( TopAbs_FORWARD );
587             BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
588             BB.Add( NewE, NewV.Oriented(TopAbs_REVERSED) );
589
590             NewEdges.Append( NewE );
591             EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
592             EVmap( SeamEdge ).Append( NewV );
593             EWmap( SeamEdge ).Append( NonSeamWires(i) );
594
595             prevpar = par;
596             PrevV = NewV;
597           }
598           //The last edge
599           TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
600           NewE = TopoDS::Edge( aLocalShape );
601           //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
602           par = LastPar;
603           if (Abs(prevpar-par) > Precision::Confusion())
604           {
605             BB.Range( NewE, prevpar, par );
606             NewE.Orientation( TopAbs_FORWARD );
607             BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
608             BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
609             NewEdges.Append( NewE );
610           }
611
612           //Substitute anEdge by NewEdges
613           aSub.Substitute( anEdge, NewEdges );
614         }
615
616         //Sorting of EPmap and EVmap and removing repeating points from them
617         iter.Initialize( EPmap );
618         for (; iter.More(); iter.Next())
619         {
620           TColStd_SequenceOfReal Seq;
621           Seq = iter.Value();
622           TopTools_SequenceOfShape SeqShape;
623           SeqShape = EVmap( iter.Key() );
624           TopTools_SequenceOfShape SeqShape2;
625           SeqShape2 = EWmap( iter.Key() );
626           for (i = 1; i < Seq.Length(); i++)
627             for (j = i+1; j <= Seq.Length(); j++)
628               if (Seq(j) < Seq(i))
629               {
630                 Standard_Real temp = Seq(i);
631                 Seq(i) = Seq(j);
632                 Seq(j) = temp;
633                 TopoDS_Shape tmp = SeqShape(i);
634                 SeqShape(i) = SeqShape(j);
635                 SeqShape(j) = tmp;
636                 tmp = SeqShape2(i);
637                 SeqShape2(i) = SeqShape2(j);
638                 SeqShape2(j) = tmp;
639               }
640               EPmap( iter.Key() ) = Seq;
641               EVmap( iter.Key() ) = SeqShape;
642               EWmap( iter.Key() ) = SeqShape2;
643         }
644         iter.Initialize( EPmap );
645         for (; iter.More(); iter.Next())
646         {
647           TColStd_SequenceOfReal Seq;
648           Seq = iter.Value();
649           TopTools_SequenceOfShape SeqShape;
650           SeqShape = EVmap( iter.Key() );
651           TopTools_SequenceOfShape SeqShape2;
652           SeqShape2 = EWmap( iter.Key() );
653           Standard_Boolean remove = Standard_True;
654           while (remove)
655           {
656             remove = Standard_False;
657             for (i = 1; i < Seq.Length(); i++)
658               if (Abs(Seq(i)-Seq(i+1)) <= Precision::Confusion())
659               {
660                 Seq.Remove(i+1);
661                 SeqShape.Remove(i+1);
662                 SeqShape2.Remove(i+1);
663                 remove = Standard_True;
664               }
665           }
666           EPmap( iter.Key() ) = Seq;
667           EVmap( iter.Key() ) = SeqShape;
668           EWmap( iter.Key() ) = SeqShape2;
669         }
670
671         //Reconstruction of seam edges
672         TopTools_DataMapOfShapeShape VEmap;
673         iter.Initialize( Emap );
674         for (; iter.More(); iter.Next())
675         {
676           TopoDS_Edge anEdge = TopoDS::Edge( iter.Key() );
677           Standard_Boolean onepoint = Standard_False;
678           TopTools_ListOfShape NewEdges;
679           TColStd_SequenceOfReal Seq;
680           Seq = iter.Value();
681           TColStd_SequenceOfReal Seq2;
682           Seq2 = EPmap( anEdge );
683           TopTools_SequenceOfShape SeqVer;
684           SeqVer = EVmap( anEdge );
685           TopTools_SequenceOfShape SeqWire;
686           SeqWire = EWmap( anEdge );
687           TopoDS_Vertex Vfirst, Vlast;
688           TopExp::Vertices( anEdge, Vfirst, Vlast );
689           Standard_Real fpar, lpar, FirstPar, LastPar;
690           BRep_Tool::Range( anEdge, FirstPar, LastPar );
691           fpar = FirstPar;
692           lpar = Seq(1);
693           TopoDS_Edge NewE;
694           Standard_Integer firstind = 1;
695           if (Abs(fpar-lpar) <= Precision::Confusion())
696           {
697             firstind = 2;
698             fpar = Seq(1);
699             lpar = Seq(2);
700           }
701           else
702           {
703             if (Seq.Length()%2 != 0)
704             {
705               VEmap.Bind( Vfirst, anEdge );
706               firstind = 2;
707               fpar = Seq(1);
708               if (Seq.Length() > 2)
709                 lpar = Seq(2);
710               else
711                 onepoint = Standard_True;
712             }
713           }
714           if (!onepoint)
715           {
716             TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
717             NewE = TopoDS::Edge( aLocalShape );
718             //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
719             BB.Range( NewE, fpar, lpar );
720             NewE.Orientation( TopAbs_FORWARD );
721             if (firstind == 1)
722             {
723               BB.Add( NewE, Vfirst.Oriented(TopAbs_FORWARD) );
724               aLocalShape = SeqVer(1).Oriented(TopAbs_REVERSED);
725               BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
726               //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_REVERSED) ) );
727             }
728             else
729             {
730               aLocalShape = SeqVer(1).Oriented(TopAbs_FORWARD);
731               BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
732               aLocalShape = SeqVer(2).Oriented(TopAbs_REVERSED);
733               BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
734               //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_FORWARD) ) );
735               //BB.Add( NewE, TopoDS::Vertex( SeqVer(2).Oriented(TopAbs_REVERSED) ) );
736             }
737             NewEdges.Append( NewE );
738
739             firstind++;
740             for (i = firstind; i < Seq.Length(); i += 2)
741             {
742               aLocalShape = anEdge.EmptyCopied();
743               NewE = TopoDS::Edge( aLocalShape );
744               //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
745               fpar = Seq(i);
746               lpar = Seq(i+1);
747               BB.Range( NewE, fpar, lpar );
748               //Find vertices
749               for (j = 1; j <= Seq2.Length(); j++)
750                 if (Abs(fpar-Seq2(j)) <= Precision::Confusion())
751                   break;
752               NewE.Orientation( TopAbs_FORWARD );
753               TopoDS_Shape aLocalShapeCur = SeqVer(j).Oriented(TopAbs_FORWARD);
754               BB.Add( NewE, TopoDS::Vertex( aLocalShapeCur) );
755               aLocalShapeCur = SeqVer(j+1).Oriented(TopAbs_REVERSED);
756               BB.Add( NewE, TopoDS::Vertex( aLocalShapeCur ) );
757               //BB.Add( NewE, TopoDS::Vertex( SeqVer(j).Oriented(TopAbs_FORWARD) ) );
758               //BB.Add( NewE, TopoDS::Vertex( SeqVer(j+1).Oriented(TopAbs_REVERSED) ) );
759               NewEdges.Append( NewE );
760             }
761           }
762
763           i = Seq.Length();
764           fpar = Seq(i);
765           lpar = LastPar;
766           if (Abs(fpar-lpar) <= Precision::Confusion())
767             continue;
768           TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
769           NewE = TopoDS::Edge( aLocalShape );
770           //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
771           BB.Range( NewE, fpar, lpar );
772           NewE.Orientation( TopAbs_FORWARD );
773           aLocalShape = SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD);
774           BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
775           //BB.Add( NewE, TopoDS::Vertex( SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD) ) );
776           BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
777           NewEdges.Append( NewE );
778
779           //Substitute anEdge by NewEdges
780           aSub.Substitute( anEdge, NewEdges );
781         }
782
783         //Removing edges connected with missing extremities of seam edges
784         TopTools_DataMapIteratorOfDataMapOfShapeShape itve( VEmap );
785         for (; itve.More(); itve.Next())
786         {
787           TopoDS_Shape V = itve.Key();
788           TopoDS_Shape E = itve.Value();
789           TopoDS_Shape W;
790           for (i = 1; i <= Eseq.Length(); i++)
791             if (E.IsSame( Eseq(i) ))
792             {
793               W = Wseq(i);
794               break;
795             }
796             TopoDS_Shape Etoremove;
797             eit.Initialize( W );
798             for (; eit.More(); eit.Next())
799             {
800               TopoDS_Edge CurE = TopoDS::Edge( eit.Value() );
801               if (CurE.IsSame( E ))
802                 continue;
803               TopoDS_Vertex Vfirst, Vlast;
804               TopExp::Vertices( CurE, Vfirst, Vlast );
805               if (Vfirst.IsSame( V ) || Vlast.IsSame( V ))
806               {
807                 Etoremove = CurE;
808                 break;
809               }
810             }
811             if (! Etoremove.IsNull())
812             {
813               W.Free( Standard_True );
814               BB.Remove( W, Etoremove );
815             }
816         }
817
818         aSub.Build( myShape );
819         if (aSub.IsCopied( myShape ))
820         {
821           const TopTools_ListOfShape& listSh = aSub.Copy( myShape );
822           if (! listSh.IsEmpty())
823             myShape = listSh.First();
824         }
825
826         //Reconstruction of wires
827         TopTools_ListOfShape theCopy;
828         TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itww( WWmap );
829         for (; itww.More(); itww.Next())
830         {
831           CurWire = itww.Key();
832           theCopy = aSub.Copy( CurWire );
833           CurWire = theCopy.First();
834           CurWire.Free( Standard_True );
835           TopTools_ListIteratorOfListOfShape itl( itww.Value() );
836           for (; itl.More(); itl.Next())
837           {
838             TopoDS_Shape aWire = itl.Value();
839             CurFace = WFmap( aWire );
840             theCopy = aSub.Copy( aWire );
841             aWire = theCopy.First();
842             //Adjusting period
843             TopLoc_Location L;
844             Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( TopoDS::Face(CurFace), L );
845             eit.Initialize( aWire );
846             for (; eit.More(); eit.Next())
847             {
848               TopoDS_Edge anEdge = TopoDS::Edge( eit.Value() );
849               gp_Pnt2d Pfirst, Plast, Pmid;
850               BRep_Tool::UVPoints( anEdge, TopoDS::Face(CurFace), Pfirst, Plast );
851               BRepAdaptor_Curve2d bc2d( anEdge, TopoDS::Face(CurFace) );
852               Pmid = bc2d.Value( (bc2d.FirstParameter()+bc2d.LastParameter())/2. );
853               gp_Vec2d offset;
854               Standard_Boolean translate = Standard_False;
855               if (Pfirst.X()-2.*M_PI > Precision::Confusion() ||
856                 Plast.X()-2.*M_PI > Precision::Confusion()  ||
857                 Pmid.X()-2.*M_PI > Precision::Confusion())
858               {
859                 offset.SetCoord( -2.*M_PI, 0 );
860                 translate = Standard_True;
861               }
862               if (Pfirst.X() < -Precision::Confusion() ||
863                 Plast.X() < -Precision::Confusion()  ||
864                 Pmid.X() < -Precision::Confusion())
865               {
866                 offset.SetCoord( 2.*M_PI, 0 );
867                 translate = Standard_True;
868               }
869               if (translate)
870               {
871                 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
872                 BRep_ListIteratorOfListOfCurveRepresentation itcr( TE->ChangeCurves() );
873                 Handle(BRep_GCurve) GC;
874
875                 for (; itcr.More(); itcr.Next())
876                 {
877                   GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
878                   if (!GC.IsNull() && GC->IsCurveOnSurface( theSurf, L ))
879                   {
880                     Handle(Geom2d_Curve) PC = GC->PCurve();
881                     PC = Handle(Geom2d_Curve)::DownCast( PC->Translated( offset ) );
882                     GC->PCurve( PC );
883                     TE->ChangeCurves().Remove( itcr );
884                     TE->ChangeCurves().Append( GC );
885                     break;
886                   }
887                 }
888               }
889             }
890             ///////////////////
891             eit.Initialize( aWire, Standard_False );
892             for (; eit.More(); eit.Next())
893             {
894               TopoDS_Shape anEdge = eit.Value();
895               BB.Add( CurWire, anEdge );
896             }
897             if (aSub.IsCopied( CurFace ))
898             {
899               theCopy = aSub.Copy( CurFace );
900               CurFace = theCopy.First();
901             }
902             CurFace.Free( Standard_True );
903             BB.Remove( CurFace, aWire );
904           }
905         }
906 }
907 //=======================================================================
908 //function : CorrectVertexTol
909 //purpose  : 
910 //=======================================================================
911
912 void BRepOffsetAPI_DraftAngle::CorrectVertexTol()
913 {
914   TopTools_MapOfShape anInitVertices, anInitEdges, aNewEdges;
915   TopExp_Explorer anExp(myInitialShape, TopAbs_EDGE);
916   for(; anExp.More(); anExp.Next())
917   {
918     anInitEdges.Add(anExp.Current());
919     TopoDS_Iterator anIter(anExp.Current());
920     for(; anIter.More(); anIter.Next())
921     {
922       anInitVertices.Add(anIter.Value());
923     }
924   }
925   //
926
927   BRep_Builder aBB;
928   myVtxToReplace.Clear();
929   anExp.Init(myShape, TopAbs_EDGE);
930   for(; anExp.More(); anExp.Next())
931   {
932     const TopoDS_Shape& anE = anExp.Current();
933     //Skip old (not modified) edges
934     if(anInitEdges.Contains(anE))
935       continue;
936     //
937     //Skip processed edges
938     if(aNewEdges.Contains(anE))
939       continue;
940     //
941     aNewEdges.Add(anE);
942     //
943     Standard_Real anETol = BRep_Tool::Tolerance(TopoDS::Edge(anE));
944     TopoDS_Iterator anIter(anE);
945     for(; anIter.More(); anIter.Next())
946     {
947       const TopoDS_Vertex& aVtx = TopoDS::Vertex(anIter.Value());
948       if(anInitVertices.Contains(aVtx))
949       {
950         if(myVtxToReplace.IsBound(aVtx))
951         {
952           aBB.UpdateVertex(TopoDS::Vertex(myVtxToReplace(aVtx)), anETol + Epsilon(anETol));
953         }
954         else
955         {
956           Standard_Real aVTol = BRep_Tool::Tolerance(aVtx);
957           if(aVTol < anETol)
958           {
959             TopoDS_Vertex aNewVtx;
960             gp_Pnt aVPnt = BRep_Tool::Pnt(aVtx);
961             aBB.MakeVertex(aNewVtx, aVPnt,anETol + Epsilon(anETol));
962             aNewVtx.Orientation(aVtx.Orientation());
963             myVtxToReplace.Bind(aVtx, aNewVtx);
964           }
965         }
966       }
967       else
968       {
969         aBB.UpdateVertex(aVtx, anETol + Epsilon(anETol));
970       }
971     }
972   }
973   //
974   if(myVtxToReplace.IsEmpty())
975   {
976     return;
977   }
978   //
979   mySubs.Clear();
980   TopTools_DataMapIteratorOfDataMapOfShapeShape anIter(myVtxToReplace);
981   for(; anIter.More(); anIter.Next())
982   {
983     mySubs.Replace(anIter.Key(), anIter.Value());
984   }
985   mySubs.Apply( myShape );
986   myShape = mySubs.Value(myShape);
987   //
988 }