0026811: Coding rules - drop unused Draw Harness command deboucle
[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 : ModifiedFaces
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       myGenerated.Append(ModifiedShape (S));
220  
221     }
222   }
223   return myGenerated;
224 }
225
226 //=======================================================================
227 //function : ModifiedFaces
228 //purpose  : 
229 //=======================================================================
230
231 const TopTools_ListOfShape& BRepOffsetAPI_DraftAngle::Modified(const TopoDS_Shape& S) 
232 {
233   myGenerated.Clear();
234   Standard_NullObject_Raise_if(myInitialShape.IsNull(),"");
235   Handle(Draft_Modification) DMod = Handle(Draft_Modification)::DownCast (myModification);
236
237   if (S.ShapeType() == TopAbs_FACE) {
238     Handle(Geom_Surface) Surf;
239     TopLoc_Location      L;
240     Standard_Real        Tol;
241     Standard_Boolean     RW,RF;
242     
243     if (!DMod->NewSurface(TopoDS::Face(S), Surf, L, Tol, RW, RF)) {
244       // Ce n est pas une generation => peut etre une  modif
245       myGenerated.Append(ModifiedShape (S));
246       if (myGenerated.Extent() == 1 && myGenerated.First().IsSame(S)) {
247         myGenerated.Clear();
248       }
249     }
250   }
251   return myGenerated;
252 }
253
254
255 //=======================================================================
256 //function : Build
257 //purpose  : 
258 //=======================================================================
259
260 void BRepOffsetAPI_DraftAngle::Build()
261 {
262   Handle(Draft_Modification)::DownCast (myModification)->Perform();
263   if (!Handle(Draft_Modification)::DownCast (myModification)->IsDone()) {
264     NotDone();
265   }
266   else {
267     DoModif(myInitialShape);
268     //BRepLib::SameParameter( myShape, 1.0e-7, Standard_True ); //patch
269     CorrectWires();
270     BRepLib::SameParameter( myShape, 1.0e-7, Standard_True ); //patch
271   }
272 }
273
274 //=======================================================================
275 //function : CorrectWires
276 //purpose  : 
277 //=======================================================================
278
279 void BRepOffsetAPI_DraftAngle::CorrectWires()
280 {
281   Standard_Real TolInter = 1.e-7;
282   Standard_Integer i, j, k;
283
284   TopTools_SequenceOfShape Eseq;
285   TopTools_SequenceOfShape Wseq;
286   TopTools_SequenceOfShape Fseq;
287   TopoDS_Shape CurEdge, CurWire, CurFace;
288   TopoDS_Iterator wit, eit;
289
290   TopExp_Explorer fexp( myShape, TopAbs_FACE );
291   for (; fexp.More(); fexp.Next())
292     {
293       CurFace = fexp.Current();
294       wit.Initialize( CurFace );
295       for (; wit.More(); wit.Next())
296         {
297           CurWire = wit.Value();
298           TopTools_MapOfShape emap;
299           eit.Initialize( CurWire );
300           for (; eit.More(); eit.Next())
301             emap.Add( eit.Value() );
302           TopTools_MapIteratorOfMapOfShape mapit( emap );
303           for (; mapit.More(); mapit.Next())
304             {
305               CurEdge = mapit.Key();
306               if (BRepTools::IsReallyClosed( TopoDS::Edge(CurEdge), TopoDS::Face(CurFace) ))
307                 {
308                   Eseq.Append( CurEdge );
309                   Wseq.Append( CurWire );
310                   Fseq.Append( CurFace );
311                 }
312             }
313         }
314     }
315
316   BRepFill_DataMapOfShapeSequenceOfReal Emap;
317
318   TopTools_SequenceOfShape NonSeam;
319   TopTools_SequenceOfShape NonSeamWires;
320   BRepOffsetAPI_SequenceOfSequenceOfReal ParsNonSeam;
321   BRepOffsetAPI_SequenceOfSequenceOfShape Seam;
322   BRepOffsetAPI_SequenceOfSequenceOfReal ParsSeam;
323
324   TopTools_DataMapOfShapeShape WFmap;
325   TopTools_DataMapOfShapeListOfShape WWmap;
326   for (i = 1; i <= Eseq.Length(); i++)
327     {
328       CurEdge = Eseq(i);
329       CurWire = Wseq(i);
330       CurFace = Fseq(i);
331       wit.Initialize( CurFace );
332       for (; wit.More(); wit.Next())
333         {
334           TopoDS_Shape aWire = wit.Value();
335           if (! aWire.IsSame( CurWire ))
336             {
337               TColgp_SequenceOfPnt pts;
338               TopTools_SequenceOfShape edges;
339               TColStd_SequenceOfReal pars;
340               Standard_Boolean Wadd = Standard_False;
341               eit.Initialize( aWire );
342               for (; eit.More(); eit.Next())
343                 {
344                   TopoDS_Shape anEdge = eit.Value();
345                   TopOpeBRep_EdgesIntersector EInter;
346                   EInter.SetFaces( CurFace, CurFace );
347                   EInter.ForceTolerances( TolInter, TolInter );
348                   EInter.Perform( CurEdge, anEdge );
349                   if (EInter.IsEmpty())
350                     {
351                       EInter.Perform( CurEdge.Reversed(), anEdge );
352                       if (EInter.IsEmpty())
353                         continue;
354                     }
355                   Wadd = Standard_True;
356                   if (! WFmap.IsBound( aWire ))
357                     WFmap.Bind( aWire, CurFace );
358                   Standard_Integer ind = 0;
359                   for (j = 1; j <= NonSeam.Length(); j++)
360                     if (anEdge.IsSame( NonSeam(j) ))
361                       {
362                         ind = j;
363                         break;
364                       }
365                   if (ind == 0)
366                     {
367                       NonSeam.Append( anEdge );
368                       NonSeamWires.Append( aWire );
369                       ind = NonSeam.Length();
370                       TColStd_SequenceOfReal emptyseq1, emptyseq2;
371                       TopTools_SequenceOfShape emptyedgeseq;
372                       ParsNonSeam.Append( emptyseq1 );
373                       Seam.Append( emptyedgeseq );
374                       ParsSeam.Append( emptyseq2 );
375                     }
376                   if (! Emap.IsBound( CurEdge ))
377                     {
378                       TColStd_SequenceOfReal emptyseq;
379                       Emap.Bind( CurEdge, emptyseq );
380                     }
381                   EInter.InitPoint();
382                   for (; EInter.MorePoint(); EInter.NextPoint())
383                     {
384                       const TopOpeBRep_Point2d& bp = EInter.Point();
385                       if (bp.IsVertex(2))
386                         {
387                           gp_Pnt Pnt = bp.Value();
388                           Standard_Integer ied = 0;
389                           for (j = 1; j <= pts.Length(); j++)
390                             if (Pnt.IsEqual( pts(j), Precision::Confusion() ))
391                               {
392                                 ied = j;
393                                 break;
394                               }
395                           if (ied == 0)
396                             {
397                               pts.Append( Pnt );
398                               edges.Append( anEdge );
399                               pars.Append( bp.Parameter(2) );
400                               Emap(CurEdge).Append( bp.Parameter(1) );
401                               ParsNonSeam(ind).Append( bp.Parameter(2) );
402                               Seam(ind).Append( CurEdge );
403                               ParsSeam(ind).Append( bp.Parameter(1) );
404                             }
405                           /*
406                           else
407                             {
408                               Standard_Real ParOnSeam = bp.Parameter(1);
409                               Standard_Real Par1 = pars(ied);
410                               Standard_Real Par2 = bp.Parameter(2);
411                               BRepAdaptor_Curve2d SeamCurve( CurEdge, CurFace );
412                               BRepAdaptor_Curve2d Curve1( edges(ied), CurFace );
413                               BRepAdaptor_Curve2d Curve2( anEdge. CurFace );
414                               gp_Pnt2d P2d;
415                               gp_Vec2d SeamDer, Der1, Der2;
416                               //SeamCurve->D1( ParOnSeam, P2d, SeamDer );
417                               //Curve1->D1( Par1, P2d, Der1 );
418                               //Curve2->D1( Par2, P2d, Der2 );
419                               Standard_Real Crossed1 = SeamDer ^ Der1;
420                               Standard_Real Crossed2 = SeamDer ^ Der2;
421                               //if (Crossed1 > 0
422                             }
423                           */
424                         }
425                       else // ! bp.IsVertex(2)
426                         {
427                           //Temporary the case of tangency is not implemented
428                           Emap(CurEdge).Append( bp.Parameter(1) );
429                           ParsNonSeam(ind).Append( bp.Parameter(2) );
430                           Seam(ind).Append( CurEdge );
431                           ParsSeam(ind).Append( bp.Parameter(1) );
432                         }
433                     } //for (; EInter.MorePoint(); EInter.NextPoint())
434                 } //for (; eit.More(); eit.Next())
435               if (Wadd)
436                 {
437                   if (! WWmap.IsBound( CurWire ))
438                     {
439                       TopTools_ListOfShape emptylist;
440                       WWmap.Bind( CurWire, emptylist );
441                     }
442                   WWmap(CurWire).Append( aWire );
443                 }
444             } //if (! aWire.IsSame( CurWire ))
445         } //for (; wit.More(); wit.Next())
446     } //for (i = 1; i <= Eseq.Length(); i++)
447
448   //Sorting
449   for (i = 1; i <= NonSeam.Length(); i++)
450     for (j = 1; j < ParsNonSeam(i).Length(); j++)
451       for (k = j+1; k <= ParsNonSeam(i).Length(); k++)
452         if (ParsNonSeam(i)(k) < ParsNonSeam(i)(j))
453           {
454             Standard_Real temp = ParsNonSeam(i)(j);
455             ParsNonSeam(i)(j) = ParsNonSeam(i)(k);
456             ParsNonSeam(i)(k) = temp;
457             TopoDS_Shape tmp = Seam(i)(j);
458             Seam(i)(j) = Seam(i)(k);
459             Seam(i)(k) = tmp;
460             temp = ParsSeam(i)(j);
461             ParsSeam(i)(j) = ParsSeam(i)(k);
462             ParsSeam(i)(k) = temp;
463           }
464   BRepFill_DataMapIteratorOfDataMapOfShapeSequenceOfReal iter( Emap );
465   for (; iter.More(); iter.Next())
466     {
467       TColStd_SequenceOfReal Seq;
468       Seq = iter.Value();
469       for (i = 1; i < Seq.Length(); i++)
470       for (j = i+1; j <= Seq.Length(); j++)
471         if (Seq(j) < Seq(i))
472           {
473             Standard_Real temp = Seq(i);
474             Seq(i) = Seq(j);
475             Seq(j) = temp;
476           }
477       Emap( iter.Key() ) = Seq;
478     }
479   BRepFill_DataMapOfShapeSequenceOfReal EPmap;
480   TopTools_DataMapOfShapeSequenceOfShape EVmap; //Seam
481   TopTools_DataMapOfShapeSequenceOfShape EWmap; //Seam and wires intersecting it
482   iter.Initialize( Emap );
483   for (; iter.More(); iter.Next())
484     {
485       TColStd_SequenceOfReal parseq;
486       EPmap.Bind( iter.Key(), parseq );
487       TopTools_SequenceOfShape shapeseq;
488       EVmap.Bind( iter.Key(), shapeseq );
489       TopTools_SequenceOfShape shapeseq2;
490       EWmap.Bind( iter.Key(), shapeseq2 );
491     }
492
493   //Reconstruction of non-seam edges
494   BRepTools_Substitution aSub;
495   BRep_Builder BB;
496   for (i = 1; i <= NonSeam.Length(); i++)
497     {
498       TopoDS_Edge anEdge = TopoDS::Edge( NonSeam(i) );
499       TopTools_ListOfShape NewEdges;
500       TopoDS_Edge NewE;
501       TopoDS_Vertex Vfirst, Vlast;
502       TopExp::Vertices( anEdge, Vfirst, Vlast );
503       Standard_Real par, FirstPar, LastPar;
504       BRep_Tool::Range( anEdge, FirstPar, LastPar );
505       Standard_Integer firstind = 1;
506       par = ParsNonSeam(i)(1);
507       TopoDS_Edge SeamEdge = TopoDS::Edge( Seam(i)(1) );
508       //Find the face
509       for (j = 1; j <= Eseq.Length(); j++)
510         if (SeamEdge.IsSame( Eseq(j) ))
511           break;
512       TopoDS_Face theFace = TopoDS::Face( Fseq(j) );
513       TopLoc_Location L;
514       Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( theFace, L );
515       if (Abs(par-FirstPar) <= Precision::Confusion())
516         {
517           BB.UpdateVertex( Vfirst, ParsSeam(i)(1), SeamEdge, BRep_Tool::Tolerance(Vfirst) );
518           EPmap( SeamEdge ).Append( ParsSeam(i)(1) );
519           EVmap( SeamEdge ).Append( Vfirst );
520           EWmap( SeamEdge ).Append( NonSeamWires(i) );
521           firstind = 2;
522         }
523       Standard_Real prevpar = FirstPar;
524       TopoDS_Vertex PrevV = Vfirst;
525       for (j = firstind; j <= ParsNonSeam(i).Length(); j++)
526         {
527           TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
528           NewE = TopoDS::Edge( aLocalShape );
529           //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
530           TopoDS_Vertex NewV;
531           par = ParsNonSeam(i)(j);
532           BB.Range( NewE, prevpar, par );
533           SeamEdge = TopoDS::Edge( Seam(i)(j) );
534           if (j == ParsNonSeam(i).Length() && Abs(par-LastPar) <= Precision::Confusion())
535             {
536               NewV = Vlast;
537               if (firstind == 2 && j == 2)
538                 {
539                   BB.UpdateVertex( Vlast, ParsSeam(i)(j), SeamEdge, BRep_Tool::Tolerance(Vlast) );
540                   EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
541                   EVmap( SeamEdge ).Append( Vlast );
542                   EWmap( SeamEdge ).Append( NonSeamWires(i) );
543                   break;
544                 }
545             }
546           else
547             {
548               BRepAdaptor_Curve bcur( NewE );
549               gp_Pnt Point = bcur.Value( par );
550               NewV = BRepLib_MakeVertex( Point );
551               BB.UpdateVertex( NewV, par, NewE, 10.*Precision::Confusion() );
552             }
553           BB.UpdateVertex( NewV, ParsSeam(i)(j), SeamEdge, 10.*Precision::Confusion() );
554           NewE.Orientation( TopAbs_FORWARD );
555           BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
556           BB.Add( NewE, NewV.Oriented(TopAbs_REVERSED) );
557
558           NewEdges.Append( NewE );
559           EPmap( SeamEdge ).Append( ParsSeam(i)(j) );
560           EVmap( SeamEdge ).Append( NewV );
561           EWmap( SeamEdge ).Append( NonSeamWires(i) );
562
563           prevpar = par;
564           PrevV = NewV;
565         }
566       //The last edge
567       TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
568       NewE = TopoDS::Edge( aLocalShape );
569       //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
570       par = LastPar;
571       if (Abs(prevpar-par) > Precision::Confusion())
572         {
573           BB.Range( NewE, prevpar, par );
574           NewE.Orientation( TopAbs_FORWARD );
575           BB.Add( NewE, PrevV.Oriented(TopAbs_FORWARD) );
576           BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
577           NewEdges.Append( NewE );
578         }
579
580       //Substitute anEdge by NewEdges
581       aSub.Substitute( anEdge, NewEdges );
582     }
583   
584   //Sorting of EPmap and EVmap and removing repeating points from them
585   iter.Initialize( EPmap );
586   for (; iter.More(); iter.Next())
587     {
588       TColStd_SequenceOfReal Seq;
589       Seq = iter.Value();
590       TopTools_SequenceOfShape SeqShape;
591       SeqShape = EVmap( iter.Key() );
592       TopTools_SequenceOfShape SeqShape2;
593       SeqShape2 = EWmap( iter.Key() );
594       for (i = 1; i < Seq.Length(); i++)
595       for (j = i+1; j <= Seq.Length(); j++)
596         if (Seq(j) < Seq(i))
597           {
598             Standard_Real temp = Seq(i);
599             Seq(i) = Seq(j);
600             Seq(j) = temp;
601             TopoDS_Shape tmp = SeqShape(i);
602             SeqShape(i) = SeqShape(j);
603             SeqShape(j) = tmp;
604             tmp = SeqShape2(i);
605             SeqShape2(i) = SeqShape2(j);
606             SeqShape2(j) = tmp;
607           }
608       EPmap( iter.Key() ) = Seq;
609       EVmap( iter.Key() ) = SeqShape;
610       EWmap( iter.Key() ) = SeqShape2;
611     }
612   iter.Initialize( EPmap );
613   for (; iter.More(); iter.Next())
614     {
615       TColStd_SequenceOfReal Seq;
616       Seq = iter.Value();
617       TopTools_SequenceOfShape SeqShape;
618       SeqShape = EVmap( iter.Key() );
619       TopTools_SequenceOfShape SeqShape2;
620       SeqShape2 = EWmap( iter.Key() );
621       Standard_Boolean remove = Standard_True;
622       while (remove)
623         {
624           remove = Standard_False;
625           for (i = 1; i < Seq.Length(); i++)
626             if (Abs(Seq(i)-Seq(i+1)) <= Precision::Confusion())
627               {
628                 Seq.Remove(i+1);
629                 SeqShape.Remove(i+1);
630                 SeqShape2.Remove(i+1);
631                 remove = Standard_True;
632               }
633         }
634       EPmap( iter.Key() ) = Seq;
635       EVmap( iter.Key() ) = SeqShape;
636       EWmap( iter.Key() ) = SeqShape2;
637     }
638
639   //Reconstruction of seam edges
640   TopTools_DataMapOfShapeShape VEmap;
641   iter.Initialize( Emap );
642   for (; iter.More(); iter.Next())
643     {
644       TopoDS_Edge anEdge = TopoDS::Edge( iter.Key() );
645       Standard_Boolean onepoint = Standard_False;
646       TopTools_ListOfShape NewEdges;
647       TColStd_SequenceOfReal Seq;
648       Seq = iter.Value();
649       TColStd_SequenceOfReal Seq2;
650       Seq2 = EPmap( anEdge );
651       TopTools_SequenceOfShape SeqVer;
652       SeqVer = EVmap( anEdge );
653       TopTools_SequenceOfShape SeqWire;
654       SeqWire = EWmap( anEdge );
655       TopoDS_Vertex Vfirst, Vlast;
656       TopExp::Vertices( anEdge, Vfirst, Vlast );
657       Standard_Real fpar, lpar, FirstPar, LastPar;
658       BRep_Tool::Range( anEdge, FirstPar, LastPar );
659       fpar = FirstPar;
660       lpar = Seq(1);
661       TopoDS_Edge NewE;
662       Standard_Integer firstind = 1;
663       if (Abs(fpar-lpar) <= Precision::Confusion())
664         {
665           firstind = 2;
666           fpar = Seq(1);
667           lpar = Seq(2);
668         }
669       else
670         {
671           if (Seq.Length()%2 != 0)
672             {
673               VEmap.Bind( Vfirst, anEdge );
674               firstind = 2;
675               fpar = Seq(1);
676               if (Seq.Length() > 2)
677                 lpar = Seq(2);
678               else
679                 onepoint = Standard_True;
680             }
681         }
682       if (!onepoint)
683         {
684           TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
685           NewE = TopoDS::Edge( aLocalShape );
686           //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
687           BB.Range( NewE, fpar, lpar );
688           NewE.Orientation( TopAbs_FORWARD );
689           if (firstind == 1)
690             {
691               BB.Add( NewE, Vfirst.Oriented(TopAbs_FORWARD) );
692               aLocalShape = SeqVer(1).Oriented(TopAbs_REVERSED);
693               BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
694               //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_REVERSED) ) );
695             }
696           else
697             {
698               aLocalShape = SeqVer(1).Oriented(TopAbs_FORWARD);
699               BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
700               aLocalShape = SeqVer(2).Oriented(TopAbs_REVERSED);
701               BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
702               //BB.Add( NewE, TopoDS::Vertex( SeqVer(1).Oriented(TopAbs_FORWARD) ) );
703               //BB.Add( NewE, TopoDS::Vertex( SeqVer(2).Oriented(TopAbs_REVERSED) ) );
704             }
705           NewEdges.Append( NewE );
706           
707           firstind++;
708           for (i = firstind; i < Seq.Length(); i += 2)
709             {
710               aLocalShape = anEdge.EmptyCopied();
711               NewE = TopoDS::Edge( aLocalShape );
712               //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
713               fpar = Seq(i);
714               lpar = Seq(i+1);
715               BB.Range( NewE, fpar, lpar );
716               //Find vertices
717               for (j = 1; j <= Seq2.Length(); j++)
718                 if (Abs(fpar-Seq2(j)) <= Precision::Confusion())
719                   break;
720               NewE.Orientation( TopAbs_FORWARD );
721               TopoDS_Shape aLocalShapeCur = SeqVer(j).Oriented(TopAbs_FORWARD);
722               BB.Add( NewE, TopoDS::Vertex( aLocalShapeCur) );
723               aLocalShapeCur = SeqVer(j+1).Oriented(TopAbs_REVERSED);
724               BB.Add( NewE, TopoDS::Vertex( aLocalShapeCur ) );
725               //BB.Add( NewE, TopoDS::Vertex( SeqVer(j).Oriented(TopAbs_FORWARD) ) );
726               //BB.Add( NewE, TopoDS::Vertex( SeqVer(j+1).Oriented(TopAbs_REVERSED) ) );
727               NewEdges.Append( NewE );
728             }
729         }
730
731       i = Seq.Length();
732       fpar = Seq(i);
733       lpar = LastPar;
734       if (Abs(fpar-lpar) <= Precision::Confusion())
735         continue;
736       TopoDS_Shape aLocalShape = anEdge.EmptyCopied();
737       NewE = TopoDS::Edge( aLocalShape );
738       //NewE = TopoDS::Edge( anEdge.EmptyCopied() );
739       BB.Range( NewE, fpar, lpar );
740       NewE.Orientation( TopAbs_FORWARD );
741       aLocalShape = SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD);
742       BB.Add( NewE, TopoDS::Vertex( aLocalShape ) );
743       //BB.Add( NewE, TopoDS::Vertex( SeqVer(SeqVer.Length()).Oriented(TopAbs_FORWARD) ) );
744       BB.Add( NewE, Vlast.Oriented(TopAbs_REVERSED) );
745       NewEdges.Append( NewE );
746
747       //Substitute anEdge by NewEdges
748       aSub.Substitute( anEdge, NewEdges );
749     }
750
751   //Removing edges connected with missing extremities of seam edges
752   TopTools_DataMapIteratorOfDataMapOfShapeShape itve( VEmap );
753   for (; itve.More(); itve.Next())
754     {
755       TopoDS_Shape V = itve.Key();
756       TopoDS_Shape E = itve.Value();
757       TopoDS_Shape W;
758       for (i = 1; i <= Eseq.Length(); i++)
759         if (E.IsSame( Eseq(i) ))
760           {
761             W = Wseq(i);
762             break;
763           }
764       TopoDS_Shape Etoremove;
765       eit.Initialize( W );
766       for (; eit.More(); eit.Next())
767         {
768           TopoDS_Edge CurE = TopoDS::Edge( eit.Value() );
769           if (CurE.IsSame( E ))
770             continue;
771           TopoDS_Vertex Vfirst, Vlast;
772           TopExp::Vertices( CurE, Vfirst, Vlast );
773           if (Vfirst.IsSame( V ) || Vlast.IsSame( V ))
774             {
775               Etoremove = CurE;
776               break;
777             }
778         }
779       if (! Etoremove.IsNull())
780         {
781           W.Free( Standard_True );
782           BB.Remove( W, Etoremove );
783         }
784     }
785
786   aSub.Build( myShape );
787   if (aSub.IsCopied( myShape ))
788     {
789       const TopTools_ListOfShape& listSh = aSub.Copy( myShape );
790       if (! listSh.IsEmpty())
791         myShape = listSh.First();
792     }
793
794   //Reconstruction of wires
795   TopTools_ListOfShape theCopy;
796   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itww( WWmap );
797   for (; itww.More(); itww.Next())
798     {
799       CurWire = itww.Key();
800       theCopy = aSub.Copy( CurWire );
801       CurWire = theCopy.First();
802       CurWire.Free( Standard_True );
803       TopTools_ListIteratorOfListOfShape itl( itww.Value() );
804       for (; itl.More(); itl.Next())
805         {
806           TopoDS_Shape aWire = itl.Value();
807           CurFace = WFmap( aWire );
808           theCopy = aSub.Copy( aWire );
809           aWire = theCopy.First();
810           //Adjusting period
811           TopLoc_Location L;
812           Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( TopoDS::Face(CurFace), L );
813           eit.Initialize( aWire );
814           for (; eit.More(); eit.Next())
815             {
816               TopoDS_Edge anEdge = TopoDS::Edge( eit.Value() );
817               gp_Pnt2d Pfirst, Plast, Pmid;
818               BRep_Tool::UVPoints( anEdge, TopoDS::Face(CurFace), Pfirst, Plast );
819               BRepAdaptor_Curve2d bc2d( anEdge, TopoDS::Face(CurFace) );
820               Pmid = bc2d.Value( (bc2d.FirstParameter()+bc2d.LastParameter())/2. );
821               gp_Vec2d offset;
822               Standard_Boolean translate = Standard_False;
823               if (Pfirst.X()-2.*M_PI > Precision::Confusion() ||
824                   Plast.X()-2.*M_PI > Precision::Confusion()  ||
825                   Pmid.X()-2.*M_PI > Precision::Confusion())
826                 {
827                   offset.SetCoord( -2.*M_PI, 0 );
828                   translate = Standard_True;
829                 }
830               if (Pfirst.X() < -Precision::Confusion() ||
831                   Plast.X() < -Precision::Confusion()  ||
832                   Pmid.X() < -Precision::Confusion())
833                 {
834                   offset.SetCoord( 2.*M_PI, 0 );
835                   translate = Standard_True;
836                 }
837               if (translate)
838                 {
839                   const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
840                   BRep_ListIteratorOfListOfCurveRepresentation itcr( TE->ChangeCurves() );
841                   Handle(BRep_GCurve) GC;
842                   
843                   for (; itcr.More(); itcr.Next())
844                     {
845                       GC = Handle(BRep_GCurve)::DownCast(itcr.Value());
846                       if (!GC.IsNull() && GC->IsCurveOnSurface( theSurf, L ))
847                         {
848                           Handle(Geom2d_Curve) PC = GC->PCurve();
849                           PC = Handle(Geom2d_Curve)::DownCast( PC->Translated( offset ) );
850                           GC->PCurve( PC );
851                           TE->ChangeCurves().Remove( itcr );
852                           TE->ChangeCurves().Append( GC );
853                           break;
854                         }
855                     }
856                 }
857             }
858           ///////////////////
859           eit.Initialize( aWire, Standard_False );
860           for (; eit.More(); eit.Next())
861             {
862               TopoDS_Shape anEdge = eit.Value();
863               BB.Add( CurWire, anEdge );
864             }
865           if (aSub.IsCopied( CurFace ))
866             {
867               theCopy = aSub.Copy( CurFace );
868               CurFace = theCopy.First();
869             }
870           CurFace.Free( Standard_True );
871           BB.Remove( CurFace, aWire );
872         }
873     }
874 }