0024286: Wrong result done by General Fuse algorithm.
authoremv <emv@opencascade.com>
Thu, 31 Oct 2013 13:25:02 +0000 (17:25 +0400)
committerbugmaster <bugmaster@opencascade.com>
Fri, 1 Nov 2013 06:04:04 +0000 (10:04 +0400)
1. Instead of the tolerance value of the face the resolution of the surface of the face is used in
   the Face Classifier algorithm to define the state of the 2d point relative to that face.
2. Replace the vertices involved in PostTreatFF (treatment of section edges) with their images
   (new vertices created in PostTreatFF) in all pave blocks.
3. New value of the result in the test case boolean bsection L8.

Test cases for issue CR24286

src/BOPAlgo/BOPAlgo_PaveFiller.cdl
src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
src/IntTools/IntTools_FClass2d.cxx
tests/boolean/bsection/L8
tests/bugs/modalg_5/bug24286 [new file with mode: 0644]

index f67b43c..657f48f 100644 (file)
@@ -39,7 +39,8 @@ uses
     DataMapOfIntegerListOfInteger from BOPCol, 
     DataMapOfShapeListOfShape from BOPCol,
     IndexedDataMapOfShapeListOfShape from BOPCol, 
-    DataMapOfIntegerReal from BOPCol,
+    DataMapOfIntegerReal from BOPCol, 
+    DataMapOfIntegerInteger from BOPCol,
     --  
     Context from BOPInt,
     -- 
@@ -174,23 +175,36 @@ is
         theMVOn:MapOfInteger from BOPCol) 
       returns Boolean from Standard 
       is protected; 
-        
-    PutPaveOnCurve(me:out; 
-        theMVOn:MapOfInteger from BOPCol; 
-        theTolR3D:Real from Standard; 
-        theNC:out Curve from BOPDS; 
-        nF1:Integer from Standard; 
-        nF2:Integer from Standard;
-        theMVEF:MapOfInteger from BOPCol; 
-        theMVTol:out DataMapOfIntegerReal from BOPCol) 
-      is protected;  
+
+    PutPavesOnCurve(me:out; 
+        theMVOn   : MapOfInteger from BOPCol; 
+        theTolR3D : Real from Standard; 
+        theNC     : out Curve from BOPDS;  
+        nF1       : Integer from Standard; 
+        nF2       : Integer from Standard; 
+        theMI     : MapOfInteger from BOPCol; 
+        theMVEF   : MapOfInteger from BOPCol; 
+        theMVTol  : out DataMapOfIntegerReal from BOPCol) 
+      is protected;   
+    ---Purpose: 
+    -- Checks and puts paves from <theMVOn> on the curve <theNC>.
 
     ExtendedTolerance(me:out; 
-        nV:Integer from Standard; 
-        aMI:MapOfInteger from BOPCol; 
-        aTolVExt:out Real from  Standard) 
+        nV       : Integer from Standard; 
+        aMI      : MapOfInteger from BOPCol; 
+        aTolVExt : out Real from  Standard;
+        aType    : Integer from Standard = 0) 
       returns Boolean from  Standard 
-      is protected;
+      is protected; 
+    ---Purpose: 
+    -- Depending on the parameter aType it checks whether  
+    -- the vertex nV was created in EE or EF intersections. 
+    -- If so, it increases aTolVExt from tolerance value of vertex to  
+    -- the max distance from vertex nV to the ends of the range of common part. 
+    -- Possible values of aType: 
+    -- 1 - checks only EE; 
+    -- 2 - checks only EF;
+    -- other - checks both types of intersections.
         
     PutBoundPaveOnCurve(me:out;  
         theF1: Face from TopoDS;  
@@ -221,10 +235,14 @@ is
     PostTreatFF(me:out; 
         theMSCPB:out IndexedDataMapOfShapeCoupleOfPaveBlocks from BOPDS; 
         theMVI:out DataMapOfShapeInteger from BOPCol;  
-        theDMExEd:out DataMapOfPaveBlockListOfPaveBlock from BOPDS;
+        theDMExEdges:out DataMapOfPaveBlockListOfPaveBlock from BOPDS; 
+        theDMI:out DataMapOfIntegerInteger from BOPCol;
         theAllocator:out BaseAllocator from BOPCol) 
       returns Integer from Standard 
-      is protected; 
+      is protected;  
+    ---Purpose: 
+    -- Treatment of section edges.
+    
     --
     --  Treatment of degenerated edges  
     -- 
@@ -254,46 +272,69 @@ is
       is protected; 
        
     PutEFPavesOnCurve(me:out; 
-        nF1        : Integer from Standard; 
-        nF2        : Integer from Standard; 
         theNC      : out Curve from BOPDS; 
-        theMVEF    : MapOfInteger from BOPCol; 
+        theMI      : MapOfInteger from BOPCol;
+        theMVEF    : MapOfInteger from BOPCol;
         theMVTol   : out DataMapOfIntegerReal from BOPCol)
-      is protected;
+      is protected; 
+    ---Purpose: 
+    -- Checks and puts paves created in EF intersections on the curve <theNC>.
  
     PutStickPavesOnCurve(me:out; 
-        nF1        : Integer from Standard; 
-        nF2        : Integer from Standard; 
+        aF1        : Face from TopoDS; 
+        aF2        : Face from TopoDS;  
+        theMI      : MapOfInteger from BOPCol;
         theNC      : out Curve from BOPDS; 
         theMVStick : MapOfInteger from BOPCol; 
         theMVTol   : out DataMapOfIntegerReal from BOPCol)
-      is protected; 
+      is protected;  
+    ---Purpose: 
+    -- Puts stick paves on the curve <theNC>
  
     GetStickVertices(me:out; 
         nF1        : Integer from Standard; 
         nF2        : Integer from Standard; 
         theMVStick : out MapOfInteger from BOPCol;
-        theMVEFk   : out MapOfInteger from BOPCol)
-      is protected; 
+        theMVEF    : out MapOfInteger from BOPCol; 
+        theMI      : out MapOfInteger from BOPCol)
+      is protected;  
+    ---Purpose: 
+    -- Collects indices of vertices created in all intersections between 
+    -- two faces (<nF1> and <nF2>) to the map <theMVStick>. 
+    -- Also, it collects indices of EF vertices to the <theMVEF> map  
+    -- and indices of all subshapes of these two faces to the <theMI> map.
  
-    GetFullFaceMap(me:out; 
+    GetFullShapeMap(me:out; 
         nF    : Integer from Standard; 
         theMI : out MapOfInteger from BOPCol) 
       is protected; 
-       
-       
+    ---Purpose: 
+    -- Collects index nF and indices of all subshapes of the shape with index <nF>
+    -- to the map <theMI>. 
+    
     RemoveUsedVertices(me:out; 
         theNC : out Curve from BOPDS; 
         theMV : out MapOfInteger from BOPCol)  
-      is protected;
+      is protected; 
+    ---Purpose: 
+    -- Removes indices of vertices that are already on the
+    -- curve <theNC> from the map <theMV>.  
+    -- It is used in PutEFPavesOnCurve and PutStickPavesOnCurve methods.
  
     PutPaveOnCurve(me:out; 
         nV        : Integer from Standard; 
         theTolR3D : Real from Standard;
-        theNC     : Curve from BOPDS;
-        thePB     : out PaveBlock from BOPDS; 
-        theMVTol  : out DataMapOfIntegerReal from BOPCol) 
-      is protected;
+        theNC     : out Curve from BOPDS; 
+        theMI     : MapOfInteger from BOPCol;
+        theMVTol  : out DataMapOfIntegerReal from BOPCol;
+        aType     : Integer from Standard = 0)
+      is protected; 
+    ---Purpose: 
+    -- Puts the pave nV on the curve theNC.  
+    -- Parameter aType defines whether to check the pave with 
+    -- extended tolerance: 
+    -- 0 - do not perform the check; 
+    -- other - perform the check (aType goes to ExtendedTolerance).
  
     ProcessExistingPaveBlocks(me:out; 
         theInt     : Integer from Standard; 
@@ -302,26 +343,35 @@ is
         theMVI     : out DataMapOfShapeInteger from BOPCol; 
         theMVB     : MapOfInteger from BOPCol; 
         theMPB     : out MapOfPaveBlock from BOPDS)
-      is  protected;        
+      is  protected; 
+    ---Purpose:             
+    -- Adds the existing edges from the map <theMPBOnIn> which interfere  
+    -- with the vertices from <theMVB> map to the post treatment of section edges.
  
     UpdateExistingPaveBlocks(me:out; 
         thePB   : PaveBlock from BOPDS;
         theLPB  : out ListOfPaveBlock from BOPDS; 
         nF1     : Integer from Standard; 
         nF2     : Integer from Standard)
-      is protected;
+      is protected; 
+    ---Purpose: 
+    -- Replaces existing pave block <thePB> with new pave blocks <theLPB>. 
+    -- The list <theLPB> contains images of <thePB> which were created in 
+    -- the post treatment of section edges.
  
     TreatNewVertices(me:out; 
         theMVI    : IndexedDataMapOfShapeInteger from BOPCol; 
         theImages : out IndexedDataMapOfShapeListOfShape from BOPCol) 
-      is protected;
+      is protected; 
+    ---Purpose: 
+    -- Treatment of vertices that were created in EE intersections. 
  
     PutClosingPaveOnCurve (me:out; 
         aNC :out Curve from BOPDS)  
       is protected; 
-    ---Purpose:             
-    --- Put paves on the curve <aBC> in case when <aBC>   
-    --- is closed 3D-curve  
+    ---Purpose: 
+    -- Put paves on the curve <aBC> in case when <aBC>   
+    -- is closed 3D-curve  
      
     PreparePostTreatFF(me:out; 
         aInt   : Integer from Standard; 
@@ -355,8 +405,8 @@ is
     -- to make it interfere with edge
     
     ForceInterfVF(me:out; 
-        nV:Integer from Standard; 
-        nF:Integer from Standard) 
+        nV : Integer from Standard; 
+        nF : Integer from Standard) 
       returns Boolean from Standard
       is protected;
     ---Purpose: 
@@ -370,8 +420,27 @@ is
       is protected; 
     ---Purpose: 
     -- Checks if there are any common or intersecting sub shapes
-    -- between two planar faces. 
-
+    -- between two planar faces.  
+     
+    SplitEdge(me:out; 
+        nE  : Integer from Standard; 
+        nV1 : Integer from Standard; 
+        aT1 : Real from Standard;
+        nV2 : Integer from Standard; 
+        aT2 : Real from Standard) 
+    returns Integer from Standard 
+    is protected;
+    ---Purpose: 
+    -- Creates new edge from the edge nE with vertices nV1 and nV2 
+    -- and returns the index of that new edge in the DS.
+    UpdatePaveBlocks(me:out;  
+        theDMI : DataMapOfIntegerInteger from BOPCol) 
+    is protected; 
+    ---Purpose: 
+    -- Updates pave blocks which have the paves with indices contained  
+    -- in the map <theDMI>.
+        
 fields  
     myArguments   : ListOfShape from BOPCol is protected;  
     myDS          : PDS from BOPDS is protected; 
index f27070b..3db584a 100644 (file)
@@ -151,12 +151,12 @@ void BOPAlgo_PaveFiller::PerformFF()
       Standard_Boolean bToIntersect;
       //
       if (aMI.Add(nF1)) {
-        myDS->UpdateFaceInfoOn(nF1);
-        myDS->UpdateFaceInfoIn(nF1);
+        myDS->UpdateFaceInfoOn(nF1);
+        myDS->UpdateFaceInfoIn(nF1);
       }
       if (aMI.Add(nF2)) {
-        myDS->UpdateFaceInfoOn(nF2);
-        myDS->UpdateFaceInfoIn(nF2);
+        myDS->UpdateFaceInfoOn(nF2);
+        myDS->UpdateFaceInfoIn(nF2);
       }
       //
       bToIntersect = CheckPlanes(nF1, nF2);
@@ -261,8 +261,7 @@ void BOPAlgo_PaveFiller::PerformFF()
 //function : MakeBlocks
 //purpose  : 
 //=======================================================================
-
-  void BOPAlgo_PaveFiller::MakeBlocks()
+void BOPAlgo_PaveFiller::MakeBlocks()
 {
   Standard_Integer aNbFF;
   //
@@ -289,15 +288,16 @@ void BOPAlgo_PaveFiller::PerformFF()
   BOPCol_ListOfInteger aLSE(aAllocator);
   BOPCol_MapOfInteger aMVOnIn(100, aAllocator), aMF(100, aAllocator),
                       aMVStick(100,aAllocator), aMVEF(100, aAllocator),
-                      aMVB(100, aAllocator);
+                      aMVB(100, aAllocator), aMI(100, aAllocator);
   BOPDS_MapOfPaveBlock aMPBOnIn(100, aAllocator),
                        aMPBAdd(100, aAllocator);
   BOPDS_ListOfPaveBlock aLPB(aAllocator);
   BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMSCPB(100, aAllocator); 
   BOPCol_DataMapOfShapeInteger aMVI(100, aAllocator);
-  BOPDS_DataMapOfPaveBlockListOfPaveBlock aDMExEdges;
+  BOPDS_DataMapOfPaveBlockListOfPaveBlock aDMExEdges(100, aAllocator);
   BOPCol_DataMapOfIntegerReal aMVTol(100, aAllocator);
   BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItMV;
+  BOPCol_DataMapOfIntegerInteger aDMI(100, aAllocator);
   //
   for (i=0; i<aNbFF; ++i) {
     BOPDS_InterfFF& aFF=aFFs(i);
@@ -357,7 +357,7 @@ void BOPAlgo_PaveFiller::PerformFF()
     // 2. Treat Curves
     aMVStick.Clear();
     aMVEF.Clear();
-    GetStickVertices(nF1, nF2, aMVStick, aMVEF);
+    GetStickVertices(nF1, nF2, aMVStick, aMVEF, aMI);
     //
     for (j=0; j<aNbC; ++j) {
       BOPDS_Curve& aNC=aVC.ChangeValue(j);
@@ -365,12 +365,12 @@ void BOPAlgo_PaveFiller::PerformFF()
       // DEBt
       aNC.InitPaveBlock1();
       //
-      PutPaveOnCurve(aMVOnIn, aTolR3D, aNC, nF1, nF2, aMVEF, aMVTol);
+      PutPavesOnCurve(aMVOnIn, aTolR3D, aNC, nF1, nF2, aMI, aMVEF, aMVTol);
       //
-      PutStickPavesOnCurve(nF1, nF2, aNC, aMVStick, aMVTol);
+      PutStickPavesOnCurve(aF1, aF2, aMI, aNC, aMVStick, aMVTol);
       //904/F7
       if (aNbC == 1) {
-        PutEFPavesOnCurve(nF1, nF2, aNC, aMVEF, aMVTol);
+        PutEFPavesOnCurve(aNC, aMI, aMVEF, aMVTol);
       }
       //
       if (aIC.HasBounds()) {
@@ -490,19 +490,23 @@ void BOPAlgo_PaveFiller::PerformFF()
   }//for (i=0; i<aNbFF; ++i) {
   // 
   // post treatment
-  myErrorStatus=PostTreatFF(aMSCPB, aMVI, aDMExEdges, aAllocator);
+  myErrorStatus=PostTreatFF(aMSCPB, aMVI, aDMExEdges, aDMI, aAllocator);
   if (myErrorStatus) {
     return;
   }
   //
   // update face info
   UpdateFaceInfo(aDMExEdges);
+  //Update all pave blocks
+  UpdatePaveBlocks(aDMI);
   //-----------------------------------------------------scope t
   aMF.Clear();
   aMVStick.Clear();
   aMPBOnIn.Clear();
   aMVOnIn.Clear();
   aDMExEdges.Clear();
+  aMI.Clear();
+  aDMI.Clear();
   aAllocator.Nullify();
 }
 
@@ -514,6 +518,7 @@ void BOPAlgo_PaveFiller::PerformFF()
     (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
      BOPCol_DataMapOfShapeInteger& aMVI,
      BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
+     BOPCol_DataMapOfIntegerInteger& aDMI,
      Handle(NCollection_BaseAllocator)& theAllocator)
 {
   Standard_Integer iRet, aNbS;
@@ -695,8 +700,6 @@ void BOPAlgo_PaveFiller::PerformFF()
             iE=aMVI.Find(aE);
           }
           // append new PaveBlock to aLPBC
-          Handle(BOPDS_PaveBlock) aPBC=new BOPDS_PaveBlock();
-          //
           aPB1->SetEdge(iE);
           aLPBC.Append(aPB1);
         } // if (!aNbLPBx) {
@@ -742,6 +745,11 @@ void BOPAlgo_PaveFiller::PerformFF()
                   iV=aMVI.Find(aV);
                 }
               }
+              const BOPDS_Pave& aP1 = !j ? aPB1->Pave1() : aPB1->Pave2();
+              if (aP1.Parameter() == aPave[j].Parameter() && aP1.Index() != iV) {
+                aDMI.Bind(aP1.Index(), iV);
+              }
+              //
               aPave[j].SetIndex(iV);
             }
             //
@@ -782,8 +790,7 @@ void BOPAlgo_PaveFiller::PerformFF()
 //function : UpdateFaceInfo
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_PaveFiller::UpdateFaceInfo(
-       BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME)
+void BOPAlgo_PaveFiller::UpdateFaceInfo(BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME)
 {
   Standard_Integer i, j, nV1, nF1, nF2, 
                    aNbFF, aNbC, aNbP, aNbS, aNbPBIn;
@@ -869,7 +876,6 @@ void BOPAlgo_PaveFiller::PerformFF()
     }//for (j=1; j<=aNbPBIn; ++j) {
   }//for (i=0; i<aNbS; ++i) {
 }
-
 //=======================================================================
 //function : IsExistingVertex
 //purpose  : 
@@ -970,12 +976,12 @@ void BOPAlgo_PaveFiller::PerformFF()
 {
   Standard_Boolean bRet;
   Standard_Real aT1, aT2, aTm, aTx;
-  Standard_Integer nSp, iFlag, nV11, nV12, nV21, nV22;
+  Standard_Integer nSp, iFlag1, iFlag2, nV11, nV12, nV21, nV22;
   gp_Pnt aP1, aPm, aP2;
   Bnd_Box aBoxP1, aBoxPm, aBoxP2;
   BOPDS_MapIteratorOfMapOfPaveBlock aIt;
   //
-  bRet=Standard_True;
+  bRet=Standard_False;
   const IntTools_Curve& aIC=theNC.Curve();
   //
   thePB->Range(aT1, aT2);
@@ -1000,25 +1006,32 @@ void BOPAlgo_PaveFiller::PerformFF()
     aPB->Indices(nV21, nV22);
     nSp=aPB->Edge();
     const BOPDS_ShapeInfo& aSISp=myDS->ChangeShapeInfo(nSp);
+    const TopoDS_Edge& aSp=(*(TopoDS_Edge *)(&aSISp.Shape()));
     const Bnd_Box& aBoxSp=aSISp.Box();
-    if (!aBoxSp.IsOut(aBoxP1) && !aBoxSp.IsOut(aBoxPm) && !aBoxSp.IsOut(aBoxP2)) {
-      const TopoDS_Edge& aSp=(*(TopoDS_Edge *)(&aSISp.Shape()));
-      iFlag=(nV11 == nV21 || nV11 == nV22) ? 0 : 
-                     myContext->ComputePE(aP1, theTolR3D, aSp, aTx);
-      if (!iFlag) {
-        iFlag=(nV12 == nV21 || nV12 == nV22) ? 0 :
-                       myContext->ComputePE(aP2, theTolR3D, aSp, aTx);
-        if (!iFlag) {
-          iFlag=myContext->ComputePE(aPm, theTolR3D, aSp, aTx);
-          if (!iFlag) {
-            aPBOut = aPB;
-            return bRet;
-          }
-        }
+    //
+    iFlag1 = (nV11 == nV21 || nV11 == nV22) ? 2 : (!aBoxSp.IsOut(aBoxP1) ? 1 : 0);
+    iFlag2 = (nV12 == nV21 || nV12 == nV22) ? 2 : (!aBoxSp.IsOut(aBoxP2) ? 1 : 0);
+    if (iFlag1 && iFlag2) {
+      if (aBoxSp.IsOut(aBoxPm) || myContext->ComputePE(aPm, theTolR3D, aSp, aTx)) {
+        continue;
+      }
+      //
+      if (iFlag1 == 1) {
+        iFlag1 = !myContext->ComputePE(aP1, theTolR3D, aSp, aTx);
+      }
+      //
+      if (iFlag2 == 1) {
+        iFlag2 = !myContext->ComputePE(aP2, theTolR3D, aSp, aTx);
+      }
+      //
+      if (iFlag1 && iFlag2) {
+        aPBOut = aPB;
+        bRet=Standard_True;
+        break;
       }
     }
   }
-  return !bRet;
+  return bRet;
 }
 
 //=======================================================================
@@ -1125,88 +1138,58 @@ void BOPAlgo_PaveFiller::PerformFF()
 }
 
 //=======================================================================
-//function : PutPaveOnCurve
+//function : PutPavesOnCurve
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_PaveFiller::PutPaveOnCurve(const BOPCol_MapOfInteger& aMVOnIn,
-                                          const Standard_Real aTolR3D,
-                                          BOPDS_Curve& aNC,
-                                          const Standard_Integer nF1,
-                                          const Standard_Integer nF2,
-                                          const BOPCol_MapOfInteger& aMVEF,
-                                          BOPCol_DataMapOfIntegerReal& aMVTol)
+  void BOPAlgo_PaveFiller::PutPavesOnCurve(const BOPCol_MapOfInteger& aMVOnIn,
+                                           const Standard_Real aTolR3D,
+                                           BOPDS_Curve& aNC,
+                                           const Standard_Integer nF1,
+                                           const Standard_Integer nF2,
+                                           const BOPCol_MapOfInteger& aMI,
+                                           const BOPCol_MapOfInteger& aMVEF,
+                                           BOPCol_DataMapOfIntegerReal& aMVTol)
 {
-  Standard_Boolean bIsVertexOnLine, bInBothFaces;
+  Standard_Boolean bInBothFaces;
   Standard_Integer nV;
-  Standard_Real aT, aTol, aTolNew;
-  BOPDS_Pave aPave;
-  //
   BOPCol_MapIteratorOfMapOfInteger aIt;
   //
-  Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
-  const IntTools_Curve& aIC=aNC.Curve();
   const Bnd_Box& aBoxC=aNC.Box();
   //
+  //Put EF vertices first
+  aIt.Initialize(aMVEF);
+  for (; aIt.More(); aIt.Next()) {
+    nV=aIt.Value();
+    PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, 2);
+  }
+  //Put all other vertices
   aIt.Initialize(aMVOnIn);
   for (; aIt.More(); aIt.Next()) {
     nV=aIt.Value();
-    const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
-    const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
-    //
-    if (!aMVEF.Contains(nV)) {
-      const Bnd_Box& aBoxV=aSIV.Box();
-      //
-      if (aBoxC.IsOut(aBoxV)){
-        continue; 
-      }
-      if (!myDS->IsNewShape(nV)) {
-        const BOPDS_FaceInfo& aFI1 = myDS->FaceInfo(nF1);
-        const BOPDS_FaceInfo& aFI2 = myDS->FaceInfo(nF2);
-        //
-        bInBothFaces = (aFI1.VerticesOn().Contains(nV) ||
-                        aFI1.VerticesIn().Contains(nV))&&
-                          (aFI2.VerticesOn().Contains(nV) ||
-                           aFI2.VerticesIn().Contains(nV));
-        if (!bInBothFaces) {
-          continue;
-        }
-      }
+    if (aMVEF.Contains(nV)) {
+      continue;
     }
     //
-    bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT);
-    if (!bIsVertexOnLine) {
-      BOPCol_MapOfInteger aMI;
-      //
-      aTol = BRep_Tool::Tolerance(aV);
-      //
-      GetFullFaceMap(nF1, aMI);
-      GetFullFaceMap(nF2, aMI);
-      //
-      ExtendedTolerance(nV, aMI, aTol);
-      bIsVertexOnLine=myContext->IsVertexOnLine(aV, aTol, aIC, aTolR3D, aT);
-    }   
+    const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
+    const Bnd_Box& aBoxV=aSIV.Box();
     //
-    if (bIsVertexOnLine) {
-      aPave.SetIndex(nV);
-      aPave.SetParameter(aT);
-      //
-      aPB->AppendExtPave(aPave);
-      //
-      aTol = BRep_Tool::Tolerance(aV);
-      //
-      BOPTools_AlgoTools::UpdateVertex (aIC, aT, aV);
+    if (aBoxC.IsOut(aBoxV)){
+      continue;
+    }
+    if (!myDS->IsNewShape(nV)) {
+      const BOPDS_FaceInfo& aFI1 = myDS->FaceInfo(nF1);
+      const BOPDS_FaceInfo& aFI2 = myDS->FaceInfo(nF2);
       //
-      if (!aMVTol.IsBound(nV)) {
-        aTolNew = BRep_Tool::Tolerance(aV);
-        if (aTolNew > aTol) {
-          aMVTol.Bind(nV, aTol);
-        }
+      bInBothFaces = (aFI1.VerticesOn().Contains(nV) ||
+                      aFI1.VerticesIn().Contains(nV))&&
+                     (aFI2.VerticesOn().Contains(nV) ||
+                      aFI2.VerticesIn().Contains(nV));
+      if (!bInBothFaces) {
+        continue;
       }
-      // 
-      BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV);
-      Bnd_Box& aBoxDS=aSIDS.ChangeBox();
-      BRepBndLib::Add(aV, aBoxDS);
     }
+    //
+    PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, 1);
   }
 }
 
@@ -1214,35 +1197,44 @@ void BOPAlgo_PaveFiller::PerformFF()
 //function : ExtendedTolerance
 //purpose  : 
 //=======================================================================
-  Standard_Boolean BOPAlgo_PaveFiller::ExtendedTolerance(const Standard_Integer nV,
-                                                         const BOPCol_MapOfInteger& aMI,
-                                                         Standard_Real& aTolVExt)
+Standard_Boolean BOPAlgo_PaveFiller::ExtendedTolerance(const Standard_Integer nV,
+                                                       const BOPCol_MapOfInteger& aMI,
+                                                       Standard_Real& aTolVExt,
+                                                       const Standard_Integer aType)
 {
   Standard_Boolean bFound = Standard_False;
   if (!(myDS->IsNewShape(nV))) {
     return bFound;
   }
-
-  Standard_Integer i, k, aNbLines;
+  //
+  Standard_Integer i, k, aNbLines, aNbInt;
   Standard_Real aT11, aT12, aD1, aD2, aD;
   TopoDS_Vertex aV;
   gp_Pnt aPV, aP11, aP12;
-
+  //
+  k = 0;
+  aNbInt = 2;
+  if (aType == 1) {
+    aNbInt = 1;
+  } else if (aType == 2) {
+    k = 1;
+  }
+  //
   aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
   aPV=BRep_Tool::Pnt(aV);
   //
   BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
-
-  for (k=0; k<2; ++k) {
+  //
+  for (; k<aNbInt; ++k) {
     aNbLines = !k ? aEEs.Extent() : aEFs.Extent();
     for (i = 0; i < aNbLines; ++i) {
       BOPDS_Interf *aInt = !k ? (BOPDS_Interf*) (&aEEs(i)) :
-                                (BOPDS_Interf*) (&aEFs(i));
+        (BOPDS_Interf*) (&aEFs(i));
       if (aInt->IndexNew() == nV) {
         if (aMI.Contains(aInt->Index1()) && aMI.Contains(aInt->Index2())) {
           const IntTools_CommonPrt& aComPrt = !k ? aEEs(i).CommonPart() :
-                                                   aEFs(i).CommonPart();
+            aEFs(i).CommonPart();
           //
           const TopoDS_Edge& aE1=aComPrt.Edge1();
           aComPrt.Range1(aT11, aT12);
@@ -1259,7 +1251,6 @@ void BOPAlgo_PaveFiller::PerformFF()
       }//if (aInt->IndexNew() == nV) {
     }//for (i = 0; i < aNbLines; ++i) {
   }//for (k=0; k<2; ++k) {
-
   return bFound;
 }
 
@@ -1273,24 +1264,21 @@ void BOPAlgo_PaveFiller::PerformFF()
 {
   Standard_Integer nE, nF, nFOpposite, aNbEFs, i;
   Standard_Real U1, U2, V1, V2, f, l;
-  BOPCol_MapOfInteger aMIF1, aMIF2;
+  BOPCol_MapOfInteger aMI;
   //
   //collect indexes of all shapes from nF1 and nF2.
-  GetFullFaceMap(nF1, aMIF1);
-  GetFullFaceMap(nF2, aMIF2);
+  GetFullShapeMap(nF1, aMI);
+  GetFullShapeMap(nF2, aMI);
   //
   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
   aNbEFs = aEFs.Extent();
   //
   for(i = 0; i < aNbEFs; ++i) {
     const BOPDS_InterfEF& aEF = aEFs(i);
-    nE = aEF.Index1();
-    nFOpposite = aEF.Index2();
-    if((aMIF1.Contains(nE) && aMIF2.Contains(nFOpposite)) ||
-       (aMIF1.Contains(nFOpposite) && aMIF2.Contains(nE))) {
-      //
-      IntTools_CommonPrt aCP = aEF.CommonPart();
-      if(aCP.Type() == TopAbs_VERTEX) {
+    if (aEF.HasIndexNew()) {
+      aEF.Indices(nE, nFOpposite);
+      if(aMI.Contains(nE) && aMI.Contains(nFOpposite)) {
+        const IntTools_CommonPrt& aCP = aEF.CommonPart();
         Standard_Real aPar = aCP.VertexParameter1();
         const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&myDS->Shape(nE)));
         const TopoDS_Face& aFOpposite = (*(TopoDS_Face*)(&myDS->Shape(nFOpposite)));
@@ -1343,9 +1331,8 @@ void BOPAlgo_PaveFiller::PerformFF()
 //function : ProcessUnUsedVertices
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_PaveFiller::PutEFPavesOnCurve(const Standard_Integer /*nF1*/,
-                                             const Standard_Integer /*nF2*/,
-                                             BOPDS_Curve& aNC,
+  void BOPAlgo_PaveFiller::PutEFPavesOnCurve(BOPDS_Curve& aNC,
+                                             const BOPCol_MapOfInteger& aMI,
                                              const BOPCol_MapOfInteger& aMVEF,
                                              BOPCol_DataMapOfIntegerReal& aMVTol)
 {
@@ -1373,10 +1360,8 @@ void BOPAlgo_PaveFiller::PerformFF()
   BOPDS_Pave aPave;
   //
   const Handle(Geom_Curve)& aC3D=aIC.Curve();
-  Handle(BOPDS_PaveBlock)& aPB = aNC.ChangePaveBlock1();
-
   GeomAPI_ProjectPointOnCurve& aProjPT = myContext->ProjPT(aC3D);
-  
+  //
   BOPCol_MapIteratorOfMapOfInteger aItMI;
   aItMI.Initialize(aMV);
   for (; aItMI.More(); aItMI.Next()) {
@@ -1387,7 +1372,7 @@ void BOPAlgo_PaveFiller::PerformFF()
     Standard_Integer aNbPoints = aProjPT.NbPoints();
     if (aNbPoints) {
       aDist = aProjPT.LowerDistance();
-      PutPaveOnCurve(nV, aDist, aNC, aPB, aMVTol);
+      PutPaveOnCurve(nV, aDist, aNC, aMI, aMVTol);
     }
   }
 }
@@ -1396,8 +1381,9 @@ void BOPAlgo_PaveFiller::PerformFF()
 //function : ProcessUnUsedVertices
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_PaveFiller::PutStickPavesOnCurve(const Standard_Integer nF1,
-                                                const Standard_Integer nF2,
+  void BOPAlgo_PaveFiller::PutStickPavesOnCurve(const TopoDS_Face& aF1,
+                                                const TopoDS_Face& aF2,
+                                                const BOPCol_MapOfInteger& aMI,
                                                 BOPDS_Curve& aNC,
                                                 const BOPCol_MapOfInteger& aMVStick,
                                                 BOPCol_DataMapOfIntegerReal& aMVTol)
@@ -1411,40 +1397,36 @@ void BOPAlgo_PaveFiller::PerformFF()
   }
   //
   GeomAbs_SurfaceType aType1, aType2;
-  const TopoDS_Face& aF1 = (*(TopoDS_Face*)(&myDS->Shape(nF1)));  
-  const TopoDS_Face& aF2 = (*(TopoDS_Face*)(&myDS->Shape(nF2)));  
   Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
   Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
   GeomAdaptor_Surface aGAS1(aS1);
   GeomAdaptor_Surface aGAS2(aS2);
-  
   //
   aType1=aGAS1.GetType();
   aType2=aGAS2.GetType();
   //
-  if(aType1==GeomAbs_Torus  || aType2==GeomAbs_Torus) {
-    Standard_Integer nV, m, n;
-    Standard_Real aTC[2], aD, aD2, u, v, aDT2, aScPr, aDScPr;
+  if (aType1==GeomAbs_Torus  || aType2==GeomAbs_Torus) {
     GeomAbs_CurveType aTypeC;
-    gp_Pnt aPC[2], aPV;
-    gp_Dir aDN[2];
-    gp_Pnt2d aP2D;
-    
-    Handle(Geom2d_Curve) aC2D[2];
-    //
-    aDT2=2e-7;     // the rich criteria
-    aDScPr=5.e-9;  // the creasing criteria
     //
     const IntTools_Curve& aIC=aNC.Curve();
-    //Handle(Geom_Curve) aC3D=aIC.Curve(); //DEB
     aTypeC=aIC.Type();
     if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
+      Handle(Geom2d_Curve) aC2D[2];
       //
-      aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]);
       aC2D[0]=aIC.FirstCurve2d();
       aC2D[1]=aIC.SecondCurve2d();
       if (!aC2D[0].IsNull() && !aC2D[1].IsNull()) {
+        Standard_Integer nV, m, n;
+        Standard_Real aTC[2], aD, aD2, u, v, aDT2, aScPr, aDScPr;
+        gp_Pnt aPC[2], aPV;
+        gp_Dir aDN[2];
+        gp_Pnt2d aP2D;
         BOPCol_MapIteratorOfMapOfInteger aItMI, aItMI1;
+        //
+        aDT2=2e-7;     // the rich criteria
+        aDScPr=5.e-9;  // the creasing criteria
+        aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]);
+        //
         aItMI.Initialize(aMV);
         for (; aItMI.More(); aItMI.Next()) {
           nV = aItMI.Value();
@@ -1477,8 +1459,7 @@ void BOPAlgo_PaveFiller::PerformFF()
             // The intersection curve aIC is vanishing curve (the crease)
             aD=sqrt(aD2);
             //
-            Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
-            PutPaveOnCurve(nV, aD, aNC, aPB, aMVTol);
+            PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol);
           }
         }//for (jVU=1; jVU=aNbVU; ++jVU) {
       }
@@ -1493,10 +1474,10 @@ void BOPAlgo_PaveFiller::PerformFF()
   void BOPAlgo_PaveFiller::GetStickVertices(const Standard_Integer nF1,
                                             const Standard_Integer nF2,
                                             BOPCol_MapOfInteger& aMVStick,
-                                            BOPCol_MapOfInteger& aMVEF)
+                                            BOPCol_MapOfInteger& aMVEF,
+                                            BOPCol_MapOfInteger& aMI)
 {
-  BOPCol_MapOfInteger aMIF1, aMIF2;
-  Standard_Integer nV1, nV2, nE1, nE2, nV, nE, nF, nVNew, i;
+  Standard_Integer nS1, nS2, nVNew, aTypeInt, i;
   //
   BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
   BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
@@ -1504,73 +1485,35 @@ void BOPAlgo_PaveFiller::PerformFF()
   BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
   BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
   //
-  Standard_Integer aNbVVs, aNbVEs, aNbEEs, aNbVFs, aNbEFs;
-  aNbVVs = aVVs.Extent();
-  aNbVEs = aVEs.Extent();
-  aNbEEs = aEEs.Extent();
-  aNbVFs = aVFs.Extent();
-  aNbEFs = aEFs.Extent();
-  //
-  //collect indexes of all shapes from nF1 and nF2.
-  GetFullFaceMap(nF1, aMIF1);
-  GetFullFaceMap(nF2, aMIF2);
-  //collect VV interferences
-  for(i = 0; i < aNbVVs; ++i) {
-    const BOPDS_InterfVV& aVV = aVVs(i);
-    nV1 = aVV.Index1();
-    nV2 = aVV.Index2();
-    if((aMIF1.Contains(nV1) && aMIF2.Contains(nV2)) ||
-       (aMIF1.Contains(nV2) && aMIF2.Contains(nV1))) {
-      if (aVV.HasIndexNew()) {
-        nVNew = aVV.IndexNew();
-        aMVStick.Add(nVNew);
-      }
-    }
-  }
-  //collect VE interferences
-  for(i = 0; i < aNbVEs; ++i) {
-    const BOPDS_InterfVE& aVE = aVEs(i);
-    nV = aVE.Index1();
-    nE = aVE.Index2();
-    if((aMIF1.Contains(nV) && aMIF2.Contains(nE)) ||
-       (aMIF1.Contains(nE) && aMIF2.Contains(nV))) {
-      aMVStick.Add(nV);
-    }
-  }
-  //collect EE interferences
-  for(i = 0; i < aNbEEs; ++i) {
-    const BOPDS_InterfEE& aEE = aEEs(i);
-    nE1 = aEE.Index1();
-    nE2 = aEE.Index2();
-    if((aMIF1.Contains(nE1) && aMIF2.Contains(nE2)) ||
-       (aMIF1.Contains(nE2) && aMIF2.Contains(nE1))) {
-      IntTools_CommonPrt aCP = aEE.CommonPart();
-      if(aCP.Type() == TopAbs_VERTEX) {
-        nVNew = aEE.IndexNew();
-        aMVStick.Add(nVNew);
+  Standard_Integer aNbLines[5] = {aVVs.Extent(), aVEs.Extent(), aEEs.Extent(),
+                                  aVFs.Extent(), aEFs.Extent()};
+  //collect indices of all shapes from nF1 and nF2.
+  aMI.Clear();
+  GetFullShapeMap(nF1, aMI);
+  GetFullShapeMap(nF2, aMI);
+  //
+  //collect VV, VE, EE, VF interferences
+  for (aTypeInt = 0; aTypeInt < 4; ++aTypeInt) {
+    for (i = 0; i < aNbLines[aTypeInt]; ++i) {
+      BOPDS_Interf* aInt = (aTypeInt==0) ? (BOPDS_Interf*)(&aVVs(i)) : 
+        ((aTypeInt==1) ? (BOPDS_Interf*)(&aVEs(i)) :
+         ((aTypeInt==2) ? (BOPDS_Interf*)(&aEEs(i)) : (BOPDS_Interf*)(&aVFs(i))));
+      if (aInt->HasIndexNew()) {
+        aInt->Indices(nS1, nS2);
+        if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
+          nVNew = aInt->IndexNew();
+          aMVStick.Add(nVNew);
+        }
       }
     }
   }
-  //collect VF interferences
-  for(i = 0; i < aNbVFs; ++i) {
-    const BOPDS_InterfVF& aVF = aVFs(i);
-    nV = aVF.Index1();
-    nF = aVF.Index2();
-    if((aMIF1.Contains(nV) && aMIF2.Contains(nF)) ||
-       (aMIF1.Contains(nF) && aMIF2.Contains(nV))) {
-      aMVStick.Add(nV);
-    }
-  }
   //collect EF interferences
-  for(i = 0; i < aNbEFs; ++i) {
-    const BOPDS_InterfEF& aEF = aEFs(i);
-    nE = aEF.Index1();
-    nF = aEF.Index2();
-    if((aMIF1.Contains(nE) && aMIF2.Contains(nF)) ||
-       (aMIF1.Contains(nF) && aMIF2.Contains(nE))) {
-      IntTools_CommonPrt aCP = aEF.CommonPart();
-      if(aCP.Type() == TopAbs_VERTEX) {
-        nVNew = aEF.IndexNew();
+  for (i = 0; i < aNbLines[4]; ++i) {
+    const BOPDS_InterfEF& aInt = aEFs(i);
+    if (aInt.HasIndexNew()) {
+      aInt.Indices(nS1, nS2);
+      if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
+        nVNew = aInt.IndexNew();
         aMVStick.Add(nVNew);
         aMVEF.Add(nVNew);
       }
@@ -1579,31 +1522,23 @@ void BOPAlgo_PaveFiller::PerformFF()
 }
 
 //=======================================================================
-// function: GetFullFaceMap
+// function: GetFullShapeMap
 // purpose: 
 //=======================================================================
-void BOPAlgo_PaveFiller::GetFullFaceMap(const Standard_Integer nF,
-                                        BOPCol_MapOfInteger& aMI)
+void BOPAlgo_PaveFiller::GetFullShapeMap(const Standard_Integer nF,
+                                         BOPCol_MapOfInteger& aMI)
 {
-  Standard_Integer nV, nE;
-  TopoDS_Edge aE;
-  TopoDS_Vertex aV;
-  //face
+  BOPCol_ListIteratorOfListOfInteger aIt;
+  Standard_Integer nS;
+  //
+  const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
+  const BOPCol_ListOfInteger& aLI = aSI.SubShapes();
+  //
   aMI.Add(nF);
-  //edges
-  const TopoDS_Face& aF = (*(TopoDS_Face*)(&myDS->Shape(nF)));
-  TopExp_Explorer anExp(aF, TopAbs_EDGE);
-  for (; anExp.More(); anExp.Next()) {
-    aE = (*(TopoDS_Edge *)(&anExp.Current()));
-    nE = myDS->Index(aE);
-    aMI.Add(nE);
-  }
-  //vertices
-  TopExp_Explorer anExpV(aF, TopAbs_VERTEX);
-  for (; anExpV.More(); anExpV.Next()) {
-    aV = (*(TopoDS_Vertex *)(&anExpV.Current()));
-    nV = myDS->Index(aV);
-    aMI.Add(nV);
+  aIt.Initialize(aLI);
+  for (; aIt.More(); aIt.Next()) {
+    nS = aIt.Value();
+    aMI.Add(nS);
   }
 }
 
@@ -1637,18 +1572,27 @@ void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC,
 //=======================================================================
   void BOPAlgo_PaveFiller::PutPaveOnCurve(const Standard_Integer nV,
                                           const Standard_Real aTolR3D,
-                                          const BOPDS_Curve& aNC, 
-                                          Handle(BOPDS_PaveBlock)& aPB,
-                                          BOPCol_DataMapOfIntegerReal& aMVTol)
+                                          BOPDS_Curve& aNC,
+                                          const BOPCol_MapOfInteger& aMI,
+                                          BOPCol_DataMapOfIntegerReal& aMVTol,
+                                          const Standard_Integer iCheckExtend)
 {
   Standard_Boolean bIsVertexOnLine;
   Standard_Real aT, aTol, aTolNew;
   BOPDS_Pave aPave;
   //
   const TopoDS_Vertex aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
+  Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
   const IntTools_Curve& aIC = aNC.Curve();
   //
   bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT);
+  if (!bIsVertexOnLine && iCheckExtend) {
+    aTol = BRep_Tool::Tolerance(aV);
+    //
+    ExtendedTolerance(nV, aMI, aTol, iCheckExtend);
+    bIsVertexOnLine=myContext->IsVertexOnLine(aV, aTol, aIC, aTolR3D, aT);
+  }
+  //
   if (bIsVertexOnLine) {
     aPave.SetIndex(nV);
     aPave.SetParameter(aT);
@@ -1975,7 +1919,7 @@ void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC,
 //=======================================================================
 Standard_Boolean 
   BOPAlgo_PaveFiller::CheckPlanes(const Standard_Integer nF1,
-                                 const Standard_Integer nF2)const
+                                  const Standard_Integer nF2)const
 {
   Standard_Boolean bToIntersect;
   Standard_Integer i, nV2, iCnt;
@@ -1998,11 +1942,11 @@ Standard_Boolean
     for (; aIt.More(); aIt.Next()) {
       nV2=aIt.Value();
       if (aMVIn1.Contains(nV2) || aMVOn1.Contains(nV2)) {
-       ++iCnt;
-       if (iCnt>1) {
-         bToIntersect=!bToIntersect;
-         break;
-       }
+        ++iCnt;
+        if (iCnt>1) {
+          bToIntersect=!bToIntersect;
+          break;
+        }
       }
     }
   }
@@ -2010,6 +1954,72 @@ Standard_Boolean
   return bToIntersect;
 }
 //=======================================================================
+//function : UpdatePaveBlocks
+//purpose  : 
+//=======================================================================
+void BOPAlgo_PaveFiller::UpdatePaveBlocks(const BOPCol_DataMapOfIntegerInteger& aDMI)
+{
+  if (aDMI.IsEmpty()) {
+    return;
+  }
+  //
+  Standard_Integer nSp, aNbPBP, nV[2], i, j;
+  Standard_Real aT[2];
+  Standard_Boolean bCB, bRebuild;
+  BOPDS_ListIteratorOfListOfPaveBlock aItPB;
+  BOPDS_MapOfPaveBlock aMPB;
+  //
+  BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
+  aNbPBP = aPBP.Extent();
+  for (i=0; i<aNbPBP; ++i) {
+    BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
+    //
+    aItPB.Initialize(aLPB);
+    for (; aItPB.More(); aItPB.Next()) {
+      Handle(BOPDS_PaveBlock) aPB=aItPB.Value();
+      const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
+      bCB = !aCB.IsNull();
+      if (bCB) {
+        aPB=aCB->PaveBlock1();
+      }
+      //
+      if (aMPB.Add(aPB)) {
+        bRebuild = Standard_False;
+        aPB->Indices(nV[0], nV[1]);
+        aPB->Range(aT[0], aT[1]);
+        //
+        for (j = 0; j < 2; ++j) {
+          if (aDMI.IsBound(nV[j])) {
+            BOPDS_Pave aPave;
+            //
+            nV[j] = aDMI.Find(nV[j]);
+            aPave.SetIndex(nV[j]);
+            aPave.SetParameter(aT[j]);
+            //
+            bRebuild = Standard_True;
+            if (!j) {
+              aPB->SetPave1(aPave);
+            } else {
+              aPB->SetPave2(aPave);
+            }
+          }
+        }
+        //
+        if (bRebuild) {
+          nSp = SplitEdge(aPB->Edge(), nV[0], aT[0], nV[1], aT[1]);
+          if (bCB) {
+            aCB->SetEdge(nSp);
+          }
+          else {
+            aPB->SetEdge(nSp);
+          }
+        }// if (bRebuild) {
+      }// if (aMPB.Add(aPB)) {
+    }// for (; aItPB.More(); aItPB.Next()) {
+  }// for (i=0; i<aNbPBP; ++i) {
+  aMPB.Clear();
+}
+//=======================================================================
 //function : ToleranceFF
 //purpose  : Computes the TolFF according to the tolerance value and 
 //           types of the faces.
index 6219119..b77ca8f 100644 (file)
@@ -76,18 +76,12 @@ static void UpdateVertices(const TopoDS_Edge& aE,
     return;
   }
   //
-  Standard_Boolean bCB,bV1, bV2;
+  Standard_Boolean bCB, bV1, bV2;
   Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, nOrE;
   Standard_Real aT1, aT2;
-  TopoDS_Vertex aV1, aV2;
-  TopoDS_Edge aE, aSp;
   Handle(NCollection_IncAllocator) aAllocator;
   BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB;
   Handle(BOPDS_PaveBlock) aPB, aPBx;
-  
-  BOPDS_ShapeInfo aSI;
-  //
-  aSI.SetShapeType(TopAbs_EDGE);
   //-----------------------------------------------------scope f
   //
   aAllocator=new NCollection_IncAllocator();
@@ -129,30 +123,10 @@ static void UpdateVertices(const TopoDS_Edge& aE,
       //
       if (aMPB.Add(aPB)) {
         nE=aPB->OriginalEdge();
+        aPB->Indices(nV1, nV2);
+        aPB->Range(aT1, aT2);
         //
-        const BOPDS_Pave& aPave1=aPB->Pave1();
-        aPave1.Contents(nV1, aT1);
-        //
-        const BOPDS_Pave& aPave2=aPB->Pave2();
-        aPave2.Contents(nV2, aT2);
-        //
-        aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
-        aE.Orientation(TopAbs_FORWARD);
-        //
-        aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
-        aV1.Orientation(TopAbs_FORWARD); 
-        //
-        aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
-        aV2.Orientation(TopAbs_REVERSED); 
-        //
-        BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);  
-        //
-        aSI.SetShape(aSp);
-        //
-        Bnd_Box& aBox=aSI.ChangeBox();
-        BRepBndLib::Add(aSp, aBox);
-        //
-        nSp=myDS->Append(aSI);
+        nSp = SplitEdge(nE, nV1, aT1, nV2, aT2);
         //
         if (bCB) {
           aCB->SetEdge(nSp);
@@ -170,6 +144,43 @@ static void UpdateVertices(const TopoDS_Edge& aE,
 }
 
 //=======================================================================
+// function: SplitEdge
+// purpose: 
+//=======================================================================
+Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE, 
+                                               const Standard_Integer nV1,
+                                               const Standard_Real aT1, 
+                                               const Standard_Integer nV2, 
+                                               const Standard_Real aT2)
+{
+  Standard_Integer nSp;
+  TopoDS_Vertex aV1, aV2;
+  TopoDS_Edge aE, aSp;
+  BOPDS_ShapeInfo aSI;
+  //
+  aSI.SetShapeType(TopAbs_EDGE);
+  //
+  aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
+  aE.Orientation(TopAbs_FORWARD);
+  //
+  aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
+  aV1.Orientation(TopAbs_FORWARD); 
+  //
+  aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
+  aV2.Orientation(TopAbs_REVERSED); 
+  //
+  BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);  
+  //
+  aSI.SetShape(aSp);
+  //
+  Bnd_Box& aBox=aSI.ChangeBox();
+  BRepBndLib::Add(aSp, aBox);
+  //
+  nSp=myDS->Append(aSI);
+  return nSp;
+}
+
+//=======================================================================
 // function: MakePCurves
 // purpose: 
 //=======================================================================
index b6f5034..73a1012 100755 (executable)
@@ -526,7 +526,7 @@ IntTools_FClass2d::IntTools_FClass2d()
 //purpose  : 
 //=======================================================================
   TopAbs_State IntTools_FClass2d::Perform(const gp_Pnt2d& _Puv,
-                                         const Standard_Boolean RecadreOnPeriodic) const
+                                          const Standard_Boolean RecadreOnPeriodic) const
 { 
   Standard_Integer nbtabclass = TabClass.Length();
   if (nbtabclass == 0)
@@ -549,83 +549,93 @@ IntTools_FClass2d::IntTools_FClass2d()
   const Standard_Real    uperiod = IsUPer ? surf->UPeriod() : 0.0;
   const Standard_Real    vperiod = IsVPer ? surf->VPeriod() : 0.0;
 
-  Standard_Boolean urecadre = Standard_False;
-  Standard_Boolean vrecadre = Standard_False;
+  Standard_Boolean urecadre, vrecadre, bUseClassifier;
   Standard_Integer dedans = 1;
-
+  //
+  urecadre = Standard_False;
+  vrecadre = Standard_False;
+  //
   if (RecadreOnPeriodic) {
     
     if (IsUPer) {
       if (uu < Umin)
-       while (uu < Umin) {
-         uu += uperiod;
-       }
+        while (uu < Umin) {
+          uu += uperiod;
+        }
       else {
-       while (uu >= Umin){
-         uu -= uperiod;
-       }
-       uu += uperiod;
+        while (uu >= Umin){
+          uu -= uperiod;
+        }
+        uu += uperiod;
       }
     }// if (IsUPer) {
     
     if (IsVPer) {
       if (vv < Vmin)
-       while (vv < Vmin){
-         vv += vperiod;
-       }
+        while (vv < Vmin){
+          vv += vperiod;
+        }
       else {
-       while (vv >= Vmin) {
-         vv -= vperiod;
-       }
-       vv += vperiod;
+        while (vv >= Vmin) {
+          vv -= vperiod;
+        }
+        vv += vperiod;
       }
     }//if (IsVPer) {
   }
-
+  //
   for(;;) {
     dedans = 1;
     gp_Pnt2d Puv(u,v);
-      
-    if(TabOrien(1)!=-1) {
+    bUseClassifier = (TabOrien(1) == -1);
+    if(!bUseClassifier) {
       Standard_Integer n, cur, TabOrien_n ;
       for(n=1; n<=nbtabclass; n++) { 
-       cur = ((CSLib_Class2d *)TabClass(n))->SiDans(Puv);
-       TabOrien_n=TabOrien(n);
-
-       if(cur==1) { 
-         if(TabOrien_n==0) { 
-           dedans = -1; 
-           break;
-         }
-       }
-       else if(cur==-1) { 
-         if(TabOrien_n==1) {  
-           dedans = -1; 
-           break;
-         }
-       }
-       else { 
-         dedans = 0;
-         break;
-       }
+        cur = ((CSLib_Class2d *)TabClass(n))->SiDans(Puv);
+        TabOrien_n=TabOrien(n);
+        
+        if(cur==1) { 
+          if(TabOrien_n==0) { 
+            dedans = -1; 
+            break;
+          }
+        }
+        else if(cur==-1) { 
+          if(TabOrien_n==1) {  
+            dedans = -1; 
+            break;
+          }
+        }
+        else { 
+          dedans = 0;
+          break;
+        }
       } // for(n=1; n<=nbtabclass; n++)
-
+      
       if(dedans==0) { 
-       BRepClass_FaceClassifier aClassifier;
-       aClassifier.Perform(Face,Puv,Toluv);
-       Status = aClassifier.State();
-      }
-      if(dedans == 1) { 
-       Status = TopAbs_IN;
-      }
-      if(dedans == -1) {
-       Status = TopAbs_OUT;
+        bUseClassifier = Standard_True;
+      } 
+      else {
+        Status = (dedans == 1) ? TopAbs_IN : TopAbs_OUT;
       }
     } // if(TabOrien(1)!=-1) {
-    
-    else {  //-- TabOrien(1)=-1   Wrong Wire
+    //compute state of the point using face classifier
+    if (bUseClassifier) {
+      //compute tolerance to use in face classifier
+      Standard_Real aURes, aVRes, aFCTol;
+      Standard_Boolean bUIn, bVIn;
+      //
+      aURes = surf->UResolution(Toluv);
+      aVRes = surf->VResolution(Toluv);
+      //
+      bUIn = (u >= Umin) && (u <= Umax);
+      bVIn = (v >= Vmin) && (v <= Vmax);
+      //
+      aFCTol = (bUIn==bVIn) ? Max(aURes, aVRes) : 
+        (!bUIn ? aURes : aVRes);
+      //
       BRepClass_FaceClassifier aClassifier;
-      aClassifier.Perform(Face,Puv,Toluv);
+      aClassifier.Perform(Face,Puv,aFCTol);
       Status = aClassifier.State();
     }
     
@@ -641,25 +651,25 @@ IntTools_FClass2d::IntTools_FClass2d()
     }
     else {
       if (IsUPer){
-       u += uperiod;
+        u += uperiod;
       }
     }
 
     if (u > Umax || !IsUPer) {
       if (!vrecadre){
-       v = vv;
-       vrecadre = Standard_True;
+        v = vv;
+        vrecadre = Standard_True;
       }
       else {
-       if (IsVPer){
-         v += vperiod;
-       }
+        if (IsVPer){
+          v += vperiod;
+        }
       }
 
       u = uu;
       
       if (v > Vmax || !IsVPer) {
-       return Status;
+        return Status;
       }
     }
   } //while (1)
index 46e9432..3549f43 100644 (file)
@@ -2,4 +2,4 @@ restore [locate_data_file GEN747_nofog.rle] a
 explode a
 bsection result a_1 a_2
 
-set length 79.8847
+set length 72.4222
diff --git a/tests/bugs/modalg_5/bug24286 b/tests/bugs/modalg_5/bug24286
new file mode 100644 (file)
index 0000000..e8981ae
--- /dev/null
@@ -0,0 +1,31 @@
+puts "========="
+puts "OCC24286"
+puts "========="
+puts ""
+###########################################################
+# Wrong result done by General Fuse algorithm
+###########################################################
+
+restore [locate_data_file bug24286_pipeFiss.brep] b1
+restore [locate_data_file bug24286_shellFiss.brep] b2
+
+bclearobjects
+bcleartools
+baddobjects b1 b2
+
+bfillds
+bbuild result
+
+set square 281195
+
+set nb_v_good 12
+set nb_e_good 22
+set nb_w_good 10
+set nb_f_good 10
+set nb_sh_good 1
+set nb_sol_good 0
+set nb_compsol_good 0
+set nb_compound_good 2
+set nb_shape_good 57
+
+set 2dviewer 1