0026555: Modeling Algorithms - Exception-safe status reporting in BRepOffset_MakeOffset
[occt.git] / src / BRepOffset / BRepOffset_MakeOffset.cxx
index 834ab96..2c3077f 100644 (file)
 #include <BRepBuilderAPI_Sewing.hxx>
 #include <Geom_Line.hxx>
 #include <NCollection_Vector.hxx>
+#include <NCollection_IncAllocator.hxx>
 //
 #include <BOPAlgo_MakerVolume.hxx>
 #include <BOPTools_AlgoTools.hxx>
-#include <BOPCol_ListOfShape.hxx>
 
 #include <stdio.h>
 // POP for NT
@@ -159,7 +159,7 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
       for (it1LE.Initialize(AsDes->Descendant(NE)); it1LE.More(); it1LE.Next()) {
         if (AsDes->Ascendant(it1LE.Value()).Extent() < 3) {
           LVP.Append(it1LE.Value());
-          cout <<"Vertex on at least 3 edges."<<endl;
+          std::cout <<"Vertex on at least 3 edges."<<std::endl;
 #ifdef DRAW
           if (AffichInt2d) {
             sprintf (name,"VP_%d",NVP++);
@@ -168,7 +168,7 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
 #endif
         }
         else if (AsDes->Ascendant(it1LE.Value()).Extent() > 3) {
-          cout <<"Vertex on more than 3 edges."<<endl;
+          std::cout <<"Vertex on more than 3 edges."<<std::endl;
 #ifdef DRAW
           if (AffichInt2d) {
             sprintf (name,"VM_%d",NVM++);
@@ -235,7 +235,7 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
       j++;
     }
     i++;
-    cout <<" distmin between VP : "<<distmin<<endl;
+    std::cout <<" distmin between VP : "<<distmin<<std::endl;
   }
 }  
 #endif
@@ -245,7 +245,7 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges,
 // static methods
 //=======================================================================
 static
-  void GetEnlargedFaces(const TopoDS_Shape& theShape,
+  void GetEnlargedFaces(const TopTools_ListOfShape& theFaces,
                         const BRepOffset_DataMapOfShapeOffset& theMapSF,
                         const TopTools_DataMapOfShapeShape& theMES,
                         TopTools_DataMapOfShapeShape& theFacesOrigins,
@@ -253,8 +253,7 @@ static
                         TopTools_ListOfShape& theLSF);
 
 static
-  Standard_Boolean BuildShellsCompleteInter(const BOPCol_ListOfShape& theLF,
-                                            const BOPCol_IndexedDataMapOfShapeListOfShape& theOrigins,
+  Standard_Boolean BuildShellsCompleteInter(const TopTools_ListOfShape& theLF,
                                             BRepAlgo_Image& theImage,
                                             TopoDS_Shape& theShells);
 
@@ -285,22 +284,23 @@ static
   Standard_Boolean IsPlanar(const TopoDS_Shape& theS);
 
 static
-  void TrimEdge(TopoDS_Edge&                  NE,
-                const Handle(BRepAlgo_AsDes)& AsDes2d,
-                Handle(BRepAlgo_AsDes)& AsDes,
-                TopTools_DataMapOfShapeShape& theETrimEInf);
+  Standard_Boolean TrimEdge(TopoDS_Edge& NE,
+                            const Handle(BRepAlgo_AsDes)& AsDes2d,
+                            Handle(BRepAlgo_AsDes)& AsDes,
+                            TopTools_DataMapOfShapeShape& theETrimEInf);
 
 static 
-  void TrimEdges(const TopoDS_Shape& theShape,
-                 const Standard_Real theOffset,
-                 BRepOffset_DataMapOfShapeOffset& theMapSF,
-                 TopTools_DataMapOfShapeShape& theMES,
-                 TopTools_DataMapOfShapeShape& theBuild,
-                 Handle(BRepAlgo_AsDes)& theAsDes,
-                 Handle(BRepAlgo_AsDes)& theAsDes2d,
-                 TopTools_IndexedMapOfShape& theNewEdges,
-                 TopTools_DataMapOfShapeShape& theETrimEInf,
-                 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins);
+  Standard_Boolean TrimEdges(const TopoDS_Shape& theShape,
+                             const Standard_Real theOffset,
+                             const BRepOffset_Analyse& Analyse,
+                             BRepOffset_DataMapOfShapeOffset& theMapSF,
+                             TopTools_DataMapOfShapeShape& theMES,
+                             TopTools_DataMapOfShapeShape& theBuild,
+                             Handle(BRepAlgo_AsDes)& theAsDes,
+                             Handle(BRepAlgo_AsDes)& theAsDes2d,
+                             TopTools_IndexedMapOfShape& theNewEdges,
+                             TopTools_DataMapOfShapeShape& theETrimEInf,
+                             TopTools_DataMapOfShapeListOfShape& theEdgesOrigins);
 
 static
   void AppendToList(TopTools_ListOfShape& theL,
@@ -321,6 +321,26 @@ static Standard_Real ComputeMaxDist(const gp_Pln& thePlane,
 
 static void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList);
 //---------------------------------------------------------------------
+
+static TopAbs_Orientation OrientationOfEdgeInFace(const TopoDS_Edge& theEdge,
+                                                  const TopoDS_Face& theFace)
+{
+  TopAbs_Orientation anOr = TopAbs_EXTERNAL;
+  
+  TopExp_Explorer Explo(theFace, TopAbs_EDGE);
+  for (; Explo.More(); Explo.Next())
+  {
+    const TopoDS_Shape& anEdge = Explo.Current();
+    if (anEdge.IsSame(theEdge))
+    {
+      anOr = anEdge.Orientation();
+      break;
+    }
+  }
+
+  return anOr;
+}
+
 //
 static Standard_Boolean FindParameter(const TopoDS_Vertex& V, 
                                       const TopoDS_Edge& E,
@@ -481,7 +501,7 @@ static void GetEdgePoints(const TopoDS_Edge& anEdge,
 //=======================================================================
 static void FillContours(const TopoDS_Shape& aShape,
                          const BRepOffset_Analyse& Analyser,
-                         TopTools_DataMapOfShapeListOfShape& Contours,
+                         TopTools_IndexedDataMapOfShapeListOfShape& Contours,
                          TopTools_DataMapOfShapeShape& MapEF)
 {
   TopTools_ListOfShape Edges;
@@ -490,26 +510,26 @@ static void FillContours(const TopoDS_Shape& aShape,
   BRepTools_WireExplorer Wexp;
 
   for (; Explo.More(); Explo.Next())
+  {
+    TopoDS_Face aFace = TopoDS::Face(Explo.Current());
+    TopoDS_Iterator itf(aFace);
+    for (; itf.More(); itf.Next())
     {
-      TopoDS_Face aFace = TopoDS::Face(Explo.Current());
-      TopoDS_Iterator itf(aFace);
-      for (; itf.More(); itf.Next())
+      TopoDS_Wire aWire = TopoDS::Wire(itf.Value());
+      for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next())
+      {
+        TopoDS_Edge anEdge = Wexp.Current();
+        if (BRep_Tool::Degenerated(anEdge))
+          continue;
+        const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge);
+        if (!Lint.IsEmpty() && Lint.First().Type() == ChFiDS_FreeBound)
         {
-          TopoDS_Wire aWire = TopoDS::Wire(itf.Value());
-          for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next())
-            {
-              TopoDS_Edge anEdge = Wexp.Current();
-              if (BRep_Tool::Degenerated(anEdge))
-                continue;
-              const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge);
-              if (!Lint.IsEmpty() && Lint.First().Type() == BRepOffset_FreeBoundary)
-                {
-                  MapEF.Bind(anEdge, aFace);
-                  Edges.Append(anEdge);
-                }
-            }
+          MapEF.Bind(anEdge, aFace);
+          Edges.Append(anEdge);
         }
+      }
     }
+  }
 
   TopTools_ListIteratorOfListOfShape itl;
   while (!Edges.IsEmpty())
@@ -534,7 +554,7 @@ static void FillContours(const TopoDS_Shape& aShape,
                 break;
               }
           }
-      Contours.Bind(StartVertex, aContour);
+      Contours.Add(StartVertex, aContour);
     }
 }
 
@@ -629,6 +649,8 @@ void BRepOffset_MakeOffset::Clear()
   myFaceOffset     .Clear();
   myAsDes          ->Clear();
   myDone     = Standard_False;
+  myGenerated.Clear();
+  myResMap.Clear();
 }
 
 //=======================================================================
@@ -680,13 +702,7 @@ static void RemoveCorks (TopoDS_Shape&               S,
       B.Add(SS,Cork);
     }
     else {
-      //Faces.Remove (Cork);
-      //begin instead of Remove//
-      TopoDS_Shape LastShape = Faces(Faces.Extent());
-      Faces.RemoveLast();
-      if (Faces.FindIndex(Cork) != 0)
-        Faces.Substitute(Faces.FindIndex(Cork), LastShape);
-      //end instead of Remove  //
+      Faces.RemoveKey(Cork);
       Faces.Add(Cork); // to reset it with proper orientation.
     }
   }
@@ -731,7 +747,10 @@ static void MakeList (TopTools_ListOfShape&             OffsetFaces,
     const TopoDS_Shape& Root = itLOF.Value();
     if (!myFaces.Contains(Root)) {
       if (myInitOffsetFace.HasImage(Root)) {
-        OffsetFaces.Append(myInitOffsetFace.Image(Root).First());
+        TopTools_ListIteratorOfListOfShape aItLS(myInitOffsetFace.Image(Root));
+        for (; aItLS.More(); aItLS.Next()) {
+          OffsetFaces.Append(aItLS.Value());
+        }
       }
     }
   }
@@ -778,7 +797,7 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
     // Check Error() method.
     return;
   }
-
+  myError = BRepOffset_NoError;
   TopAbs_State       Side = TopAbs_IN;
   if (myOffset < 0.) Side = TopAbs_OUT;
 
@@ -789,6 +808,11 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
   // There are possible second variant: analytical continuation of arcsin.
   Standard_Real TolAngleCoeff = Min(myTol / (Abs(myOffset * 0.5) + Precision::Confusion()), 1.0);
   Standard_Real TolAngle = 4*ASin(TolAngleCoeff);
+  if ((myJoin == GeomAbs_Intersection) && myInter && myIsPlanar)
+  {
+    myAnalyse.SetOffsetValue (myOffset);
+    myAnalyse.SetFaceOffsetMap (myFaceOffset);
+  }
   myAnalyse.Perform(myShape,TolAngle);
   //---------------------------------------------------
   // Construction of Offset from preanalysis.
@@ -802,6 +826,10 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
     BuildOffsetByArc();
   else if (myJoin == GeomAbs_Intersection) 
     BuildOffsetByInter();
+  if (myError != BRepOffset_NoError)
+  {
+    return;
+  }
   //-----------------
   // Auto unwinding.
   //-----------------
@@ -854,6 +882,10 @@ void BRepOffset_MakeOffset::MakeOffsetShape()
   // Coding of regularities.
   //----------------------------------
   EncodeRegularity();
+  //----------------------------------
+  // Replace roots in history maps
+  //----------------------------------
+  ReplaceRoots();
   //----------------------
   // Creation of solids.
   //----------------------
@@ -937,14 +969,14 @@ void BRepOffset_MakeOffset::MakeThickSolid()
 #ifdef OCCT_DEBUG
       if(YaResult == 0)
         {
-        cout << "OffsetShape does not contain a FACES." << endl;
+        std::cout << "OffsetShape does not contain a FACES." << std::endl;
         }
 #endif
       }
 #ifdef OCCT_DEBUG
     else
       {
-      cout << "OffsetShape is null!" << endl;
+      std::cout << "OffsetShape is null!" << std::endl;
       }
 #endif
 
@@ -1034,11 +1066,11 @@ void BRepOffset_MakeOffset::MakeOffsetFaces(BRepOffset_DataMapOfShapeOffset& the
     aCurOffset = myFaceOffset.IsBound(aF) ? myFaceOffset(aF) : myOffset;
     BRepOffset_Offset OF(aF, aCurOffset, ShapeTgt, OffsetOutside, myJoin);
     TopTools_ListOfShape Let;
-    myAnalyse.Edges(aF,BRepOffset_Tangent,Let);
+    myAnalyse.Edges(aF,ChFiDS_Tangential,Let);
     TopTools_ListIteratorOfListOfShape itl(Let);    
     for (; itl.More(); itl.Next()) {
       const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value());
-      if ( !ShapeTgt.IsBound(Cur)) {
+      if ( !ShapeTgt.IsBound(Cur) && !myAnalyse.HasGenerated (Cur)) {
         TopoDS_Shape aLocalShape = OF.Generated(Cur);
         const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape);
         ShapeTgt.Bind(Cur,OF.Generated(Cur));
@@ -1047,14 +1079,14 @@ void BRepOffset_MakeOffset::MakeOffsetFaces(BRepOffset_DataMapOfShapeOffset& the
         TopExp::Vertices (OTE,OV1,OV2);      
         TopTools_ListOfShape LE;
         if (!ShapeTgt.IsBound(V1)) {
-          myAnalyse.Edges(V1,BRepOffset_Tangent,LE);
+          myAnalyse.Edges(V1,ChFiDS_Tangential,LE);
           const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1);
           if (LE.Extent() == LA.Extent())
             ShapeTgt.Bind(V1,OV1);
         }
         if (!ShapeTgt.IsBound(V2)) {
           LE.Clear();
-          myAnalyse.Edges(V2,BRepOffset_Tangent,LE);
+          myAnalyse.Edges(V2,ChFiDS_Tangential,LE);
           const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2);
           if (LE.Extent() == LA.Extent())
             ShapeTgt.Bind(V2,OV2);
@@ -1063,6 +1095,14 @@ void BRepOffset_MakeOffset::MakeOffsetFaces(BRepOffset_DataMapOfShapeOffset& the
     }
     theMapSF.Bind(aF,OF);
   }
+  //
+  const TopTools_ListOfShape& aNewFaces = myAnalyse.NewFaces();
+  for (TopTools_ListOfShape::Iterator it (aNewFaces); it.More(); it.Next())
+  {
+    const TopoDS_Face& aF = TopoDS::Face (it.Value());
+    BRepOffset_Offset OF(aF, 0.0, ShapeTgt, OffsetOutside, myJoin);
+    theMapSF.Bind (aF, OF);
+  }
 }
 
 //=======================================================================
@@ -1073,7 +1113,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
 {
 #ifdef OCCT_DEBUG
   if ( ChronBuild) {
-    cout << " CONSTRUCTION OF OFFSETS :" << endl;
+    std::cout << " CONSTRUCTION OF OFFSETS :" << std::endl;
     Clock.Reset();
     Clock.Start();
   }
@@ -1110,12 +1150,20 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   // Intersection with caps.
   Inter3.ContextIntByInt(myFaces,ExtentContext,MapSF,myAnalyse,MES,Build,Failed,myIsPlanar);
 
-
+  TopTools_ListOfShape aLFaces;
+  for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next())
+    aLFaces.Append (Exp.Current());
+  for (TopTools_ListOfShape::Iterator it (myAnalyse.NewFaces()); it.More(); it.Next())
+    aLFaces.Append (it.Value());
   //---------------------------------------------------------------------------------
   // Extension of neighbor edges of new edges and intersection between neighbors.
   //--------------------------------------------------------------------------------
   Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes();
-  IntersectEdges(myShape, MapSF, MES, Build, AsDes, AsDes2d);
+  IntersectEdges(aLFaces, MapSF, MES, Build, AsDes, AsDes2d);
+  if (myError != BRepOffset_NoError)
+  {
+    return;
+  }
   //-----------------------------------------------------------
   // Great restriction of new edges and update of AsDes.
   //------------------------------------------ ----------------
@@ -1126,7 +1174,11 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   //Map of edges obtained after FACE-FACE (offsetted) intersection.
   //Key1 is edge trimmed by intersection points with other edges;
   //Item is not-trimmed edge. 
-  TrimEdges(myShape, myOffset, MapSF, MES, Build, AsDes, AsDes2d, NewEdges, aETrimEInf, anEdgesOrigins);
+  if (!TrimEdges(myShape, myOffset, myAnalyse, MapSF, MES, Build, AsDes, AsDes2d, NewEdges, aETrimEInf, anEdgesOrigins))
+  {
+    myError = BRepOffset_CannotTrimEdges;
+    return;
+  }
   //
   //--------------------------------- 
   // Intersection 2D on //
@@ -1135,7 +1187,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   TopTools_DataMapOfShapeShape aFacesOrigins; // offset face - initial face
   TopTools_ListOfShape LFE; 
   BRepAlgo_Image     IMOE;
-  GetEnlargedFaces(myShape, MapSF, MES, aFacesOrigins, IMOE, LFE);
+  GetEnlargedFaces(aLFaces, MapSF, MES, aFacesOrigins, IMOE, LFE);
   //
   TopTools_ListIteratorOfListOfShape itLFE(LFE);
   for (; itLFE.More(); itLFE.Next())
@@ -1163,7 +1215,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   TopTools_MapOfShape aMFDone;
   //
   if ((myJoin == GeomAbs_Intersection) && myInter && myIsPlanar) {
-    BuildSplitsOfExtendedFaces(LFE, AsDes, anEdgesOrigins, aFacesOrigins, aETrimEInf, IMOE);
+    BuildSplitsOfExtendedFaces(LFE, myAnalyse, AsDes, anEdgesOrigins, aFacesOrigins, aETrimEInf, IMOE);
     //
     TopTools_ListIteratorOfListOfShape aItLF(LFE);
     for (; aItLF.More(); aItLF.Next()) {
@@ -1181,8 +1233,9 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   //---------------------------
   // MAJ SD. for faces //
   //---------------------------
-  for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
-    const TopoDS_Shape& FI   = Exp.Current();
+  for (TopTools_ListOfShape::Iterator it (aLFaces); it.More(); it.Next())
+  {
+    const TopoDS_Shape& FI   = it.Value();
     myInitOffsetFace.SetRoot(FI);
     TopoDS_Face  OF  = MapSF(FI).Face();
     if (MES.IsBound(OF)) {
@@ -1311,9 +1364,9 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   // Add methods for supporting history.
   TopTools_MapOfShape aMapEdges;
 
-  for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
-    const TopoDS_Shape& aFaceRef = Exp.Current();
-
+  for (TopTools_ListOfShape::Iterator it (aLFaces); it.More(); it.Next())
+  {
+    const TopoDS_Shape& aFaceRef = it.Value();
     Exp2.Init(aFaceRef.Oriented(TopAbs_FORWARD), TopAbs_EDGE);
 
     for (; Exp2.More(); Exp2.Next()) {
@@ -1419,6 +1472,46 @@ void BRepOffset_MakeOffset::BuildOffsetByInter()
   DEBVerticesControl (COES,myAsDes);
   if ( ChronBuild) Clock.Show();
 #endif
+
+}
+
+//=======================================================================
+//function : ReplaceRoots
+//purpose  : 
+//=======================================================================
+void BRepOffset_MakeOffset::ReplaceRoots()
+{
+  // Replace the artificial faces and edges in InitOffset maps with the original ones.
+  TopTools_MapOfShape View;
+  for (TopExp_Explorer anExpF (myShape, TopAbs_EDGE); anExpF.More(); anExpF.Next())
+  {
+    const TopoDS_Shape& aF = anExpF.Current();
+    for (TopExp_Explorer anExpE (aF, TopAbs_EDGE); anExpE.More(); anExpE.Next())
+    {
+      const TopoDS_Shape& aE = anExpE.Current();
+      if (!View.Add (aE))
+        continue;
+
+      TopoDS_Shape aFGen = myAnalyse.Generated (aE);
+      if (aFGen.IsNull())
+        continue;
+
+      myInitOffsetFace.ReplaceRoot (aFGen, aE);
+
+      for (TopoDS_Iterator itV (aE); itV.More(); itV.Next())
+      {
+        const TopoDS_Shape& aV = itV.Value();
+        if (!View.Add (aV))
+          continue;
+
+        TopoDS_Shape aEGen = myAnalyse.Generated (aV);
+        if (aEGen.IsNull())
+          continue;
+
+        myInitOffsetEdge.ReplaceRoot (aEGen, aV);
+      }
+    }
+  }
 }
 
 //=======================================================================
@@ -1429,7 +1522,7 @@ void BRepOffset_MakeOffset::BuildOffsetByArc()
 {
 #ifdef OCCT_DEBUG
   if ( ChronBuild) {
-    cout << " CONSTRUCTION OF OFFSETS :" << endl;
+    std::cout << " CONSTRUCTION OF OFFSETS :" << std::endl;
     Clock.Reset();
     Clock.Start();
   }
@@ -1447,8 +1540,8 @@ void BRepOffset_MakeOffset::BuildOffsetByArc()
   //--------------------------------------------------------
   // Construction of tubes on edge.
   //--------------------------------------------------------
-  BRepOffset_Type    OT = BRepOffset_Convex;
-  if (myOffset < 0.) OT = BRepOffset_Concave; 
+  ChFiDS_TypeOfConcavity OT = ChFiDS_Convex;
+  if (myOffset < 0.) OT = ChFiDS_Concave; 
    
   for (Exp.Init(myShape,TopAbs_EDGE); Exp.More(); Exp.Next()) {
     const TopoDS_Edge& E = TopoDS::Edge(Exp.Current());
@@ -1550,7 +1643,7 @@ void BRepOffset_MakeOffset::BuildOffsetByArc()
       // Particular processing if V is at least a free border.
       //-------------------------------------------------------------
       TopTools_ListOfShape LBF;
-      myAnalyse.Edges(V,BRepOffset_FreeBoundary,LBF);
+      myAnalyse.Edges(V,ChFiDS_FreeBound,LBF);
       if (!LBF.IsEmpty()) {        
         Standard_Boolean First = Standard_True;
         for (it.Initialize(LE) ; it.More(); it.Next()) {
@@ -1576,8 +1669,8 @@ void BRepOffset_MakeOffset::BuildOffsetByArc()
   //------------------------------------------------------
   // MAJ SD.
   //------------------------------------------------------
-  BRepOffset_Type    RT = BRepOffset_Concave;
-  if (myOffset < 0.) RT = BRepOffset_Convex;
+  ChFiDS_TypeOfConcavity RT = ChFiDS_Concave;
+  if (myOffset < 0.) RT = ChFiDS_Convex;
   BRepOffset_DataMapIteratorOfDataMapOfShapeOffset It(MapSF);
   for ( ; It.More(); It.Next()) {
     const TopoDS_Shape& SI = It.Key(); 
@@ -1638,7 +1731,7 @@ void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& /*Modif*/)
 {
 #ifdef OCCT_DEBUG
   if ( ChronBuild) {
-    cout << " AUTODEBOUCLAGE:" << endl;
+    std::cout << " AUTODEBOUCLAGE:" << std::endl;
     Clock.Reset();
     Clock.Start();
   }    
@@ -1721,8 +1814,8 @@ void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF)
   // Reconstruction of faces.
   //---------------------------
   TopoDS_Face        F,NF;
-  BRepOffset_Type    RT = BRepOffset_Concave;
-  if (myOffset < 0.) RT = BRepOffset_Convex;
+  ChFiDS_TypeOfConcavity RT = ChFiDS_Concave;
+  if (myOffset < 0.) RT = ChFiDS_Convex;
   TopoDS_Shape       OE,NE;
   TopAbs_Orientation Or;
 
@@ -1809,8 +1902,8 @@ void BRepOffset_MakeOffset::UpdateFaceOffset()
   CopiedMap.Assign(myFaceOffset);
   TopTools_DataMapIteratorOfDataMapOfShapeReal it(CopiedMap);
 
-  BRepOffset_Type    RT = BRepOffset_Convex;
-  if (myOffset < 0.) RT = BRepOffset_Concave;
+  ChFiDS_TypeOfConcavity RT = ChFiDS_Convex;
+  if (myOffset < 0.) RT = ChFiDS_Concave;
 
   for ( ; it.More(); it.Next()) {
     const TopoDS_Face& F = TopoDS::Face(it.Key());
@@ -1822,9 +1915,9 @@ void BRepOffset_MakeOffset::UpdateFaceOffset()
     TopTools_MapOfShape Dummy;
     Build.Add(Co,F);
     if (myJoin == GeomAbs_Arc)
-      myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent,RT);
+      myAnalyse.AddFaces(F,Co,Dummy,ChFiDS_Tangential,RT);
     else   
-      myAnalyse.AddFaces(F,Co,Dummy,BRepOffset_Tangent);
+      myAnalyse.AddFaces(F,Co,Dummy,ChFiDS_Tangential);
 
     TopExp_Explorer exp(Co,TopAbs_FACE);
     for (; exp.More(); exp.Next()) {
@@ -2213,36 +2306,30 @@ void BRepOffset_MakeOffset::CorrectConicalFaces()
         }
       }
     }
-    TopoDS_Iterator anIt(Sol);
-    Standard_Boolean SolIsNull = !anIt.More();
+    Standard_Integer nbs = Sol.NbChildren();
+    Standard_Boolean SolIsNull = (nbs == 0);
     //Checking solid
-    if(!SolIsNull)
+    if (nbs > 1)
     {
-      Standard_Integer nbs = 0;
-      while(anIt.More()) {anIt.Next(); ++nbs;}
-      if(nbs > 1)
+      BRepCheck_Analyzer aCheck (Sol, Standard_False);
+      if (!aCheck.IsValid ())
       {
-        BRepCheck_Analyzer aCheck(Sol, Standard_False);
-        if(!aCheck.IsValid())
+        TopTools_ListOfShape aSolList;
+        CorrectSolid (Sol, aSolList);
+        if (!aSolList.IsEmpty ())
         {
-          TopTools_ListOfShape aSolList;
-          CorrectSolid(Sol, aSolList);
-          if(!aSolList.IsEmpty())
+          BB.Add (NC, Sol);
+          TopTools_ListIteratorOfListOfShape aSLIt (aSolList);
+          for (; aSLIt.More (); aSLIt.Next ())
           {
-            BB.Add(NC, Sol);
-            TopTools_ListIteratorOfListOfShape aSLIt(aSolList);
-            for(; aSLIt.More(); aSLIt.Next())
-            {
-              BB.Add(NC, aSLIt.Value());
-            }
-            SolIsNull = Standard_True;
+            BB.Add (NC, aSLIt.Value ());
           }
+          SolIsNull = Standard_True;
         }
       }
     }
     //
-    anIt.Initialize(NC);
-    Standard_Boolean NCIsNull = !anIt.More();
+    Standard_Boolean NCIsNull = (NC.NbChildren() == 0);
     if((!SolIsNull) && (!NCIsNull))
     {
       BB.Add(NC, Sol);
@@ -2280,11 +2367,24 @@ void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter)
 {
 #ifdef OCCT_DEBUG
   if (ChronBuild) {
-    cout << " INTERSECTION 3D:" << endl;
+    std::cout << " INTERSECTION 3D:" << std::endl;
     Clock.Reset();
     Clock.Start();  
   }
 #endif
+
+  // In the Complete Intersection mode, implemented currently for planar
+  // solids only, there is no need to intersect the faces here.
+  // This intersection will be performed in the method BuildShellsCompleteInter
+  // where the special treatment is applied to produced faces.
+  //
+  // Make sure to match the parameters in which the method
+  // BuildShellsCompleteInter is called.
+  if (myInter && (myJoin == GeomAbs_Intersection) && myIsPlanar &&
+      !myThickening && myFaces.IsEmpty() && IsSolid(myShape))
+    return;
+
+
   TopTools_ListOfShape OffsetFaces;  // list of faces // created.
   MakeList (OffsetFaces,myInitOffsetFace,myFaces);
 
@@ -2327,7 +2427,7 @@ void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Mod
 {
 #ifdef OCCT_DEBUG
   if (ChronBuild) {
-    cout << " INTERSECTION 2D:" << endl;
+    std::cout << " INTERSECTION 2D:" << std::endl;
     Clock.Reset();
     Clock.Start();  
   }
@@ -2367,7 +2467,7 @@ void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif)
 {
 #ifdef OCCT_DEBUG
   if (ChronBuild) {
-     cout << " DEBOUCLAGE 2D:" << endl;
+     std::cout << " DEBOUCLAGE 2D:" << std::endl;
      Clock.Reset();
      Clock.Start(); 
   }
@@ -2415,7 +2515,7 @@ void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/)
 {
 #ifdef OCCT_DEBUG
   if (ChronBuild) {  
-    cout << " RECONSTRUCTION OF FACES:" << endl;
+    std::cout << " RECONSTRUCTION OF FACES:" << std::endl;
     Clock.Reset();
     Clock.Start();
   }
@@ -2488,18 +2588,17 @@ static void UpdateInitOffset (BRepAlgo_Image&         myInitOffset,
 //=======================================================================
 void BRepOffset_MakeOffset::MakeMissingWalls ()
 {
-  TopTools_DataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary)
+  TopTools_IndexedDataMapOfShapeListOfShape Contours; //Start vertex + list of connected edges (free boundary)
   TopTools_DataMapOfShapeShape MapEF; //Edges of contours: edge + face
   Standard_Real OffsetVal = Abs(myOffset);
 
   FillContours(myShape, myAnalyse, Contours, MapEF);
 
-  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter(Contours);
-  for (; iter.More(); iter.Next())
+  for (Standard_Integer ic = 1; ic <= Contours.Extent(); ic++)
   {
-    TopoDS_Vertex StartVertex = TopoDS::Vertex(iter.Key());
+    TopoDS_Vertex StartVertex = TopoDS::Vertex(Contours.FindKey(ic));
     TopoDS_Edge StartEdge;
-    const TopTools_ListOfShape& aContour = iter.Value();
+    const TopTools_ListOfShape& aContour = Contours(ic);
     TopTools_ListIteratorOfListOfShape itl(aContour);
     Standard_Boolean FirstStep = Standard_True;
     TopoDS_Edge PrevEdge;
@@ -2508,6 +2607,7 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
     for (; itl.More(); itl.Next())
     {
       TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
+      TopoDS_Face aFaceOfEdge = TopoDS::Face(MapEF(anEdge));
 
       // Check for offset existence.
       if (!myInitOffsetEdge.HasImage(anEdge))
@@ -2847,6 +2947,12 @@ void BRepOffset_MakeOffset::MakeMissingWalls ()
       }
       BRepLib::SameParameter(NewFace);
       BRepTools::Update(NewFace);
+      //Check orientation
+      TopAbs_Orientation anOr = OrientationOfEdgeInFace(anEdge, aFaceOfEdge);
+      TopAbs_Orientation OrInNewFace = OrientationOfEdgeInFace(anEdge, NewFace);
+      if (OrInNewFace != TopAbs::Reverse(anOr))
+        NewFace.Reverse();
+      ///////////////////
       myWalls.Append(NewFace);
       if (ArcOnV2)
       {
@@ -2917,20 +3023,21 @@ void BRepOffset_MakeOffset::MakeShells ()
 {
 #ifdef OCCT_DEBUG
   if (ChronBuild) {  
-    cout << " RECONSTRUCTION OF SHELLS:" << endl;
+    std::cout << " RECONSTRUCTION OF SHELLS:" << std::endl;
     Clock.Reset();
     Clock.Start();
   }
 #endif
   //
-  TopTools_IndexedDataMapOfShapeListOfShape anOrigins;
-  //
-  BOPCol_ListOfShape aLSF;
+  // Prepare list of splits of the offset faces to make the shells
+  TopTools_ListOfShape aLSF;
   const TopTools_ListOfShape& R = myImageOffset.Roots();
   TopTools_ListIteratorOfListOfShape it(R);
   //
   for (; it.More(); it.Next()) {
-    const TopoDS_Shape& aF = it.Value();
+    TopoDS_Shape aF = it.Value();
+    if (myThickening) //offsetted faces must change their orientations
+      aF.Reverse();
     //
     TopTools_ListOfShape Image;
     myImageOffset.LastImage(aF,Image);
@@ -2938,12 +3045,6 @@ void BRepOffset_MakeOffset::MakeShells ()
     for (; it2.More(); it2.Next()) {
       const TopoDS_Shape& aFIm = it2.Value();
       aLSF.Append(aFIm);
-      //
-      TopTools_ListOfShape *pLOr = anOrigins.ChangeSeek(aFIm);
-      if (!pLOr) {
-        pLOr = &anOrigins(anOrigins.Add(aFIm, TopTools_ListOfShape()));
-      }
-      pLOr->Append(aF);
     }
   }
   //
@@ -2971,7 +3072,7 @@ void BRepOffset_MakeOffset::MakeShells ()
       IsSolid(myShape) && myIsPlanar) {
     //
     TopoDS_Shape aShells;
-    bDone = BuildShellsCompleteInter(aLSF, anOrigins, myImageOffset, aShells);
+    bDone = BuildShellsCompleteInter(aLSF, myImageOffset, aShells);
     if (bDone) {
       myOffsetShape = aShells;
     }
@@ -2979,7 +3080,7 @@ void BRepOffset_MakeOffset::MakeShells ()
   //
   if (!bDone) {
     BRepTools_Quilt Glue;
-    BOPCol_ListIteratorOfListOfShape aItLS(aLSF);
+    TopTools_ListIteratorOfListOfShape aItLS(aLSF);
     for (; aItLS.More(); aItLS.Next()) {
       Glue.Add(aItLS.Value());
     }
@@ -3042,35 +3143,29 @@ void BRepOffset_MakeOffset::MakeSolid ()
       }
     }
   }
-  TopoDS_Iterator anIt(Sol);
-  Standard_Boolean SolIsNull = !anIt.More();
+  Standard_Integer nbs = Sol.NbChildren();
+  Standard_Boolean SolIsNull = (nbs == 0);
   //Checking solid
-  if(!SolIsNull)
+  if (nbs > 1)
   {
-    Standard_Integer nbs = 0;
-    while(anIt.More()) {anIt.Next(); ++nbs;}
-    if(nbs > 1)
+    BRepCheck_Analyzer aCheck (Sol, Standard_False);
+    if (!aCheck.IsValid ())
     {
-      BRepCheck_Analyzer aCheck(Sol, Standard_False);
-      if(!aCheck.IsValid())
+      TopTools_ListOfShape aSolList;
+      CorrectSolid (Sol, aSolList);
+      if (!aSolList.IsEmpty ())
       {
-        TopTools_ListOfShape aSolList;
-        CorrectSolid(Sol, aSolList);
-        if(!aSolList.IsEmpty())
+        B.Add (NC, Sol);
+        TopTools_ListIteratorOfListOfShape aSLIt (aSolList);
+        for (; aSLIt.More (); aSLIt.Next ())
         {
-          B.Add(NC, Sol);
-          TopTools_ListIteratorOfListOfShape aSLIt(aSolList);
-          for(; aSLIt.More(); aSLIt.Next())
-          {
-            B.Add(NC, aSLIt.Value());
-          }
-          SolIsNull = Standard_True;
+          B.Add (NC, aSLIt.Value ());
         }
+        SolIsNull = Standard_True;
       }
     }
   }
-  anIt.Initialize(NC);
-  Standard_Boolean NCIsNull = !anIt.More();
+  Standard_Boolean NCIsNull = (NC.NbChildren() == 0);
   if((!SolIsNull) && (!NCIsNull))
   {
     B.Add(NC, Sol);
@@ -3115,7 +3210,7 @@ void BRepOffset_MakeOffset::SelectShells ()
     const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
     const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E);
     if (LA.Extent() < 2) {
-      if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) {
+      if (myAnalyse.Type(E).First().Type() == ChFiDS_FreeBound) {
               FreeEdges.Add(E);                       
       }
     }  
@@ -3182,7 +3277,7 @@ void BRepOffset_MakeOffset::EncodeRegularity ()
 {
 #ifdef OCCT_DEBUG
   if (ChronBuild) {  
-    cout << " CODING OF REGULARITIES:" << endl;
+    std::cout << " CODING OF REGULARITIES:" << std::endl;
     Clock.Reset();
     Clock.Start();
   }
@@ -3209,7 +3304,7 @@ void BRepOffset_MakeOffset::EncodeRegularity ()
     
     if (LofOF.Extent() != 2) {
 #ifdef OCCT_DEBUG_VERB
-    cout << " Edge shared by " << LofOF.Extent() << " Faces" << endl;
+    std::cout << " Edge shared by " << LofOF.Extent() << " Faces" << std::endl;
 #endif
       continue;
     }
@@ -3316,7 +3411,7 @@ void BRepOffset_MakeOffset::EncodeRegularity ()
         if ( myAnalyse.HasAncestor(Ed)) {
           const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed);
           if (LI.Extent()       == 1   && 
-              LI.First().Type() == BRepOffset_Tangent) {
+              LI.First().Type() == ChFiDS_Tangential) {
             B.Continuity(OE,F1,F2,GeomAbs_G1);
           }
         }
@@ -3804,7 +3899,7 @@ void UpdateHistory(const TopTools_ListOfShape& theLF,
 //function : IntersectEdges
 //purpose  : 
 //=======================================================================
-void BRepOffset_MakeOffset::IntersectEdges(const TopoDS_Shape& theShape,
+void BRepOffset_MakeOffset::IntersectEdges(const TopTools_ListOfShape& theFaces,
                                            BRepOffset_DataMapOfShapeOffset& theMapSF,
                                            TopTools_DataMapOfShapeShape& theMES,
                                            TopTools_DataMapOfShapeShape& theBuild,
@@ -3813,14 +3908,18 @@ void BRepOffset_MakeOffset::IntersectEdges(const TopoDS_Shape& theShape,
 {
   Standard_Real aTolF;
   TopTools_IndexedDataMapOfShapeListOfShape aDMVV;
-  TopExp_Explorer aExp(theShape, TopAbs_FACE);
   // intersect edges created from edges
   TopTools_IndexedMapOfShape aMFV;
-  for (; aExp.More(); aExp.Next()) {
-    const TopoDS_Face& aF = TopoDS::Face(aExp.Current());
-    aTolF = BRep_Tool::Tolerance(aF);
-    BRepOffset_Inter2d::ConnexIntByInt
-      (aF, theMapSF(aF), theMES, theBuild, theAsDes2d, myOffset, aTolF, aMFV, aDMVV);
+  for (TopTools_ListOfShape::Iterator it (theFaces); it.More(); it.Next())
+  {
+    const TopoDS_Face& aF  = TopoDS::Face (it.Value());
+    aTolF = BRep_Tool::Tolerance (aF);
+    if (!BRepOffset_Inter2d::ConnexIntByInt(aF, theMapSF(aF), theMES, theBuild, theAsDes2d,
+                                            myOffset, aTolF, myAnalyse, aMFV, aDMVV))
+    {
+      myError = BRepOffset_CannotExtentEdge;
+      return;
+    }
   }
   // intersect edges created from vertices
   Standard_Integer i, aNbF = aMFV.Extent();
@@ -3828,35 +3927,55 @@ void BRepOffset_MakeOffset::IntersectEdges(const TopoDS_Shape& theShape,
     const TopoDS_Face& aF = TopoDS::Face(aMFV(i));
     aTolF = BRep_Tool::Tolerance(aF);
     BRepOffset_Inter2d::ConnexIntByIntInVert
-      (aF, theMapSF(aF), theMES, theBuild, theAsDes, theAsDes2d, aTolF, aDMVV);
+      (aF, theMapSF(aF), theMES, theBuild, theAsDes, theAsDes2d, aTolF, myAnalyse, aDMVV);
   }
   //
   // fuse vertices on edges
-  BRepOffset_Inter2d::FuseVertices(aDMVV, theAsDes2d);
+  if (!BRepOffset_Inter2d::FuseVertices(aDMVV, theAsDes2d))
+  {
+    myError = BRepOffset_CannotFuseVertices;
+    return;
+  }
 }
 
 //=======================================================================
 //function : TrimEdges
 //purpose  : 
 //=======================================================================
-void TrimEdges(const TopoDS_Shape& theShape,
-               const Standard_Real theOffset,
-               BRepOffset_DataMapOfShapeOffset& theMapSF,
-               TopTools_DataMapOfShapeShape& theMES,
-               TopTools_DataMapOfShapeShape& theBuild,
-               Handle(BRepAlgo_AsDes)& theAsDes,
-               Handle(BRepAlgo_AsDes)& theAsDes2d,
-               TopTools_IndexedMapOfShape& theNewEdges,
-               TopTools_DataMapOfShapeShape& theETrimEInf,
-               TopTools_DataMapOfShapeListOfShape& theEdgesOrigins)
+Standard_Boolean TrimEdges(const TopoDS_Shape& theShape,
+                 const Standard_Real theOffset,
+                 const BRepOffset_Analyse& Analyse,
+                 BRepOffset_DataMapOfShapeOffset& theMapSF,
+                 TopTools_DataMapOfShapeShape& theMES,
+                 TopTools_DataMapOfShapeShape& theBuild,
+                 Handle(BRepAlgo_AsDes)& theAsDes,
+                 Handle(BRepAlgo_AsDes)& theAsDes2d,
+                 TopTools_IndexedMapOfShape& theNewEdges,
+                 TopTools_DataMapOfShapeShape& theETrimEInf,
+                 TopTools_DataMapOfShapeListOfShape& theEdgesOrigins)
 {
   TopExp_Explorer Exp,Exp2,ExpC;
   TopoDS_Shape    NE;
   TopoDS_Edge     TNE;
   TopoDS_Face     NF;
-  //
-  for (Exp.Init(theShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) {
-    const TopoDS_Face& FI = TopoDS::Face(Exp.Current());
+
+  TopTools_ListOfShape aLFaces;
+  for (Exp.Init (theShape, TopAbs_FACE); Exp.More(); Exp.Next())
+    aLFaces.Append (Exp.Current());
+
+  TopTools_MapOfShape aMFGenerated;
+  TopTools_IndexedDataMapOfShapeListOfShape aDMEF;
+  for (TopTools_ListOfShape::Iterator it (Analyse.NewFaces()); it.More(); it.Next())
+  {
+    const TopoDS_Shape& aFG = it.Value();
+    aLFaces.Append (aFG);
+    aMFGenerated.Add (aFG);
+    TopExp::MapShapesAndUniqueAncestors (aFG, TopAbs_EDGE, TopAbs_FACE, aDMEF);
+  }
+
+  for (TopTools_ListOfShape::Iterator it (aLFaces); it.More(); it.Next())
+  {
+    const TopoDS_Face& FI  = TopoDS::Face (it.Value());
     NF = theMapSF(FI).Face();
     if (theMES.IsBound(NF)) {
       NF = TopoDS::Face(theMES(NF));
@@ -3891,7 +4010,8 @@ void TrimEdges(const TopoDS_Shape& theShape,
         // trim edges
         if (NE.ShapeType() == TopAbs_EDGE) {
           if (theNewEdges.Add(NE)) {
-            TrimEdge (TopoDS::Edge(NE),theAsDes2d,theAsDes, theETrimEInf);
+            if (!TrimEdge (TopoDS::Edge(NE),theAsDes2d,theAsDes, theETrimEInf))
+              return Standard_False;
           }
         }
         else {
@@ -3904,7 +4024,8 @@ void TrimEdges(const TopoDS_Shape& theShape,
             TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current());
             if (theNewEdges.Add(NEC)) {
               if (!theAsDes2d->Descendant(NEC).IsEmpty()) {
-                TrimEdge (NEC,theAsDes2d, theAsDes, theETrimEInf);
+                if(!TrimEdge (NEC,theAsDes2d, theAsDes, theETrimEInf))
+                  return Standard_False;
               }
               else {
                 if (theAsDes->HasAscendant(NEC)) {
@@ -3919,7 +4040,9 @@ void TrimEdges(const TopoDS_Shape& theShape,
         if (aS.ShapeType() != TopAbs_EDGE) {
           continue;
         }
-        //
+        if (aMFGenerated.Contains (FI) && aDMEF.FindFromKey (aS).Extent() == 1)
+          continue;
+
         NE = theMapSF(FI).Generated(aS);
         //// modified by jgv, 19.12.03 for OCC4455 ////
         NE.Orientation(aS.Orientation());
@@ -3934,7 +4057,8 @@ void TrimEdges(const TopoDS_Shape& theShape,
           NE = theMES(NE);
           NE.Orientation(aS.Orientation());
           if (theNewEdges.Add(NE)) {
-            TrimEdge (TopoDS::Edge(NE), theAsDes2d, theAsDes, theETrimEInf);
+            if (!TrimEdge (TopoDS::Edge(NE), theAsDes2d, theAsDes, theETrimEInf))
+              return Standard_False;
           } 
         }
         else {
@@ -3950,6 +4074,7 @@ void TrimEdges(const TopoDS_Shape& theShape,
       } 
     }
   }
+  return Standard_True;
 }
 
 //=======================================================================
@@ -3957,7 +4082,7 @@ void TrimEdges(const TopoDS_Shape& theShape,
 //purpose  : Trim the edge of the largest of descendants in AsDes2d.
 //           Order in AsDes two vertices that have trimmed the edge.
 //=======================================================================
-void TrimEdge(TopoDS_Edge&                  NE,
+Standard_Boolean TrimEdge(TopoDS_Edge&                  NE,
               const Handle(BRepAlgo_AsDes)& AsDes2d,
               Handle(BRepAlgo_AsDes)& AsDes,
               TopTools_DataMapOfShapeShape& theETrimEInf)
@@ -3995,7 +4120,9 @@ void TrimEdge(TopoDS_Edge&                  NE,
         gp_Pnt thePoint = BRep_Tool::Pnt(V);
         GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve);
         if (Projector.NbPoints() == 0)
-          throw Standard_ConstructionError("BRepOffset_MakeOffset::TrimEdge no projection");
+        {
+          return Standard_False;
+        }
         U = Projector.LowerDistanceParameter();
       }
       if (U < UMin) {
@@ -4007,7 +4134,7 @@ void TrimEdge(TopoDS_Edge&                  NE,
     }
     //
     if (V1.IsNull() || V2.IsNull()) {
-      throw Standard_ConstructionError("BRepOffset_MakeOffset::TrimEdge");
+      return Standard_False;
     }
     if (!V1.IsSame(V2)) {
       NE.Free( Standard_True );
@@ -4044,28 +4171,28 @@ void TrimEdge(TopoDS_Edge&                  NE,
       theETrimEInf.Bind(NE, aSourceEdge);
     }
   }
+  return Standard_True;
 }
 
 //=======================================================================
 //function : GetEnlargedFaces
 //purpose  : 
 //=======================================================================
-void GetEnlargedFaces(const TopoDS_Shape& theShape,
+void GetEnlargedFaces(const TopTools_ListOfShape& theFaces,
                       const BRepOffset_DataMapOfShapeOffset& theMapSF,
                       const TopTools_DataMapOfShapeShape& theMES,
                       TopTools_DataMapOfShapeShape& theFacesOrigins,
                       BRepAlgo_Image& theImage,
                       TopTools_ListOfShape& theLSF)
 {
-  TopExp_Explorer aExp(theShape, TopAbs_FACE);
-  for (; aExp.More(); aExp.Next()) {
-    const TopoDS_Shape& FI  = aExp.Current();
+  for (TopTools_ListOfShape::Iterator it (theFaces); it.More(); it.Next())
+  {
+    const TopoDS_Shape& FI  = it.Value();
     const TopoDS_Shape& OFI = theMapSF(FI).Face();
     if (theMES.IsBound(OFI)) {
       const TopoDS_Face& aLocalFace = TopoDS::Face(theMES(OFI));
       theLSF.Append(aLocalFace);
       theImage.SetRoot(aLocalFace);
-      //
       theFacesOrigins.Bind(aLocalFace, FI);
     }
   }
@@ -4077,8 +4204,7 @@ void GetEnlargedFaces(const TopoDS_Shape& theShape,
 //           In case there will be more than just one solid, it will be
 //           rebuilt using only outer faces.
 //=======================================================================
-Standard_Boolean BuildShellsCompleteInter(const BOPCol_ListOfShape& theLF,
-                                          const BOPCol_IndexedDataMapOfShapeListOfShape& theOrigins,
+Standard_Boolean BuildShellsCompleteInter(const TopTools_ListOfShape& theLF,
                                           BRepAlgo_Image& theImage,
                                           TopoDS_Shape& theShells)
 {
@@ -4090,7 +4216,7 @@ Standard_Boolean BuildShellsCompleteInter(const BOPCol_ListOfShape& theLF,
   aMV1.SetAvoidInternalShapes(Standard_True);
   aMV1.Perform();
   //
-  Standard_Boolean bDone = (aMV1.ErrorStatus() == 0);
+  Standard_Boolean bDone = ! aMV1.HasErrors();
   if (!bDone) {
     return bDone;
   }
@@ -4102,11 +4228,47 @@ Standard_Boolean BuildShellsCompleteInter(const BOPCol_ListOfShape& theLF,
     // result is the alone solid, nothing to do
     return GetSubShapes(aResult1, TopAbs_SHELL, theShells);
   }
-  //
-  // it is necessary to rebuild the solids, avoiding internal faces
-  //
-  // map faces to solids
-  TopTools_IndexedDataMapOfShapeListOfShape aDMFS;
+
+  // Allocators for effective memory allocations
+  // Global allocator for the long-living containers
+  Handle(NCollection_IncAllocator) anAllocGlob = new NCollection_IncAllocator;
+  // Local allocator for the local containers
+  Handle(NCollection_IncAllocator) anAllocLoc = new NCollection_IncAllocator;
+
+  // Since the <theImage> object does not support multiple ancestors,
+  // prepare local copy of the origins, which will be used to resolve
+  // non-manifold solids produced by Maker Volume algorithm by comparison
+  // of the normal directions of the split faces with their origins.
+  TopTools_DataMapOfShapeListOfShape anOrigins(1, anAllocGlob);
+  TopTools_ListIteratorOfListOfShape aItLR(theImage.Roots());
+  for (; aItLR.More(); aItLR.Next())
+  {
+    const TopoDS_Shape& aFR = aItLR.Value();
+
+    // Reset the local allocator
+    anAllocLoc->Reset();
+    // Find the last splits of the root face, including the ones
+    // created during MakeVolume operation
+    TopTools_ListOfShape aLFIm(anAllocLoc);
+    theImage.LastImage(aFR, aLFIm);
+
+    TopTools_ListIteratorOfListOfShape aItLFIm(aLFIm);
+    for (; aItLFIm.More(); aItLFIm.Next())
+    {
+      const TopoDS_Shape& aFIm = aItLFIm.Value();
+      TopTools_ListOfShape *pLFOr = anOrigins.ChangeSeek(aFIm);
+      if (!pLFOr) {
+        pLFOr = anOrigins.Bound(aFIm, TopTools_ListOfShape(anAllocGlob));
+      }
+      pLFOr->Append(aFR);
+    }
+  }
+
+  // Reset the local allocator
+  anAllocLoc->Reset();
+  // It is necessary to rebuild the solids, avoiding internal faces
+  // Map faces to solids
+  TopTools_IndexedDataMapOfShapeListOfShape aDMFS(1, anAllocLoc);
   TopExp::MapShapesAndAncestors(aResult1, TopAbs_FACE, TopAbs_SOLID, aDMFS);
   //
   Standard_Integer i, aNb = aDMFS.Extent();
@@ -4117,23 +4279,23 @@ Standard_Boolean BuildShellsCompleteInter(const BOPCol_ListOfShape& theLF,
   }
   //
   // get faces attached to only one solid
-  BOPCol_ListOfShape aLF2;
+  TopTools_ListOfShape aLF(anAllocLoc);
   for (i = 1; i <= aNb; ++i) {
     const TopTools_ListOfShape& aLS = aDMFS(i);
     if (aLS.Extent() == 1) {
       const TopoDS_Shape& aF = aDMFS.FindKey(i);
-      aLF2.Append(aF);
+      aLF.Append(aF);
     }
   }
   //
   // make solids from the new list
   BOPAlgo_MakerVolume aMV2;
-  aMV2.SetArguments(aLF2);
+  aMV2.SetArguments(aLF);
   // no need to intersect this time
   aMV2.SetIntersect(Standard_False);
   aMV2.SetAvoidInternalShapes(Standard_True);
   aMV2.Perform();
-  bDone = (aMV2.ErrorStatus() == 0);
+  bDone = ! aMV2.HasErrors();
   if (!bDone) {
     return bDone;
   }
@@ -4149,24 +4311,30 @@ Standard_Boolean BuildShellsCompleteInter(const BOPCol_ListOfShape& theLF,
     return bDone;
   }
   //
-  // the result is non-manifold - resolve it comparing normals
+  aLF.Clear();
+  aDMFS.Clear();
+  anAllocLoc->Reset();
+
+  // the result is non-manifold - resolve it comparing normal
   // directions of the offset faces and original faces
-  BOPCol_ListOfShape aLF3;
-  for (; aExp.More(); aExp.Next()) {
+  for (; aExp.More(); aExp.Next())
+  {
     const TopoDS_Face& aF = TopoDS::Face(aExp.Current());
-    //
-    // check orientation
-    if (!theOrigins.Contains(aF)) {
-      aLF3.Append(aF);
+    const TopTools_ListOfShape* pLFOr = anOrigins.Seek(aF);
+    if (!pLFOr)
+    {
+      Standard_ASSERT_INVOKE("BRepOffset_MakeOffset::BuildShellsCompleteInterSplit(): "
+                             "Origins map does not contain the split face");
       continue;
     }
-    //
-    const TopTools_ListOfShape& aLFOr = theOrigins.FindFromKey(aF);
-    TopTools_ListIteratorOfListOfShape aItLF(aLFOr);
-    for (; aItLF.More(); aItLF.Next()) {
-      const TopoDS_Face& aFOr = TopoDS::Face(aItLF.Value());
-      if (BRepOffset_Tool::CheckPlanesNormals(aF, aFOr)) {
-        aLF3.Append(aF);
+    // Check orientation
+    TopTools_ListIteratorOfListOfShape aItLOr(*pLFOr);
+    for (; aItLOr.More(); aItLOr.Next())
+    {
+      const TopoDS_Face& aFOr = TopoDS::Face(aItLOr.Value());
+      if (BRepOffset_Tool::CheckPlanesNormals(aF, aFOr))
+      {
+        aLF.Append(aF);
         break;
       }
     }
@@ -4174,11 +4342,11 @@ Standard_Boolean BuildShellsCompleteInter(const BOPCol_ListOfShape& theLF,
   //
   // make solid from most outer faces with correct normal direction
   BOPAlgo_MakerVolume aMV3;
-  aMV3.SetArguments(aLF3);
+  aMV3.SetArguments(aLF);
   aMV3.SetIntersect(Standard_False);
   aMV3.SetAvoidInternalShapes(Standard_True);
   aMV3.Perform();
-  bDone = (aMV3.ErrorStatus() == 0);
+  bDone = ! aMV3.HasErrors();
   if (!bDone) {
     return bDone;
   }
@@ -4187,6 +4355,113 @@ Standard_Boolean BuildShellsCompleteInter(const BOPCol_ListOfShape& theLF,
   return GetSubShapes(aResult3, TopAbs_SHELL, theShells);
 }
 
+//=======================================================================
+//function : Generated
+//purpose  : 
+//=======================================================================
+const TopTools_ListOfShape& BRepOffset_MakeOffset::Generated (const TopoDS_Shape& theS)
+{
+  myGenerated.Clear();
+  const TopAbs_ShapeEnum aType = theS.ShapeType();
+  switch (aType)
+  {
+    case TopAbs_VERTEX:
+    {
+      if (myAnalyse.HasAncestor (theS))
+      {
+        TopTools_MapOfShape aMFence;
+        const TopTools_ListOfShape& aLA = myAnalyse.Ancestors (theS);
+        TopTools_ListOfShape::Iterator itLA (aLA);
+        for (; myGenerated.IsEmpty() && itLA.More(); itLA.Next())
+        {
+          const TopoDS_Shape& aE = itLA.Value();
+          if (!myInitOffsetEdge.HasImage (aE))
+            continue;
+          TopTools_ListOfShape aLEIm;
+          myInitOffsetEdge.LastImage (aE, aLEIm);
+          TopTools_ListOfShape::Iterator itLEIm (aLEIm);
+          for (; myGenerated.IsEmpty() && itLEIm.More(); itLEIm.Next())
+          {
+            TopoDS_Iterator itV (itLEIm.Value());
+            for (; itV.More(); itV.Next())
+            {
+              if (!aMFence.Add (itV.Value()))
+              {
+                myGenerated.Append (itV.Value());
+                break;
+              }
+            }
+          }
+        }
+      }
+    }
+    Standard_FALLTHROUGH
+    case TopAbs_EDGE:
+    {
+      if (myInitOffsetEdge.HasImage (theS))
+      {
+        myInitOffsetEdge.LastImage (theS, myGenerated);
+      }
+    }
+    Standard_FALLTHROUGH
+    case TopAbs_FACE:
+    {
+      if (myInitOffsetFace.HasImage (theS))
+      {
+        myInitOffsetFace.LastImage (theS, myGenerated);
+      }
+      break;
+    }
+    case TopAbs_SOLID:
+    {
+      if (theS.IsSame (myShape))
+        myGenerated.Append (myOffsetShape);
+      break;
+    }
+    default:
+      break;
+  }
+
+  if (myResMap.IsEmpty())
+    TopExp::MapShapes (myOffsetShape, myResMap);
+
+  for (TopTools_ListOfShape::Iterator it (myGenerated); it.More();)
+  {
+    if (myResMap.Contains (it.Value()))
+      it.Next();
+    else
+      myGenerated.Remove (it);
+  }
+
+  return myGenerated;
+}
+
+//=======================================================================
+//function : Modified
+//purpose  : 
+//=======================================================================
+const TopTools_ListOfShape& BRepOffset_MakeOffset::Modified (const TopoDS_Shape&)
+{
+  myGenerated.Clear();
+  return myGenerated;
+}
+
+//=======================================================================
+//function : IsDeleted
+//purpose  : 
+//=======================================================================
+Standard_Boolean BRepOffset_MakeOffset::IsDeleted (const TopoDS_Shape& theS)
+{
+  if (myResMap.IsEmpty())
+    TopExp::MapShapes (myOffsetShape, myResMap);
+
+  if (myResMap.Contains (theS))
+    return Standard_False;
+
+  return Generated (theS).IsEmpty()
+      && Modified  (theS).IsEmpty();
+}
+
 //=======================================================================
 //function : GetSubShapes
 //purpose  :