0028599: Replacement of old Boolean operations with new ones in BRepProj_Projection...
[occt.git] / src / BOPAlgo / BOPAlgo_PaveFiller_5.cxx
index fa44303..7aa22d1 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-#include <BOPAlgo_PaveFiller.ixx>
-
-#include <NCollection_IncAllocator.hxx>
 
 #include <Bnd_Box.hxx>
-
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <BRep_Tool.hxx>
-
-#include <IntTools_EdgeFace.hxx>
-#include <IntTools_Range.hxx>
-#include <IntTools_SequenceOfCommonPrts.hxx>
-#include <IntTools_CommonPrt.hxx>
-#include <BOPTools_AlgoTools.hxx>
-
-#include <BOPCol_MapOfInteger.hxx>
-
-#include <BOPInt_Context.hxx>
-
+#include <BOPAlgo_PaveFiller.hxx>
+#include <BOPAlgo_Alerts.hxx>
+#include <BOPAlgo_Tools.hxx>
+#include <BOPDS_CommonBlock.hxx>
+#include <BOPDS_CoupleOfPaveBlocks.hxx>
+#include <BOPDS_Curve.hxx>
+#include <BOPDS_DS.hxx>
 #include <BOPDS_Interf.hxx>
 #include <BOPDS_Iterator.hxx>
-#include <BOPDS_PaveBlock.hxx>
 #include <BOPDS_MapOfPaveBlock.hxx>
-#include <BOPDS_DataMapOfPaveBlockListOfInteger.hxx>
-#include <BOPDS_CommonBlock.hxx>
 #include <BOPDS_Pave.hxx>
-
+#include <BOPDS_PaveBlock.hxx>
 #include <BOPTools_AlgoTools.hxx>
-#include <BOPDS_CoupleOfPaveBlocks.hxx>
-#include <BRepBndLib.hxx>
-#include <BOPAlgo_Tools.hxx>
-#include <BOPInt_Tools.hxx>
-#include <BRepAdaptor_Curve.hxx>
+#include <BOPTools_Parallel.hxx>
 #include <BRep_Builder.hxx>
-#include <GeomAPI_ProjectPointOnSurf.hxx>
+#include <BRep_Tool.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <gp_Pnt.hxx>
+#include <IntTools_CommonPrt.hxx>
+#include <IntTools_Context.hxx>
+#include <IntTools_EdgeFace.hxx>
+#include <IntTools_Range.hxx>
+#include <IntTools_SequenceOfCommonPrts.hxx>
+#include <IntTools_Tools.hxx>
+#include <NCollection_Vector.hxx>
+#include <Precision.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
 
+//=======================================================================
+//class    : BOPAlgo_EdgeFace
+//purpose  : 
+//=======================================================================
+class BOPAlgo_EdgeFace : 
+  public IntTools_EdgeFace,
+  public BOPAlgo_Algo {
+ public:
+  DEFINE_STANDARD_ALLOC
+  
+  BOPAlgo_EdgeFace() : 
+    IntTools_EdgeFace(), 
+    BOPAlgo_Algo(),
+    myIE(-1), myIF(-1) {
+  };
+  //
+  virtual ~BOPAlgo_EdgeFace(){
+  };
+  //
+  void SetIndices(const Standard_Integer nE,
+                  const Standard_Integer nF) {
+    myIE=nE;
+    myIF=nF;
+  }
+  //
+  void Indices(Standard_Integer& nE,
+               Standard_Integer& nF) {
+    nE=myIE;
+    nF=myIF;
+  }
+  //
+  void SetNewSR(const IntTools_Range& aR){
+    myNewSR=aR;
+  }
+  //
+  IntTools_Range& NewSR(){
+    return myNewSR;
+  }
+  //
+  void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
+    myPB=aPB;
+  }
+  //
+  Handle(BOPDS_PaveBlock)& PaveBlock() {
+    return myPB;
+  }
+  //
+  void SetFuzzyValue(const Standard_Real theFuzz) {
+    IntTools_EdgeFace::SetFuzzyValue(theFuzz);
+  }
+  //
+  virtual void Perform() {
+    BOPAlgo_Algo::UserBreak();
+    try
+    {
+      OCC_CATCH_SIGNALS
 
+      IntTools_EdgeFace::Perform();
+    }
+    catch (Standard_Failure)
+    {
+      AddError(new BOPAlgo_AlertIntersectionFailed);
+    }
+  }
+  //
+ protected:
+  Standard_Integer myIE;
+  Standard_Integer myIF;
+  IntTools_Range myNewSR;
+  Handle(BOPDS_PaveBlock) myPB;
+};
+//
+//=======================================================================
+typedef NCollection_Vector<BOPAlgo_EdgeFace> BOPAlgo_VectorOfEdgeFace; 
+//
+typedef BOPTools_ContextFunctor 
+  <BOPAlgo_EdgeFace,
+  BOPAlgo_VectorOfEdgeFace,
+  Handle(IntTools_Context), 
+  IntTools_Context> BOPAlgo_EdgeFaceFunctor;
+//
+typedef BOPTools_ContextCnt 
+  <BOPAlgo_EdgeFaceFunctor,
+  BOPAlgo_VectorOfEdgeFace,
+  Handle(IntTools_Context)> BOPAlgo_EdgeFaceCnt;
+//
 //=======================================================================
 //function : PerformEF
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_PaveFiller::PerformEF()
+void BOPAlgo_PaveFiller::PerformEF()
 {
-  Standard_Integer iSize;
-  //
-  myErrorStatus=0;
+  FillShrunkData(TopAbs_EDGE, TopAbs_FACE);
   //
   myIterator->Initialize(TopAbs_EDGE, TopAbs_FACE);
-  iSize=myIterator->ExpectedLength();
+  Standard_Integer iSize = myIterator->ExpectedLength();
   if (!iSize) {
     return; 
   }
-  //----------------------------------------------------------------------
-  Standard_Boolean bJustAdd, bV[2];
-  Standard_Integer nE, nF, aDiscretize, i, aNbCPrts, iX, nV[2];
-  Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2, aDeflection;
-  Handle(NCollection_IncAllocator) aAllocator;
+  //
+  Standard_Integer nE, nF;
+  //
+  if (myGlue == BOPAlgo_GlueFull) {
+    // there is no need to intersect edges with faces in this mode
+    // just initialize FaceInfo for faces
+    for (; myIterator->More(); myIterator->Next()) {
+      myIterator->Value(nE, nF);
+      if (!myDS->ShapeInfo(nE).HasFlag()) {
+        myDS->ChangeFaceInfo(nF);
+      }
+    }
+    return;
+  }
+  //
+  Standard_Boolean bV[2], bIsPBSplittable;
+  Standard_Boolean bV1, bV2, bExpressCompute;
+  Standard_Integer nV1, nV2;
+  Standard_Integer i, aNbCPrts, iX, nV[2];
+  Standard_Integer aNbEdgeFace, k;
+  Standard_Real aTolE, aTolF, aTS1, aTS2, aT1, aT2;
+  Handle(NCollection_BaseAllocator) aAllocator;
   TopAbs_ShapeEnum aType;
   BOPDS_ListIteratorOfListOfPaveBlock aIt;
+  BOPAlgo_VectorOfEdgeFace aVEdgeFace; 
   //-----------------------------------------------------scope f
   //
-  BRep_Builder aBB;
+  aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
   //
-  aAllocator=new NCollection_IncAllocator();
-  
-  BOPCol_MapOfInteger aMIEFC(100, aAllocator);
+  TColStd_MapOfInteger aMIEFC(100, aAllocator);
   BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMVCPB(100, aAllocator);
   BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, aAllocator);
-  //
-  aDiscretize=35;
-  aDeflection=0.01;
+  BOPAlgo_DataMapOfPaveBlockBndBox aDMPBBox(100, aAllocator);
   //
   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
-  aEFs.SetStartSize(iSize);
   aEFs.SetIncrement(iSize);
-  aEFs.Init();
   //
   for (; myIterator->More(); myIterator->Next()) {
-    myIterator->Value(nE, nF, bJustAdd);
-    if(bJustAdd) {
-      continue;
-    }
+    myIterator->Value(nE, nF);
     //
     const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
     if (aSIE.HasFlag()){//degenerated 
     //
     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
     const BOPDS_IndexedMapOfPaveBlock& aMPBF=aFI.PaveBlocksOn();
-    const BOPCol_MapOfInteger& aMIFOn=aFI.VerticesOn();
-    const BOPCol_MapOfInteger& aMIFIn=aFI.VerticesIn();
+    //
+    const TColStd_MapOfInteger& aMVIn=aFI.VerticesIn();
+    const TColStd_MapOfInteger& aMVOn=aFI.VerticesOn();
     //
     aTolE=BRep_Tool::Tolerance(aE);
     aTolF=BRep_Tool::Tolerance(aF);
         continue;
       }
       //
-      if (!aPB->HasShrunkData()) {
-        FillShrunkData(aPB);
-        if (myWarningStatus) {
-          continue;
-        }
-      }
-      //
       Bnd_Box aBBE;
-      aPB->ShrunkData(aTS1, aTS2, aBBE);
+      if (!GetPBBox(aE, aPB, aDMPBBox, aT1, aT2, aTS1, aTS2, aBBE)) {
+        continue;
+      }
       //
       if (aBBF.IsOut (aBBE)) {
         continue;
       }
       //
-      // -----------f
-      IntTools_EdgeFace aEdgeFace;
+      aPBR->Indices(nV1, nV2);
+      bV1=aMVIn.Contains(nV1) || aMVOn.Contains(nV1);
+      bV2=aMVIn.Contains(nV2) || aMVOn.Contains(nV2);
+      bExpressCompute=bV1 && bV2;
+      //
+      BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace.Appended();
+      //
+      aEdgeFace.SetIndices(nE, nF);
+      aEdgeFace.SetPaveBlock(aPB);
       //
       aEdgeFace.SetEdge (aE);
       aEdgeFace.SetFace (aF);
-      aEdgeFace.SetTolE (aTolE);
-      aEdgeFace.SetTolF (aTolF);
-      aEdgeFace.SetDiscretize (aDiscretize);
-      aEdgeFace.SetDeflection (aDeflection);
-      aEdgeFace.SetContext(myContext);
+      aEdgeFace.SetFuzzyValue(myFuzzyValue);
+      aEdgeFace.UseQuickCoincidenceCheck(bExpressCompute);
       //
       IntTools_Range aSR(aTS1, aTS2);
       IntTools_Range anewSR=aSR;
       BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, anewSR);
+      aEdgeFace.SetNewSR(anewSR);
       //
-      aPB->Range(aT1, aT2);
       IntTools_Range aPBRange(aT1, aT2);
       aSR = aPBRange;
       BOPTools_AlgoTools::CorrectRange(aE, aF, aSR, aPBRange);
-      //
       aEdgeFace.SetRange (aPBRange);
+      aEdgeFace.SetProgressIndicator(myProgressIndicator);
       //
-      aEdgeFace.Perform();
-      if (!aEdgeFace.IsDone()) {
-        continue;
-      }
-      //
-      aPB->Indices(nV[0], nV[1]);
-      //
-      const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeFace.CommonParts();
-      aNbCPrts=aCPrts.Length();
-      for (i=1; i<=aNbCPrts; ++i) {
-        const IntTools_CommonPrt& aCPart=aCPrts(i);
-        aType=aCPart.Type();
-        switch (aType) {
-        case TopAbs_VERTEX:  {
+    }//for (; aIt.More(); aIt.Next()) {
+  }//for (; myIterator->More(); myIterator->Next()) {
+  //
+  aNbEdgeFace=aVEdgeFace.Length();
+  //=================================================================
+  BOPAlgo_EdgeFaceCnt::Perform(myRunParallel, aVEdgeFace, myContext);
+  //=================================================================
+  //
+  for (k=0; k < aNbEdgeFace; ++k) {
+    BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace(k);
+    if (!aEdgeFace.IsDone() || aEdgeFace.HasErrors()) {
+      // Warn about failed intersection of sub-shapes
+      AddIntersectionFailedWarning(aEdgeFace.Edge(), aEdgeFace.Face());
+      continue;
+    }
+    //
+    const IntTools_SequenceOfCommonPrts& aCPrts=aEdgeFace.CommonParts();
+    aNbCPrts = aCPrts.Length();
+    if (!aNbCPrts) {
+      continue;
+    }
+    //
+    aEdgeFace.Indices(nE, nF);
+    //
+    const TopoDS_Edge& aE=aEdgeFace.Edge();
+    const TopoDS_Face& aF=aEdgeFace.Face();
+    //
+    aTolE=BRep_Tool::Tolerance(aE);
+    aTolF=BRep_Tool::Tolerance(aF);
+    const IntTools_Range& anewSR=aEdgeFace.NewSR();
+    Handle(BOPDS_PaveBlock)& aPB=aEdgeFace.PaveBlock();
+    //
+    aPB->Range(aT1, aT2);
+    aPB->Indices(nV[0], nV[1]);
+    bIsPBSplittable = aPB->IsSplittable();
+    //
+    anewSR.Range(aTS1, aTS2);
+    //
+    if (aCPrts(1).Type() == TopAbs_VERTEX) {
+      // for the intersection type VERTEX
+      // extend vertices ranges using Edge/Edge intersections
+      // between the edge aE and the edges of the face aF.
+      // thereby the edge's intersection range is reduced
+      ReduceIntersectionRange(nV[0], nV[1], nE, nF, aTS1, aTS2);
+    }
+    //
+    IntTools_Range aR1(aT1, aTS1), aR2(aTS2, aT2);
+    //
+    BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
+    const TColStd_MapOfInteger& aMIFOn=aFI.VerticesOn();
+    const TColStd_MapOfInteger& aMIFIn=aFI.VerticesIn();
+    //
+    Standard_Boolean bLinePlane = Standard_False;
+    if (aNbCPrts) {
+      BRepAdaptor_Curve aBAC(aE);
+      bLinePlane = (aBAC.GetType() == GeomAbs_Line &&
+                    myContext->SurfaceAdaptor(aF).GetType() == GeomAbs_Plane);
+    }
+    //
+    for (i=1; i<=aNbCPrts; ++i) {
+      const IntTools_CommonPrt& aCPart=aCPrts(i);
+      aType=aCPart.Type();
+      switch (aType) {
+        case TopAbs_VERTEX: {
           Standard_Boolean bIsOnPave[2];
           Standard_Integer j;
           Standard_Real aT, aTolToDecide; 
           TopoDS_Vertex aVnew;
-          
-          BOPInt_Tools::VertexParameter(aCPart, aT);
+          //
+          IntTools_Tools::VertexParameter(aCPart, aT);
           BOPTools_AlgoTools::MakeNewVertex(aE, aT, aF, aVnew);
           //
           const IntTools_Range& aR=aCPart.Range1();
           aTolToDecide=5.e-8;
           //
-          IntTools_Range aR1(aT1, anewSR.First()), aR2(anewSR.Last(), aT2);
-          //
-          bIsOnPave[0]=BOPInt_Tools::IsInRange(aR1, aR, aTolToDecide); 
-          bIsOnPave[1]=BOPInt_Tools::IsInRange(aR2, aR, aTolToDecide); 
+          bIsOnPave[0]=IntTools_Tools::IsInRange(aR1, aR, aTolToDecide); 
+          bIsOnPave[1]=IntTools_Tools::IsInRange(aR2, aR, aTolToDecide); 
           //
-          if (bIsOnPave[0] && bIsOnPave[1]) {
+          if ((bIsOnPave[0] && bIsOnPave[1]) || 
+              (bLinePlane && (bIsOnPave[0] || bIsOnPave[1]))) {
             bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
             bV[1]=CheckFacePaves(nV[1], aMIFOn, aMIFIn);
             if (bV[0] && bV[1]) {
-              iX=aEFs.Append()-1;
               IntTools_CommonPrt aCP = aCPart;
               aCP.SetType(TopAbs_EDGE);
-              BOPDS_InterfEF& aEF=aEFs(iX);
+              BOPDS_InterfEF& aEF=aEFs.Appended();
+              iX=aEFs.Length()-1;
               aEF.SetIndices(nE, nF);
               aEF.SetCommonPart(aCP);
               myDS->AddInterf(nE, nF);
-              // 3          
+              //
+              aMIEFC.Add(nF);
+              //           
               BOPAlgo_Tools::FillMap(aPB, nF, aMPBLI, aAllocator);
               break;
             }
           }
+          //
+          if (!bIsPBSplittable) {
+            continue;
+          }
+          //
           for (j=0; j<2; ++j) {
             if (bIsOnPave[j]) {
               bV[j]=CheckFacePaves(nV[j], aMIFOn, aMIFIn);
               if (bV[j]) {
-                const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV[j])));
-                BOPTools_AlgoTools::UpdateVertex(aE, aT, aV);
-                BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV[j]);
-                Bnd_Box& aBoxDS=aSIDS.ChangeBox();
-                BRepBndLib::Add(aV, aBoxDS);
+                const TopoDS_Vertex& aV=
+                  (*(TopoDS_Vertex *)(&myDS->Shape(nV[j])));
+                //
+                Standard_Real f, l, aTolVnew, aDistPP, aTolPC, aTolV;
+                //
+                const Handle(Geom_Curve)& aCur = BRep_Tool::Curve(aE, f, l);
+                //
+                gp_Pnt aP1 = BRep_Tool::Pnt(aV);
+                gp_Pnt aP2 = aCur->Value(aT);
+                //
+                aDistPP=aP1.Distance(aP2);
+                //
+                aTolPC=Precision::PConfusion();
+                aTolV=BRep_Tool::Tolerance(aV);
+                if (aDistPP > (aTolV+aTolPC)) {
+                  aTolVnew=Max(aTolE, aDistPP);
+                  UpdateVertex(nV[j], aTolVnew);
+                }
               }
               else {
                 bIsOnPave[j] = ForceInterfVF(nV[j], nF);
               continue;
             }
             //
+            Standard_Real aTolVnew = BRep_Tool::Tolerance(aVnew);
+            aTolVnew = Max(aTolVnew, Max(aTolE, aTolF));
+            BRep_Builder().UpdateVertex(aVnew, aTolVnew);
+            if (bLinePlane) {
+              // increase tolerance for Line/Plane intersection, but do not update 
+              // the vertex till its intersection with some other shape
+              IntTools_Range aCR = aCPart.Range1();
+              aTolVnew = Max(aTolVnew, (aCR.Last() - aCR.First()) / 2.);
+            }
+            //
             const gp_Pnt& aPnew = BRep_Tool::Pnt(aVnew);
-            if (!myContext->IsValidPointForFace(aPnew, aF, aTolE+aTolF)) {
+            //
+            if (!myContext->IsPointInFace(aPnew, aF, aTolVnew)) {
               continue;
             }
             //
-            aBB.UpdateVertex(aVnew, aTolE);
-            //
             aMIEFC.Add(nF);
             // 1
-            iX=aEFs.Append()-1;
-            BOPDS_InterfEF& aEF=aEFs(iX);
+            BOPDS_InterfEF& aEF=aEFs.Appended();
+            iX=aEFs.Length()-1;
             aEF.SetIndices(nE, nF);
             aEF.SetCommonPart(aCPart);
             // 2
             //
             aCPB.SetPaveBlocks(aPB, aPB);
             aCPB.SetIndexInterf(iX);
+            aCPB.SetTolerance(aTolVnew);
             aMVCPB.Add(aVnew, aCPB);
           }
         }
           aMIEFC.Add(nF);
           //
           // 1
-          iX=aEFs.Append()-1;
-          BOPDS_InterfEF& aEF=aEFs(iX);
+          BOPDS_InterfEF& aEF=aEFs.Appended();
+          iX=aEFs.Length()-1;
           aEF.SetIndices(nE, nF);
           //
           bV[0]=CheckFacePaves(nV[0], aMIFOn, aMIFIn);
             myDS->AddInterf(nE, nF);
             break;
           }
-          //update tolerance of edge if needed
-          if (aTolE < aTolF) {
-            myDS->UpdateEdgeTolerance(nE, aTolF);
-            aTolE = aTolF;
-          }
           aEF.SetCommonPart(aCPart);
           // 2
           myDS->AddInterf(nE, nF);
           break; 
         default:
           break; 
-        }//switch (aType) {
-      }//for (i=1; i<=aNbCPrts; ++i) {
-      // -----------t
-    }//for (; aIt.More(); aIt.Next()) {
-  }//for (; myIterator->More(); myIterator->Next()) {
+      }//switch (aType) {
+    }//for (i=1; i<=aNbCPrts; ++i) {
+  }// for (k=0; k < aNbEdgeEdge; ++k) {
   // 
   //=========================================
   // post treatment
   //=========================================
   BOPAlgo_Tools::PerformCommonBlocks(aMPBLI, aAllocator, myDS);
-  PerformVerticesEF(aMVCPB, aAllocator);
+  PerformNewVertices(aMVCPB, aAllocator, Standard_False);
   //
   // Update FaceInfoIn for all faces having EF common parts
-  BOPCol_MapIteratorOfMapOfInteger aItMI;
+  TColStd_MapIteratorOfMapOfInteger aItMI;
   aItMI.Initialize(aMIEFC);
   for (; aItMI.More(); aItMI.Next()) {
     nF=aItMI.Value();
     myDS->UpdateFaceInfoIn(nF);
   }
-  // Refine FaceInfoOn to remove all formal pave blocks 
-  // made during EF processing 
-  //myDS->RefineFaceInfoOn();
   //-----------------------------------------------------scope t
   aMIEFC.Clear();
   aMVCPB.Clear();
   aMPBLI.Clear();
-  aAllocator.Nullify();
-  //
-  
-}
-//=======================================================================
-//function : PerformVertices1
-//purpose  : 
-//=======================================================================
-  Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEF
-    (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMVCPB,
-     Handle(NCollection_BaseAllocator)& theAllocator)
-{
-  Standard_Integer aNbV, iRet;
-  //
-  iRet=0;
-  aNbV=theMVCPB.Extent();
-  if (!aNbV) {
-    return iRet;
-  }
-  //
-  Standard_Integer nVx, nVSD, iV, iErr, nE, iFlag, iX, i, aNbPBLI;
-  Standard_Real aT;
-  TopoDS_Shape aV;
-  BOPCol_ListIteratorOfListOfShape aItLS;
-  BOPCol_ListIteratorOfListOfInteger aItLI;
-  BOPDS_PDS aPDS;
-  BOPDS_ShapeInfo aSI;
-  BOPDS_Pave aPave;
-  //
-  BOPCol_ListOfShape aLS(theAllocator);
-  BOPCol_DataMapOfShapeInteger aMVI(100, theAllocator);
-  BOPDS_IndexedDataMapOfPaveBlockListOfInteger aMPBLI(100, theAllocator);
-  BOPAlgo_PaveFiller aPF(theAllocator); 
-  //
-  aSI.SetShapeType(TopAbs_VERTEX);
-  BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
-  //
-  // 1 prepare arguments
-  for (i=1; i<=aNbV; ++i) {
-    const TopoDS_Shape& aS=theMVCPB.FindKey(i);
-    aLS.Append(aS);
-  }
-  //
-  // 2 Fuse vertices
-  aPF.SetArguments(aLS);
-  aPF.Perform();
-  iErr=aPF.ErrorStatus();
-  if (iErr) {
-    iRet=1;
-    return iRet;
-  }
-  aPDS=aPF.PDS();
-  //
-  // 3 Add new vertices to theDS; 
-  // 4 Map PaveBlock/ListOfVertices to add to this PaveBlock ->aMPBLI
-  aItLS.Initialize(aLS);
-  for (; aItLS.More(); aItLS.Next()) {
-    const TopoDS_Shape& aVx=aItLS.Value();
-    nVx=aPDS->Index(aVx);
-    //
-    if (aPDS->HasShapeSD(nVx, nVSD)) {
-      aV=aPDS->Shape(nVSD);
-    }
-    else {
-      aV=aVx;
-    }
-    // index of new vertex in theDS -> iV
-    if (!aMVI.IsBound(aV)) {
-      aSI.SetShape(aV);
-      iV=myDS->Append(aSI);
-      //
-      BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(iV);
-      Bnd_Box& aBox=aSIDS.ChangeBox();
-      BRepBndLib::Add(aV, aBox);
-      //
-      aMVI.Bind(aV, iV);
-    }
-    else {
-      iV=aMVI.Find(aV);
-    }
-    //
-    BOPDS_CoupleOfPaveBlocks &aCPB=theMVCPB.ChangeFromKey(aVx);
-    aCPB.SetIndex(iV);
-    // update EF interference
-    iX=aCPB.IndexInterf();
-    BOPDS_InterfEF& aEF=aEFs(iX);
-    aEF.SetIndexNew(iV);
-    // map aMPBLI
-    const Handle(BOPDS_PaveBlock)& aPB=aCPB.PaveBlock1();
-    if (aMPBLI.Contains(aPB)) {
-      BOPCol_ListOfInteger& aLI=aMPBLI.ChangeFromKey(aPB);
-      aLI.Append(iV);
-    }
-    else {
-      BOPCol_ListOfInteger aLI(theAllocator);
-      aLI.Append(iV);
-      aMPBLI.Add(aPB, aLI);
-    }
-  }
-  //
-  // 5 
-  // 5.1  Compute Extra Paves and 
-  // 5.2. Add Extra Paves to the PaveBlocks
-  aNbPBLI=aMPBLI.Extent();
-  for (i=1; i<=aNbPBLI; ++i) {
-    Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
-    const BOPCol_ListOfInteger& aLI=aMPBLI.FindFromIndex(i);
-    nE=aPB->OriginalEdge();
-    const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
-    // 
-    aItLI.Initialize(aLI);
-    for (; aItLI.More(); aItLI.Next()) {
-      nVx=aItLI.Value();
-      const TopoDS_Vertex& aVx=(*(TopoDS_Vertex *)(&myDS->Shape(nVx)));
-      //
-      iFlag=myContext->ComputeVE (aVx, aE, aT);
-      if (!iFlag) {
-        aPave.SetIndex(nVx);
-        aPave.SetParameter(aT);
-        aPB->AppendExtPave(aPave);
-      }
-    }
-  }
-  // 6  Split PaveBlocksa
-  for (i=1; i<=aNbPBLI; ++i) {
-    Handle(BOPDS_PaveBlock) aPB=aMPBLI.FindKey(i);
-    nE=aPB->OriginalEdge();
-    // 3
-    if (!myDS->IsCommonBlock(aPB)) {
-      myDS->UpdatePaveBlock(aPB);
-    }
-    else {
-      const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
-      myDS->UpdateCommonBlock(aCB);
-    }    
-  }//for (; aItMPBLI.More(); aItMPBLI.Next()) {
-  // 
-  return iRet;
+  ////aAllocator.Nullify();
 }
 //=======================================================================
 // function: CheckFacePaves
 // purpose: 
 //=======================================================================
-  Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves (const Standard_Integer nVx,
-                                                       const BOPCol_MapOfInteger& aMIFOn,
-                                                       const BOPCol_MapOfInteger& aMIFIn)
+Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves 
+  (const Standard_Integer nVx,
+   const TColStd_MapOfInteger& aMIFOn,
+   const TColStd_MapOfInteger& aMIFIn)
 {
   Standard_Boolean bRet;
   Standard_Integer nV;
-  BOPCol_MapIteratorOfMapOfInteger aIt;
+  TColStd_MapIteratorOfMapOfInteger aIt;
   //
   bRet=Standard_False;
   //
 // function: CheckFacePaves
 // purpose: 
 //=======================================================================
-  Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves (const TopoDS_Vertex& aVnew,
-                                                       const BOPCol_MapOfInteger& aMIF)
+Standard_Boolean BOPAlgo_PaveFiller::CheckFacePaves 
+  (const TopoDS_Vertex& aVnew,
+   const TColStd_MapOfInteger& aMIF)
 {
   Standard_Boolean bRet;
   Standard_Integer nV, iFlag;
-  BOPCol_MapIteratorOfMapOfInteger aIt;
+  TColStd_MapIteratorOfMapOfInteger aIt;
   //
   bRet=Standard_True;
   //
 //function : ForceInterfVF
 //purpose  : 
 //=======================================================================
-Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF(const Standard_Integer nV, 
-                                                   const Standard_Integer nF)
+Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF
+  (const Standard_Integer nV, 
+   const Standard_Integer nF)
 {
   Standard_Boolean bRet;
+  Standard_Integer iFlag, nVx;
+  Standard_Real U, V, aTolVNew;
   //
   bRet = Standard_False;
   const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
   const TopoDS_Face&   aF = *(TopoDS_Face*)  &myDS->Shape(nF);
   //
-  GeomAPI_ProjectPointOnSurf& aProj = myContext->ProjPS(aF);
-  const gp_Pnt& aP = BRep_Tool::Pnt(aV);
-  aProj.Perform(aP);
-  if (!aProj.IsDone()) {
-    return bRet;
-  }
-  Standard_Real aDist, U, V;
-  //
-  aDist=aProj.LowerDistance();
-  aProj.LowerDistanceParameters(U, V);
+  iFlag = myContext->ComputeVF(aV, aF, U, V, aTolVNew, myFuzzyValue);
+  if (iFlag == 0 || iFlag == -2) {
+    bRet=!bRet;
   //
-  gp_Pnt2d aP2d(U, V);
-  bRet = myContext->IsPointInFace (aF, aP2d);
-  if (bRet) {
-    Standard_Integer i;
-    BRep_Builder aBB;
-    //
     BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
-    i=aVFs.Append()-1;
-    BOPDS_InterfVF& aVF=aVFs(i);
+    aVFs.SetIncrement(10);
+    // 1
+    BOPDS_InterfVF& aVF=aVFs.Appended();
+    //
     aVF.SetIndices(nV, nF);
     aVF.SetUV(U, V);
-    //
+    // 2
     myDS->AddInterf(nV, nF);
     //
-    aBB.UpdateVertex(aV, aDist);
-    BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV);
-    Bnd_Box& aBoxDS=aSIDS.ChangeBox();
-    BRepBndLib::Add(aV, aBoxDS);
+    // 3 update vertex V/F if necessary
+    nVx=UpdateVertex(nV, aTolVNew);
+    // 4
+    if (myDS->IsNewShape(nVx)) {
+      aVF.SetIndexNew(nVx);
+    }
     //
     BOPDS_FaceInfo& aFI=myDS->ChangeFaceInfo(nF);
-    BOPCol_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();
-    aMVIn.Add(nV);
+    TColStd_MapOfInteger& aMVIn=aFI.ChangeVerticesIn();
+    aMVIn.Add(nVx);
+    //
+    // check for self-interference
+    Standard_Integer iRV = myDS->Rank(nV);
+    if (iRV >= 0 && iRV == myDS->Rank(nF)) {
+      // add warning status
+      TopoDS_Compound aWC;
+      BRep_Builder().MakeCompound(aWC);
+      BRep_Builder().Add(aWC, aV);
+      BRep_Builder().Add(aWC, aF);
+      AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC));
+    }
+
   }
-  //
   return bRet;
 }
-
+//=======================================================================
+//function : ReduceIntersectionRange
+//purpose  : 
+//=======================================================================
+void BOPAlgo_PaveFiller::ReduceIntersectionRange(const Standard_Integer theV1,
+                                                 const Standard_Integer theV2,
+                                                 const Standard_Integer theE,
+                                                 const Standard_Integer theF,
+                                                 Standard_Real& theTS1,
+                                                 Standard_Real& theTS2)
+{
+  if (!myDS->IsNewShape(theV1) &&
+      !myDS->IsNewShape(theV2)) {
+    return;
+  }
+  //
+  if (!myDS->HasInterfShapeSubShapes(theE, theF)) {
+    return;
+  }
+  //
+  BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE();
+  Standard_Integer aNbEEs = aEEs.Length();
+  if (!aNbEEs) {
+    return;
+  }
+  //
+  Standard_Integer i, nV, nE1, nE2;
+  Standard_Real aTR1, aTR2;
+  //
+  // get face's edges to check that E/E contains the edge from the face
+  TColStd_MapOfInteger aMFE;
+  const TColStd_ListOfInteger& aLI = myDS->ShapeInfo(theF).SubShapes();
+  TColStd_ListIteratorOfListOfInteger aItLI(aLI);
+  for (; aItLI.More(); aItLI.Next()) {
+    nE1 = aItLI.Value();
+    if (myDS->ShapeInfo(nE1).ShapeType() == TopAbs_EDGE) {
+      aMFE.Add(nE1);
+    }
+  }
+  //
+  for (i = 0; i < aNbEEs; ++i) {
+    BOPDS_InterfEE& aEE = aEEs(i);
+    if (!aEE.HasIndexNew()) {
+      continue;
+    }
+    //
+    // check the vertex
+    nV = aEE.IndexNew();
+    if (nV != theV1 && nV != theV2) {
+      continue;
+    }
+    //
+    // check that the intersection is between the edge
+    // and one of the face's edge
+    aEE.Indices(nE1, nE2);
+    if (((theE != nE1) && (theE != nE2)) ||
+        (!aMFE.Contains(nE1) && !aMFE.Contains(nE2))) {
+      continue;
+    }
+    //
+    // update the intersection range
+    const IntTools_CommonPrt& aCPart = aEE.CommonPart();
+    const IntTools_Range& aCRange = 
+      (theE == nE1) ? aCPart.Range1() : aCPart.Ranges2().First();
+    aCRange.Range(aTR1, aTR2);
+    //
+    if (nV == theV1) {
+      if (theTS1 < aTR2) {
+        theTS1 = aTR2;
+      }
+    }
+    else {
+      if (theTS2 > aTR1) {
+        theTS2 = aTR1;
+      }
+    }
+  }
+}