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