0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / BRepOffset / BRepOffset_MakeOffset.cxx
1 // File:        BRepOffset_MakeOffset.cxx
2 // Created:     Fri Oct 27 10:30:44 1995
3 // Author:      Yves FRICAUD
4 //              <yfr@stylox>
5
6
7 //  Modified by skv - Tue Mar 15 16:20:43 2005
8 // Add methods for supporting history.
9
10 //  Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455
11
12 #include <BRepOffset_MakeOffset.ixx>
13 #include <BRepOffset_Analyse.hxx>
14 #include <BRepOffset_DataMapOfShapeOffset.hxx> 
15 #include <BRepOffset_DataMapOfShapeMapOfShape.hxx>
16 #include <BRepOffset_DataMapIteratorOfDataMapOfShapeOffset.hxx>
17 #include <BRepOffset_Interval.hxx>
18 #include <BRepOffset_ListOfInterval.hxx>
19 #include <BRepOffset_Offset.hxx>
20 #include <BRepOffset_Tool.hxx>
21 #include <BRepOffset_Inter2d.hxx>
22 #include <BRepOffset_Inter3d.hxx>
23 #include <BRepOffset_MakeLoops.hxx>
24
25
26 #include <BRepAdaptor_Surface.hxx>
27 #include <BRepCheck_Edge.hxx>
28 #include <BRepCheck_Vertex.hxx>
29 #include <BRepLib.hxx>
30 #include <BRepLib_MakeVertex.hxx>
31 #include <BRep_Builder.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRep_TVertex.hxx>
34 #include <BRepTools_Quilt.hxx>
35 #include <BRepClass3d_SolidClassifier.hxx>
36 #include <gp_Pnt.hxx>
37
38 #include <TopExp.hxx>
39 #include <TopExp_Explorer.hxx>
40 #include <TopoDS.hxx>
41 #include <TopoDS_Solid.hxx>
42 #include <TopoDS_Shell.hxx>
43 #include <TopoDS_Compound.hxx>
44 #include <TopoDS_Face.hxx>
45 #include <TopoDS_Edge.hxx>
46 #include <TopoDS_Vertex.hxx>
47
48 #include <TopTools_MapOfShape.hxx>
49 #include <TopTools_MapIteratorOfMapOfShape.hxx>
50 #include <TopTools_ListOfShape.hxx>
51 #include <TopTools_ListIteratorOfListOfShape.hxx>
52 #include <TopTools_DataMapOfShapeShape.hxx>
53 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
54 #include <TopTools_DataMapIteratorOfDataMapOfShapeReal.hxx>
55 #include <TColStd_ListIteratorOfListOfInteger.hxx>
56
57 #include <Standard_NotImplemented.hxx>
58 #include <Standard_ConstructionError.hxx>
59 #include <Precision.hxx>
60
61 #include <TopTools_SequenceOfShape.hxx>
62 #include <Geom_OffsetSurface.hxx>
63 #include <Geom_ConicalSurface.hxx>
64 #include <TopTools_IndexedMapOfShape.hxx>
65 #include <BRep_TEdge.hxx>
66 #include <BRepTools.hxx>
67 #include <gp_Cone.hxx>
68 #include <ElSLib.hxx>
69 #include <ElCLib.hxx>
70 #include <gp_Lin2d.hxx>
71 #include <GCE2d_MakeLine.hxx>
72 #include <Geom2d_Line.hxx>
73 #include <TopoDS_Iterator.hxx>
74 #include <BRepLib_MakeFace.hxx>
75 #include <Geom_Circle.hxx>
76
77 #include <BRep_PointRepresentation.hxx>
78 #include <BRep_ListIteratorOfListOfPointRepresentation.hxx>
79 #include <GeomAPI_ProjectPointOnCurve.hxx>
80
81 #include <BRepAdaptor_Curve.hxx>
82 #include <BRepAdaptor_Curve2d.hxx>
83 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
84 #include <Geom_SphericalSurface.hxx>
85 #include <TopoDS_Wire.hxx>
86 #include <BRepTools_Substitution.hxx>
87 #include <Geom_TrimmedCurve.hxx>
88 #include <Geom2d_TrimmedCurve.hxx>
89
90 #include <BRepTools_WireExplorer.hxx>
91 #include <BRepLib_MakeEdge.hxx>
92 #include <gce_MakeDir.hxx>
93 #include <GC_MakeCylindricalSurface.hxx>
94 #include <gce_MakeCone.hxx>
95 #include <Geom_SurfaceOfLinearExtrusion.hxx>
96
97 #include <Geom2dAdaptor_HCurve.hxx>
98 #include <GeomAdaptor_HSurface.hxx>
99 #include <Adaptor3d_CurveOnSurface.hxx>
100 #include <GeomLib.hxx>
101 #include <GeomFill_Generator.hxx>
102
103
104 // POP for NT
105 #include <stdio.h>
106
107 #ifdef DRAW
108
109 #include <DBRep.hxx>
110 #endif
111 #ifdef DEB
112 #include <OSD_Chronometer.hxx>
113
114   Standard_Boolean AffichInt2d = Standard_False;       
115   Standard_Boolean AffichOffC  = Standard_False;       
116   Standard_Boolean ChronBuild  = Standard_False;
117   Standard_Integer NbAE        = 0;
118   Standard_Integer NbAF        = 0;  
119   static OSD_Chronometer  Clock;
120   char name[100];
121
122
123
124
125 //=======================================================================
126 //function :  DEBVerticesControl
127 //purpose  : 
128 //=======================================================================
129
130 static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
131                                       Handle(BRepAlgo_AsDes)      AsDes)
132 {
133   Standard_Integer NVP = 0;
134   Standard_Integer NVM = 0;
135   Standard_Integer NVN = 0;
136
137   TopTools_ListOfShape               LVP;
138   //TopTools_MapIteratorOfMapOfShape   it;
139   TopTools_ListIteratorOfListOfShape it1LE ;    
140   TopTools_ListIteratorOfListOfShape it2LE ;
141   
142   //for (it.Initialize(NewEdges) ; it.More(); it.Next()) {
143   Standard_Integer i;
144   for (i = 1; i <= NewEdges.Extent(); i++) {
145     const TopoDS_Edge& NE = TopoDS::Edge(NewEdges(i));
146     if (AsDes->HasDescendant(NE)) {
147       for (it1LE.Initialize(AsDes->Descendant(NE)); it1LE.More(); it1LE.Next()) {
148         if (AsDes->Ascendant(it1LE.Value()).Extent() < 3) {
149           LVP.Append(it1LE.Value());
150           cout <<"Vertex on at least 3 edges."<<endl;
151 #ifdef DRAW
152           if (AffichInt2d) {
153             sprintf (name,"VP_%d",NVP++);
154             DBRep::Set(name,it1LE.Value());
155           }
156 #endif
157         }
158         else if (AsDes->Ascendant(it1LE.Value()).Extent() > 3) {
159           cout <<"Vertex on more than 3 edges."<<endl;
160 #ifdef DRAW
161           if (AffichInt2d) {
162             sprintf (name,"VM_%d",NVM++);
163             DBRep::Set(name,it1LE.Value());
164           }
165 #endif
166           
167         }
168         else {
169 #ifdef DRAW
170           if (AffichInt2d) {
171             sprintf (name,"VN_%d",NVN++);
172             DBRep::Set(name,it1LE.Value());
173           }
174 #endif
175         }
176       }
177     }
178   }
179   //------------------------------------------------
180   // Try to mix spoiled vertices.
181   //------------------------------------------------
182   BRep_Builder B;
183   TopTools_ListIteratorOfListOfShape it1(LVP);
184   Standard_Real                      TolConf = 1.e-5;
185   Standard_Real                      Tol     = Precision::Confusion();
186   //Standard_Integer                   i = 1;
187   
188   i = 1;
189   for ( ; it1.More(); it1.Next()) {
190     TopoDS_Shape   V1 = it1.Value();
191     gp_Pnt         P1 = BRep_Tool::Pnt(TopoDS::Vertex(V1));
192     Standard_Real  distmin = Precision::Infinite();
193     TopTools_ListIteratorOfListOfShape it2(LVP);
194     Standard_Integer j = 1;
195
196     for ( ; it2.More(); it2.Next()) {
197       if (j > i) {
198         TopoDS_Shape V2 = it2.Value();
199         gp_Pnt       P2 = BRep_Tool::Pnt(TopoDS::Vertex(V2));
200         if (!V1.IsSame(V2)) {
201           Standard_Real       dist    = P1.Distance(P2);
202           if (dist < distmin) distmin = dist;
203           if (dist < TolConf) {
204             Standard_Real UV2;
205             TopoDS_Edge   EWE2;
206             const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2);
207             TopTools_ListIteratorOfListOfShape itAsDes;
208             for (itAsDes.Initialize(EdgeWithV2); itAsDes.More(); itAsDes.Next()) {
209               EWE2  = TopoDS::Edge(itAsDes.Value());
210               TopoDS_Shape aLocalShape = V2.Oriented(TopAbs_INTERNAL);
211               UV2   = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2);
212               aLocalShape = V1.Oriented(TopAbs_INTERNAL) ;
213               B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol);
214 //            UV2   = 
215 //              BRep_Tool::Parameter(TopoDS::Vertex(),EWE2);
216 //            B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),
217 //                           UV2,EWE2,Tol);
218             }
219             AsDes->Replace(V2,V1);
220           }
221         }
222       }
223       j++;
224     }
225     i++;
226     cout <<" distmin between VP : "<<distmin<<endl;
227   }
228 }  
229 #endif
230
231
232 static void UpdateTolerance (      TopoDS_Shape&               myShape,
233                              const TopTools_IndexedMapOfShape& myFaces);
234
235
236 static Standard_Boolean FindParameter(const TopoDS_Vertex& V, 
237                                       const TopoDS_Edge& E,
238                                       Standard_Real& U)
239 {
240   // Search the vertex in the edge
241
242   Standard_Boolean rev = Standard_False;
243   TopoDS_Shape VF;
244   TopAbs_Orientation orient = TopAbs_INTERNAL;
245
246   TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD));
247
248   // if the edge has no vertices
249   // and is degenerated use the vertex orientation
250   // RLE, june 94
251
252   if (!itv.More() && BRep_Tool::Degenerated(E)) {
253     orient = V.Orientation();
254   }
255
256   while (itv.More()) {
257     const TopoDS_Shape& Vcur = itv.Value();
258     if (V.IsSame(Vcur)) {
259       if (VF.IsNull()) {
260         VF = Vcur;
261       }
262       else {
263         rev = E.Orientation() == TopAbs_REVERSED;
264         if (Vcur.Orientation() == V.Orientation()) {
265           VF = Vcur;
266         }
267       }
268     }
269     itv.Next();
270   }
271   
272   if (!VF.IsNull()) orient = VF.Orientation();
273  
274   Standard_Real f,l;
275
276   if (orient ==  TopAbs_FORWARD) {
277     BRep_Tool::Range(E,f,l);
278     //return (rev) ? l : f;
279     U = (rev) ? l : f;
280     return Standard_True;
281   }
282  
283   else if (orient ==  TopAbs_REVERSED) {
284     BRep_Tool::Range(E,f,l);
285     //return (rev) ? f : l;
286     U = (rev) ? f : l;
287     return Standard_True;
288    }
289
290   else {
291     TopLoc_Location L;
292     const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l);
293     L = L.Predivided(V.Location());
294     if (!C.IsNull() || BRep_Tool::Degenerated(E)) {
295       BRep_ListIteratorOfListOfPointRepresentation itpr
296         ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
297
298       while (itpr.More()) {
299         const Handle(BRep_PointRepresentation)& pr = itpr.Value();
300         if (pr->IsPointOnCurve(C,L)) {
301           Standard_Real p = pr->Parameter();
302           Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux
303           if (!C.IsNull()) {
304             // Closed curves RLE 16 june 94
305             if (Precision::IsNegativeInfinite(f))
306               {
307                 //return pr->Parameter();//p;
308                 U = pr->Parameter();
309                 return Standard_True;
310               }
311             if (Precision::IsPositiveInfinite(l))
312               {
313                 //return pr->Parameter();//p;
314                 U = pr->Parameter();
315                 return Standard_True;
316               }
317             gp_Pnt Pf = C->Value(f).Transformed(L.Transformation());
318             gp_Pnt Pl = C->Value(l).Transformed(L.Transformation());
319             Standard_Real tol = BRep_Tool::Tolerance(V);
320             if (Pf.Distance(Pl) < tol) {
321               if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) {
322                 if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f;
323                 else                                   res = l;//p = l;
324               }
325             }
326           }
327           //return res;//p;
328           U = res;
329           return Standard_True;
330         }
331         itpr.Next();
332       }
333     }
334     else {
335       // no 3d curve !!
336       // let us try with the first pcurve
337       Handle(Geom2d_Curve) PC;
338       Handle(Geom_Surface) S;
339       BRep_Tool::CurveOnSurface(E,PC,S,L,f,l);
340       L = L.Predivided(V.Location()); 
341       BRep_ListIteratorOfListOfPointRepresentation itpr
342         ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points());
343
344       while (itpr.More()) {
345         const Handle(BRep_PointRepresentation)& pr = itpr.Value();
346         if (pr->IsPointOnCurveOnSurface(PC,S,L)) {
347           Standard_Real p = pr->Parameter();
348           // Closed curves RLE 16 june 94
349           if (PC->IsClosed()) {
350             if ((p == PC->FirstParameter()) || 
351                 (p == PC->LastParameter())) {
352               if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter();
353               else                                   p = PC->LastParameter();
354             }
355           }
356           //return p;
357           U = p;
358           return Standard_True;
359         }
360         itpr.Next();
361       }
362     }
363   }
364   
365   //Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge");
366   return Standard_False;
367 }
368
369 //=======================================================================
370 //function : GetEdgePoints
371 //purpose  : gets the first, last and middle points of the edge
372 //=======================================================================
373 static void GetEdgePoints(const TopoDS_Edge& anEdge,
374                                       const TopoDS_Face& aFace,
375                                       gp_Pnt& fPnt, gp_Pnt& mPnt,
376                                       gp_Pnt& lPnt)
377 {
378   Standard_Real f, l;
379   Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( anEdge, aFace, f, l );
380   gp_Pnt2d fPnt2d = theCurve->Value(f);
381   gp_Pnt2d lPnt2d = theCurve->Value(l);
382   gp_Pnt2d mPnt2d = theCurve->Value(0.5*(f + l));
383   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
384   fPnt = aSurf->Value(fPnt2d.X(),fPnt2d.Y());
385   lPnt = aSurf->Value(lPnt2d.X(),lPnt2d.Y());
386   mPnt = aSurf->Value(mPnt2d.X(), mPnt2d.Y());
387 }
388
389 //=======================================================================
390 //function : FillContours
391 //purpose  : fills free boundary contours and faces connected (MapEF)
392 //=======================================================================
393 static void FillContours(const TopoDS_Shape& aShape,
394                          const BRepOffset_Analyse& Analyser,
395                          TopTools_DataMapOfShapeListOfShape& Contours,
396                          TopTools_DataMapOfShapeShape& MapEF)
397 {
398   TopTools_ListOfShape Edges;
399
400   TopExp_Explorer Explo(aShape, TopAbs_FACE);
401   BRepTools_WireExplorer Wexp;
402
403   for (; Explo.More(); Explo.Next())
404     {
405       TopoDS_Face aFace = TopoDS::Face(Explo.Current());
406       TopoDS_Iterator itf(aFace);
407       for (; itf.More(); itf.Next())
408         {
409           TopoDS_Wire aWire = TopoDS::Wire(itf.Value());
410           for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next())
411             {
412               TopoDS_Edge anEdge = Wexp.Current();
413               if (BRep_Tool::Degenerated(anEdge))
414                 continue;
415               const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge);
416               if (!Lint.IsEmpty() && Lint.First().Type() == BRepOffset_FreeBoundary)
417                 {
418                   MapEF.Bind(anEdge, aFace);
419                   Edges.Append(anEdge);
420                 }
421             }
422         }
423     }
424
425   TopTools_ListIteratorOfListOfShape itl;
426   while (!Edges.IsEmpty())
427     {
428       TopoDS_Edge StartEdge = TopoDS::Edge(Edges.First());
429       Edges.RemoveFirst();
430       TopoDS_Vertex StartVertex, CurVertex;
431       TopExp::Vertices(StartEdge, StartVertex, CurVertex, Standard_True);
432       TopTools_ListOfShape aContour;
433       aContour.Append(StartEdge);
434       while (!CurVertex.IsSame(StartVertex))
435         for (itl.Initialize(Edges); itl.More(); itl.Next())
436           {
437             TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
438             TopoDS_Vertex V1, V2;
439             TopExp::Vertices(anEdge, V1, V2);
440             if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
441               {
442                 aContour.Append(anEdge);
443                 CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
444                 Edges.Remove(itl);
445                 break;
446               }
447           }
448       Contours.Bind(StartVertex, aContour);
449     }
450 }
451
452 //=======================================================================
453 //function : BRepOffset_MakeOffset
454 //purpose  : 
455 //=======================================================================
456
457 BRepOffset_MakeOffset::BRepOffset_MakeOffset()
458 {
459   myAsDes = new BRepAlgo_AsDes();
460 }
461
462
463 //=======================================================================
464 //function : BRepOffset_MakeOffset
465 //purpose  : 
466 //=======================================================================
467
468 BRepOffset_MakeOffset::BRepOffset_MakeOffset(const TopoDS_Shape&    S, 
469                                              const Standard_Real    Offset, 
470                                              const Standard_Real    Tol, 
471                                              const BRepOffset_Mode  Mode, 
472                                              const Standard_Boolean Inter, 
473                                              const Standard_Boolean SelfInter, 
474                                              const GeomAbs_JoinType Join,
475                                              const Standard_Boolean Thickening)
476
477 myOffset     (Offset),
478 myTol        (Tol),
479 myShape      (S),
480 myMode       (Mode),
481 myInter      (Inter),
482 mySelfInter  (SelfInter),
483 myJoin       (Join),
484 myThickening (Thickening),
485 myDone     (Standard_False)
486
487 {
488   myAsDes = new BRepAlgo_AsDes();
489   MakeOffsetShape();
490 }
491
492
493 //=======================================================================
494 //function : Initialize
495 //purpose  : 
496 //=======================================================================
497
498 void BRepOffset_MakeOffset::Initialize(const TopoDS_Shape&    S, 
499                                        const Standard_Real    Offset, 
500                                        const Standard_Real    Tol, 
501                                        const BRepOffset_Mode  Mode,
502                                        const Standard_Boolean Inter,
503                                        const Standard_Boolean SelfInter,
504                                        const GeomAbs_JoinType Join,
505                                        const Standard_Boolean Thickening)
506 {
507   myOffset     = Offset;
508   myShape      = S;
509   myTol        = Tol;
510   myMode       = Mode;
511   myInter      = Inter;
512   mySelfInter  = SelfInter;
513   myJoin       = Join;
514   myThickening = Thickening;
515   myDone     = Standard_False;
516   Clear();
517 }
518
519
520 //=======================================================================
521 //function : Clear
522 //purpose  : 
523 //=======================================================================
524
525 void BRepOffset_MakeOffset::Clear()
526 {
527   myOffsetShape.Nullify();
528   myInitOffsetFace .Clear();
529   myInitOffsetEdge .Clear();
530   myImageOffset    .Clear();
531   myFaces          .Clear();  
532   myFaceOffset     .Clear();
533   myAsDes          ->Clear();
534   myDone     = Standard_False;
535 }
536
537 //=======================================================================
538 //function : AddFace
539 //purpose  : 
540 //=======================================================================
541
542 void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) {
543   myFaces.Add(F);    
544   //-------------
545   // MAJ SD.
546   //-------------
547   myInitOffsetFace.SetRoot (F)  ;    
548   myInitOffsetFace.Bind    (F,F);
549   myImageOffset.SetRoot    (F)  ;  
550 }
551
552 //=======================================================================
553 //function : SetOffsetOnFace
554 //purpose  : 
555 //=======================================================================
556
557 void BRepOffset_MakeOffset::SetOffsetOnFace(const TopoDS_Face&  F, 
558                                             const Standard_Real Off)
559 {
560   if ( myFaceOffset.IsBound(F)) myFaceOffset.UnBind(F);
561   myFaceOffset.Bind(F,Off);
562 }
563
564 //=======================================================================
565 //function : RemoveCorks
566 //purpose  : 
567 //=======================================================================
568
569 static void RemoveCorks (TopoDS_Shape&               S,
570                          TopTools_IndexedMapOfShape& Faces)
571 {  
572   TopoDS_Compound SS;
573   BRep_Builder    B;
574   B.MakeCompound (SS);
575   //-----------------------------------------------------
576   // Construction of a shape without caps.
577   // and Orientation of caps as in shape S.
578   //-----------------------------------------------------
579   TopExp_Explorer exp(S,TopAbs_FACE);
580   for (; exp.More(); exp.Next()) {
581     const TopoDS_Shape& Cork = exp.Current(); 
582     if (!Faces.Contains(Cork)) {
583       B.Add(SS,Cork);
584     }
585     else {
586       //Faces.Remove (Cork);
587       //begin instead of Remove//
588       TopoDS_Shape LastShape = Faces(Faces.Extent());
589       Faces.RemoveLast();
590       if (Faces.FindIndex(Cork) != 0)
591         Faces.Substitute(Faces.FindIndex(Cork), LastShape);
592       //end instead of Remove  //
593       Faces.Add(Cork); // to reset it with proper orientation.
594     }
595   }
596   S = SS;
597 #ifdef DRAW
598   if ( AffichOffC) 
599     DBRep::Set("myInit", SS);
600 #endif
601
602 }
603
604 static Standard_Boolean IsConnectedShell( const TopoDS_Shape& S )
605 {  
606   BRepTools_Quilt Glue;
607   Glue.Add( S );
608
609   TopoDS_Shape SS = Glue.Shells();
610   TopExp_Explorer Explo( SS, TopAbs_SHELL );
611   Explo.Next();
612   if (Explo.More())
613     return Standard_False;
614   
615   return Standard_True;
616 }
617
618
619 //=======================================================================
620 //function : MakeList
621 //purpose  : 
622 //=======================================================================
623
624 static void MakeList (TopTools_ListOfShape&             OffsetFaces,
625                       const BRepAlgo_Image&             myInitOffsetFace,
626                       const TopTools_IndexedMapOfShape& myFaces)
627 {
628   TopTools_ListIteratorOfListOfShape itLOF(myInitOffsetFace.Roots());
629   for ( ; itLOF.More(); itLOF.Next()) {
630     const TopoDS_Shape& Root = itLOF.Value();
631     if (!myFaces.Contains(Root))
632       OffsetFaces.Append(myInitOffsetFace.Image(Root).First());
633   }
634 }
635
636 //=======================================================================
637 //function : EvalMax
638 //purpose  : 
639 //=======================================================================
640
641 static void EvalMax(const TopoDS_Shape& S, Standard_Real& Tol)
642 {
643   TopExp_Explorer exp;
644   for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) {
645     const TopoDS_Vertex& V    = TopoDS::Vertex(exp.Current());
646     Standard_Real        TolV = BRep_Tool::Tolerance(V); 
647     if (TolV > Tol) Tol = TolV;
648   }
649   //Patch
650   Tol *= 5.;
651 }
652
653 //=======================================================================
654 //function : MakeOffsetShape
655 //purpose  : 
656 //=======================================================================
657
658 void BRepOffset_MakeOffset::MakeOffsetShape()
659 {  
660   myDone     = Standard_False;
661   //------------------------------------------
662   // Construction of myShape without caps.
663   //------------------------------------------
664   RemoveCorks (myShape,myFaces);
665   
666   if (! IsConnectedShell(myShape))
667     Standard_ConstructionError::Raise("BRepOffset_MakeOffset : Incorrect set of faces to remove, the remaining shell is not connected");
668
669   if (Abs(myOffset) < myTol) return;
670
671   TopAbs_State       Side = TopAbs_IN;
672   if (myOffset < 0.) Side = TopAbs_OUT;
673   // ------------
674   // Preanalyse.
675   // ------------
676   EvalMax(myShape,myTol);
677   if (myTol > Abs(myOffset*0.5)) {
678     Standard_ConstructionError::Raise("BRepOffset_MakeOffset : Tol > Offset");
679   }
680   Standard_Real TolAngle = 4*ASin(myTol/Abs(myOffset*0.5));
681   myAnalyse.Perform(myShape,TolAngle);
682   //---------------------------------------------------
683   // Construction of Offset from preanalysis.
684   //---------------------------------------------------  
685   //----------------------------
686   // MaJ of SD Face - Offset
687   //----------------------------
688   UpdateFaceOffset();
689
690   if (myJoin == GeomAbs_Arc)          
691     BuildOffsetByArc();
692   else if (myJoin == GeomAbs_Intersection) 
693     BuildOffsetByInter();
694   //-----------------
695   // Auto unwinding.
696   //-----------------
697   // if (mySelfInter)  SelfInter(Modif);
698   //-----------------
699   // Intersection 3d .
700   //-----------------
701   BRepOffset_Inter3d Inter(myAsDes,Side,myTol);
702   Intersection3D (Inter);
703   //-----------------
704   // Intersection2D
705   //-----------------
706   TopTools_IndexedMapOfShape& Modif    = Inter.TouchedFaces(); 
707   TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges();
708
709   if (!Modif.IsEmpty()) Intersection2D (Modif,NewEdges);
710   //-------------------------------------------------------
711   // Unwinding 2D and reconstruction of modified faces
712   //----------------------------------------------------
713   MakeLoops (Modif);
714   //-----------------------------------------------------
715   // Reconstruction of non modified faces sharing 
716   // reconstructed edges
717   //------------------------------------------------------
718   if (!Modif.IsEmpty()) MakeFaces (Modif);
719
720   if (myThickening)
721     MakeMissingWalls();
722
723   //-------------------------
724   // Construction of shells.
725   //-------------------------
726   MakeShells ();
727   //--------------
728   // Unwinding 3D.
729   //--------------
730   SelectShells ();
731   //----------------------------------
732   // Coding of regularities.
733   //----------------------------------
734   EncodeRegularity();
735   //----------------------
736   // Creation of solids.
737   //----------------------
738   MakeSolid ();
739
740   //-----------------------------
741   // MAJ Tolerance edge and Vertex
742   // ----------------------------
743   if (!myOffsetShape.IsNull()) {
744     UpdateTolerance (myOffsetShape,myFaces);
745     BRepLib::UpdateTolerances( myOffsetShape );
746   }
747
748   CorrectConicalFaces();
749
750   myDone = Standard_True;
751 }
752
753
754
755 //=======================================================================
756 //function : MakeThickSolid
757 //purpose  : 
758 //=======================================================================
759
760 void BRepOffset_MakeOffset::MakeThickSolid() 
761 {
762   //--------------------------------------------------------------
763   // Construction of shell parallel to shell (initial without cap).
764   //--------------------------------------------------------------
765   MakeOffsetShape ();
766
767   //--------------------------------------------------------------------
768   // Construction of a solid with the initial shell, parallel shell 
769   // limited by caps.
770   //--------------------------------------------------------------------
771   if (!myFaces.IsEmpty()) {
772     TopoDS_Solid    Res;
773     TopExp_Explorer exp;
774     BRep_Builder    B;
775     Standard_Integer NbF = myFaces.Extent();
776
777     B.MakeSolid(Res);
778
779     BRepTools_Quilt Glue;
780     for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
781       NbF++;
782       Glue.Add (exp.Current());
783     } 
784     Standard_Boolean YaResult = 0;
785     if (!myOffsetShape.IsNull()) {
786       for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next()) {
787         YaResult = 1;
788         Glue.Add (exp.Current().Reversed());
789       }
790     }
791     if (YaResult == 0) {
792       myDone = Standard_False;
793       return;
794     }
795     myOffsetShape = Glue.Shells();
796     for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
797       B.Add(Res,exp.Current());
798     }
799     Res.Closed(Standard_True);
800     myOffsetShape = Res;
801
802     // Test of Validity of the result of thick Solid 
803     // more face than the initial solid.
804         
805     Standard_Integer NbOF = 0;
806     for (exp.Init(myOffsetShape,TopAbs_FACE);exp.More(); exp.Next()) {
807       NbOF++;
808     }
809     if (NbOF <= NbF) {
810       myDone = Standard_False;
811       return;
812     }
813   }
814
815   if (myOffset > 0 ) myOffsetShape.Reverse();  
816
817   myDone = Standard_True;
818 }
819
820 //=======================================================================
821 //function : IsDone
822 //purpose  : 
823 //=======================================================================
824
825 Standard_Boolean BRepOffset_MakeOffset::IsDone() const
826 {
827   return myDone;
828 }
829
830 //=======================================================================
831 //function : Error
832 //purpose  : 
833 //=======================================================================
834
835 BRepOffset_Error BRepOffset_MakeOffset::Error() const
836 {
837   return myError;
838 }
839
840 //=======================================================================
841 //function : Shape
842 //purpose  : 
843 //=======================================================================
844
845 const TopoDS_Shape&  BRepOffset_MakeOffset::Shape() const 
846 {
847   return myOffsetShape;
848 }
849
850 //=======================================================================
851 //function : TrimEdge
852 //purpose  : Trim the edge of the largest of descendants in AsDes2d.
853 //           Order in AsDes two vertices that have trimmed the edge.
854 //=======================================================================
855
856 static void TrimEdge (TopoDS_Edge&                  NE,
857                       const Handle(BRepAlgo_AsDes)& AsDes2d,
858                             Handle(BRepAlgo_AsDes)& AsDes)
859 {
860   Standard_Real aSameParTol = Precision::Confusion();
861   
862   TopoDS_Vertex V1,V2;
863   Standard_Real U;
864   Standard_Real UMin =  Precision::Infinite();
865   Standard_Real UMax = -UMin;
866
867   const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE);
868   
869   if (LE.Extent() > 1) {
870     TopTools_ListIteratorOfListOfShape it (LE);
871     for (; it.More(); it.Next()) {
872       TopoDS_Vertex V = TopoDS::Vertex(it.Value());
873       if (NE.Orientation() == TopAbs_REVERSED)
874         V.Reverse();
875       //V.Orientation(TopAbs_INTERNAL);
876       if (!FindParameter(V, NE, U))
877         {
878           Standard_Real f, l;
879           Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l);
880           gp_Pnt thePoint = BRep_Tool::Pnt(V);
881           GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve);
882           if (Projector.NbPoints() == 0)
883             Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection");
884           U = Projector.LowerDistanceParameter();
885         }
886       if (U < UMin) {
887         UMin = U; V1   = V;
888       }
889       if (U > UMax) {
890         UMax = U; V2   = V;
891       }
892     }
893     if (V1.IsNull() || V2.IsNull()) {
894       Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge");
895     }
896     if (!V1.IsSame(V2)) {
897       NE.Free( Standard_True );
898       BRep_Builder B;
899       TopAbs_Orientation Or = NE.Orientation();
900       NE.Orientation(TopAbs_FORWARD);
901       TopoDS_Vertex VF,VL;
902       TopExp::Vertices (NE,VF,VL);
903       B.Remove(NE,VF);
904       B.Remove(NE,VL);
905       B.Add  (NE,V1.Oriented(TopAbs_FORWARD));
906       B.Add  (NE,V2.Oriented(TopAbs_REVERSED));
907       B.Range(NE,UMin,UMax);
908       NE.Orientation(Or);
909       AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD));
910       AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED));
911       BRepLib::SameParameter(NE, aSameParTol, Standard_True);
912     }
913   }
914 }
915
916 //=======================================================================
917 //function : BuildOffsetByInter
918 //purpose  : 
919 //=======================================================================
920 void BRepOffset_MakeOffset::BuildOffsetByInter()
921 {
922 #ifdef  DEB
923   if ( ChronBuild) {
924     cout << " CONSTRUCTION OF OFFSETS :" << endl;
925     Clock.Reset();
926     Clock.Start();
927   }
928 #endif
929
930   BRepOffset_DataMapOfShapeOffset MapSF;
931   TopTools_MapOfShape             Done;
932   Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False;
933   //--------------------------------------------------------
934   // Construction of faces parallel to initial faces
935   //--------------------------------------------------------
936   TopExp_Explorer Exp;
937   TopTools_ListOfShape LF;
938   TopTools_ListIteratorOfListOfShape itLF;
939
940   BRepLib::SortFaces(myShape,LF);
941
942   TopTools_DataMapOfShapeShape ShapeTgt;
943   for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
944     const TopoDS_Face&   F = TopoDS::Face(itLF.Value());
945     Standard_Real CurOffset = myOffset;
946     if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F);
947     BRepOffset_Offset    OF(F,CurOffset,ShapeTgt,OffsetOutside,myJoin);
948     TopTools_ListOfShape Let;
949     myAnalyse.Edges(F,BRepOffset_Tangent,Let);
950     TopTools_ListIteratorOfListOfShape itl(Let);
951     
952     for ( ; itl.More(); itl.Next()) {
953       const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
954       if ( !ShapeTgt.IsBound(Cur)) {
955         TopoDS_Shape aLocalShape = OF.Generated(Cur);
956         const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
957 //      const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur));
958         ShapeTgt.Bind(Cur,OF.Generated(Cur));
959         TopoDS_Vertex V1,V2,OV1,OV2;
960         TopExp::Vertices (Cur,V1,V2);
961         TopExp::Vertices (OTE,OV1,OV2);      
962         TopTools_ListOfShape LE;
963         if (!ShapeTgt.IsBound(V1)) {
964           myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
965           const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
966           if (LE.Extent() == LA.Extent())
967             ShapeTgt.Bind(V1,OV1);
968         }
969         if (!ShapeTgt.IsBound(V2)) {
970           LE.Clear();
971           myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
972           const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
973           if (LE.Extent() == LA.Extent())
974             ShapeTgt.Bind(V2,OV2);
975         }
976       }
977     }
978     MapSF.Bind(F,OF);
979   }
980   //--------------------------------------------------------------------
981   // MES   : Map of OffsetShape -> Extended Shapes.
982   // Build : Map of Initial SS  -> OffsetShape build by Inter.
983   //                               can be an edge or a compound of edges       
984   //---------------------------------------------------------------------
985   TopTools_DataMapOfShapeShape MES;  
986   TopTools_DataMapOfShapeShape Build; 
987   TopTools_ListOfShape         Failed;
988   TopAbs_State                 Side = TopAbs_IN;  
989   Handle(BRepAlgo_AsDes)       AsDes = new BRepAlgo_AsDes();
990
991   //-------------------------------------------------------------------
992   // Extension of faces and calculation of new edges of intersection.
993   //-------------------------------------------------------------------
994   Standard_Boolean  ExtentContext = 0;
995   if (myOffset > 0) ExtentContext = 1;
996
997   BRepOffset_Inter3d Inter3 (AsDes,Side,myTol);
998   // Intersection between parallel faces
999   Inter3.ConnexIntByInt(myShape,MapSF,myAnalyse,MES,Build,Failed );
1000   // Intersection with caps.
1001   Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed );
1002
1003
1004   //---------------------------------------------------------------------------------
1005   // Extension of neighbor edges of new edges and intersection between neighbors.
1006   //--------------------------------------------------------------------------------
1007   Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
1008   for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1009     const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
1010 //  Modified by skv - Mon Jan 12 11:50:02 2004 OCC4455 Begin
1011 //    BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myTol);
1012     BRepOffset_Inter2d::ConnexIntByInt (FI,MapSF(FI),MES,Build,AsDes2d,myOffset, myTol);
1013 //  Modified by skv - Mon Jan 12 11:50:03 2004 OCC4455 End
1014   }
1015   //-----------------------------------------------------------
1016   // Great restriction of new edges and update of AsDes.
1017   //------------------------------------------ ----------------
1018   TopTools_IndexedMapOfShape NewEdges;
1019   TopExp_Explorer Exp2,ExpC;
1020   TopoDS_Shape    NE;
1021   TopoDS_Edge     TNE;
1022   TopoDS_Face     NF;
1023   
1024   for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1025     const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
1026     NF = MapSF(FI).Face();
1027     if (MES.IsBound(NF)) {NF = TopoDS::Face(MES(NF));}
1028     TopTools_MapOfShape View;
1029     for (Exp2.Init(FI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); Exp2.More(); Exp2.Next()) {
1030       const TopoDS_Edge& EI = TopoDS::Edge(Exp2.Current());
1031       if (View.Add(EI)) {
1032         if (Build.IsBound(EI)) {
1033           NE = Build(EI);
1034           if (NE.ShapeType() == TopAbs_EDGE) {
1035             if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);}
1036           }
1037           else {
1038             //------------------------------------------------------------
1039             // The Intersections are on several edges.
1040             // The pieces without intersections with neighbors  
1041             // are removed from AsDes.
1042             //------------------------------------------------------------
1043             for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
1044               if (NewEdges.Add(ExpC.Current())) {
1045                 TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current());
1046                 NEC.Free(Standard_True);
1047                 if (!AsDes2d->Descendant(NEC).IsEmpty()) {
1048                   TrimEdge (NEC,AsDes2d,AsDes);
1049                 }
1050                 else {
1051                   AsDes->Remove(NEC);
1052                 }
1053               }
1054             }
1055           }
1056         }
1057         else {
1058           NE = MapSF(FI).Generated(EI);
1059           //// modified by jgv, 19.12.03 for OCC4455 ////
1060           NE.Orientation( EI.Orientation() );
1061           ///////////////////////////////////////////////
1062           if (MES.IsBound(NE)) {
1063             NE = MES(NE);
1064             NE.Orientation(EI.Orientation());
1065             if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);} 
1066           }
1067           AsDes->Add(NF,NE);
1068         } 
1069       }
1070     }
1071   }
1072   
1073   //--------------------------------- 
1074   // Intersection 2D on //
1075   //---------------------------------  
1076   TopTools_ListOfShape LFE; 
1077   BRepAlgo_Image     IMOE;
1078   for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1079     const TopoDS_Shape& FI  = Exp.Current();
1080     const TopoDS_Shape& OFI = MapSF(FI).Face();
1081     if (MES.IsBound(OFI)) {
1082       const TopoDS_Face& NF = TopoDS::Face(MES(OFI));
1083       LFE.Append(NF);
1084       IMOE.SetRoot(NF);
1085     }
1086   }
1087   
1088   TopTools_ListIteratorOfListOfShape itLFE(LFE);
1089   for (; itLFE.More(); itLFE.Next()) {
1090     const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value());
1091     BRepOffset_Inter2d::Compute(AsDes,NEF,NewEdges,myTol);
1092   }
1093   //----------------------------------------------
1094   // Intersections 2d on caps.
1095   //----------------------------------------------
1096   Standard_Integer i;
1097   for (i = 1; i <= myFaces.Extent(); i++) {
1098     const TopoDS_Face& Cork = TopoDS::Face(myFaces(i));
1099     BRepOffset_Inter2d::Compute(AsDes,Cork,NewEdges,myTol);
1100   }
1101
1102   //-------------------------------
1103   // Unwinding of extended Faces.
1104   //-------------------------------
1105   myMakeLoops.Build(LFE  ,AsDes,IMOE);
1106
1107 #ifdef DEB
1108   TopTools_IndexedMapOfShape COES;
1109 #endif
1110   //---------------------------
1111   // MAJ SD. for faces //
1112   //---------------------------
1113   for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1114     const TopoDS_Shape& FI   = Exp.Current();
1115     myInitOffsetFace.SetRoot(FI);
1116     TopoDS_Face  OF  = MapSF(FI).Face();
1117     if (MES.IsBound(OF)) {
1118       OF = TopoDS::Face(MES(OF));
1119       if (IMOE.HasImage(OF)) {
1120         const TopTools_ListOfShape& LOFE = IMOE.Image(OF);
1121         myInitOffsetFace.Bind(FI,LOFE);
1122         for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) {
1123           const TopoDS_Shape& OFE =  itLF.Value();
1124           myImageOffset.SetRoot(OFE);
1125 #ifdef DRAW
1126           if (AffichInt2d) {
1127             sprintf(name,"AF_%d",NbAF++);
1128             DBRep::Set(name,OFE);
1129           }
1130 #endif
1131           TopTools_MapOfShape View;
1132           for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
1133                Exp2.More(); Exp2.Next()) {
1134             const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
1135             
1136             myAsDes->Add (OFE,COE);
1137 #ifdef DRAW
1138             if (AffichInt2d) {
1139               sprintf(name,"AE_%d",NbAE++);
1140               DBRep::Set(name,COE);
1141               COES.Add(COE);
1142             }
1143 #endif
1144             if (View.Add(COE)){
1145               if (!myAsDes->HasDescendant(COE)) {
1146                 TopoDS_Vertex CV1,CV2;
1147                 TopExp::Vertices(COE,CV1,CV2);
1148                 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1149                 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));     
1150               }
1151             }
1152           }
1153         }
1154       }
1155       else {
1156         myInitOffsetFace.Bind(FI,OF);
1157         myImageOffset.SetRoot(OF);
1158 #ifdef DRAW 
1159         if (AffichInt2d) {
1160           sprintf(name,"AF_%d",NbAF++);
1161           DBRep::Set(name,OF);
1162         }
1163 #endif
1164         const TopTools_ListOfShape& LE = AsDes->Descendant(OF);
1165         for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
1166           const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
1167           if (IMOE.HasImage(OE)) {
1168             const TopTools_ListOfShape& LOE = IMOE.Image(OE);
1169             TopTools_ListIteratorOfListOfShape itLOE(LOE);
1170             for (; itLOE.More(); itLOE.Next()) {
1171               TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation());
1172               const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape);
1173 //            const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation()));
1174               myAsDes->Add(OF,COE);
1175 #ifdef DRAW
1176               if (AffichInt2d) {
1177                 sprintf(name,"AE_%d",NbAE++);
1178                 DBRep::Set(name,COE);
1179                 COES.Add(COE);
1180               }
1181 #endif
1182               
1183               if (!myAsDes->HasDescendant(COE)) {
1184                 TopoDS_Vertex CV1,CV2;
1185                 TopExp::Vertices(COE,CV1,CV2);
1186                 if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1187                 if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));     
1188               }
1189             }
1190           }
1191           else {
1192             myAsDes->Add(OF,OE);
1193 #ifdef DRAW
1194             if (AffichInt2d) {
1195               sprintf(name,"AE_%d",NbAE++);
1196               DBRep::Set(name,OE);
1197               COES.Add(OE);
1198             }
1199 #endif
1200
1201             const TopTools_ListOfShape& LV = AsDes->Descendant(OE);
1202             myAsDes->Add(OE,LV);
1203           }
1204         }
1205       }
1206     }
1207     else {
1208       myInitOffsetFace.Bind(FI,OF);
1209       myImageOffset.SetRoot(OF);
1210       TopTools_MapOfShape View;
1211       for (Exp2.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
1212            Exp2.More(); Exp2.Next()) {
1213
1214         const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current());
1215         myAsDes->Add (OF,COE);
1216 #ifdef DRAW
1217         if (AffichInt2d) {
1218           sprintf(name,"AE_%d",NbAE++);
1219           DBRep::Set(name,COE);
1220           COES.Add(COE);
1221         }
1222 #endif
1223         
1224         if (View.Add(Exp2.Current())) {
1225           if (!myAsDes->HasDescendant(COE)) {
1226             TopoDS_Vertex CV1,CV2;
1227             TopExp::Vertices(COE,CV1,CV2);
1228             if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1229             if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); 
1230           }
1231         }
1232       } 
1233     }
1234   }
1235   //  Modified by skv - Tue Mar 15 16:20:43 2005
1236   // Add methods for supporting history.
1237   TopTools_MapOfShape aMapEdges;
1238
1239   for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
1240     const TopoDS_Shape& aFaceRef = Exp.Current();
1241
1242     Exp2.Init(aFaceRef.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
1243
1244     for (; Exp2.More(); Exp2.Next()) {
1245       const TopoDS_Shape& anEdgeRef = Exp2.Current();
1246
1247       if (aMapEdges.Add(anEdgeRef)) {
1248         myInitOffsetEdge.SetRoot(anEdgeRef);
1249         if (Build.IsBound(anEdgeRef)) {
1250           TopoDS_Shape aNewShape = Build(anEdgeRef);
1251           
1252           if (aNewShape.ShapeType() == TopAbs_EDGE) {
1253             if (IMOE.HasImage(aNewShape)) {
1254               const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewShape);
1255               
1256               myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
1257             } else
1258               myInitOffsetEdge.Bind (anEdgeRef, aNewShape);
1259           } else { // aNewShape != TopAbs_EDGE
1260             TopTools_ListOfShape aListNewEdge;
1261             
1262             for (ExpC.Init(aNewShape, TopAbs_EDGE); ExpC.More(); ExpC.Next()) {
1263               const TopoDS_Shape &aResEdge = ExpC.Current();
1264               
1265               if (IMOE.HasImage(aResEdge)) {
1266                 const TopTools_ListOfShape& aListNewE = IMOE.Image(aResEdge);
1267                 TopTools_ListIteratorOfListOfShape aNewEIter(aListNewE);
1268                 
1269                 for (; aNewEIter.More(); aNewEIter.Next())
1270                   aListNewEdge.Append(aNewEIter.Value());
1271               } else
1272                 aListNewEdge.Append(aResEdge);
1273             }
1274             
1275             myInitOffsetEdge.Bind (anEdgeRef, aListNewEdge);
1276           }
1277         } 
1278         else { // Free boundary.
1279           TopoDS_Shape aNewEdge = MapSF(aFaceRef).Generated(anEdgeRef);
1280
1281           if (MES.IsBound(aNewEdge))
1282             aNewEdge = MES(aNewEdge);
1283
1284           if (IMOE.HasImage(aNewEdge)) {
1285             const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge);
1286
1287             myInitOffsetEdge.Bind (anEdgeRef, aListNewE);
1288           } else
1289             myInitOffsetEdge.Bind (anEdgeRef, aNewEdge);
1290         }
1291       }
1292     }
1293   }
1294 //  Modified by skv - Tue Mar 15 16:20:43 2005
1295
1296   //---------------------------
1297   // MAJ SD. for caps 
1298   //---------------------------
1299   //TopTools_MapOfShape View; 
1300   for (i = 1; i <= myFaces.Extent(); i++) {
1301     const TopoDS_Shape& Cork = myFaces(i);
1302     const TopTools_ListOfShape& LE = AsDes->Descendant(Cork);
1303     for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) {
1304       const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value());
1305       if (IMOE.HasImage(OE)) {
1306         const TopTools_ListOfShape& LOE = IMOE.Image(OE);
1307         TopTools_ListIteratorOfListOfShape itLOE(LOE);
1308         for (; itLOE.More(); itLOE.Next()) {
1309           const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value());
1310           myAsDes->Add(Cork,COE.Oriented(OE.Orientation())) ;
1311 #ifdef DRAW
1312           if (AffichInt2d) {
1313             sprintf(name,"AE_%d",NbAE++);
1314             DBRep::Set(name,COE);
1315             COES.Add(COE);
1316           }
1317 #endif
1318           
1319           if (!myAsDes->HasDescendant(COE)) {
1320             TopoDS_Vertex CV1,CV2;
1321             TopExp::Vertices(COE,CV1,CV2);
1322             if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD));
1323             if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED));   
1324           }
1325         }
1326       }
1327       else {
1328         myAsDes->Add(Cork,OE);
1329         if (AsDes->HasDescendant(OE)) {
1330           myAsDes->Add(OE,AsDes->Descendant(OE));
1331         }
1332 #ifdef DRAW
1333         if (AffichInt2d) {
1334           sprintf(name,"AE_%d",NbAE++);
1335           DBRep::Set(name,OE);
1336           COES.Add(OE);
1337         }
1338 #endif
1339       }
1340     }
1341   }
1342   
1343 #ifdef DEB
1344   DEBVerticesControl (COES,myAsDes);
1345   if ( ChronBuild) Clock.Show();
1346 #endif
1347 }
1348
1349
1350 //=======================================================================
1351 //function : BuildOffsetByArc
1352 //purpose  : 
1353 //=======================================================================
1354 void BRepOffset_MakeOffset::BuildOffsetByArc()
1355 {
1356 #ifdef  DEB
1357   if ( ChronBuild) {
1358     cout << " CONSTRUCTION OF OFFSETS :" << endl;
1359     Clock.Reset();
1360     Clock.Start();
1361   }
1362 #endif
1363
1364   BRepOffset_DataMapOfShapeOffset MapSF;
1365   TopTools_MapOfShape             Done;
1366   Standard_Boolean OffsetOutside = (myOffset > 0.)? Standard_True : Standard_False;
1367   //--------------------------------------------------------
1368   // Construction of faces parallel to initial faces
1369   //--------------------------------------------------------
1370   TopExp_Explorer Exp;
1371   TopTools_ListOfShape LF;
1372   TopTools_ListIteratorOfListOfShape itLF;
1373
1374   BRepLib::SortFaces(myShape,LF);
1375
1376   TopTools_DataMapOfShapeShape EdgeTgt;
1377   for (itLF.Initialize(LF); itLF.More(); itLF.Next()) {
1378     const TopoDS_Face&   F = TopoDS::Face(itLF.Value());
1379     Standard_Real CurOffset = myOffset;
1380     if (myFaceOffset.IsBound(F)) CurOffset = myFaceOffset(F);
1381     BRepOffset_Offset    OF(F,CurOffset,EdgeTgt,OffsetOutside,myJoin);
1382     TopTools_ListOfShape Let;
1383     myAnalyse.Edges(F,BRepOffset_Tangent,Let);
1384     TopTools_ListIteratorOfListOfShape itl(Let);
1385     
1386     for ( ; itl.More(); itl.Next()) {
1387       const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
1388       if ( !EdgeTgt.IsBound(Cur)) {
1389         TopoDS_Shape aLocalShape = OF.Generated(Cur);
1390         const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
1391 //      const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur));
1392         EdgeTgt.Bind(Cur,OF.Generated(Cur));
1393         TopoDS_Vertex V1,V2,OV1,OV2;
1394         TopExp::Vertices (Cur,V1,V2);
1395         TopExp::Vertices (OTE,OV1,OV2);      
1396         TopTools_ListOfShape LE;
1397         if (!EdgeTgt.IsBound(V1)) {
1398           myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
1399           const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
1400           if (LE.Extent() == LA.Extent())
1401             EdgeTgt.Bind(V1,OV1);
1402         }
1403         if (!EdgeTgt.IsBound(V2)) {
1404           LE.Clear();
1405           myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
1406           const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
1407           if (LE.Extent() == LA.Extent())
1408               EdgeTgt.Bind(V2,OV2);
1409         }
1410       }
1411     }
1412     MapSF.Bind(F,OF);
1413   }
1414   //--------------------------------------------------------
1415   // Construction of tubes on edge.
1416   //--------------------------------------------------------
1417   BRepOffset_Type    OT = BRepOffset_Convex;
1418   if (myOffset < 0.) OT = BRepOffset_Concave; 
1419    
1420   for (Exp.Init(myShape,TopAbs_EDGE); Exp.More(); Exp.Next()) {
1421     const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
1422     if (Done.Add(E)) {
1423       const TopTools_ListOfShape& Anc = myAnalyse.Ancestors(E);
1424       if (Anc.Extent() == 2) {
1425         const BRepOffset_ListOfInterval& L = myAnalyse.Type(E);
1426         if (!L.IsEmpty() && L.First().Type() == OT) {
1427           Standard_Real CurOffset = myOffset;
1428           if ( myFaceOffset.IsBound(Anc.First()))
1429             CurOffset = myFaceOffset(Anc.First());
1430           TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
1431           TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1432           aLocalShape = MapSF(Anc.Last()).Generated(E);
1433           TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape);
1434 //        TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
1435 //        TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E));
1436           // find if exits tangent edges in the original shape
1437           TopoDS_Edge E1f, E1l;
1438           TopoDS_Vertex V1f, V1l;
1439           TopExp::Vertices(E,V1f,V1l);
1440           TopTools_ListOfShape TangE;
1441           myAnalyse.TangentEdges(E,V1f,TangE);
1442           // find if the pipe on the tangent edges are soon created.
1443           TopTools_ListIteratorOfListOfShape itl(TangE);
1444           Standard_Boolean Find = Standard_False;
1445           for ( ; itl.More() && !Find; itl.Next()) {
1446             if ( MapSF.IsBound(itl.Value())) {
1447               TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f);
1448               E1f  = TopoDS::Edge(aLocalShape);
1449 //            E1f  = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f));
1450               Find = Standard_True;
1451             }
1452           }
1453           TangE.Clear();
1454           myAnalyse.TangentEdges(E,V1l,TangE);
1455           // find if the pipe on the tangent edges are soon created.
1456           itl.Initialize(TangE);
1457           Find = Standard_False;
1458           for ( ; itl.More() && !Find; itl.Next()) {
1459             if ( MapSF.IsBound(itl.Value())) {
1460               TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l);
1461               E1l  = TopoDS::Edge(aLocalShape);
1462 //            E1l  = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l));
1463               Find = Standard_True;
1464             }
1465           }
1466           BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l);
1467           MapSF.Bind(E,OF);
1468         }
1469       }
1470       else {
1471         // ----------------------
1472         // free border.
1473         // ----------------------
1474         TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E);
1475         TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape);
1476 ///     TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E));
1477         myInitOffsetEdge.SetRoot(E); // skv: supporting history.
1478         myInitOffsetEdge.Bind (E,EOn1);      
1479       }
1480     }
1481   }
1482
1483   //--------------------------------------------------------
1484   // Construction of spheres on vertex.
1485   //--------------------------------------------------------
1486   Done.Clear();
1487   TopTools_ListIteratorOfListOfShape it;
1488
1489   for (Exp.Init(myShape,TopAbs_VERTEX); Exp.More(); Exp.Next()) {
1490     const TopoDS_Vertex& V = TopoDS::Vertex (Exp.Current());
1491     if (Done.Add(V)) {
1492       const TopTools_ListOfShape& LA = myAnalyse.Ancestors(V);
1493       TopTools_ListOfShape LE;
1494       myAnalyse.Edges(V,OT,LE);
1495
1496       if (LE.Extent() >= 3 && LE.Extent() == LA.Extent()) {
1497         TopTools_ListOfShape LOE;
1498         //--------------------------------------------------------
1499         // Return connected edges on tubes.
1500         //--------------------------------------------------------
1501         for (it.Initialize(LE) ; it.More(); it.Next()) {
1502           LOE.Append(MapSF(it.Value()).Generated(V).Reversed());
1503         }
1504         //----------------------
1505         // construction sphere.
1506         //-----------------------
1507         const TopTools_ListOfShape& LLA = myAnalyse.Ancestors(LA.First());
1508         const TopoDS_Shape& FF = LLA.First();
1509         Standard_Real CurOffset = myOffset;
1510         if ( myFaceOffset.IsBound(FF))
1511           CurOffset = myFaceOffset(FF);
1512         
1513         BRepOffset_Offset OF(V,LOE,CurOffset);
1514         MapSF.Bind(V,OF);
1515       }
1516       //--------------------------------------------------------------
1517       // Particular processing if V is at least a free border.
1518       //-------------------------------------------------------------
1519       TopTools_ListOfShape LBF;
1520       myAnalyse.Edges(V,BRepOffset_FreeBoundary,LBF);
1521       if (!LBF.IsEmpty()) {     
1522         Standard_Boolean First = Standard_True;
1523         for (it.Initialize(LE) ; it.More(); it.Next()) {
1524           if (First) {
1525             myInitOffsetEdge.SetRoot(V); // skv: supporting history.
1526             myInitOffsetEdge.Bind(V,MapSF(it.Value()).Generated(V));
1527             First = Standard_False;
1528           }
1529           else {
1530             myInitOffsetEdge.Add(V,MapSF(it.Value()).Generated(V));
1531           }
1532         } 
1533       }
1534     }
1535   }
1536
1537   //------------------------------------------------------------
1538   // Extension of parallel faces to the context.
1539   // Extended faces are ordered in DS and removed from MapSF.
1540   //------------------------------------------------------------
1541   if (!myFaces.IsEmpty()) ToContext (MapSF);
1542
1543   //------------------------------------------------------
1544   // MAJ SD.
1545   //------------------------------------------------------
1546   BRepOffset_Type    RT = BRepOffset_Concave;
1547   if (myOffset < 0.) RT = BRepOffset_Convex;
1548   BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(MapSF);
1549   for ( ; It.More(); It.Next()) {
1550     const TopoDS_Shape& SI = It.Key(); 
1551     const BRepOffset_Offset& SF = It.Value();
1552     if (SF.Status() == BRepOffset_Reversed ||
1553         SF.Status() == BRepOffset_Degenerated ) {
1554       //------------------------------------------------
1555       // Degenerated or returned faces are not stored.
1556       //------------------------------------------------
1557       continue; 
1558     }   
1559
1560     const TopoDS_Face&  OF = It.Value().Face();
1561     myInitOffsetFace.Bind    (SI,OF);      
1562     myInitOffsetFace.SetRoot (SI);      // Initial<-> Offset
1563     myImageOffset.SetRoot    (OF);      // FaceOffset root of images
1564     
1565     if (SI.ShapeType() == TopAbs_FACE) {
1566       for (Exp.Init(SI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
1567            Exp.More(); Exp.Next()) {
1568         //--------------------------------------------------------------------
1569         // To each face are associatedthe edges that restrict that 
1570         // The edges that do not generate tubes or are not tangent
1571         // to two faces are removed.
1572         //--------------------------------------------------------------------
1573         const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
1574         const BRepOffset_ListOfInterval& L  = myAnalyse.Type(E);
1575         if (!L.IsEmpty() && L.First().Type() != RT) {
1576           TopAbs_Orientation OO  = E.Orientation();
1577           TopoDS_Shape aLocalShape = It.Value().Generated(E);
1578           TopoDS_Edge        OE  = TopoDS::Edge(aLocalShape);
1579 //        TopoDS_Edge        OE  = TopoDS::Edge(It.Value().Generated(E));
1580           myAsDes->Add (OF,OE.Oriented(OO));
1581         }
1582       }
1583     }
1584     else {
1585       for (Exp.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
1586            Exp.More(); Exp.Next()) {
1587         myAsDes->Add (OF,Exp.Current());
1588       }
1589     }
1590   }
1591
1592 #ifdef DEB
1593   if ( ChronBuild) Clock.Show();
1594 #endif
1595 }
1596
1597
1598
1599 //=======================================================================
1600 //function : SelfInter
1601 //purpose  : 
1602 //=======================================================================
1603
1604 void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& Modif)
1605 {
1606 #ifdef DEB
1607   if ( ChronBuild) {
1608     cout << " AUTODEBOUCLAGE:" << endl;
1609     Clock.Reset();
1610     Clock.Start();
1611   }    
1612 #endif  
1613
1614   Standard_NotImplemented::Raise();
1615
1616 #ifdef DEB
1617   if ( ChronBuild) Clock.Show();
1618 #endif
1619 }
1620
1621
1622 //=======================================================================
1623 //function : ToContext
1624 //purpose  : 
1625 //=======================================================================
1626
1627 void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
1628 {
1629   TopTools_DataMapOfShapeShape        Created;   
1630   TopTools_DataMapOfShapeShape        MEF;
1631   TopTools_IndexedMapOfShape          FacesToBuild;
1632   TopTools_ListIteratorOfListOfShape  itl;
1633   TopExp_Explorer                     exp;
1634
1635 //  TopAbs_State       Side = TopAbs_IN;  
1636 //  if (myOffset < 0.) Side = TopAbs_OUT;
1637
1638   TopAbs_State       Side = TopAbs_OUT; 
1639
1640   /*
1641   Standard_Integer i;
1642   for (i = 1; i <= myFaces.Extent(); i++) {
1643     const TopoDS_Face& CF = TopoDS::Face(myFaces(i));
1644     for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
1645          exp.More(); exp.Next()) {
1646       const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1647       if (!myAnalyse.HasAncestor(E)) {
1648         //----------------------------------------------------------------
1649         // The edges of context faces that are not in the initial shape
1650         // can appear in the result.
1651         //----------------------------------------------------------------
1652         //myAsDes->Add(CF,E);
1653       }  
1654     }
1655   }
1656   */
1657   
1658   //--------------------------------------------------------
1659   // Determine the edges and faces reconstructed by  
1660   // intersection.
1661   //---------------------------------------------------------
1662   Standard_Integer j;
1663   for (j = 1; j <= myFaces.Extent(); j++) {
1664     const TopoDS_Face& CF = TopoDS::Face(myFaces(j));
1665     for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
1666          exp.More(); exp.Next()) {
1667       const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); 
1668       if (myAnalyse.HasAncestor(E)) {
1669         const TopTools_ListOfShape& LEA = myAnalyse.Ancestors(E);
1670         for (itl.Initialize(LEA); itl.More(); itl.Next()) {
1671           const BRepOffset_Offset& OF = MapSF(itl.Value());
1672           FacesToBuild.Add(itl.Value());
1673           MEF.Bind(OF.Generated(E),CF);
1674         }
1675         TopoDS_Vertex V[2];
1676         TopExp::Vertices(E,V[0],V[1]);
1677         for (Standard_Integer i = 0; i < 2; i++) {
1678           const TopTools_ListOfShape& LVA =  myAnalyse.Ancestors(V[i]);
1679           for ( itl.Initialize(LVA); itl.More(); itl.Next()) {
1680             const TopoDS_Edge& EV = TopoDS::Edge(itl.Value());
1681             if (MapSF.IsBound(EV)) {
1682               const BRepOffset_Offset& OF = MapSF(EV);
1683               FacesToBuild.Add(EV);
1684               MEF.Bind(OF.Generated(V[i]),CF);
1685             }
1686           }
1687         }
1688       }
1689     }
1690   }
1691   //---------------------------
1692   // Reconstruction of faces.
1693   //---------------------------
1694   TopoDS_Face        F,NF;
1695   BRepOffset_Type    RT = BRepOffset_Concave;
1696   if (myOffset < 0.) RT = BRepOffset_Convex;
1697   TopoDS_Shape       OE,NE;
1698   TopAbs_Orientation Or;
1699
1700   for (j = 1; j <= FacesToBuild.Extent(); j++) {
1701     const TopoDS_Shape& S   = FacesToBuild(j);
1702     BRepOffset_Offset   BOF;
1703     BOF = MapSF(S);
1704     F = TopoDS::Face(BOF.Face());
1705     BRepOffset_Tool::ExtentFace(F,Created,MEF,Side,myTol,NF);
1706     MapSF.UnBind(S);
1707     //--------------
1708     // MAJ SD.
1709     //--------------
1710     myInitOffsetFace.Bind    (S,NF);      
1711     myInitOffsetFace.SetRoot (S);      // Initial<-> Offset
1712     myImageOffset.SetRoot    (NF);
1713
1714     if (S.ShapeType() == TopAbs_FACE) {
1715       for (exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
1716            exp.More(); exp.Next()) {
1717         
1718         const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
1719         const BRepOffset_ListOfInterval& L  = myAnalyse.Type(E);
1720         OE = BOF.Generated(E);
1721         Or = E.Orientation();
1722         OE.Orientation(Or);
1723         if (!L.IsEmpty() && L.First().Type() != RT) {
1724           if (Created.IsBound(OE)) {
1725             NE = Created(OE); 
1726             if (NE.Orientation() == TopAbs_REVERSED) 
1727               NE.Orientation(TopAbs::Reverse(Or));
1728             else
1729               NE.Orientation(Or);
1730             myAsDes->Add(NF,NE);
1731           }
1732           else {
1733             myAsDes->Add(NF,OE);
1734           }
1735         }
1736       }
1737     }
1738     else {
1739       //------------------
1740       // Tube
1741       //---------------------
1742       for (exp.Init(NF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); 
1743            exp.More(); exp.Next()) {
1744         myAsDes->Add (NF,exp.Current());
1745       }
1746     }    
1747     MapSF.UnBind(S);
1748   }
1749
1750   //------------------
1751   // MAJ free borders
1752   //------------------
1753   TopTools_DataMapIteratorOfDataMapOfShapeShape itc;
1754   for (itc.Initialize(Created); itc.More(); itc.Next()) {
1755     OE = itc.Key();
1756     NE = itc.Value();
1757     if (myInitOffsetEdge.IsImage(OE)) {
1758       TopoDS_Shape E = myInitOffsetEdge.ImageFrom (OE);
1759       Or = myInitOffsetEdge.Image(E).First().Orientation();
1760       if (NE.Orientation() == TopAbs_REVERSED) 
1761         NE.Orientation(TopAbs::Reverse(Or));
1762       else
1763         NE.Orientation(Or);
1764       myInitOffsetEdge.Remove(OE);
1765       myInitOffsetEdge.Bind(E,NE);
1766     }
1767   }
1768 }
1769
1770
1771 //=======================================================================
1772 //function : UpdateFaceOffset
1773 //purpose  : 
1774 //=======================================================================
1775
1776 void BRepOffset_MakeOffset::UpdateFaceOffset()
1777 {
1778   TopTools_MapOfShape M;
1779   TopTools_DataMapOfShapeReal CopiedMap;
1780   CopiedMap.Assign(myFaceOffset);
1781   TopTools_DataMapIteratorOfDataMapOfShapeReal it(CopiedMap);
1782
1783   BRepOffset_Type    RT = BRepOffset_Convex;
1784   if (myOffset < 0.) RT = BRepOffset_Concave;
1785
1786   for ( ; it.More(); it.Next()) {
1787     const TopoDS_Face& F = TopoDS::Face(it.Key());
1788     Standard_Real CurOffset = CopiedMap(F);
1789     if ( !M.Add(F)) continue;
1790     TopoDS_Compound Co;
1791     BRep_Builder Build;
1792     Build.MakeCompound(Co);
1793     TopTools_MapOfShape Dummy;
1794     Build.Add(Co,F);
1795     if (myJoin == GeomAbs_Arc)
1796       myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent,RT);
1797     else   
1798       myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent);
1799
1800     TopExp_Explorer exp(Co,TopAbs_FACE);
1801     for (; exp.More(); exp.Next()) {
1802       const TopoDS_Face& FF = TopoDS::Face(exp.Current());
1803       if ( !M.Add(FF)) continue;
1804       if ( myFaceOffset.IsBound(FF))
1805         myFaceOffset.UnBind(FF);
1806       myFaceOffset.Bind(FF,CurOffset);
1807     }
1808   }
1809 }
1810
1811 //=======================================================================
1812 //function : CorrectConicalFaces
1813 //purpose  : 
1814 //=======================================================================
1815
1816 void BRepOffset_MakeOffset::CorrectConicalFaces()
1817 {
1818   TopTools_SequenceOfShape Cones;
1819   TopTools_SequenceOfShape Circs;
1820   TopTools_SequenceOfShape Seams;
1821   Standard_Real TolApex = 1.e-5;
1822
1823   Standard_Integer i;
1824
1825   TopTools_DataMapOfShapeListOfShape FacesOfCone;
1826   //TopTools_DataMapOfShapeShape DegEdges;
1827   TopExp_Explorer Explo( myOffsetShape, TopAbs_FACE );
1828   if (myJoin == GeomAbs_Arc)
1829     {
1830       for (; Explo.More(); Explo.Next())
1831         {
1832           TopoDS_Face aFace = TopoDS::Face( Explo.Current() );
1833           Handle(Geom_Surface) aSurf = BRep_Tool::Surface( aFace );
1834           //if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
1835           //aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface(); //???
1836           
1837           TopTools_IndexedMapOfShape Emap;
1838           TopExp::MapShapes( aFace, TopAbs_EDGE, Emap );
1839           for (i = 1; i <= Emap.Extent(); i++)
1840             {
1841               TopoDS_Edge anEdge = TopoDS::Edge( Emap(i) );
1842               //Standard_Real f, l;
1843               //Handle(Geom_Curve) theCurve = BRep_Tool::Curve( anEdge, f, l );
1844               //Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &anEdge.TShape());
1845               if (BRep_Tool::Degenerated(anEdge))
1846                 {
1847                   //Check if anEdge is a really degenerated edge or not
1848                   BRepAdaptor_Curve BACurve(anEdge, aFace);
1849                   gp_Pnt Pfirst, Plast, Pmid;
1850                   Pfirst = BACurve.Value(BACurve.FirstParameter());
1851                   Plast  = BACurve.Value(BACurve.LastParameter());
1852                   Pmid   = BACurve.Value((BACurve.FirstParameter()+BACurve.LastParameter())/2.);
1853                   if (Pfirst.Distance(Plast) <= TolApex &&
1854                       Pfirst.Distance(Pmid)  <= TolApex)
1855                     continue;
1856                   //Cones.Append( aFace );
1857                   //Circs.Append( anEdge );
1858                   //TopoDS_Vertex Vdeg = TopExp::FirstVertex( anEdge );
1859                   TopoDS_Edge OrEdge = 
1860                     TopoDS::Edge( myInitOffsetEdge.Root( anEdge) );
1861                   TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
1862                   if ( FacesOfCone.IsBound(VF) )
1863                     {
1864                       //add a face to the existing list
1865                       TopTools_ListOfShape& aFaces = FacesOfCone.ChangeFind(VF);
1866                       aFaces.Append (aFace);
1867                       //DegEdges.Bind(aFace, anEdge);
1868                     }
1869                   else
1870                     {
1871                       //the vertex is not in the map => create a new key and items
1872                       TopTools_ListOfShape aFaces;
1873                       aFaces.Append (aFace);
1874                       FacesOfCone.Bind(VF, aFaces);
1875                       //DegEdges.Bind(aFace, anEdge);
1876                     }
1877                 }
1878             } //for (i = 1; i <= Emap.Extent(); i++)
1879         } //for (; fexp.More(); fexp.Next())
1880     } //if (myJoin == GeomAbs_Arc)
1881
1882   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Cone(FacesOfCone);
1883   BRep_Builder BB;
1884   TopLoc_Location L;
1885   for (; Cone.More(); Cone.Next() ) {
1886     gp_Sphere theSphere;
1887     Handle(Geom_SphericalSurface) aSphSurf;
1888     TopoDS_Wire SphereWire;
1889     BB.MakeWire(SphereWire);
1890     TopoDS_Vertex anApex = TopoDS::Vertex(Cone.Key());
1891     const TopTools_ListOfShape& Faces = Cone.Value(); //FacesOfCone(anApex);
1892     TopTools_ListIteratorOfListOfShape itFaces(Faces);
1893     Standard_Boolean isFirstFace = Standard_True;
1894     gp_Pnt FirstPoint;
1895     TopoDS_Vertex theFirstVertex, CurFirstVertex;
1896     for (; itFaces.More(); itFaces.Next())
1897       {
1898         TopoDS_Face aFace = TopoDS::Face(itFaces.Value()); //TopoDS::Face(Faces.First());
1899         TopoDS_Edge DegEdge; // = TopoDS::Edge(DegEdges(aFace));
1900         for (Explo.Init(aFace, TopAbs_EDGE); Explo.More(); Explo.Next())
1901           {
1902             DegEdge = TopoDS::Edge(Explo.Current());
1903             if (BRep_Tool::Degenerated(DegEdge))
1904               {
1905                 TopoDS_Edge OrEdge = TopoDS::Edge( myInitOffsetEdge.Root( DegEdge) );
1906                 TopoDS_Vertex VF = TopExp::FirstVertex( OrEdge );
1907                 if (VF.IsSame(anApex))
1908                   break;
1909               }
1910           }
1911         TopoDS_Shape aLocalDegShape = DegEdge.Oriented(TopAbs_FORWARD);
1912         TopoDS_Edge CurEdge = TopoDS::Edge(aLocalDegShape);
1913         BB.Degenerated(CurEdge, Standard_False);
1914         BB.SameRange(CurEdge, Standard_False);
1915         BB.SameParameter(CurEdge, Standard_False);
1916         gp_Pnt fPnt, lPnt, mPnt;
1917         GetEdgePoints(CurEdge, aFace, fPnt, mPnt, lPnt);
1918         Standard_Real f, l;
1919         BRep_Tool::Range(CurEdge, f, l);
1920         if (isFirstFace)
1921           {
1922             gp_Vec aVec1(fPnt, mPnt);
1923             gp_Vec aVec2(fPnt, lPnt);
1924             gp_Vec aNorm = aVec1.Crossed(aVec2);
1925             gp_Pnt theApex = BRep_Tool::Pnt(anApex);
1926             gp_Vec ApexToFpnt(theApex, fPnt);
1927             gp_Vec Ydir = aNorm ^ ApexToFpnt;
1928             gp_Vec Xdir = Ydir ^ aNorm;
1929             //Xdir.Rotate(gp_Ax1(theApex, aNorm), -f);
1930             gp_Ax2 anAx2(theApex, gp_Dir(aNorm), gp_Dir(Xdir));
1931             theSphere.SetRadius(myOffset);
1932             theSphere.SetPosition(gp_Ax3(anAx2) /*gp_Ax3(theApex, gp_Dir(aNorm))*/);
1933             aSphSurf = new Geom_SphericalSurface(theSphere);
1934             FirstPoint = fPnt;
1935             theFirstVertex = BRepLib_MakeVertex(fPnt);
1936             CurFirstVertex = theFirstVertex;
1937           }
1938
1939         TopoDS_Vertex v1, v2, FirstVert, EndVert;
1940         TopExp::Vertices(CurEdge, v1, v2);
1941         FirstVert = CurFirstVertex;
1942         if (lPnt.Distance(FirstPoint) <= Precision::Confusion())
1943           EndVert = theFirstVertex;
1944         else
1945           EndVert = BRepLib_MakeVertex(lPnt);
1946         CurEdge.Free( Standard_True );
1947         BB.Remove(CurEdge, v1);
1948         BB.Remove(CurEdge, v2);
1949         BB.Add(CurEdge, FirstVert.Oriented(TopAbs_FORWARD));
1950         BB.Add(CurEdge, EndVert.Oriented(TopAbs_REVERSED));
1951         //take the curve from sphere an put it to the edge
1952         Standard_Real Uf, Vf, Ul, Vl;
1953         ElSLib::Parameters( theSphere, fPnt, Uf, Vf );
1954         ElSLib::Parameters( theSphere, lPnt, Ul, Vl );
1955         if (Abs(Ul) <= Precision::Confusion())
1956           Ul = 2.*M_PI;
1957         Handle(Geom_Curve) aCurv = aSphSurf->VIso(Vf);
1958         /*
1959         if (!isFirstFace)
1960           {
1961             gp_Circ aCircle = (Handle(Geom_Circle)::DownCast(aCurv))->Circ();
1962             if (Abs(Uf - f) > Precision::Confusion())
1963               {
1964                 aCircle.Rotate(aCircle.Axis(), f - Uf);
1965                 aCurv = new Geom_Circle(aCircle);
1966               }
1967           }
1968         */
1969         Handle(Geom_TrimmedCurve) aTrimCurv = new Geom_TrimmedCurve(aCurv, Uf, Ul);
1970         BB.UpdateEdge(CurEdge, aTrimCurv, Precision::Confusion());
1971         BB.Range(CurEdge, Uf, Ul, Standard_True);
1972         Handle(Geom2d_Line) theLin2d = new Geom2d_Line( gp_Pnt2d( 0., Vf ), gp::DX2d() );
1973         Handle(Geom2d_TrimmedCurve) theTrimLin2d = new Geom2d_TrimmedCurve(theLin2d, Uf, Ul);
1974         BB.UpdateEdge(CurEdge, theTrimLin2d, aSphSurf, L, Precision::Confusion());
1975         BB.Range(CurEdge, aSphSurf, L, Uf, Ul);
1976         BRepLib::SameParameter(CurEdge);
1977         BB.Add(SphereWire, CurEdge);
1978         //Modifying correspondent edges in aFace: substitute vertices common with CurEdge
1979         BRepAdaptor_Curve2d BAc2d(CurEdge, aFace);
1980         gp_Pnt2d fPnt2d, lPnt2d;
1981         fPnt2d = BAc2d.Value(BAc2d.FirstParameter());
1982         lPnt2d = BAc2d.Value(BAc2d.LastParameter());
1983         TopTools_IndexedMapOfShape Emap;
1984         TopExp::MapShapes(aFace, TopAbs_EDGE, Emap);
1985         TopoDS_Edge EE [2];
1986         Standard_Integer j = 0, k;
1987         for (k = 1; k <= Emap.Extent(); k++)
1988           {
1989             const TopoDS_Edge& anEdge = TopoDS::Edge(Emap(k));
1990             if (!BRep_Tool::Degenerated(anEdge))
1991               {
1992                 TopoDS_Vertex V1, V2;
1993                 TopExp::Vertices(anEdge, V1, V2);
1994                 if (V1.IsSame(v1) || V2.IsSame(v1))
1995                   EE[j++] = anEdge;
1996               }
1997           }
1998         for (k = 0; k < j; k++)
1999           {
2000             TopoDS_Shape aLocalShape = EE[k].Oriented(TopAbs_FORWARD);
2001             TopoDS_Edge Eforward = TopoDS::Edge(aLocalShape);
2002             Eforward.Free(Standard_True);
2003             TopoDS_Vertex V1, V2;
2004             TopExp::Vertices( Eforward, V1, V2 );
2005             BRepAdaptor_Curve2d EEc( Eforward, aFace );
2006             gp_Pnt2d p2d1, p2d2;
2007             p2d1 = EEc.Value(EEc.FirstParameter());
2008             p2d2 = EEc.Value(EEc.LastParameter());
2009             if (V1.IsSame(v1))
2010               {
2011                 TopoDS_Vertex NewV = (p2d1.Distance(fPnt2d) <= Precision::Confusion())?
2012                   FirstVert : EndVert;
2013                 BB.Remove( Eforward, V1 );
2014                 BB.Add( Eforward, NewV.Oriented(TopAbs_FORWARD) );
2015               }
2016             else
2017               {
2018                 TopoDS_Vertex NewV = (p2d2.Distance(fPnt2d) <= Precision::Confusion())?
2019                   FirstVert : EndVert;
2020                 BB.Remove( Eforward, V2 );
2021                 BB.Add( Eforward, NewV.Oriented(TopAbs_REVERSED) );
2022               }
2023           }
2024
2025         isFirstFace = Standard_False;
2026         CurFirstVertex = EndVert;
2027       }
2028     //Building new spherical face
2029     Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
2030     gp_Pnt2d p2d1, p2d2;
2031     TopTools_ListOfShape EdgesOfWire;
2032     TopoDS_Iterator itw(SphereWire);
2033     for (; itw.More(); itw.Next())
2034       {
2035         const TopoDS_Edge& anEdge = TopoDS::Edge(itw.Value());
2036         EdgesOfWire.Append(anEdge);
2037         Standard_Real f, l;
2038         Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(anEdge, aSphSurf, L, f, l);
2039         p2d1 = aC2d->Value(f);
2040         p2d2 = aC2d->Value(l);
2041         if (p2d1.X() < Ufirst)
2042           Ufirst = p2d1.X();
2043         if (p2d1.X() > Ulast)
2044           Ulast = p2d1.X();
2045         if (p2d2.X() < Ufirst)
2046           Ufirst = p2d2.X();
2047         if (p2d2.X() > Ulast)
2048           Ulast = p2d2.X();
2049       }
2050     TopTools_ListOfShape NewEdges;
2051     TopoDS_Edge FirstEdge;
2052     TopTools_ListIteratorOfListOfShape itl(EdgesOfWire);
2053     for (; itl.More(); itl.Next())
2054       {
2055         FirstEdge = TopoDS::Edge(itl.Value());
2056         Standard_Real f, l;
2057         Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(FirstEdge, aSphSurf, L, f, l);
2058         p2d1 = aC2d->Value(f);
2059         p2d2 = aC2d->Value(l);
2060         if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion())
2061           {
2062             EdgesOfWire.Remove(itl);
2063             break;
2064           }
2065       }
2066     NewEdges.Append(FirstEdge);
2067     TopoDS_Vertex Vf1, CurVertex;
2068     TopExp::Vertices(FirstEdge, Vf1, CurVertex);
2069     itl.Initialize(EdgesOfWire);
2070     while (itl.More())
2071       {
2072         const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
2073         TopoDS_Vertex V1, V2;
2074         TopExp::Vertices(anEdge, V1, V2);
2075         if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex))
2076           {
2077             NewEdges.Append(anEdge);
2078             CurVertex = (V1.IsSame(CurVertex))? V2 : V1;
2079             EdgesOfWire.Remove(itl);
2080           }
2081         else
2082           itl.Next();
2083       }
2084
2085     Standard_Real Vfirst, Vlast;
2086     if (p2d1.Y() > 0.)
2087       {
2088         Vfirst = p2d1.Y(); Vlast = M_PI/2.;
2089       }
2090     else
2091       {
2092         Vfirst = -M_PI/2.; Vlast = p2d1.Y();
2093       }
2094     TopoDS_Face NewSphericalFace = BRepLib_MakeFace(aSphSurf, Ufirst, Ulast, Vfirst, Vlast, Precision::Confusion());
2095     TopoDS_Edge OldEdge;
2096     for (Explo.Init(NewSphericalFace, TopAbs_EDGE); Explo.More(); Explo.Next())
2097       {
2098         OldEdge = TopoDS::Edge(Explo.Current());
2099         if (!BRep_Tool::Degenerated(OldEdge))
2100           {
2101             BRepAdaptor_Curve2d BAc2d(OldEdge, NewSphericalFace);
2102             p2d1 = BAc2d.Value(BAc2d.FirstParameter());
2103             p2d2 = BAc2d.Value(BAc2d.LastParameter());
2104             if (Abs(p2d1.X() - Ufirst) <= Precision::Confusion() &&
2105                 Abs(p2d2.X() - Ulast)  <= Precision::Confusion())
2106               break;
2107           }
2108       }
2109     TopoDS_Vertex V1, V2;
2110     TopExp::Vertices(OldEdge, V1, V2);
2111     TopTools_ListOfShape LV1, LV2;
2112     LV1.Append(Vf1);
2113     LV2.Append(CurVertex);
2114     BRepTools_Substitution theSubstitutor;
2115     theSubstitutor.Substitute(V1, LV1);
2116     if (!V1.IsSame(V2))
2117       theSubstitutor.Substitute(V2, LV2);
2118     theSubstitutor.Substitute(OldEdge, NewEdges);
2119     theSubstitutor.Build(NewSphericalFace);
2120     if (theSubstitutor.IsCopied(NewSphericalFace))
2121       {
2122         const TopTools_ListOfShape& listSh = theSubstitutor.Copy(NewSphericalFace);
2123         NewSphericalFace = TopoDS::Face(listSh.First());
2124       }
2125
2126     //Adding NewSphericalFace to the shell
2127     Explo.Init( myOffsetShape, TopAbs_SHELL );
2128     TopoDS_Shape theShell = Explo.Current();
2129     theShell.Free( Standard_True );
2130     BB.Add( theShell, NewSphericalFace );
2131   }
2132
2133   Explo.Init( myOffsetShape, TopAbs_SHELL );
2134
2135   if (Explo.More()) {
2136     TopoDS_Shape theShell = Explo.Current();
2137     theShell.Closed( Standard_True );
2138   }
2139
2140 /*
2141   //Reconstructing
2142   BRep_Builder BB;
2143   for (i = 1; i <= Cones.Length(); i++)
2144     {
2145       TopoDS_Face Cone = TopoDS::Face( Cones(i) );
2146       TopoDS_Edge Circ = TopoDS::Edge( Circs(i) );
2147       TopoDS_Edge Seam = TopoDS::Edge( Seams(i) );
2148       if (Circ.IsNull()) //case 1 with big offset
2149         {
2150           //ExtraFace is absent
2151           
2152           Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
2153
2154           if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2155             aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2156           gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2157           gp_Pnt apex = theCone.Apex();
2158           Standard_Real Uapex, Vapex;
2159           ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2160           if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2161             apex = OffSurf->Value( Uapex, Vapex );
2162
2163           //Making new degenerated edge
2164           Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
2165           TopoDS_Edge NewEdge;
2166           BB.MakeEdge( NewEdge );
2167           NewEdge.Orientation(TopAbs_FORWARD);
2168           BB.UpdateEdge( NewEdge, theLine, Cone, Precision::Confusion() );
2169           BB.Range( NewEdge, 0., 2.*M_PI );
2170           BB.SameParameter( NewEdge, Standard_True );
2171           BB.SameRange( NewEdge, Standard_True );
2172           BB.Degenerated( NewEdge, Standard_True );
2173           TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
2174           BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
2175           BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
2176
2177           //Reconstructing Seam
2178           Standard_Real f, l, par, cpar;
2179           Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
2180           gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
2181           par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
2182           TopoDS_Shape aLocalShape = Seam.Oriented(TopAbs_FORWARD);
2183           TopoDS_Vertex cver = TopExp::LastVertex( TopoDS::Edge(aLocalShape) );
2184           cpar = BRep_Tool::Parameter( cver, Seam, Cone );
2185           if (Abs(f-cpar) < Abs(l-cpar))
2186             BB.Range( Seam, par, l );
2187           else
2188             BB.Range( Seam, f, par );
2189           Seam.Free( Standard_True );
2190           TopoDS_Shape cver1;
2191           TopoDS_Iterator iter( Seam );
2192           for (; iter.More(); iter.Next())
2193             {
2194               cver1 = iter.Value();
2195               if (cver1.IsSame(cver))
2196                 break;
2197             }
2198           BB.Remove( Seam, cver1 );
2199           if (Abs(f-cpar) < Abs(l-cpar))
2200             BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
2201           else
2202             BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
2203
2204           //Adding NewEdge into Cone
2205           TopoDS_Shape theWire;
2206           for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2207             {
2208               theWire = fexp.Current();
2209               Standard_Boolean found = Standard_False;
2210               for (iter.Initialize( theWire ); iter.More(); iter.Next())
2211                 {
2212                   if (Seam.IsSame( iter.Value() ))
2213                     {
2214                       found = Standard_True;
2215                       break;
2216                     }
2217                 }
2218               if (found)
2219                 break;
2220             }
2221           theWire.Free( Standard_True );
2222           NewEdge.Orientation( TopAbs::Compose(theWire.Orientation(),TopAbs_REVERSED) );
2223           BB.Add( theWire, NewEdge );
2224         } //end of case 1 with big offset
2225       else
2226         {
2227           Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Circ.TShape());
2228           if (! TE->Degenerated()) //case 1
2229             {
2230               //Find ExtraFace
2231               TopoDS_Face ExtraFace;
2232               for (fexp.Init( myOffsetShape, TopAbs_FACE ); fexp.More(); fexp.Next())
2233                 {
2234                   ExtraFace = TopoDS::Face( fexp.Current() );
2235                   if (ExtraFace.IsSame( Cone ))
2236                     continue;
2237                   Standard_Boolean found = Standard_False;
2238                   TopExp_Explorer eexp( ExtraFace, TopAbs_EDGE );
2239                   for (; eexp.More(); eexp.Next())
2240                     if (Circ.IsSame( eexp.Current() ))
2241                       {
2242                         found = Standard_True;
2243                         break;
2244                       }
2245                   if (found)
2246                     break;
2247                 }
2248               
2249               Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
2250               if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2251                 aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2252               gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2253               gp_Pnt apex = theCone.Apex();
2254               Standard_Real Uapex, Vapex;
2255               ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2256               if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2257                 apex = OffSurf->Value( Uapex, Vapex );
2258               
2259               //Making new degenerated edge
2260               Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
2261               TopoDS_Edge NewEdge;
2262               BB.MakeEdge( NewEdge );
2263               NewEdge.Orientation(TopAbs_FORWARD);
2264               BB.UpdateEdge( NewEdge, theLine, Cone, BRep_Tool::Tolerance( Circ ) );
2265               BB.Range( NewEdge, 0., 2.*M_PI );
2266               BB.SameParameter( NewEdge, Standard_True );
2267               BB.SameRange( NewEdge, Standard_True );
2268               BB.Degenerated( NewEdge, Standard_True );
2269               TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
2270               BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
2271               BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
2272               
2273               TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
2274               
2275               //Reconstructing Seam
2276               Standard_Real f, l, par, cpar;
2277               Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
2278               gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
2279               par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
2280               cpar = BRep_Tool::Parameter( cver, Seam, Cone );
2281               if (Abs(f-cpar) < Abs(l-cpar))
2282                 BB.Range( Seam, par, l );
2283               else
2284                 BB.Range( Seam, f, par );
2285               Seam.Free( Standard_True );
2286               TopoDS_Shape cver1;
2287               TopoDS_Iterator iter( Seam );
2288               for (; iter.More(); iter.Next())
2289                 {
2290                   cver1 = iter.Value();
2291                   if (cver1.IsSame(cver))
2292                     break;
2293                 }
2294               BB.Remove( Seam, cver1 );
2295               if (Abs(f-cpar) < Abs(l-cpar))
2296                 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
2297               else
2298                 BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
2299               
2300               //Removing ExtraFace from the shell
2301               fexp.Init( myOffsetShape, TopAbs_SHELL );
2302               TopoDS_Shape theShell = fexp.Current();
2303               theShell.Free( Standard_True );
2304               TopoDS_Shape ExtraFace1;
2305               for (iter.Initialize( theShell ); iter.More(); iter.Next())
2306                 {
2307                   ExtraFace1 = iter.Value();
2308                   if (ExtraFace1.IsSame(ExtraFace))
2309                     break;
2310                 }
2311               BB.Remove( theShell, ExtraFace1 );
2312               
2313               //Substitute Circ by NewEdge in Cone
2314               TopoDS_Shape theWire;
2315               TopoDS_Shape Circ1;
2316               for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2317                 {
2318                   theWire = fexp.Current();
2319                   Standard_Boolean found = Standard_False;
2320                   for (iter.Initialize( theWire ); iter.More(); iter.Next())
2321                     {
2322                       Circ1 = iter.Value();
2323                       if (Circ1.IsSame(Circ))
2324                         {
2325                           found = Standard_True;
2326                           break;
2327                         }
2328                     }
2329                   if (found)
2330                     break;
2331                 }
2332               TopAbs_Orientation Or = Circ1.Orientation();
2333               theWire.Free( Standard_True );
2334               BB.Remove( theWire, Circ1 );
2335               BB.Add( theWire, NewEdge.Oriented(Or) );
2336             } //end of case 1
2337           else // Circ is degenerated
2338             {
2339               if (myOffset > 0. && myJoin == GeomAbs_Arc) //case 2
2340                 {
2341                   TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
2342                   
2343                   TopoDS_Face OrCone = TopoDS::Face( myInitOffsetFace.Root( Cone ) );
2344                   Handle(Geom_Surface) aSurf = BRep_Tool::Surface( OrCone ), OffSurf = aSurf;
2345                   if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2346                     aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2347                   gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2348                   gp_Pnt apex = theCone.Apex();
2349                   if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2350                     {
2351                       Standard_Real Uapex, Vapex;
2352                       ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2353                       apex = OffSurf->Value( Uapex, Vapex );
2354                     }
2355
2356                   Standard_Real f, l;
2357                   Handle(Geom_Curve) ccur = BRep_Tool::Curve( Circ, f, l );
2358                   gp_Ax2 Axe2 = (Handle(Geom_Circle)::DownCast(ccur))->Circ().Position();
2359                   gp_Ax3 Axe3( Axe2 );
2360                   Axe3.SetLocation( apex );
2361                   gp_Sphere theSphere( Axe3, myOffset );
2362
2363                   gp_Pnt OrPnt = BRep_Tool::Pnt(cver);
2364                   Standard_Real Uor, Vor;
2365                   ElSLib::Parameters( theSphere, OrPnt, Uor, Vor );
2366                   TopoDS_Face NewFace;
2367                   if (Vor > 0.)
2368                     NewFace = BRepLib_MakeFace( theSphere, 0., 2.*M_PI, Vor, M_PI/2. );
2369                   else
2370                     NewFace = BRepLib_MakeFace( theSphere, 0., 2.*M_PI, -M_PI/2., Vor );
2371                   
2372                   //Updating the bound of NewFace
2373                   TopoDS_Edge Bound;
2374                   TopExp_Explorer eexp( NewFace, TopAbs_EDGE );
2375                   for (; eexp.More(); eexp.Next())
2376                     {
2377                       Bound = TopoDS::Edge( eexp.Current() );
2378                       Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &Bound.TShape());
2379                       if (!TE->Degenerated() && !BRepTools::IsReallyClosed( Bound, NewFace ))
2380                         break;
2381                     }
2382                   Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( Circ, Cone, f, l );
2383                   BB.UpdateEdge( Bound, pcurve, Cone, BRep_Tool::Tolerance(Circ) );
2384                   TopoDS_Vertex bver = TopExp::FirstVertex( Bound );
2385                   BB.UpdateVertex( bver, BRep_Tool::Tolerance(cver) );
2386                   
2387                   //Updating cver in Seam
2388                   TopoDS_Vertex cver1;
2389                   TopoDS_Iterator iter( Seam );
2390                   for (; iter.More(); iter.Next())
2391                     {
2392                       cver1 = TopoDS::Vertex( iter.Value() );
2393                       if (cver1.IsSame(cver))
2394                         break;
2395                     }
2396                   TopAbs_Orientation Or = cver1.Orientation();
2397                   Seam.Free( Standard_True );
2398                   BB.Remove( Seam, cver1 );
2399                   BB.Add( Seam, bver.Oriented(Or) );
2400                   
2401                   //Substitute Circ by Bound in Cone
2402                   TopoDS_Shape theWire;
2403                   TopoDS_Shape Circ1;
2404                   for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2405                     {
2406                       theWire = fexp.Current();
2407                       Standard_Boolean found = Standard_False;
2408                       for (iter.Initialize( theWire ); iter.More(); iter.Next())
2409                         {
2410                           Circ1 = iter.Value();
2411                           if (Circ1.IsSame(Circ))
2412                             {
2413                               found = Standard_True;
2414                               break;
2415                             }
2416                         }
2417                       if (found)
2418                         break;
2419                     }
2420                   Or = Circ1.Orientation();
2421                   theWire.Free( Standard_True );
2422                   BB.Remove( theWire, Circ1 );
2423                   BB.Add( theWire, Bound.Oriented(Or) );
2424                   
2425                   //Adding NewFace to the shell
2426                   fexp.Init( myOffsetShape, TopAbs_SHELL );
2427                   TopoDS_Shape theShell = fexp.Current();
2428                   theShell.Free( Standard_True );
2429                   BB.Add( theShell, NewFace );
2430                   
2431                   theShell.Closed( Standard_True );
2432                 } //end of case 2
2433               else // if ((myOffset > 0. && myJoin == GeomAbs_Intersection) || myOffset < 0.) //case 3, 4
2434                 {
2435                   Handle(Geom_Surface) aSurf = BRep_Tool::Surface( Cone ), OffSurf = aSurf;
2436                   if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2437                     aSurf = (Handle(Geom_OffsetSurface)::DownCast(aSurf))->BasisSurface();
2438                   gp_Cone theCone = (Handle(Geom_ConicalSurface)::DownCast(aSurf))->Cone();
2439                   gp_Pnt apex = theCone.Apex();
2440                   Standard_Real Uapex, Vapex;
2441                   ElSLib::Parameters( theCone, apex, Uapex, Vapex );
2442                   if (aSurf->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2443                     apex = OffSurf->Value( Uapex, Vapex );
2444                   
2445                   //Making new degenerated edge
2446                   Handle(Geom2d_Line) theLine = GCE2d_MakeLine( gp_Pnt2d( 0., Vapex ), gp_Pnt2d( 2.*M_PI, Vapex ) );
2447                   TopoDS_Edge NewEdge;
2448                   BB.MakeEdge( NewEdge );
2449                   NewEdge.Orientation(TopAbs_FORWARD);
2450                   BB.UpdateEdge( NewEdge, theLine, Cone, BRep_Tool::Tolerance( Circ ) );
2451                   BB.Range( NewEdge, 0., 2.*M_PI );
2452                   BB.SameParameter( NewEdge, Standard_True );
2453                   BB.SameRange( NewEdge, Standard_True );
2454                   BB.Degenerated( NewEdge, Standard_True );
2455                   TopoDS_Vertex Apex = BRepLib_MakeVertex( apex );
2456                   BB.Add( NewEdge, Apex.Oriented(TopAbs_FORWARD) );
2457                   BB.Add( NewEdge, Apex.Oriented(TopAbs_REVERSED) );
2458                   
2459                   TopoDS_Vertex cver = TopExp::FirstVertex( Circ );
2460                   
2461                   //Reconstructing Seam
2462                   Standard_Real f, l, par, cpar;
2463                   Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( Seam, Cone, f, l );
2464                   gp_Lin2d aLine = (Handle(Geom2d_Line)::DownCast(theCurve))->Lin2d();
2465                   par = ElCLib::Parameter( aLine, gp_Pnt2d( Uapex, Vapex ) );
2466                   cpar = BRep_Tool::Parameter( cver, Seam, Cone );
2467                   if (Abs(f-cpar) < Abs(l-cpar))
2468                     BB.Range( Seam, par, l );
2469                   else
2470                     BB.Range( Seam, f, par );
2471                   Seam.Free( Standard_True );
2472                   TopoDS_Shape cver1;
2473                   TopoDS_Iterator iter( Seam );
2474                   for (; iter.More(); iter.Next())
2475                     {
2476                       cver1 = iter.Value();
2477                       if (cver1.IsSame(cver))
2478                         break;
2479                     }
2480                   BB.Remove( Seam, cver1 );
2481                   if (Abs(f-cpar) < Abs(l-cpar))
2482                     BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_FORWARD) ) );
2483                   else
2484                     BB.Add( Seam, Apex.Oriented( TopAbs::Compose(Seam.Orientation(),TopAbs_REVERSED) ) );
2485                   
2486                   //Substitute Circ by NewEdge in Cone
2487                   TopoDS_Shape theWire;
2488                   TopoDS_Shape Circ1;
2489                   for (fexp.Init( Cone, TopAbs_WIRE ); fexp.More(); fexp.Next())
2490                     {
2491                       theWire = fexp.Current();
2492                       Standard_Boolean found = Standard_False;
2493                       for (iter.Initialize( theWire ); iter.More(); iter.Next())
2494                         {
2495                           Circ1 = iter.Value();
2496                           if (Circ1.IsSame(Circ))
2497                             {
2498                               found = Standard_True;
2499                               break;
2500                             }
2501                         }
2502                       if (found)
2503                         break;
2504                     }
2505                   TopAbs_Orientation Or = Circ1.Orientation();
2506                   theWire.Free( Standard_True );
2507                   BB.Remove( theWire, Circ1 );
2508                   BB.Add( theWire, NewEdge.Oriented(Or) );
2509                   
2510                   fexp.Init( myOffsetShape, TopAbs_SHELL );
2511                   TopoDS_Shape theShell = fexp.Current();
2512                   theShell.Closed( Standard_True );
2513                 } //end of case 3, 4
2514             }
2515         } //else (! Circ.IsNull())
2516     }
2517 */
2518
2519   Standard_Integer            NbShell = 0;
2520   TopoDS_Compound             NC;
2521   TopoDS_Shape                S1;
2522   BB.MakeCompound (NC);
2523   
2524   for (Explo.Init(myOffsetShape,TopAbs_SHELL); Explo.More(); Explo.Next()) {
2525     const TopoDS_Shell& Sh = TopoDS::Shell(Explo.Current());
2526     NbShell++;
2527     if (Sh.Closed()) {
2528       TopoDS_Solid  Sol;
2529       BB.MakeSolid  (Sol);
2530       BB.Add        (Sol,Sh);
2531       Sol.Closed(Standard_True);
2532       BB.Add (NC,Sol);
2533       if (NbShell == 1) S1 = Sol;
2534     }
2535     else {
2536       BB.Add (NC,Sh);
2537       if (NbShell == 1) S1 = Sh;
2538     }
2539   }
2540   if (NbShell == 1) myOffsetShape = S1;
2541   else              myOffsetShape = NC;
2542 }
2543
2544
2545 //=======================================================================
2546 //function : Intersection3D
2547 //purpose  : 
2548 //=======================================================================
2549
2550 void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter)
2551 {
2552 #ifdef DEB
2553   if (ChronBuild) {
2554     cout << " INTERSECTION 3D:" << endl;
2555     Clock.Reset();
2556     Clock.Start();  
2557   }
2558 #endif
2559   TopTools_ListOfShape OffsetFaces;  // list of faces // created.
2560   MakeList (OffsetFaces,myInitOffsetFace,myFaces);
2561
2562   if (!myFaces.IsEmpty()) {     
2563     Standard_Boolean InSide = (myOffset < 0.); // Temporary
2564     // it is necessary to calculate Inside taking account of the concavity or convexity of edges
2565     // between the cap and the part.
2566
2567     if (myJoin == GeomAbs_Arc) 
2568       Inter.ContextIntByArc (myFaces,InSide,myAnalyse,myInitOffsetFace,myInitOffsetEdge);
2569   }
2570   if (myInter) {
2571     //-------------
2572     //Complete.
2573     //-------------
2574     Inter.CompletInt (OffsetFaces,myInitOffsetFace);
2575     TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges();
2576     if (myJoin == GeomAbs_Intersection) {
2577       BRepOffset_Tool::CorrectOrientation (myShape,NewEdges,myAsDes,myInitOffsetFace,myOffset);
2578     }
2579   }
2580   else {
2581     //--------------------------------
2582     // Only between neighbor faces.
2583     //--------------------------------
2584     Inter.ConnexIntByArc(OffsetFaces,myShape,myAnalyse,myInitOffsetFace);
2585   }
2586 #ifdef DEB
2587   if ( ChronBuild) Clock.Show();
2588 #endif
2589 }
2590
2591 //=======================================================================
2592 //function : Intersection2D
2593 //purpose  : 
2594 //=======================================================================
2595
2596 void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Modif,
2597                                            const TopTools_IndexedMapOfShape& NewEdges)
2598 {
2599 #ifdef DEB
2600   if (ChronBuild) {
2601     cout << " INTERSECTION 2D:" << endl;
2602     Clock.Reset();
2603     Clock.Start();  
2604   }
2605 #endif
2606   //--------------------------------------------------------
2607   // calculate intersections2d on faces concerned by 
2608   // intersection3d
2609   //---------------------------------------------------------
2610   //TopTools_MapIteratorOfMapOfShape it(Modif);
2611   //-----------------------------------------------
2612   // Intersection of edges 2 by 2.
2613   //-----------------------------------------------
2614   Standard_Integer i;
2615   for (i = 1; i <= Modif.Extent(); i++) {
2616     const TopoDS_Face& F  = TopoDS::Face(Modif(i));
2617     BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol);
2618   }
2619
2620 #ifdef DEB
2621   if (AffichInt2d) {
2622     DEBVerticesControl (NewEdges,myAsDes);
2623   }
2624   if ( ChronBuild) Clock.Show();
2625 #endif
2626 }
2627
2628
2629 //=======================================================================
2630 //function : MakeLoops
2631 //purpose  : 
2632 //=======================================================================
2633
2634 void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif)
2635 {
2636 #ifdef DEB
2637   if (ChronBuild) {
2638      cout << " DEBOUCLAGE 2D:" << endl;
2639      Clock.Reset();
2640      Clock.Start(); 
2641   }
2642 #endif
2643   //TopTools_MapIteratorOfMapOfShape    it(Modif);
2644   TopTools_ListOfShape                LF,LC;
2645   //-----------------------------------------
2646   // unwinding of faces // modified.
2647   //-----------------------------------------
2648   Standard_Integer i;
2649   for (i = 1; i <= Modif.Extent(); i++) { 
2650     if (!myFaces.Contains(Modif(i)))
2651       LF.Append(Modif(i));
2652   }
2653   myMakeLoops.Build(LF,myAsDes,myImageOffset);
2654
2655   //-----------------------------------------
2656   // unwinding of caps.
2657   //-----------------------------------------
2658   for (i = 1; i <= myFaces.Extent(); i++)
2659     LC.Append(myFaces(i));
2660
2661   Standard_Boolean   InSide = 1;
2662   if (myOffset > 0 ) InSide = 0;
2663   myMakeLoops.BuildOnContext(LC,myAnalyse,myAsDes,myImageOffset,InSide);
2664
2665 #ifdef DEB
2666   if ( ChronBuild) Clock.Show();
2667 #endif
2668 }
2669
2670 //=======================================================================
2671 //function : MakeFaces
2672 //purpose  : Reconstruction of topologically unchanged faces that
2673 //           share edges that were reconstructed.
2674 //=======================================================================
2675
2676 void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& Modif)
2677 {
2678 #ifdef DEb
2679   if (ChronBuild) {  
2680     cout << " RECONSTRUCTION OF FACES:" << endl;
2681     Clock.Reset();
2682     Clock.Start();
2683   }
2684 #endif
2685   TopTools_ListIteratorOfListOfShape itr;
2686   const TopTools_ListOfShape& Roots = myInitOffsetFace.Roots();
2687   TopTools_ListOfShape        LOF;
2688   //----------------------------------
2689   // Loop on all faces //.
2690   //----------------------------------
2691   for (itr.Initialize(Roots); itr.More(); itr.Next()) {
2692     TopoDS_Face F = TopoDS::Face(myInitOffsetFace.Image(itr.Value()).First());
2693     LOF.Append(F);
2694   }
2695   myMakeLoops.BuildFaces(LOF,myAsDes,myImageOffset);
2696   
2697 #ifdef DEB
2698   if ( ChronBuild) Clock.Show();
2699 #endif
2700 }
2701
2702 //=======================================================================
2703 //function : UpdateInitOffset
2704 //purpose  : Update and cleaning of myInitOffset 
2705 //=======================================================================
2706
2707 static void UpdateInitOffset (BRepAlgo_Image&         myInitOffset,
2708                               BRepAlgo_Image&         myImageOffset,
2709                               const TopoDS_Shape&     myOffsetShape,
2710                               const TopAbs_ShapeEnum &theShapeType) // skv
2711 {
2712   BRepAlgo_Image NIOF;
2713   const TopTools_ListOfShape& Roots = myInitOffset.Roots();
2714   TopTools_ListIteratorOfListOfShape it(Roots);
2715   for (; it.More(); it.Next()) {
2716     NIOF.SetRoot (it.Value());    
2717   }
2718   for (it.Initialize(Roots); it.More(); it.Next()) {
2719     const TopoDS_Shape& SI = it.Value();
2720     TopTools_ListOfShape LI;
2721     TopTools_ListOfShape L1;
2722     myInitOffset.LastImage(SI,L1);
2723     TopTools_ListIteratorOfListOfShape itL1(L1);
2724     for (; itL1.More(); itL1.Next()) {
2725       const TopoDS_Shape& O1 = itL1.Value();
2726       TopTools_ListOfShape L2;
2727       myImageOffset.LastImage(O1,L2);
2728       LI.Append(L2);
2729     }
2730     NIOF.Bind(SI,LI);
2731   }
2732 //  Modified by skv - Mon Apr  4 18:17:27 2005 Begin
2733 //  Supporting history.
2734 //   NIOF.Filter(myOffsetShape,TopAbs_FACE);
2735   NIOF.Filter(myOffsetShape, theShapeType);
2736 //  Modified by skv - Mon Apr  4 18:17:27 2005 End
2737   myInitOffset = NIOF;
2738 }
2739
2740 //=======================================================================
2741 //function : MakeMissingWalls
2742 //purpose  : 
2743 //=======================================================================
2744
2745 void BRepOffset_MakeOffset::MakeMissingWalls ()
2746 {
2747   TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary)
2748   TopTools_DataMapOfShapeShape MapEF; //Edges of contours: edge + face
2749   Standard_Real OffsetVal = Abs(myOffset);
2750
2751   FillContours(myShape, myAnalyse, Contours, MapEF);
2752
2753   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter(Contours);
2754   for (; iter.More(); iter.Next())
2755     {
2756       TopoDS_Vertex StartVertex = TopoDS::Vertex(iter.Key());
2757       TopoDS_Edge StartEdge;
2758       const TopTools_ListOfShape& aContour = iter.Value();
2759       TopTools_ListIteratorOfListOfShape itl(aContour);
2760       Standard_Boolean FirstStep = Standard_True;
2761       TopoDS_Edge PrevEdge;
2762       TopoDS_Vertex PrevVertex = StartVertex;
2763       for (; itl.More(); itl.Next())
2764         {
2765           TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
2766           if (!myInitOffsetEdge.HasImage(anEdge))
2767             continue;
2768           //if (BRep_Tool::Degenerated(anEdge))
2769             //continue;
2770           TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge));
2771           //TopoDS_Edge OE = TopoDS::Edge(myInitOffsetEdge.Image(anEdge).First());
2772           TopTools_ListOfShape LOE, LOE2;
2773           myInitOffsetEdge.LastImage( anEdge, LOE );
2774           myImageOffset.LastImage( LOE.Last(), LOE2 );
2775           TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() );
2776           ////////////////////////////////////////////////////////////////////////
2777           TopoDS_Vertex V1, V2, V3, V4;
2778           TopExp::Vertices(anEdge, V1, V2/*, Standard_True*/);
2779           TopExp::Vertices(OE,     V4, V3/*, Standard_True*/);
2780           Standard_Boolean ToReverse = Standard_False;
2781           if (!V1.IsSame(PrevVertex))
2782             {
2783               TopoDS_Vertex aVtx = V1; V1 = V2; V2 = aVtx;
2784               aVtx = V3; V3 = V4; V4 = aVtx;
2785               ToReverse = Standard_True;
2786             }
2787           //Temporary
2788           //anEdge.Reverse();
2789           OE.Orientation(TopAbs::Reverse(anEdge.Orientation()));
2790           TopoDS_Edge E3, E4;
2791           if (FirstStep)
2792             {
2793               E4 = BRepLib_MakeEdge( V1, V4 );
2794               StartEdge = E4;
2795             }
2796           else
2797             E4 = PrevEdge;
2798           Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2)));
2799           if (V2.IsSame(StartVertex) && !ArcOnV2)
2800             E3 = StartEdge;
2801           else
2802             E3 = BRepLib_MakeEdge( V2, V3 );
2803           E4.Reverse();
2804           TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD);
2805           const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge);
2806           Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD);
2807           Standard_Real ParV2 = BRep_Tool::Parameter(V2, anEdgeFWD);
2808           BRep_Builder BB;
2809           TopoDS_Wire theWire;
2810           BB.MakeWire(theWire);
2811           if (ToReverse)
2812             {
2813               BB.Add(theWire, anEdge.Reversed());
2814               BB.Add(theWire, E3.Reversed());
2815               BB.Add(theWire, OE.Reversed());
2816               BB.Add(theWire, E4.Reversed());
2817             }
2818           else
2819             {
2820               BB.Add(theWire, anEdge);
2821               BB.Add(theWire, E3);
2822               BB.Add(theWire, OE);
2823               BB.Add(theWire, E4);
2824             }
2825           BRepLib::BuildCurves3d( theWire, myTol );
2826           theWire.Closed(Standard_True);
2827           TopoDS_Face NewFace;
2828           Handle(Geom_Surface) theSurf;
2829           BRepAdaptor_Curve BAcurve(anEdge);
2830           BRepAdaptor_Curve BAcurveOE(OE);
2831           Standard_Real fpar = BAcurve.FirstParameter();
2832           Standard_Real lpar = BAcurve.LastParameter();
2833           gp_Pnt PonE  = BAcurve.Value(fpar);
2834           gp_Pnt PonOE = BAcurveOE.Value(fpar);
2835           gp_Dir OffsetDir = gce_MakeDir( PonE, PonOE );
2836           Handle(Geom2d_Line) EdgeLine2d, OELine2d, aLine2d, aLine2d2;
2837           Standard_Boolean IsPlanar = Standard_False;
2838           if (BAcurve.GetType() == GeomAbs_Circle &&
2839               BAcurveOE.GetType() == GeomAbs_Circle)
2840           {
2841             gp_Circ aCirc = BAcurve.Circle();
2842             gp_Circ aCircOE = BAcurveOE.Circle();
2843             gp_Lin anAxisLine(aCirc.Axis());
2844             gp_Dir CircAxisDir = aCirc.Axis().Direction();
2845             if (aCirc.Axis().IsParallel(aCircOE.Axis(), Precision::Confusion()) &&
2846                 anAxisLine.Contains(aCircOE.Location(), Precision::Confusion()))
2847             { //cylinder or cone
2848               if (Abs(aCirc.Radius() - aCircOE.Radius()) <= Precision::Confusion()) //case of cylinder
2849                 theSurf = GC_MakeCylindricalSurface(aCirc).Value();
2850               else //case of cone
2851               {
2852                 gp_Cone theCone = gce_MakeCone(aCirc.Location(), aCircOE.Location(),
2853                                                aCirc.Radius(), aCircOE.Radius());
2854                 gp_Ax3 theAx3(aCirc.Position());
2855                 if (CircAxisDir * theCone.Axis().Direction() < 0.)
2856                 {
2857                   theAx3.ZReverse();
2858                   CircAxisDir.Reverse();
2859                 }
2860                 theCone.SetPosition(theAx3);
2861                 theSurf = new Geom_ConicalSurface(theCone);
2862               }
2863               TopLoc_Location Loc;
2864               EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., 0.), gp_Dir2d(1., 0.));
2865               BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
2866               Standard_Real Coeff = (OffsetDir * CircAxisDir > 0.)? 1. : -1.;
2867               OELine2d = new Geom2d_Line(gp_Pnt2d(0., OffsetVal*Coeff), gp_Dir2d(1., 0.));
2868               BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
2869               aLine2d  = new Geom2d_Line(gp_Pnt2d(ParV2, 0.), gp_Dir2d(0., Coeff));
2870               aLine2d2 = new Geom2d_Line(gp_Pnt2d(ParV1, 0.), gp_Dir2d(0., Coeff));
2871               if (E3.IsSame(E4))
2872               {
2873                 if (Coeff > 0.)
2874                   BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
2875                 else
2876                 {
2877                   BB.UpdateEdge(E3, aLine2d2, aLine2d, theSurf, Loc, Precision::Confusion());
2878                   theWire.Nullify();
2879                   BB.MakeWire(theWire);
2880                   BB.Add(theWire, anEdge.Oriented(TopAbs_REVERSED));
2881                   BB.Add(theWire, E4);
2882                   BB.Add(theWire, OE.Oriented(TopAbs_FORWARD));
2883                   BB.Add(theWire, E3);
2884                   theWire.Closed(Standard_True);
2885                 }
2886               }
2887               else
2888               {
2889                 BB.SameParameter(E3, Standard_False);
2890                 BB.SameRange(E3, Standard_False);
2891                 BB.SameParameter(E4, Standard_False);
2892                 BB.SameRange(E4, Standard_False);
2893                 BB.UpdateEdge(E3, aLine2d,  theSurf, Loc, Precision::Confusion());
2894                 BB.Range(E3, theSurf, Loc, 0., OffsetVal);
2895                 BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
2896                 BB.Range(E4, theSurf, Loc, 0., OffsetVal);
2897               }
2898               NewFace = BRepLib_MakeFace(theSurf, theWire);
2899             } //cylinder or cone
2900           } //if both edges are arcs of circles
2901           if (NewFace.IsNull())
2902             {
2903               BRepLib_MakeFace MF(theWire, Standard_True); //Only plane
2904               if (MF.Error() == BRepLib_FaceDone)
2905                 {
2906                   NewFace = MF.Face();
2907                   IsPlanar = Standard_True;
2908                 }
2909               else //Extrusion (by thrusections)
2910                 {
2911                   Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
2912                   Handle(Geom_TrimmedCurve) TrEdgeCurve =
2913                     new Geom_TrimmedCurve( EdgeCurve, fpar, lpar );
2914                   Standard_Real fparOE, lparOE;
2915                   Handle(Geom_Curve) OffsetCurve = BRep_Tool::Curve(OE, fparOE, lparOE);
2916                   Handle(Geom_TrimmedCurve) TrOffsetCurve =
2917                     new Geom_TrimmedCurve( OffsetCurve, fparOE, lparOE );
2918                   GeomFill_Generator ThrusecGenerator;
2919                   ThrusecGenerator.AddCurve( TrEdgeCurve );
2920                   ThrusecGenerator.AddCurve( TrOffsetCurve );
2921                   ThrusecGenerator.Perform( Precision::PConfusion() );
2922                   theSurf = ThrusecGenerator.Surface();
2923                   //theSurf = new Geom_SurfaceOfLinearExtrusion( TrOffsetCurve, OffsetDir );
2924                   Standard_Real Uf, Ul, Vf, Vl;
2925                   theSurf->Bounds(Uf, Ul, Vf, Vl);
2926                   TopLoc_Location Loc;
2927                   EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., Vf), gp_Dir2d(1., 0.));
2928                   BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion());
2929                   OELine2d = new Geom2d_Line(gp_Pnt2d(0., Vl), gp_Dir2d(1., 0.));
2930                   BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion());
2931                   Standard_Real UonV1 = (ToReverse)? Ul : Uf;
2932                   Standard_Real UonV2 = (ToReverse)? Uf : Ul;
2933                   aLine2d  = new Geom2d_Line(gp_Pnt2d(UonV2, 0.), gp_Dir2d(0., 1.));
2934                   aLine2d2 = new Geom2d_Line(gp_Pnt2d(UonV1, 0.), gp_Dir2d(0., 1.));
2935                   if (E3.IsSame(E4))
2936                     {
2937                       BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion());
2938                       Handle(Geom_Curve) BSplC34 = theSurf->UIso( Uf );
2939                       BB.UpdateEdge(E3, BSplC34, Precision::Confusion());
2940                       BB.Range(E3, Vf, Vl);
2941                     }
2942                   else
2943                     {
2944                       BB.SameParameter(E3, Standard_False);
2945                       BB.SameRange(E3, Standard_False);
2946                       BB.SameParameter(E4, Standard_False);
2947                       BB.SameRange(E4, Standard_False);
2948                       BB.UpdateEdge(E3, aLine2d,  theSurf, Loc, Precision::Confusion());
2949                       BB.Range(E3, theSurf, Loc, Vf, Vl);
2950                       BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion());
2951                       BB.Range(E4, theSurf, Loc, Vf, Vl);
2952                       Handle(Geom_Curve) BSplC3 = theSurf->UIso( UonV2 );
2953                       BB.UpdateEdge(E3, BSplC3, Precision::Confusion());
2954                       BB.Range(E3, Vf, Vl, Standard_True); //only for 3d curve
2955                       Handle(Geom_Curve) BSplC4 = theSurf->UIso( UonV1 );
2956                       BB.UpdateEdge(E4, BSplC4, Precision::Confusion());
2957                       BB.Range(E4, Vf, Vl, Standard_True); //only for 3d curve
2958                     }
2959                   NewFace = BRepLib_MakeFace(theSurf, theWire);
2960                 }
2961             }
2962           if (!IsPlanar)
2963             {
2964               Standard_Real fparOE = BAcurveOE.FirstParameter();
2965               Standard_Real lparOE = BAcurveOE.LastParameter();
2966               TopLoc_Location Loc;
2967               if (Abs(fpar - fparOE) > Precision::Confusion())
2968                 {
2969                   const TopoDS_Edge& anE4 = (ToReverse)? E3 : E4;
2970                   gp_Pnt2d fp2d   = EdgeLine2d->Value(fpar);
2971                   gp_Pnt2d fp2dOE = OELine2d->Value(fparOE);
2972                   aLine2d2 = GCE2d_MakeLine( fp2d, fp2dOE ).Value();
2973                   Handle(Geom_Curve) aCurve;
2974                   Standard_Real FirstPar = 0., LastPar = fp2d.Distance(fp2dOE);
2975                   Geom2dAdaptor_Curve AC2d( aLine2d2, FirstPar, LastPar );
2976                   GeomAdaptor_Surface GAsurf( theSurf );
2977                   Handle(Geom2dAdaptor_HCurve) HC2d  = new Geom2dAdaptor_HCurve( AC2d );
2978                   Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
2979                   Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
2980                   Standard_Real max_deviation = 0., average_deviation;
2981                   GeomLib::BuildCurve3d(Precision::Confusion(),
2982                                         ConS, FirstPar, LastPar,
2983                                         aCurve, max_deviation, average_deviation);
2984                   BB.UpdateEdge( anE4, aCurve, max_deviation );
2985                   BB.UpdateEdge( anE4, aLine2d2, theSurf, Loc, max_deviation );
2986                   BB.Range( anE4, FirstPar, LastPar );
2987                 }
2988               if (Abs(lpar - lparOE) > Precision::Confusion())
2989                 {
2990                   const TopoDS_Edge& anE3 = (ToReverse)? E4 : E3;
2991                   gp_Pnt2d lp2d   = EdgeLine2d->Value(lpar);
2992                   gp_Pnt2d lp2dOE = OELine2d->Value(lparOE);
2993                   aLine2d = GCE2d_MakeLine( lp2d, lp2dOE ).Value();
2994                   Handle(Geom_Curve) aCurve;
2995                   Standard_Real FirstPar = 0., LastPar = lp2d.Distance(lp2dOE);
2996                   Geom2dAdaptor_Curve AC2d( aLine2d, FirstPar, LastPar );
2997                   GeomAdaptor_Surface GAsurf( theSurf );
2998                   Handle(Geom2dAdaptor_HCurve) HC2d  = new Geom2dAdaptor_HCurve( AC2d );
2999                   Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf );
3000                   Adaptor3d_CurveOnSurface ConS( HC2d, HSurf );
3001                   Standard_Real max_deviation = 0., average_deviation;
3002                   GeomLib::BuildCurve3d(Precision::Confusion(),
3003                                         ConS, FirstPar, LastPar,
3004                                         aCurve, max_deviation, average_deviation);
3005                   BB.UpdateEdge( anE3, aCurve, max_deviation );
3006                   BB.UpdateEdge( anE3, aLine2d, theSurf, Loc, max_deviation );
3007                   BB.Range( anE3, FirstPar, LastPar );
3008                 }
3009             }
3010           BRepLib::SameParameter(NewFace);
3011           BRepTools::Update(NewFace);
3012           myWalls.Append(NewFace);
3013           if (ArcOnV2)
3014             {
3015               TopoDS_Edge anArc = TopoDS::Edge(myInitOffsetEdge.Image(V2).First());
3016               TopoDS_Vertex arcV1, arcV2;
3017               TopExp::Vertices(anArc, arcV1, arcV2);
3018               Standard_Boolean ArcReverse = Standard_False;
3019               if (!arcV1.IsSame(V3))
3020                 {
3021                   TopoDS_Vertex aVtx = arcV1; arcV1 = arcV2; arcV2 = aVtx;
3022                   ArcReverse = Standard_True;
3023                 }
3024               TopoDS_Edge EA1, EA2;
3025               //EA1 = (ToReverse)? E3 : TopoDS::Edge(E3.Reversed());
3026               EA1 = E3;
3027               EA1.Reverse();
3028               if (ToReverse)
3029                 EA1.Reverse();
3030               //////////////////////////////////////////////////////
3031               if (V2.IsSame(StartVertex))
3032                 EA2 = StartEdge;
3033               else
3034                 EA2 = BRepLib_MakeEdge( V2, arcV2 );
3035               anArc.Orientation( ((ArcReverse)? TopAbs_REVERSED : TopAbs_FORWARD) );
3036               if (EA1.Orientation() == TopAbs_REVERSED)
3037                 anArc.Reverse();
3038               EA2.Orientation(TopAbs::Reverse(EA1.Orientation()));
3039               TopoDS_Wire arcWire;
3040               BB.MakeWire(arcWire);
3041               BB.Add(arcWire, EA1);
3042               BB.Add(arcWire, anArc);
3043               BB.Add(arcWire, EA2);
3044               BRepLib::BuildCurves3d( arcWire, myTol );
3045               arcWire.Closed(Standard_True);
3046               TopoDS_Face arcFace = BRepLib_MakeFace(arcWire, Standard_True);
3047               BRepTools::Update(arcFace);
3048               myWalls.Append(arcFace);
3049               TopoDS_Shape localEA2 = EA2.Oriented(TopAbs_FORWARD);
3050               const TopoDS_Edge& CEA2 = TopoDS::Edge(localEA2);
3051               PrevEdge = CEA2;
3052               PrevVertex = V2;
3053             }
3054           else
3055             {
3056               PrevEdge = E3;
3057               PrevVertex = V2;
3058             }
3059           FirstStep = Standard_False;
3060         }
3061     }
3062 }
3063
3064 //=======================================================================
3065 //function : MakeShells
3066 //purpose  : 
3067 //=======================================================================
3068
3069 void BRepOffset_MakeOffset::MakeShells ()
3070 {
3071 #ifdef DEB
3072   if (ChronBuild) {  
3073     cout << " RECONSTRUCTION OF SHELLS:" << endl;
3074     Clock.Reset();
3075     Clock.Start();
3076   }
3077 #endif
3078   BRepTools_Quilt Glue;
3079   const TopTools_ListOfShape& R = myImageOffset.Roots();
3080   TopTools_ListIteratorOfListOfShape it(R);
3081
3082   for ( ; it.More(); it.Next()) {
3083     TopTools_ListOfShape Image;
3084     myImageOffset.LastImage(it.Value(),Image);
3085     TopTools_ListIteratorOfListOfShape it2(Image);
3086     for ( ; it2.More(); it2.Next()) {
3087       Glue.Add(it2.Value());
3088     }
3089   }
3090
3091   if (myThickening)
3092     {
3093       TopExp_Explorer Explo(myShape, TopAbs_FACE);
3094       for (; Explo.More(); Explo.Next())
3095         Glue.Add(Explo.Current());
3096       
3097       for (it.Initialize(myWalls); it.More(); it.Next())
3098         Glue.Add(it.Value());
3099     }
3100
3101   myOffsetShape = Glue.Shells();
3102 }
3103
3104 //=======================================================================
3105 //function : MakeSolid
3106 //purpose  : 
3107 //=======================================================================
3108
3109 void BRepOffset_MakeOffset::MakeSolid ()
3110 {
3111  if (myOffsetShape.IsNull()) return;
3112
3113 //  Modified by skv - Mon Apr  4 18:17:27 2005 Begin
3114 //  Supporting history.
3115   UpdateInitOffset (myInitOffsetFace,myImageOffset,myOffsetShape, TopAbs_FACE);
3116   UpdateInitOffset (myInitOffsetEdge,myImageOffset,myOffsetShape, TopAbs_EDGE);
3117 //  Modified by skv - Mon Apr  4 18:17:27 2005 End
3118   TopExp_Explorer             exp;
3119   BRep_Builder                B;
3120   Standard_Integer            NbShell = 0;
3121   TopoDS_Compound             NC;
3122   TopoDS_Shape                S1;
3123   B.MakeCompound (NC);
3124
3125   for (exp.Init(myOffsetShape,TopAbs_SHELL); exp.More(); exp.Next()) {
3126     TopoDS_Shell Sh = TopoDS::Shell(exp.Current());
3127     if (myThickening && myOffset > 0.)
3128       Sh.Reverse();
3129     NbShell++;
3130     if (Sh.Closed()) {
3131       TopoDS_Solid  Sol;
3132       B.MakeSolid  (Sol);
3133       B.Add        (Sol,Sh);
3134       Sol.Closed(Standard_True);
3135       B.Add (NC,Sol);
3136       if (NbShell == 1) S1 = Sol;
3137     }
3138     else {
3139       B.Add (NC,Sh);
3140       if (NbShell == 1) S1 = Sh;
3141     }
3142   }
3143   if (NbShell == 1) myOffsetShape = S1;
3144   else              myOffsetShape = NC;
3145 }
3146
3147 //=======================================================================
3148 //function : SelectShells
3149 //purpose  : 
3150 //=======================================================================
3151
3152 void BRepOffset_MakeOffset::SelectShells ()
3153 {  
3154   TopTools_MapOfShape FreeEdges;
3155   TopExp_Explorer exp(myShape,TopAbs_EDGE);
3156   //-------------------------------------------------------------
3157   // FreeEdges all edges that can have free border in the  
3158   // parallel shell
3159   // 1 - free borders of myShape .
3160   //-------------------------------------------------------------
3161   for ( ; exp.More(); exp.Next()) {
3162     const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3163     const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E);
3164     if (LA.Extent() < 2) {
3165       if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) {
3166         FreeEdges.Add(E);                       
3167       }
3168     }  
3169   }
3170   // myShape has free borders and there are no caps
3171   // no unwinding 3d.
3172   if (!FreeEdges.IsEmpty() && myFaces.IsEmpty()) return;
3173
3174   myOffsetShape = BRepOffset_Tool::Deboucle3D(myOffsetShape,FreeEdges);
3175 }
3176
3177 //=======================================================================
3178 //function : OffsetFacesFromShapes
3179 //purpose  : 
3180 //=======================================================================
3181
3182 const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const
3183 {
3184   return myInitOffsetFace;
3185 }
3186
3187 //  Modified by skv - Tue Mar 15 16:20:43 2005 Begin
3188
3189 //=======================================================================
3190 //function : GetJoinType
3191 //purpose  : Query offset join type.
3192 //=======================================================================
3193
3194 GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const
3195 {
3196   return myJoin;
3197 }
3198
3199 //=======================================================================
3200 //function : OffsetEdgesFromShapes
3201 //purpose  : 
3202 //=======================================================================
3203
3204 const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const
3205 {
3206   return myInitOffsetEdge;
3207 }
3208
3209 //  Modified by skv - Tue Mar 15 16:20:43 2005 End
3210
3211 //=======================================================================
3212 //function : ClosingFaces
3213 //purpose  : 
3214 //=======================================================================
3215
3216 const TopTools_IndexedMapOfShape& BRepOffset_MakeOffset::ClosingFaces () const
3217 {
3218   return myFaces;
3219 }
3220
3221
3222
3223 //=======================================================================
3224 //function : EncodeRegularity
3225 //purpose  : 
3226 //=======================================================================
3227
3228 void BRepOffset_MakeOffset::EncodeRegularity ()
3229 {
3230 #ifdef DEB
3231   if (ChronBuild) {  
3232     cout << " CODING OF REGULARITIES:" << endl;
3233     Clock.Reset();
3234     Clock.Start();
3235   }
3236 #endif
3237
3238   if (myOffsetShape.IsNull()) return;
3239   // find edges G1 in the result
3240   TopExp_Explorer exp(myOffsetShape,TopAbs_EDGE);
3241
3242   BRep_Builder B;
3243   TopTools_MapOfShape MS;
3244
3245   for ( ; exp.More(); exp.Next()) {
3246     TopoDS_Edge OE  = TopoDS::Edge(exp.Current());
3247     BRepLib::BuildCurve3d(OE,myTol);
3248     TopoDS_Edge ROE = OE;
3249     
3250     if ( !MS.Add(OE)) continue;
3251       
3252     if ( myImageOffset.IsImage(OE)) 
3253       ROE = TopoDS::Edge(myImageOffset.Root(OE));
3254
3255     const TopTools_ListOfShape& LofOF    = myAsDes->Ascendant(ROE);
3256     
3257     if (LofOF.Extent() != 2) {
3258 #ifdef DEB
3259       if ( Standard_False)
3260         cout << " Edge shared by " << LofOF.Extent() << " Faces" << endl;
3261 #endif
3262       continue;
3263     }
3264
3265     const TopoDS_Face& F1 = TopoDS::Face(LofOF.First());
3266     const TopoDS_Face& F2 = TopoDS::Face(LofOF.Last() );
3267     
3268     if ( F1.IsNull() || F2.IsNull()) 
3269       continue;
3270    
3271     const TopoDS_Shape& Root1 = myInitOffsetFace.Root(F1);
3272     const TopoDS_Shape& Root2 = myInitOffsetFace.Root(F2);
3273
3274     TopAbs_ShapeEnum Type1 = Root1.ShapeType();
3275     TopAbs_ShapeEnum Type2 = Root2.ShapeType();
3276  
3277     if (F1.IsSame(F2)) {      
3278       if (BRep_Tool::IsClosed(OE,F1)) {
3279         // Temporary Debug for the Bench.
3280         // Check with YFR.
3281         // In mode intersection, the edges are not coded in myInitOffsetEdge
3282         // so, manage case by case
3283         // Note DUB; for Hidden parts, it is NECESSARY to code CN 
3284         // Analytic Surfaces.
3285         if (myJoin == GeomAbs_Intersection) {
3286           BRepAdaptor_Surface BS(F1,Standard_False);
3287           GeomAbs_SurfaceType SType = BS.GetType();
3288           if (SType == GeomAbs_Cylinder ||
3289               SType == GeomAbs_Cone     ||
3290               SType == GeomAbs_Sphere   ||
3291               SType == GeomAbs_Torus      ) {
3292             B.Continuity(OE,F1,F1,GeomAbs_CN);
3293           }
3294           else {
3295             // See YFR : MaJ of myInitOffsetFace
3296           }
3297         }
3298         else if (myInitOffsetEdge.IsImage(ROE)) {
3299           if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) {
3300             const TopoDS_Face& FRoot = TopoDS::Face(Root1);
3301             const TopoDS_Edge& EI = TopoDS::Edge(myInitOffsetEdge.ImageFrom(ROE));