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