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