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