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