0025880: fuzzy booleans with multiple tools
[occt.git] / src / BOPTools / BOPTools_AlgoTools.cxx
index d6c5e9a..1ed5095 100644 (file)
@@ -64,7 +64,8 @@
 #include <BOPCol_IndexedMapOfShape.hxx>
 #include <BOPCol_MapOfShape.hxx>
 //
-#include <BOPInt_ShrunkRange.hxx>
+#include <IntTools_ShrunkRange.hxx>
+#include <Precision.hxx>
 //
 
 static
@@ -76,7 +77,7 @@ static
   Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
                                   const BOPCol_ListOfShape& thLF,
                                   BOPTools_ListOfCoupleOfShape& theLCFF,
-                                  Handle(BOPInt_Context)& theContext);
+                                  Handle(IntTools_Context)& theContext);
 static
   TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
                                  const TopoDS_Face& aF);
@@ -89,25 +90,33 @@ static
                   const gp_Dir& aDTgt,
                   gp_Dir& aDN,
                   gp_Dir& aDB,
-                  Handle(BOPInt_Context)& theContext,
-                  GeomAPI_ProjectPointOnSurf& aProjPL);
+                  Handle(IntTools_Context)& theContext,
+                  GeomAPI_ProjectPointOnSurf& aProjPL,
+                  const Standard_Real aDt);
 static
-  Standard_Boolean FindPointInFace(const TopoDS_Edge& aE,
-                                   const TopoDS_Face& aF,
+  Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
                                    const gp_Pnt& aP,
                                    gp_Dir& aDB,
                                    gp_Pnt& aPOut,
-                                   Handle(BOPInt_Context)& theContext,
-                                   GeomAPI_ProjectPointOnSurf& aProjPL);
+                                   Handle(IntTools_Context)& theContext,
+                                   GeomAPI_ProjectPointOnSurf& aProjPL,
+                                   const Standard_Real aDt,
+                                   const Standard_Real aTolE);
+static 
+  Standard_Real MinStep3D(const TopoDS_Edge& theE1,
+                          const TopoDS_Face& theF1,
+                          const BOPTools_ListOfCoupleOfShape& theLCS,
+                          const gp_Pnt& aP);
 
 //=======================================================================
 // function: MakeConnexityBlocks
 // purpose: 
 //=======================================================================
-void BOPTools_AlgoTools::MakeConnexityBlocks (const TopoDS_Shape& theS,
-                                              const TopAbs_ShapeEnum theType1,
-                                              const TopAbs_ShapeEnum theType2,
-                                              BOPCol_ListOfShape& theLCB)
+void BOPTools_AlgoTools::MakeConnexityBlocks 
+  (const TopoDS_Shape& theS,
+   const TopAbs_ShapeEnum theType1,
+   const TopAbs_ShapeEnum theType2,
+   BOPCol_ListOfShape& theLCB)
 {
   Standard_Integer  aNbF, aNbAdd, aNbAdd1, i;
   BRep_Builder aBB;
@@ -203,7 +212,9 @@ void BOPTools_AlgoTools::OrientFacesOnShell (TopoDS_Shape& aShell)
   //
   BOPTools_AlgoTools::MakeContainer(TopAbs_SHELL, aShellNew);
   //
-  BOPTools::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aEFMap);
+  BOPTools::MapShapesAndAncestors(aShell, 
+                                  TopAbs_EDGE, TopAbs_FACE, 
+                                  aEFMap);
   aNbE=aEFMap.Extent();
   // 
   // One seam edge  in aEFMap contains  2 equivalent faces.
@@ -334,18 +345,15 @@ TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
   }
   return anOr;
 }
-
-////////////
-
-
 //=======================================================================
 // function: MakeConnexityBlock.
 // purpose: 
 //=======================================================================
-void BOPTools_AlgoTools::MakeConnexityBlock (BOPCol_ListOfShape& theLFIn,
-                                             BOPCol_IndexedMapOfShape& theMEAvoid,
-                                             BOPCol_ListOfShape& theLCB,
-                                             const Handle(NCollection_BaseAllocator)& theAllocator)
+void BOPTools_AlgoTools::MakeConnexityBlock 
+  (BOPCol_ListOfShape& theLFIn,
+   BOPCol_IndexedMapOfShape& theMEAvoid,
+   BOPCol_ListOfShape& theLCB,
+   const Handle(NCollection_BaseAllocator)& theAllocator)
 {
   Standard_Integer  aNbF, aNbAdd1, aNbAdd, i;
   TopExp_Explorer aExp;
@@ -422,10 +430,11 @@ void BOPTools_AlgoTools::MakeConnexityBlock (BOPCol_ListOfShape& theLFIn,
 // function:  ComputeStateByOnePoint
 // purpose: 
 //=======================================================================
-TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint(const TopoDS_Shape& theS,
-                                                        const TopoDS_Solid& theRef,
-                                                        const Standard_Real theTol,
-                                                        Handle(BOPInt_Context)& theContext)
+TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint
+  (const TopoDS_Shape& theS,
+   const TopoDS_Solid& theRef,
+   const Standard_Real theTol,
+   Handle(IntTools_Context)& theContext)
 {
   TopAbs_State aState;
   TopAbs_ShapeEnum aType;
@@ -447,11 +456,12 @@ TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint(const TopoDS_Shape& theS
 // function:  ComputeState
 // purpose: 
 //=======================================================================
-TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Face& theF,
-                                              const TopoDS_Solid& theRef,
-                                              const Standard_Real theTol,
-                                              BOPCol_IndexedMapOfShape& theBounds,
-                                              Handle(BOPInt_Context)& theContext)
+TopAbs_State BOPTools_AlgoTools::ComputeState
+  (const TopoDS_Face& theF,
+   const TopoDS_Solid& theRef,
+   const Standard_Real theTol,
+   BOPCol_IndexedMapOfShape& theBounds,
+   Handle(IntTools_Context)& theContext)
 {
   TopAbs_State aState;
   TopExp_Explorer aExp; 
@@ -470,7 +480,8 @@ TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Face& theF,
     //
     if (!theBounds.Contains(aSE)) {
       const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aSE));
-      aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, theContext);
+      aState=BOPTools_AlgoTools::ComputeState(aE, theRef, theTol, 
+                                              theContext);
       return aState;
     }
     if (aE1.IsNull()) {
@@ -479,8 +490,10 @@ TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Face& theF,
   }
   // !!<- process edges that are all on theRef
   if (!aE1.IsNull()) {
-    BOPTools_AlgoTools3D::PointNearEdge(aE1, theF, aP2D, aP3D, theContext);
-    aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
+    BOPTools_AlgoTools3D::PointNearEdge(aE1, theF, 
+                                        aP2D, aP3D, theContext);
+    aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, 
+                                            theContext);
   }
   //
   return aState;
@@ -489,26 +502,29 @@ TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Face& theF,
 // function:  ComputeState
 // purpose: 
 //=======================================================================
-TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Vertex& theV,
-                                              const TopoDS_Solid& theRef,
-                                              const Standard_Real theTol,
-                                              Handle(BOPInt_Context)& theContext)
+TopAbs_State BOPTools_AlgoTools::ComputeState
+  (const TopoDS_Vertex& theV,
+   const TopoDS_Solid& theRef,
+   const Standard_Real theTol,
+   Handle(IntTools_Context)& theContext)
 {
   TopAbs_State aState;
   gp_Pnt aP3D; 
   //
   aP3D=BRep_Tool::Pnt(theV);
-  aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
+  aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, 
+                                          theContext);
   return aState;
 }
 //=======================================================================
 // function:  ComputeState
 // purpose: 
 //=======================================================================
-TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Edge& theE,
-                                              const TopoDS_Solid& theRef,
-                                              const Standard_Real theTol,
-                                              Handle(BOPInt_Context)& theContext)
+TopAbs_State BOPTools_AlgoTools::ComputeState
+  (const TopoDS_Edge& theE,
+   const TopoDS_Solid& theRef,
+   const Standard_Real theTol,
+   Handle(IntTools_Context)& theContext)
 {
   Standard_Real aT1, aT2, aT = 0.;
   TopAbs_State aState;
@@ -547,7 +563,8 @@ TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Edge& theE,
     aC3D->D0(aT, aP3D);
   }
   //
-  aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, theContext);
+  aState=BOPTools_AlgoTools::ComputeState(aP3D, theRef, theTol, 
+                                          theContext);
   //
   return aState;
 }
@@ -555,10 +572,11 @@ TopAbs_State BOPTools_AlgoTools::ComputeState(const TopoDS_Edge& theE,
 // function:  ComputeState
 // purpose: 
 //=======================================================================
-TopAbs_State BOPTools_AlgoTools::ComputeState(const gp_Pnt& theP,
-                                              const TopoDS_Solid& theRef,
-                                              const Standard_Real theTol,
-                                              Handle(BOPInt_Context)& theContext)
+TopAbs_State BOPTools_AlgoTools::ComputeState
+  (const gp_Pnt& theP,
+   const TopoDS_Solid& theRef,
+   const Standard_Real theTol,
+   Handle(IntTools_Context)& theContext)
 {
   TopAbs_State aState;
   //
@@ -578,7 +596,7 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
    const TopoDS_Solid& theSolid,
    BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
    const Standard_Real theTol,
-   Handle(BOPInt_Context)& theContext)
+   Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bDegenerated;
   Standard_Integer aNbF, iRet, iFound;
@@ -633,7 +651,8 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
         break;
       }
       //
-      iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1, theContext);
+      iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF1, 
+                                              theContext);
       break;
     }
     //
@@ -643,7 +662,8 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
       //
       if (aF2.IsSame(aF1) && BRep_Tool::IsClosed(aE, aF1)) {
         // treat as it was for 1 face
-        iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2, theContext);
+        iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aF1, aF2, 
+                                                theContext);
         break;
       }
     }
@@ -653,7 +673,8 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
       return iRet; // it can not be so
     }
     else { // aNbF=2,4,6,8,...
-      iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF, theContext);
+      iRet=BOPTools_AlgoTools::IsInternalFace(theFace, aE, aLF, 
+                                              theContext);
       break;
     }
   }//for(; aExp.More(); aExp.Next()) {
@@ -675,7 +696,8 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
   //
   BOPTools::MapShapes(theSolid, TopAbs_EDGE, aBounds);
   //
-  aState=BOPTools_AlgoTools::ComputeState(theFace, theSolid, theTol, aBounds, theContext);
+  aState=BOPTools_AlgoTools::ComputeState(theFace, theSolid, 
+                                          theTol, aBounds, theContext);
   //
   iRet=(aState==TopAbs_IN)? 1 : 0;
   //
@@ -685,10 +707,11 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
 //function : IsInternalFace
 //purpose  : 
 //=======================================================================
-Standard_Integer BOPTools_AlgoTools::IsInternalFace(const TopoDS_Face& theFace,
-                                                    const TopoDS_Edge& theEdge,
-                                                    BOPCol_ListOfShape& theLF,
-                                                    Handle(BOPInt_Context)& theContext)
+Standard_Integer BOPTools_AlgoTools::IsInternalFace
+  (const TopoDS_Face& theFace,
+   const TopoDS_Edge& theEdge,
+   BOPCol_ListOfShape& theLF,
+   Handle(IntTools_Context)& theContext)
 {
   Standard_Integer aNbF, iRet;
   //
@@ -698,7 +721,8 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace(const TopoDS_Face& theFace,
   if (aNbF==2) {
     const TopoDS_Face& aF1=(*(TopoDS_Face*)(&theLF.First()));
     const TopoDS_Face& aF2=(*(TopoDS_Face*)(&theLF.Last()));
-    iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
+    iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, 
+                                            theContext);
     return iRet;
   }
   //
@@ -714,7 +738,8 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace(const TopoDS_Face& theFace,
       //
       const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aCSFF.Shape1()));
       const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCSFF.Shape2()));
-      iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, theContext);
+      iRet=BOPTools_AlgoTools::IsInternalFace(theFace, theEdge, aF1, aF2, 
+                                              theContext);
       if (iRet) {
         return iRet;
       }
@@ -731,7 +756,7 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
    const TopoDS_Edge& theEdge,
    const TopoDS_Face& theFace1,
    const TopoDS_Face& theFace2,
-   Handle(BOPInt_Context)& theContext)
+   Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bRet;
   Standard_Integer iRet;
@@ -785,11 +810,11 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
    const TopoDS_Face& theF1,
    BOPTools_ListOfCoupleOfShape& theLCSOff,
    TopoDS_Face& theFOff,
-   Handle(BOPInt_Context)& theContext)
+   Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bRet;
-  Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin;
-  Standard_Real aUmin, aUsup, aVmin, aVsup;
+  Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin, aDt3D;
+  Standard_Real aUmin, aUsup, aVmin, aVsup, aPA;
   gp_Pnt aPn1, aPn2, aPx;
   gp_Dir aDN1, aDN2, aDBF, aDBF2, aDTF;
   gp_Vec aVTgt;
@@ -799,6 +824,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
   BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
   GeomAPI_ProjectPointOnSurf aProjPL;
   //
+  aPA=Precision::Angular();
   aAngleMin=100.;
   aTwoPI=M_PI+M_PI;
   aC3D =BRep_Tool::Curve(theE1, aT1, aT2);
@@ -813,7 +839,9 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
   aPL->Bounds(aUmin, aUsup, aVmin, aVsup);
   aProjPL.Init(aPL, aUmin, aUsup, aVmin, aVsup);
   //
-  GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext, aProjPL);
+  aDt3D = MinStep3D(theE1, theF1, theLCSOff, aPx);
+  GetFaceDir(theE1, theF1, aPx, aT, aDTgt, aDN1, aDBF, theContext, 
+             aProjPL, aDt3D);
   //
   aDTF=aDN1^aDBF;
   //
@@ -825,7 +853,8 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
     const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aCS.Shape2()));
     //
     aDTgt2 = (aE2.Orientation()==aOr) ? aDTgt : aDTgt.Reversed();
-    GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext, aProjPL);
+    GetFaceDir(aE2, aF2, aPx, aT, aDTgt2, aDN2, aDBF2, theContext, 
+               aProjPL, aDt3D);
     //Angle
     aAngle=AngleWithRef(aDBF, aDBF2, aDTF);
     //
@@ -833,7 +862,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
       aAngle=aTwoPI+aAngle;
     }
     //
-    if (aAngle<Precision::Angular()) {
+    if (aAngle<aPA) {
       if (aF2==theF1) {
         aAngle=M_PI;
       }
@@ -842,6 +871,11 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
       }
     }
     //
+    if (fabs(aAngle-aAngleMin)<aPA) {
+      // the minimal angle can not be found
+      bRet=Standard_False; 
+    }
+    //
     if (aAngle<aAngleMin){
       aAngleMin=aAngle;
       theFOff=aF2;
@@ -888,9 +922,10 @@ Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
 //function : AreFacesSameDomain
 //purpose  : 
 //=======================================================================
-Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain(const TopoDS_Face& theF1,
-                                                        const TopoDS_Face& theF2,
-                                                        Handle(BOPInt_Context)& theContext)
+Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
+  (const TopoDS_Face& theF1,
+   const TopoDS_Face& theF2,
+   Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bFlag;
   Standard_Integer iErr;
@@ -922,7 +957,8 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain(const TopoDS_Face& theF1
   aTolF2=BRep_Tool::Tolerance(aF2);
   aTol=aTolF1+aTolF2;
   //
-  iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D, theContext);
+  iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D,
+                                           theContext);
   if (!iErr) {
     bFlag=theContext->IsValidPointForFace(aP, aF2, aTol);
   }
@@ -934,9 +970,10 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain(const TopoDS_Face& theF1
 //function : CheckSameGeom
 //purpose  : 
 //=======================================================================
-Standard_Boolean BOPTools_AlgoTools::CheckSameGeom(const TopoDS_Face& theF1,
-                                                   const TopoDS_Face& theF2,
-                                                   Handle(BOPInt_Context)& theContext)
+Standard_Boolean BOPTools_AlgoTools::CheckSameGeom
+  (const TopoDS_Face& theF1,
+   const TopoDS_Face& theF2,
+   Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bRet;
   Standard_Real aTolF1, aTolF2, aTol;
@@ -1009,9 +1046,10 @@ Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
 // function: IsSplitToReverse
 // purpose: 
 //=======================================================================
-Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Shape& theSp,
-                                                      const TopoDS_Shape& theSr,
-                                                      Handle(BOPInt_Context)& theContext)
+Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
+  (const TopoDS_Shape& theSp,
+   const TopoDS_Shape& theSr,
+   Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bRet;
   TopAbs_ShapeEnum aType;
@@ -1043,9 +1081,10 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Shape& theSp,
 //function :IsSplitToReverse
 //purpose  : 
 //=======================================================================
-Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Face& theFSp,
-                                                      const TopoDS_Face& theFSr,
-                                                      Handle(BOPInt_Context)& theContext)
+Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
+  (const TopoDS_Face& theFSp,
+   const TopoDS_Face& theFSr,
+   Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bRet, bFound, bInFace;
   Standard_Real aT1, aT2, aT, aU, aV, aScPr;
@@ -1084,7 +1123,8 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Face& theFSp,
     Standard_Integer iErr;
     gp_Pnt2d aP2DFSp;
     //
-    iErr=BOPTools_AlgoTools3D::PointInFace(theFSp, aPFSp, aP2DFSp, theContext);
+    iErr=BOPTools_AlgoTools3D::PointInFace(theFSp, aPFSp, aP2DFSp, 
+                                           theContext);
     if (iErr) {
       return bRet;
     }
@@ -1094,11 +1134,17 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Face& theFSp,
     if (!bFlag) {
       return bRet;
     }
+    //
+    if (theFSp.Orientation()==TopAbs_REVERSED){
+      aDNFSp.Reverse();
+    }
   }
   else {
     BRep_Tool::Range(aESp, aT1, aT2);
     aT=BOPTools_AlgoTools2D::IntermediatePoint(aT1, aT2);
-    BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT, aPFSp, aDNFSp, theContext);
+    BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aESp, theFSp, aT, 
+                                                      aPFSp, aDNFSp, 
+                                                      theContext);
   }
   //
   // Parts of theContext->ComputeVS(..) 
@@ -1110,7 +1156,7 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Face& theFSp,
   //
   aProjector.LowerDistanceParameters(aU, aV);
   gp_Pnt2d aP2D(aU, aV);
-  bInFace=theContext->IsPointInFace (theFSr, aP2D);
+  bInFace=theContext->IsPointInOnFace (theFSr, aP2D);
   if (!bInFace) {
     return bRet;
   }
@@ -1132,9 +1178,10 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Face& theFSp,
 //function :IsSplitToReverse
 //purpose  : 
 //=======================================================================
-Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse(const TopoDS_Edge& aEF1,
-                                                      const TopoDS_Edge& aEF2,
-                                                      Handle(BOPInt_Context)& theContext)
+Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
+  (const TopoDS_Edge& aEF1,
+   const TopoDS_Edge& aEF2,
+   Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bRet, bIsDegenerated;
   //
@@ -1322,7 +1369,8 @@ void BOPTools_AlgoTools::MakePCurve(const TopoDS_Edge& aE,
   aTolE=BRep_Tool::Tolerance(aE);
   //
   const Handle(Geom_Curve)& aC3DE=BRep_Tool::Curve(aE, aT1, aT2);
-  Handle(Geom_TrimmedCurve)aC3DETrim=new Geom_TrimmedCurve(aC3DE, aT1, aT2);
+  Handle(Geom_TrimmedCurve)aC3DETrim=
+    new Geom_TrimmedCurve(aC3DE, aT1, aT2);
   //
   for (i=0; i<2; ++i) {
     bPC = !i ? bPC1 : bPC2;
@@ -1350,10 +1398,12 @@ void BOPTools_AlgoTools::MakePCurve(const TopoDS_Edge& aE,
       }
     //
     if (aC3DE->IsPeriodic()) {
-      BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aT1, aT2,  aC2D, aC2DA); 
+      BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aT1, aT2,  aC2D, 
+                                               aC2DA); 
     }
     else {
-      BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D, aC2DA); 
+      BOPTools_AlgoTools2D::AdjustPCurveOnFace(aFFWD, aC3DETrim, aC2D, 
+                                               aC2DA); 
     }
     //
     aBB.UpdateEdge(aE, aC2DA, aFFWD, aTolE);
@@ -1376,7 +1426,8 @@ void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
   Standard_Real aTolV;
   BRep_Builder aBB;
   //
-  BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2, theE);
+  BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2, 
+                                    theE);
   //
   aBB.UpdateEdge(theE, theTolR3D);
   //
@@ -1446,13 +1497,67 @@ void BOPTools_AlgoTools::MakeVertex(BOPCol_ListOfShape& aLV,
                                     TopoDS_Vertex& aVnew)
 {
   Standard_Integer aNb;
-  Standard_Real aTi, aDi, aDmax;
-  gp_Pnt aPi, aP;
-  gp_XYZ aXYZ(0.,0.,0.), aXYZi;
-  BOPCol_ListIteratorOfListOfShape aIt;
   //
   aNb=aLV.Extent();
-  if (aNb) {
+  if (!aNb) {
+    return;
+  }
+  //
+  else if (aNb==1) {
+    aVnew=*((TopoDS_Vertex*)(&aLV.First()));
+    return;
+  }
+  //
+  else if (aNb==2) {
+    Standard_Integer m, n;
+    Standard_Real aR[2], dR, aD, aEps;
+    TopoDS_Vertex aV[2];
+    gp_Pnt aP[2];
+    BRep_Builder aBB;
+    //
+    aEps=RealEpsilon();
+    for (m=0; m<aNb; ++m) {
+      aV[m]=(!m)? 
+       *((TopoDS_Vertex*)(&aLV.First())):
+       *((TopoDS_Vertex*)(&aLV.Last()));
+      aP[m]=BRep_Tool::Pnt(aV[m]);
+      aR[m]=BRep_Tool::Tolerance(aV[m]);
+    }  
+    //
+    m=0; // max R
+    n=1; // min R
+    if (aR[0]<aR[1]) {
+      m=1;
+      n=0;
+    }
+    //
+    dR=aR[m]-aR[n]; // dR >= 0.
+    gp_Vec aVD(aP[m], aP[n]);
+    aD=aVD.Magnitude();
+    //
+    if (aD<=dR || aD<aEps) { 
+      aBB.MakeVertex (aVnew, aP[m], aR[m]);
+    }
+    else {
+      Standard_Real aRr;
+      gp_XYZ aXYZr;
+      gp_Pnt aPr;
+      //
+      aRr=0.5*(aR[m]+aR[n]+aD);
+      aXYZr=0.5*(aP[m].XYZ()+aP[n].XYZ()-aVD.XYZ()*(dR/aD));
+      aPr.SetXYZ(aXYZr);
+      //
+      aBB.MakeVertex (aVnew, aPr, aRr);
+    }
+    return;
+  }// else if (aNb==2) {
+  //
+  else { // if (aNb>2) 
+    Standard_Real aTi, aDi, aDmax;
+    gp_Pnt aPi, aP;
+    gp_XYZ aXYZ(0.,0.,0.), aXYZi;
+    BOPCol_ListIteratorOfListOfShape aIt;
+    //
     aIt.Initialize(aLV);
     for (; aIt.More(); aIt.Next()) {
       TopoDS_Vertex& aVi=*((TopoDS_Vertex*)(&aIt.Value()));
@@ -1486,9 +1591,10 @@ void BOPTools_AlgoTools::MakeVertex(BOPCol_ListOfShape& aLV,
 //function : GetEdgeOnFace
 //purpose  : 
 //=======================================================================
-Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace(const TopoDS_Edge& theE1,
-                                                   const TopoDS_Face& theF2,
-                                                   TopoDS_Edge& theE2)
+Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace
+(const TopoDS_Edge& theE1,
+ const TopoDS_Face& theF2,
+ TopoDS_Edge& theE2)
 {
   Standard_Boolean bFound;
   TopoDS_Iterator aItF, aItW;
@@ -1517,7 +1623,7 @@ Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace(const TopoDS_Edge& theE1,
 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
                                 const BOPCol_ListOfShape& thLF,
                                 BOPTools_ListOfCoupleOfShape& theLCFF,
-                                Handle(BOPInt_Context)& theContext)
+                                Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bFound;
   Standard_Integer i, aNbCEF;
@@ -1639,10 +1745,11 @@ Standard_Real AngleWithRef(const gp_Dir& theD1,
 // function: IsBlockInOnFace
 // purpose: 
 //=======================================================================
-Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace (const IntTools_Range& aShrR,
-                                                      const TopoDS_Face& aF,
-                                                      const TopoDS_Edge& aE1,
-                                                      Handle(BOPInt_Context)& aContext)
+Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace
+  (const IntTools_Range& aShrR,
+   const TopoDS_Face& aF,
+   const TopoDS_Edge& aE1,
+   Handle(IntTools_Context)& aContext)
 {
   Standard_Boolean bFlag;
   Standard_Real f1, l1, ULD, VLD;
@@ -1729,8 +1836,9 @@ Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace (const IntTools_Range& aShr
 //function : IsMicroEdge
 //purpose  : 
 //=======================================================================
-Standard_Boolean BOPTools_AlgoTools::IsMicroEdge(const TopoDS_Edge& aE,
-                                                 const Handle(BOPInt_Context)& aCtx) 
+Standard_Boolean BOPTools_AlgoTools::IsMicroEdge
+  (const TopoDS_Edge& aE,
+   const Handle(IntTools_Context)& aCtx) 
 {
   Standard_Boolean bRet;
   Standard_Integer iErr;
@@ -1754,8 +1862,9 @@ Standard_Boolean BOPTools_AlgoTools::IsMicroEdge(const TopoDS_Edge& aE,
     aT2=aTmp;
   }
   //
-  BOPInt_ShrunkRange aSR;
-  aSR.SetData(aE, aT1, aT2, aV1, aV2, aCtx);
+  IntTools_ShrunkRange aSR;
+  aSR.SetContext(aCtx);
+  aSR.SetData(aE, aT1, aT2, aV1, aV2);
   aSR.Perform();
   iErr=aSR.ErrorStatus();
   bRet = !(iErr==0);
@@ -1774,92 +1883,79 @@ void GetFaceDir(const TopoDS_Edge& aE,
                 const gp_Dir& aDTgt,
                 gp_Dir& aDN,
                 gp_Dir& aDB,
-                Handle(BOPInt_Context)& theContext,
-                GeomAPI_ProjectPointOnSurf& aProjPL)
+                Handle(IntTools_Context)& theContext,
+                GeomAPI_ProjectPointOnSurf& aProjPL,
+                const Standard_Real aDt)
 {
+  Standard_Real aTolE;
+  gp_Pnt aPx;
+  //
   BOPTools_AlgoTools3D::GetNormalToFaceOnEdge(aE, aF, aT, aDN);
   if (aF.Orientation()==TopAbs_REVERSED){
     aDN.Reverse();
   }
+  //
+  aTolE=BRep_Tool::Tolerance(aE); 
   aDB = aDN^aDTgt;
   //
-  gp_Pnt aPx;
-  if (!FindPointInFace(aE, aF, aP, aDB, aPx, theContext, aProjPL)) {
-    BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aE, aF, aT, aPx, aDN, theContext);
+  if (!FindPointInFace(aF, aP, aDB, aPx, theContext, aProjPL, aDt, aTolE)) {
+    BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge(aE, aF, aT, aPx, 
+                                                      aDN, theContext);
     aProjPL.Perform(aPx);
     aPx = aProjPL.NearestPoint();
     gp_Vec aVec(aP, aPx);
     aDB.SetXYZ(aVec.XYZ());
   }
 }
-
 //=======================================================================
 //function : FindPointInFace
 //purpose  : Find a point in the face in direction of <aDB>
 //=======================================================================
-Standard_Boolean FindPointInFace(const TopoDS_Edge& aE,
-                                 const TopoDS_Face& aF,
+Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
                                  const gp_Pnt& aP,
                                  gp_Dir& aDB,
                                  gp_Pnt& aPOut,
-                                 Handle(BOPInt_Context)& theContext,
-                                 GeomAPI_ProjectPointOnSurf& aProjPL) 
+                                 Handle(IntTools_Context)& theContext,
+                                 GeomAPI_ProjectPointOnSurf& aProjPL,
+                                 const Standard_Real aDt,
+                                 const Standard_Real aTolE)
 {
   Standard_Integer aNbItMax;
-  Standard_Real aDt, aDtMin, aTolE, aTolF, aDist;
+  Standard_Real aDist, aDTol, aPM, anEps;
   Standard_Boolean bRet;
-  gp_Pnt aP1;
-  BRepAdaptor_Surface aBAS;
+  gp_Pnt aP1, aPS;
   //
-  bRet = Standard_False;
-  aTolE = BRep_Tool::Tolerance(aE);
-  aTolF = BRep_Tool::Tolerance(aF);
-  aDt = 2*(aTolE+aTolF);
-  aBAS.Initialize(aF, Standard_False);
-  //
-  aDtMin=5.e-4;
-  if (aDt < aDtMin) {
-    Standard_Real aR;
-    GeomAbs_SurfaceType aSType=aBAS.GetType();
-    switch (aSType) {
-    case GeomAbs_Cylinder:
-      aR = aBAS.Cylinder().Radius();
-      break;
-    case GeomAbs_Cone: {
-      gp_Lin aL(aBAS.Cone().Axis());
-      aR = aL.Distance(aP);
-      break;
-    }
-    case GeomAbs_Sphere:
-      aR = aBAS.Sphere().Radius();
-      break;
-    case GeomAbs_Torus:
-      aR = aBAS.Torus().MinorRadius();
-      break;
-    case GeomAbs_SurfaceOfRevolution:
-      aR=1.;
-      break;
-    default:
-      aR=0.001;
-    }
-    if (aR < 0.01) {
-      aDtMin=5.e-6;
-    }
-    else if (aR > 100.) {
-      aDtMin*=10;
-    }
-    if (aDt < aDtMin) {
-      aDt=aDtMin;
-    }
+  aDTol = Precision::Angular();
+  aPM = aP.XYZ().Modulus();
+  if (aPM > 1000.) {
+    aDTol = 5.e-16 * aPM;
   }
+  bRet = Standard_False;
+  aNbItMax = 15;
+  anEps = Precision::SquareConfusion();
   //
   GeomAPI_ProjectPointOnSurf& aProj=theContext->ProjPS(aF);
-  aNbItMax = 15;
+  //
+  aPS=aP;
+  aProj.Perform(aPS);
+  if (!aProj.IsDone()) {
+    return bRet;
+  }
+  aPS=aProj.NearestPoint();
+  aProjPL.Perform(aPS);
+  aPS=aProjPL.NearestPoint();
+  //
+  aPS.SetXYZ(aPS.XYZ()+2.*aTolE*aDB.XYZ());
+  aProj.Perform(aPS);
+  if (!aProj.IsDone()) {
+    return bRet;
+  }
+  aPS=aProj.NearestPoint();
+  aProjPL.Perform(aPS);
+  aPS=aProjPL.NearestPoint();
   //
   do {
-    aP1.SetCoord(aP.X()+aDt*aDB.X(),
-                 aP.Y()+aDt*aDB.Y(),
-                 aP.Z()+aDt*aDB.Z());
+    aP1.SetXYZ(aPS.XYZ()+aDt*aDB.XYZ());
     //
     aProj.Perform(aP1);
     if (!aProj.IsDone()) {
@@ -1871,19 +1967,96 @@ Standard_Boolean FindPointInFace(const TopoDS_Edge& aE,
     aProjPL.Perform(aPOut);
     aPOut = aProjPL.NearestPoint();
     //
-    gp_Vec aV(aP, aPOut);
+    gp_Vec aV(aPS, aPOut);
+    if (aV.SquareMagnitude() < anEps) {
+      return bRet;
+    }
     aDB.SetXYZ(aV.XYZ());
-  } while (aDist>Precision::Angular() && --aNbItMax);
+  } while (aDist > aDTol && --aNbItMax);
   //
-  bRet = aDist < Precision::Angular();
+  bRet = aDist < aDTol;
   return bRet;
 }
 //=======================================================================
+//function : MinStep3D
+//purpose  : 
+//=======================================================================
+Standard_Real MinStep3D(const TopoDS_Edge& theE1,
+                        const TopoDS_Face& theF1,
+                        const BOPTools_ListOfCoupleOfShape& theLCS,
+                        const gp_Pnt& aP)
+{
+  Standard_Real aDt, aTolE, aTolF, aDtMax, aDtMin, aR;
+  BOPTools_CoupleOfShape aCS1;
+  BOPTools_ListOfCoupleOfShape aLCS;
+  BOPTools_ListIteratorOfListOfCoupleOfShape aIt;
+  BRepAdaptor_Surface aBAS;
+  //
+  aLCS = theLCS;
+  aCS1.SetShape1(theE1);
+  aCS1.SetShape2(theF1);
+  aLCS.Append(aCS1);
+  //
+  aTolE = BRep_Tool::Tolerance(theE1);
+  aDtMax = -1.;
+  aDtMin = 5.e-6;
+  //
+  aIt.Initialize(aLCS);
+  for (; aIt.More(); aIt.Next()) {
+    const BOPTools_CoupleOfShape& aCS = aIt.Value();
+    const TopoDS_Face& aF = (*(TopoDS_Face*)(&aCS.Shape2()));
+    //
+    aTolF = BRep_Tool::Tolerance(aF);
+    aDt = 2*(aTolE + aTolF);
+    //
+    aR = 0.;
+    aBAS.Initialize(aF, Standard_False);
+    GeomAbs_SurfaceType aSType = aBAS.GetType();
+    switch (aSType) {
+    case GeomAbs_Cylinder: {
+      aR = aBAS.Cylinder().Radius();
+      break;
+    }
+    case GeomAbs_Cone: {
+      gp_Lin aL(aBAS.Cone().Axis());
+      aR = aL.Distance(aP);
+      break;
+    }
+    case GeomAbs_Sphere: {
+      aDtMin = Max(aDtMin, 5.e-4);
+      aR = aBAS.Sphere().Radius();
+      break;
+    }
+    case GeomAbs_Torus: {
+      aR = aBAS.Torus().MajorRadius();
+      break;
+    }
+    default:
+      aDtMin = Max(aDtMin, 5.e-4);
+      break;
+    }
+    //
+    if (aR > 100.) {
+      Standard_Real d = 10*Precision::PConfusion();
+      aDtMin = Max(aDtMin, sqrt(d*d + 2*d*aR));
+    }
+    //
+    if (aDt > aDtMax) {
+      aDtMax = aDt;
+    }
+  }
+  //
+  if (aDtMax < aDtMin) {
+    aDtMax = aDtMin;
+  }
+  //
+  return aDtMax;
+}
+//=======================================================================
 //function : IsOpenShell
 //purpose  : 
 //=======================================================================
-Standard_Boolean 
-  BOPTools_AlgoTools::IsOpenShell(const TopoDS_Shell& aSh)
+Standard_Boolean BOPTools_AlgoTools::IsOpenShell(const TopoDS_Shell& aSh)
 {
   Standard_Boolean bRet;
   Standard_Integer i, aNbE, aNbF;
@@ -1909,7 +2082,7 @@ Standard_Boolean
       const TopoDS_Shape& aF=aItLS.Value();
       aOrF=aF.Orientation();
       if (aOrF==TopAbs_INTERNAL || aOrF==TopAbs_EXTERNAL) {
-       continue;
+        continue;
       }
       ++aNbF;
     }
@@ -1926,8 +2099,8 @@ Standard_Boolean
 //function : IsInvertedSolid
 //purpose  : 
 //=======================================================================
-Standard_Boolean 
-  BOPTools_AlgoTools::IsInvertedSolid(const TopoDS_Solid& aSolid)
+Standard_Boolean BOPTools_AlgoTools::IsInvertedSolid
+  (const TopoDS_Solid& aSolid)
 {
   Standard_Real aTolS;
   TopAbs_State aState;