0026738: Make Boolean operations safely treating arguments when running with fuzzy...
authormsv <msv@opencascade.com>
Tue, 8 Nov 2016 12:20:42 +0000 (15:20 +0300)
committerapn <apn@opencascade.com>
Tue, 8 Nov 2016 13:42:44 +0000 (16:42 +0300)
When fuzzy option is in force prevent increasing tolerance of input shapes. Instead pass increased by fuzzy value the tolerances of sub-shapes everywhere where it is needed by intersection algorithms.

The following changes in API have been made:

- The methods SetFuzzyValue and FuzzyValue have been moved from the classes BOPAlgo_ArgumentAnalyzer, BOPAlgo_Builder, and BOPAlgo_PaveFiller to the base class BOPAlgo_Algo.
- The public method BOPDS_DS::VerticesOnIn has been renamed to SubShapesOnIn, and the new output parameter theCommonPB has been added.
- In BOPTools_AlgoTools, a new argument "theFuzzyValue" has been added in the methods ComputeVV and AreFacesSameDomain.
- In IntTools_Context, a new argument "theFuzzyValue" has been added in the methods ComputeVE and ComputeVF.
- The methods SetFuzzyValue and FuzzyValue have been added in the classes IntTools_EdgeEdge, IntTools_FaceFace.
- In the class IntTools_EdgeFace, the methods SetTolE, SetTolF, TolE, TolF have been removed, and the methods SetFuzzyValue, FuzzyValue have been added.
- The new argument "theTol" has been added in the method IntTools_WLineTool::DecompositionOfWLine.

Some improvements in algorithms have been made during fighting with regressions:

- Correct initialization of pave blocks for degenerated edges.
- In BOPAlgo_PaveFiller::MakeBlocks(), filter out paves on intersection curve that were put on the curve accidentally due to wide range of E-F intersection vertex.
- In the method IntTools_Tools::ComputeTolerance the margin added to the computed tolerance has been increased up to 0.001%.
- The method BOPAlgo_PaveFiller::PutPaveOnCurve has been corrected in order to use the original vertex tolerance instead of the value increased during putting it on other curves.
- The new method BOPDS_PaveBlock::RemoveExtPave has been added.
- The vertex tolerance computation in BOPTools_AlgoTools::CorrectCurveOnSurface has been improved, taking into account intersection segments between p-curves (to avoid regression on "bugs modalg_6 bug22794").
- Improve IsExistingPaveBlock to make more stable catching of coincidence of common block with section curve (against regression "bugs modalg_4 bug697_2" on Linux).

Test case for the bug has been added.

The following test cases have been updated as improvements:
boolean gdml_private ZH2 ZI7 ZJ7
boolean volumemaker C4

The test case bugs/modalg_4/pro19653 has been corrected to make it stable. See comment inside the script for details.

The test case bugs/modalg_6/bug25880 has been corrected to suppress wrong bfuse commands.

The test bugs/modalg_6/bug26954_3 has been corrected to compare the result with more precise reference value.

The "faulty" TODO in boolean/volumemaker/A8 has been made actual for Linux as well.

//Eliminate compilation error on Linux.

50 files changed:
src/BOPAlgo/BOPAlgo_Algo.cxx
src/BOPAlgo/BOPAlgo_Algo.hxx
src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.cxx
src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.hxx
src/BOPAlgo/BOPAlgo_ArgumentAnalyzer.lxx
src/BOPAlgo/BOPAlgo_BOP.cxx
src/BOPAlgo/BOPAlgo_Builder.cxx
src/BOPAlgo/BOPAlgo_Builder.hxx
src/BOPAlgo/BOPAlgo_Builder_2.cxx
src/BOPAlgo/BOPAlgo_CheckerSI.cxx
src/BOPAlgo/BOPAlgo_PaveFiller.cxx
src/BOPAlgo/BOPAlgo_PaveFiller.hxx
src/BOPAlgo/BOPAlgo_PaveFiller_1.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_4.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx
src/BOPAlgo/BOPAlgo_PaveFiller_9.cxx
src/BOPDS/BOPDS_DS.cxx
src/BOPDS/BOPDS_DS.hxx
src/BOPDS/BOPDS_DS.lxx
src/BOPDS/BOPDS_PaveBlock.cxx
src/BOPDS/BOPDS_PaveBlock.hxx
src/BOPTools/BOPTools_AlgoTools.cxx
src/BOPTools/BOPTools_AlgoTools.hxx
src/BOPTools/BOPTools_AlgoTools_1.cxx
src/IntTools/IntTools_BeanFaceIntersector.cxx
src/IntTools/IntTools_Context.cxx
src/IntTools/IntTools_Context.hxx
src/IntTools/IntTools_EdgeEdge.cxx
src/IntTools/IntTools_EdgeEdge.hxx
src/IntTools/IntTools_EdgeEdge.lxx
src/IntTools/IntTools_EdgeFace.cxx
src/IntTools/IntTools_EdgeFace.hxx
src/IntTools/IntTools_FaceFace.cxx
src/IntTools/IntTools_FaceFace.hxx
src/IntTools/IntTools_Tools.cxx
src/IntTools/IntTools_WLineTool.cxx
src/IntTools/IntTools_WLineTool.hxx
tests/boolean/gdml_private/ZH2
tests/boolean/gdml_private/ZI7
tests/boolean/gdml_private/ZJ7
tests/boolean/volumemaker/A8
tests/boolean/volumemaker/C4
tests/bugs/modalg_4/pro19653
tests/bugs/modalg_6/bug25880
tests/bugs/modalg_6/bug26738 [new file with mode: 0644]
tests/bugs/modalg_6/bug26954_3

index b51db21..22265f9 100644 (file)
@@ -19,6 +19,7 @@
 #include <BOPAlgo_Algo.hxx>
 #include <Message_ProgressIndicator.hxx>
 #include <NCollection_BaseAllocator.hxx>
+#include <Precision.hxx>
 #include <Standard_NotImplemented.hxx>
 #include <Standard_ProgramError.hxx>
 
@@ -55,7 +56,8 @@ BOPAlgo_Algo::BOPAlgo_Algo()
   myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
   myErrorStatus(1),
   myWarningStatus(0),
-  myRunParallel(myGlobalRunParallel)
+  myRunParallel(myGlobalRunParallel),
+  myFuzzyValue(Precision::Confusion())
 {}
 //=======================================================================
 // function: 
@@ -67,7 +69,8 @@ BOPAlgo_Algo::BOPAlgo_Algo
   myAllocator(theAllocator),
   myErrorStatus(1),
   myWarningStatus(0),
-  myRunParallel(myGlobalRunParallel)
+  myRunParallel(myGlobalRunParallel),
+  myFuzzyValue(Precision::Confusion())
 {}
 
 //=======================================================================
@@ -134,6 +137,22 @@ Standard_Boolean BOPAlgo_Algo::RunParallel()const
   return myRunParallel;
 }
 //=======================================================================
+//function : SetFuzzyValue
+//purpose  : 
+//=======================================================================
+void BOPAlgo_Algo::SetFuzzyValue(const Standard_Real theFuzz)
+{
+  myFuzzyValue = Max(theFuzz, Precision::Confusion());
+}
+//=======================================================================
+//function : FuzzyValue
+//purpose  : 
+//=======================================================================
+Standard_Real BOPAlgo_Algo::FuzzyValue() const
+{
+  return myFuzzyValue;
+}
+//=======================================================================
 //function : SetProgressIndicator
 //purpose  : 
 //=======================================================================
index 6e83b43..9141e2f 100644 (file)
@@ -55,6 +55,12 @@ public:
   
   //! Returns the flag of parallel processing
   Standard_EXPORT Standard_Boolean RunParallel() const;
+
+  //! Sets the additional tolerance
+  Standard_EXPORT void SetFuzzyValue (const Standard_Real theFuzz);
+  
+  //! Returns the additional tolerance
+  Standard_EXPORT Standard_Real FuzzyValue() const;
   
   //! Set the Progress Indicator object.
   Standard_EXPORT void SetProgressIndicator (const Handle(Message_ProgressIndicator)& theObj);
@@ -83,6 +89,7 @@ Standard_EXPORT virtual ~BOPAlgo_Algo();
   Standard_Integer myErrorStatus;
   Standard_Integer myWarningStatus;
   Standard_Boolean myRunParallel;
+  Standard_Real myFuzzyValue;
   Handle(Message_ProgressIndicator) myProgressIndicator;
 
 
index ea7771d..78ee759 100644 (file)
@@ -68,8 +68,7 @@ myMergeEdgeMode(Standard_False),
 myContinuityMode(Standard_False),
 myCurveOnSurfaceMode(Standard_False),
 myEmpty1(Standard_False),
-myEmpty2(Standard_False),
-myFuzzyValue(0.)
+myEmpty2(Standard_False)
 {
 }
 //=======================================================================
@@ -79,7 +78,6 @@ myFuzzyValue(0.)
 BOPAlgo_ArgumentAnalyzer::~BOPAlgo_ArgumentAnalyzer()
 {
   myResult.Clear();
-  myToleranceMap.Clear();
 }
 
 // ================================================================================
@@ -167,26 +165,21 @@ void BOPAlgo_ArgumentAnalyzer::Perform()
     //
     UserBreak();
     //
-    // 2. Update Tolerances according to myFuzzyValue
-    UpdateTolerances();
-    //
-    UserBreak();
-    //
-    // 3. Test types
+    // 2. Test types
     if(myArgumentTypeMode) {
       TestTypes();
     }
     //
     UserBreak();
     //
-    // 4. Test self-interference
+    // 3. Test self-interference
     if(mySelfInterMode) {
       TestSelfInterferences();
     }
     //
     UserBreak();
     //
-    // 5. Test small edges
+    // 4. Test small edges
     if(mySmallEdgeMode) {
       if(!(!myResult.IsEmpty() && myStopOnFirst))
         TestSmallEdge();
@@ -194,7 +187,7 @@ void BOPAlgo_ArgumentAnalyzer::Perform()
     //
     UserBreak();
     //
-    // 6. Test possibility to rebuild faces
+    // 5. Test possibility to rebuild faces
     if(myRebuildFaceMode) {
       if(!(!myResult.IsEmpty() && myStopOnFirst))
         TestRebuildFace();
@@ -202,7 +195,7 @@ void BOPAlgo_ArgumentAnalyzer::Perform()
     //
     UserBreak();
     //
-    // 7. Test tangent
+    // 6. Test tangent
     if(myTangentMode) {
       if(!(!myResult.IsEmpty() && myStopOnFirst))
         TestTangent();
@@ -210,7 +203,7 @@ void BOPAlgo_ArgumentAnalyzer::Perform()
     //
     UserBreak();
     //
-    // 8. Test merge vertices
+    // 7. Test merge vertices
     if(myMergeVertexMode) {
       if(!(!myResult.IsEmpty() && myStopOnFirst))
         TestMergeVertex();
@@ -218,7 +211,7 @@ void BOPAlgo_ArgumentAnalyzer::Perform()
     //
     UserBreak();
     //
-    // 9. Test merge edges
+    // 8. Test merge edges
     if(myMergeEdgeMode) {
       if(!(!myResult.IsEmpty() && myStopOnFirst))
         TestMergeEdge();
@@ -226,7 +219,7 @@ void BOPAlgo_ArgumentAnalyzer::Perform()
     //
     UserBreak();
     //
-    // 10. Test shapes continuity
+    // 9. Test shapes continuity
     if(myContinuityMode) {
       if(!(!myResult.IsEmpty() && myStopOnFirst))
         TestContinuity();
@@ -234,7 +227,7 @@ void BOPAlgo_ArgumentAnalyzer::Perform()
     //
     UserBreak();
     //
-    // 11. Test validity of the curves on the surfaces
+    // 10. Test validity of the curves on the surfaces
     if(myCurveOnSurfaceMode) {
       if(!(!myResult.IsEmpty() && myStopOnFirst))
         TestCurveOnSurface();
@@ -245,8 +238,6 @@ void BOPAlgo_ArgumentAnalyzer::Perform()
     aResult.SetCheckStatus(BOPAlgo_CheckUnknown);
     myResult.Append(aResult);
   }
-  //
-  SetDefaultTolerances();
 }
 
 // ================================================================================
@@ -369,6 +360,7 @@ void BOPAlgo_ArgumentAnalyzer::TestSelfInterferences()
     aChecker.SetArguments(anArgs);
     aChecker.SetNonDestructive(Standard_True);
     aChecker.SetRunParallel(myRunParallel);
+    aChecker.SetFuzzyValue(myFuzzyValue);
     aChecker.SetProgressIndicator(myProgressIndicator);
     //
     aChecker.Perform();
@@ -913,122 +905,3 @@ void BOPAlgo_ArgumentAnalyzer::TestCurveOnSurface()
     }
   }
 }
-
-// ================================================================================
-// function: UpdateTolerances
-// purpose:
-// ================================================================================
-void BOPAlgo_ArgumentAnalyzer::UpdateTolerances()
-{
-  if (myFuzzyValue == 0.) {
-    return;
-  }
-  //
-  BOPCol_MapOfShape aMapShapes;
-  //
-  if (!myShape1.IsNull()) {
-    BOPTools::MapShapes(myShape1, aMapShapes);
-  }
-  if (!myShape2.IsNull()) {
-    BOPTools::MapShapes(myShape2, aMapShapes);
-  }
-  //
-  if (aMapShapes.IsEmpty()) {
-    return;
-  }
-  //
-  Standard_Real aTol, aFuzz;
-  TopAbs_ShapeEnum aType;
-  BOPCol_MapIteratorOfMapOfShape aIt;
-  //
-  aFuzz = myFuzzyValue / 2.;
-  aIt.Initialize(aMapShapes);
-  for (; aIt.More(); aIt.Next()) {
-    const TopoDS_Shape& aS = aIt.Value();
-    aType = aS.ShapeType();
-    //
-    switch (aType) {
-    case TopAbs_VERTEX: {
-      const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aS;
-      const Handle(BRep_TVertex)& TV = 
-        *((Handle(BRep_TVertex)*)&aV.TShape());
-      aTol = TV->Tolerance();
-      myToleranceMap.Bind(aS, aTol);
-      TV->Tolerance(aTol + aFuzz);
-      break;
-    }
-    case TopAbs_EDGE: {
-      const TopoDS_Edge& aE = *(TopoDS_Edge*)&aS;
-      const Handle(BRep_TEdge)& TE = 
-        *((Handle(BRep_TEdge)*)&aE.TShape());
-      aTol = TE->Tolerance();
-      myToleranceMap.Bind(aS, aTol);
-      TE->Tolerance(aTol + aFuzz);
-      break;
-    }
-    case TopAbs_FACE: {
-      const TopoDS_Face& aF = *(TopoDS_Face*)&aS;
-      const Handle(BRep_TFace)& TF = 
-        *((Handle(BRep_TFace)*)&aF.TShape());
-      aTol = TF->Tolerance();
-      myToleranceMap.Bind(aS, aTol);
-      TF->Tolerance(aTol + aFuzz);
-      break;
-    }
-    default:
-      break;
-    } // switch (aType) {
-  } // for (; aIt.More(); aIt.Next()) {
-}
-
-// ================================================================================
-// function: SetDefaultTolerances
-// purpose:
-// ================================================================================
-void BOPAlgo_ArgumentAnalyzer::SetDefaultTolerances()
-{
-  if (myFuzzyValue == 0.) {
-    return;
-  }
-  //
-  if (myToleranceMap.IsEmpty()) {
-    return;
-  }
-  //
-  Standard_Real aTol;
-  TopAbs_ShapeEnum aType;
-  BOPCol_DataMapIteratorOfDataMapOfShapeReal aIt;
-  //
-  aIt.Initialize(myToleranceMap);
-  for (; aIt.More(); aIt.Next()) {
-    const TopoDS_Shape& aS = aIt.Key();
-    aTol = aIt.Value();
-    aType = aS.ShapeType();
-    //
-    switch (aType) {
-    case TopAbs_VERTEX: {
-      const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aS;
-      const Handle(BRep_TVertex)& TV = 
-        *((Handle(BRep_TVertex)*)&aV.TShape());
-      TV->Tolerance(aTol);
-      break;
-    }
-    case TopAbs_EDGE: {
-      const TopoDS_Edge& aE = *(TopoDS_Edge*)&aS;
-      const Handle(BRep_TEdge)& TE = 
-        *((Handle(BRep_TEdge)*)&aE.TShape());
-      TE->Tolerance(aTol);
-      break;
-    }
-    case TopAbs_FACE: {
-      const TopoDS_Face& aF = *(TopoDS_Face*)&aS;
-      const Handle(BRep_TFace)& TF = 
-        *((Handle(BRep_TFace)*)&aF.TShape());
-      TF->Tolerance(aTol);
-      break;
-    }
-    default:
-      break;
-    } // switch (aType) {
-  } // for (; aIt.More(); aIt.Next()) {
-}
index 78ce595..540e8f2 100644 (file)
@@ -106,14 +106,6 @@ Standard_EXPORT virtual ~BOPAlgo_ArgumentAnalyzer();
   //! returns a result of test
   Standard_EXPORT const BOPAlgo_ListOfCheckResult& GetCheckResult() const;
   
-  //! Sets the additional tolerance
-    void SetFuzzyValue (const Standard_Real theFuzz);
-  
-  //! Returns the additional tolerance
-    Standard_Real FuzzyValue() const;
-
-
-
 
 protected:
 
@@ -141,19 +133,10 @@ protected:
   
   Standard_EXPORT void TestCurveOnSurface();
   
-  //! Updates the shapes tolerance values.
-  Standard_EXPORT void UpdateTolerances();
-  
-  //! Reverts the tolerance values for all entities to default values.
-  Standard_EXPORT void SetDefaultTolerances();
-
-
-
 
 private:
 
 
-
   TopoDS_Shape myShape1;
   TopoDS_Shape myShape2;
   Standard_Boolean myStopOnFirst;
@@ -170,9 +153,6 @@ private:
   Standard_Boolean myEmpty1;
   Standard_Boolean myEmpty2;
   BOPAlgo_ListOfCheckResult myResult;
-  Standard_Real myFuzzyValue;
-  BOPCol_DataMapOfShapeReal myToleranceMap;
-
 
 };
 
@@ -180,7 +160,4 @@ private:
 #include <BOPAlgo_ArgumentAnalyzer.lxx>
 
 
-
-
-
 #endif // _BOPAlgo_ArgumentAnalyzer_HeaderFile
index 8b3d304..d5102f0 100644 (file)
@@ -61,22 +61,6 @@ inline Standard_Boolean& BOPAlgo_ArgumentAnalyzer::CurveOnSurfaceMode()
 {
   return myCurveOnSurfaceMode;
 }
-//=======================================================================
-//function : SetFuzzyValue
-//purpose  : 
-//=======================================================================
-inline void BOPAlgo_ArgumentAnalyzer::SetFuzzyValue(const Standard_Real theFuzz)
-{
-  myFuzzyValue = (theFuzz < 0.) ? 0. : theFuzz;
-}
-//=======================================================================
-//function : FuzzyValue
-//purpose  : 
-//=======================================================================
-inline Standard_Real BOPAlgo_ArgumentAnalyzer::FuzzyValue() const
-{
-  return myFuzzyValue;
-}
 // inline Standard_Boolean& BOPAlgo_ArgumentAnalyzer::MergeFaceMode() 
 // {
 //   return myMergeFaceMode;
index 8d8739b..aec1a45 100644 (file)
@@ -394,6 +394,8 @@ void BOPAlgo_BOP::PerformInternal1(const BOPAlgo_PaveFiller& theFiller)
   myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller;
   myDS=myPaveFiller->PDS();
   myContext=myPaveFiller->Context();
+  myFuzzyValue = myPaveFiller->FuzzyValue();
+  myNonDestructive = myPaveFiller->NonDestructive();
   //
   // 1. CheckData
   CheckData();
index 1f0a76e..59e909c 100644 (file)
@@ -51,7 +51,6 @@ BOPAlgo_Builder::BOPAlgo_Builder()
   myShapesSD(100, myAllocator),
   mySplits(100, myAllocator),
   myOrigins(100, myAllocator),
-  myFuzzyValue(0.),
   myNonDestructive(Standard_False)
 {
 }
@@ -72,7 +71,6 @@ BOPAlgo_Builder::BOPAlgo_Builder
   myShapesSD(100, myAllocator),
   mySplits(100, myAllocator),
   myOrigins(100, myAllocator),
-  myFuzzyValue(0.),
   myNonDestructive(Standard_False)
 {
 }
@@ -186,22 +184,6 @@ BOPDS_PDS BOPAlgo_Builder::PDS()
   return myDS;
 }
 //=======================================================================
-//function : SetFuzzyValue
-//purpose  : 
-//=======================================================================
-void BOPAlgo_Builder::SetFuzzyValue(const Standard_Real theFuzz)
-{
-  myFuzzyValue = (theFuzz < 0.) ? 0. : theFuzz;
-}
-//=======================================================================
-//function : FuzzyValue
-//purpose  : 
-//=======================================================================
-Standard_Real BOPAlgo_Builder::FuzzyValue() const
-{
-  return myFuzzyValue;
-}
-//=======================================================================
 //function : SetNonDestructive
 //purpose  : 
 //=======================================================================
@@ -329,6 +311,8 @@ void BOPAlgo_Builder::PerformInternal1(const BOPAlgo_PaveFiller& theFiller)
   myPaveFiller=(BOPAlgo_PaveFiller*)&theFiller;
   myDS=myPaveFiller->PDS();
   myContext=myPaveFiller->Context();
+  myFuzzyValue = myPaveFiller->FuzzyValue();
+  myNonDestructive = myPaveFiller->NonDestructive();
   //
   // 1. CheckData
   CheckData();
index 2a229a0..238aa17 100644 (file)
@@ -93,12 +93,7 @@ Standard_EXPORT virtual ~BOPAlgo_Builder();
   //! Returns mySplits.
   Standard_EXPORT const BOPCol_DataMapOfShapeListOfShape& Splits() const;
   
-  //! Sets the additional tolerance
-  Standard_EXPORT void SetFuzzyValue (const Standard_Real theFuzz);
   
-  //! Returns the additional tolerance
-  Standard_EXPORT Standard_Real FuzzyValue() const;
-
   //! Sets the flag that defines the mode of treatment.
   //! In non-destructive mode the argument shapes are not modified. Instead
   //! a copy of a sub-shape is created in the result if it is needed to be updated.
@@ -115,7 +110,6 @@ Standard_EXPORT virtual ~BOPAlgo_Builder();
 
 protected:
 
-  
   //! Prepare information for history support
   Standard_EXPORT virtual void PrepareHistory() Standard_OVERRIDE;
   
@@ -172,21 +166,11 @@ protected:
   BOPCol_DataMapOfShapeShape myShapesSD;
   BOPCol_DataMapOfShapeListOfShape mySplits;
   BOPCol_DataMapOfShapeShape myOrigins;
-  Standard_Real myFuzzyValue;
   Standard_Boolean myNonDestructive;
 
 private:
 
-
-
-
-
 };
 
 
-
-
-
-
-
 #endif // _BOPAlgo_Builder_HeaderFile
index a19d2e0..b0607ea 100644 (file)
 #include <TopoDS_Vertex.hxx>
 
 //
-//
-//
-//
-//
-//
-//
-//
 static
   Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
                                      const BOPDS_FaceInfo& aFI2);
@@ -128,7 +121,7 @@ class BOPAlgo_PairOfShapeBoolean : public BOPAlgo_Algo {
     //  
     const TopoDS_Face& aFj=*((TopoDS_Face*)&myShape1);
     const TopoDS_Face& aFk=*((TopoDS_Face*)&myShape2);
-    myFlag=BOPTools_AlgoTools::AreFacesSameDomain(aFj, aFk, myContext);
+    myFlag=BOPTools_AlgoTools::AreFacesSameDomain(aFj, aFk, myContext, myFuzzyValue);
   }
   //
  protected: 
@@ -214,7 +207,7 @@ class BOPAlgo_VFI : public BOPAlgo_Algo {
     Standard_Real aT1, aT2, dummy;
     //
     BOPAlgo_Algo::UserBreak();
-    myFlag = myContext->ComputeVF(myV, myF, aT1, aT2, dummy);
+    myFlag = myContext->ComputeVF(myV, myF, aT1, aT2, dummy, myFuzzyValue);
   }
   //
  protected:
@@ -625,6 +618,7 @@ void BOPAlgo_Builder::FillSameDomainFaces()
         BOPAlgo_PairOfShapeBoolean& aPSB=aVPSB.Append1();
         aPSB.Shape1()=aFj;
         aPSB.Shape2()=aFk;
+        aPSB.SetFuzzyValue(myFuzzyValue);
         aPSB.SetProgressIndicator(myProgressIndicator);
       }
     }
@@ -754,6 +748,7 @@ void BOPAlgo_Builder::FillImagesFaces1()
         BOPAlgo_VFI& aVFI=aVVFI.Append1();
         aVFI.SetVertex(aVx);
         aVFI.SetFace(aFy);
+        aVFI.SetFuzzyValue(myFuzzyValue);
         aVFI.SetProgressIndicator(myProgressIndicator);
       }
     }
index 9c35a3c..cad8fc0 100644 (file)
@@ -82,8 +82,7 @@ void BOPAlgo_CheckerSI::Init()
   // 1. myDS
   myDS=new BOPDS_DS(myAllocator);
   myDS->SetArguments(myArguments);
-  myDS->SetFuzzyValue(myFuzzyValue);
-  myDS->Init();
+  myDS->Init(myFuzzyValue);
   //
   // 2.myIterator 
   BOPDS_PIteratorSI theIterSI=new BOPDS_IteratorSI(myAllocator);
@@ -256,7 +255,7 @@ void BOPAlgo_CheckerSI::PostTreat()
       const TopoDS_Face& aF1=*((TopoDS_Face*)&myDS->Shape(n1));
       const TopoDS_Face& aF2=*((TopoDS_Face*)&myDS->Shape(n2));
       bFlag=BOPTools_AlgoTools::AreFacesSameDomain
-        (aF1, aF2, myContext);
+        (aF1, aF2, myContext, myFuzzyValue);
       if (bFlag) {
         ++iFound;
       }
index d2d0b15..c24d12e 100644 (file)
@@ -37,8 +37,7 @@
 //=======================================================================
 BOPAlgo_PaveFiller::BOPAlgo_PaveFiller()
 :
-  BOPAlgo_Algo(),
-  myFuzzyValue(0.)
+  BOPAlgo_Algo()
 {
   myDS=NULL;
   myIterator=NULL;
@@ -52,8 +51,7 @@ BOPAlgo_PaveFiller::BOPAlgo_PaveFiller()
 BOPAlgo_PaveFiller::BOPAlgo_PaveFiller
   (const Handle(NCollection_BaseAllocator)& theAllocator)
 :
-  BOPAlgo_Algo(theAllocator),
-  myFuzzyValue(0.)
+  BOPAlgo_Algo(theAllocator)
 {
   myDS=NULL;
   myIterator=NULL;
@@ -165,22 +163,6 @@ const BOPCol_ListOfShape& BOPAlgo_PaveFiller::Arguments()const
   return myArguments;
 }
 //=======================================================================
-//function : SetFuzzyValue
-//purpose  : 
-//=======================================================================
-void BOPAlgo_PaveFiller::SetFuzzyValue(const Standard_Real theFuzz)
-{
-  myFuzzyValue = (theFuzz < 0.) ? 0. : theFuzz;
-}
-//=======================================================================
-//function : FuzzyValue
-//purpose  : 
-//=======================================================================
-Standard_Real BOPAlgo_PaveFiller::FuzzyValue() const
-{
-  return myFuzzyValue;
-}
-//=======================================================================
 // function: Init
 // purpose: 
 //=======================================================================
@@ -199,8 +181,7 @@ void BOPAlgo_PaveFiller::Init()
   // 1.myDS 
   myDS=new BOPDS_DS(myAllocator);
   myDS->SetArguments(myArguments);
-  myDS->SetFuzzyValue(myFuzzyValue);
-  myDS->Init();
+  myDS->Init(myFuzzyValue);
   //
   // 2.myIterator 
   myIterator=new BOPDS_Iterator(myAllocator);
@@ -232,8 +213,6 @@ void BOPAlgo_PaveFiller::Perform()
   catch (Standard_Failure) {
     myErrorStatus=11;
   } 
-  //
-  myDS->SetDefaultTolerances();
 }
 //=======================================================================
 // function: PerformInternal
index da7b118..f9b5407 100644 (file)
@@ -45,6 +45,7 @@
 #include <IntSurf_ListOfPntOn2S.hxx>
 #include <BOPCol_DataMapOfIntegerListOfInteger.hxx>
 #include <BOPDS_MapOfPaveBlock.hxx>
+#include <BOPDS_VectorOfCurve.hxx>
 #include <BOPCol_IndexedDataMapOfShapeInteger.hxx>
 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
 class IntTools_Context;
@@ -98,14 +99,7 @@ public:
 
   Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
   
-  //! Sets the additional tolerance
-  Standard_EXPORT void SetFuzzyValue (const Standard_Real theFuzz);
   
-  //! Returns the additional tolerance
-  Standard_EXPORT Standard_Real FuzzyValue() const;
-
-
-
 
 protected:
 
@@ -155,13 +149,17 @@ protected:
   
   Standard_EXPORT void TreatVerticesEE();
   
+  Standard_EXPORT void MakeSDVerticesFF(const BOPCol_DataMapOfIntegerListOfInteger& aDMVLV,
+                                        BOPCol_DataMapOfIntegerInteger& theDMNewSD);
+
   Standard_EXPORT void MakeSplitEdges();
   
   Standard_EXPORT void MakeBlocks();
   
   Standard_EXPORT void MakePCurves();
 
-  Standard_EXPORT void MakeSDVertices(const BOPCol_ListOfInteger& theVertIndices);
+  Standard_EXPORT Standard_Integer MakeSDVertices(const BOPCol_ListOfInteger& theVertIndices,
+                                                  const Standard_Boolean theAddInterfs = 1);
   
   Standard_EXPORT void ProcessDE();
   
@@ -181,8 +179,18 @@ protected:
   
 
   //! Checks and puts paves from <theMVOn> on the curve <theNC>.
-  Standard_EXPORT void PutPavesOnCurve (const BOPCol_MapOfInteger& theMVOn, const Standard_Real theTolR3D, BOPDS_Curve& theNC, const Standard_Integer nF1, const Standard_Integer nF2, const BOPCol_MapOfInteger& theMI, const BOPCol_MapOfInteger& theMVEF, BOPCol_DataMapOfIntegerReal& theMVTol);
-  
+  Standard_EXPORT void PutPavesOnCurve (const BOPCol_MapOfInteger& theMVOn, 
+                                const Standard_Real theTolR3D, 
+                                BOPDS_Curve& theNC, 
+                                const Standard_Integer nF1, 
+                                const Standard_Integer nF2, 
+                                const BOPCol_MapOfInteger& theMI, 
+                                const BOPCol_MapOfInteger& theMVEF, 
+                                BOPCol_DataMapOfIntegerReal& theMVTol,
+                                BOPCol_DataMapOfIntegerListOfInteger& aDMVLV);
+
+  Standard_EXPORT void FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC,
+                                           const Standard_Real theTolR3D);
 
   //! Depending on the parameter aType it checks whether
   //! the vertex nV was created in EE or EF intersections.
@@ -199,6 +207,7 @@ protected:
   Standard_EXPORT Standard_Boolean IsExistingPaveBlock
     (const Handle(BOPDS_PaveBlock)& thePB, const BOPDS_Curve& theNC,
      const Standard_Real theTolR3D, const BOPDS_IndexedMapOfPaveBlock& theMPB,
+     const BOPDS_MapOfPaveBlock& theMPBCommon,
      Handle(BOPDS_PaveBlock)& thePBOut, Standard_Real& theTolNew);
   
   Standard_EXPORT Standard_Boolean IsExistingPaveBlock (const Handle(BOPDS_PaveBlock)& thePB, const BOPDS_Curve& theNC, const BOPCol_ListOfInteger& theLSE);
@@ -208,7 +217,7 @@ protected:
   Standard_EXPORT Standard_Integer PostTreatFF (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
                                                 BOPCol_DataMapOfShapeInteger& theMVI,
                                                 BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDMExEdges,
-                                                BOPCol_DataMapOfIntegerInteger& theDMI,
+                                                BOPCol_DataMapOfIntegerInteger& theDMNewSD,
                                                 const BOPCol_IndexedMapOfShape& theMicroEdges,
                                                 const BOPCol_BaseAllocator& theAllocator);
   
@@ -222,11 +231,21 @@ protected:
   
 
   //! Checks and puts paves created in EF intersections on the curve <theNC>.
-  Standard_EXPORT void PutEFPavesOnCurve (BOPDS_Curve& theNC, const BOPCol_MapOfInteger& theMI, const BOPCol_MapOfInteger& theMVEF, BOPCol_DataMapOfIntegerReal& theMVTol);
+  Standard_EXPORT void PutEFPavesOnCurve (BOPDS_Curve& theNC, 
+                                const BOPCol_MapOfInteger& theMI, 
+                                const BOPCol_MapOfInteger& theMVEF, 
+                                BOPCol_DataMapOfIntegerReal& theMVTol,
+                                BOPCol_DataMapOfIntegerListOfInteger& aDMVLV);
   
 
   //! Puts stick paves on the curve <theNC>
-  Standard_EXPORT void PutStickPavesOnCurve (const TopoDS_Face& aF1, const TopoDS_Face& aF2, const BOPCol_MapOfInteger& theMI, BOPDS_Curve& theNC, const BOPCol_MapOfInteger& theMVStick, BOPCol_DataMapOfIntegerReal& theMVTol);
+  Standard_EXPORT void PutStickPavesOnCurve (const TopoDS_Face& aF1, 
+                                const TopoDS_Face& aF2, 
+                                const BOPCol_MapOfInteger& theMI, 
+                                BOPDS_Curve& theNC, 
+                                const BOPCol_MapOfInteger& theMVStick, 
+                                BOPCol_DataMapOfIntegerReal& theMVTol,
+                                BOPCol_DataMapOfIntegerListOfInteger& aDMVLV);
   
 
   //! Collects indices of vertices created in all intersections between
@@ -252,7 +271,13 @@ protected:
   //! extended tolerance:
   //! 0 - do not perform the check;
   //! other - perform the check (aType goes to ExtendedTolerance).
-  Standard_EXPORT void PutPaveOnCurve (const Standard_Integer nV, const Standard_Real theTolR3D, BOPDS_Curve& theNC, const BOPCol_MapOfInteger& theMI, BOPCol_DataMapOfIntegerReal& theMVTol, const Standard_Integer aType = 0);
+  Standard_EXPORT void PutPaveOnCurve (const Standard_Integer nV, 
+                                const Standard_Real theTolR3D, 
+                                const BOPDS_Curve& theNC, 
+                                const BOPCol_MapOfInteger& theMI, 
+                                BOPCol_DataMapOfIntegerReal& theMVTol,
+                                BOPCol_DataMapOfIntegerListOfInteger& aDMVLV,
+                                const Standard_Integer aType = 0);
   
 
   //! Adds the existing edges from the map <theMPBOnIn> which interfere
@@ -309,8 +334,8 @@ protected:
   
 
   //! Updates pave blocks which have the paves with indices contained
-  //! in the map <theDMI>.
-  Standard_EXPORT void UpdatePaveBlocks (const BOPCol_DataMapOfIntegerInteger& theDMI);
+  //! in the map <aDMNewSD>.
+  Standard_EXPORT void UpdatePaveBlocks(const BOPCol_DataMapOfIntegerInteger& aDMNewSD);
 
   //! Updates tolerance vertex nV due to V/E interference.
   //! It always creates new vertex if nV is from arguments.
@@ -368,23 +393,12 @@ protected:
   BOPDS_PIterator myIterator;
   Handle(IntTools_Context) myContext;
   BOPAlgo_SectionAttribute mySectionAttribute;
-  Standard_Real myFuzzyValue;
   Standard_Boolean myNonDestructive;
   Standard_Boolean myIsPrimary;
 
 
 private:
 
-
-
-
-
 };
 
-
-
-
-
-
-
 #endif // _BOPAlgo_PaveFiller_HeaderFile
index 1780f1f..686d907 100644 (file)
@@ -76,7 +76,7 @@ void BOPAlgo_PaveFiller::PerformVV()
     const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(n1))); 
     const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(n2))); 
     //
-    iFlag=BOPTools_AlgoTools::ComputeVV(aV1, aV2);
+    iFlag=BOPTools_AlgoTools::ComputeVV(aV1, aV2, myFuzzyValue);
     if (!iFlag) {
       BOPAlgo_Tools::FillMap(n1, n2, aMILI, aAllocator);
     }
@@ -111,59 +111,75 @@ void BOPAlgo_PaveFiller::PerformVV()
 // function: PerformVV
 // purpose: 
 //=======================================================================
-void BOPAlgo_PaveFiller::MakeSDVertices(const BOPCol_ListOfInteger& theVertIndices)
+Standard_Integer BOPAlgo_PaveFiller::MakeSDVertices
+   (const BOPCol_ListOfInteger& theVertIndices,
+    const Standard_Boolean theAddInterfs)
 {
   TopoDS_Vertex aVSD, aVn;
+  Standard_Integer nSD = -1;
   BOPCol_ListIteratorOfListOfInteger aItLI(theVertIndices);
   BOPCol_ListOfShape aLV;
   for (; aItLI.More(); aItLI.Next()) {
-    Standard_Integer nX = aItLI.Value();
-    Standard_Integer nSD;
-    if (myDS->HasShapeSD(nX, nSD)) {
-      aVSD = TopoDS::Vertex(myDS->Shape(nSD));
+    Standard_Integer nX = aItLI.Value(), nSD1;
+    if (myDS->HasShapeSD(nX, nSD1)) {
+      const TopoDS_Shape& aVSD1 = myDS->Shape(nSD1);
+      if (nSD == -1) {
+        aVSD = TopoDS::Vertex(aVSD1);
+        nSD = nSD1;
+      }
+      else {
+        aLV.Append(aVSD1);
+      }
     }
     const TopoDS_Shape& aV = myDS->Shape(nX);
     aLV.Append(aV);
   }
   BOPTools_AlgoTools::MakeVertex(aLV, aVn);
-  if (!aVSD.IsNull()) {
+  Standard_Integer nV;
+  if (nSD != -1) {
     // update old SD vertex with new value
     Handle(BRep_TVertex)& aTVertex =
       reinterpret_cast<Handle(BRep_TVertex)&>(const_cast<Handle(TopoDS_TShape)&>(aVSD.TShape()));
     aTVertex->Pnt(BRep_Tool::Pnt(aVn));
     aTVertex->Tolerance(BRep_Tool::Tolerance(aVn));
+    aVn = aVSD;
+    nV = nSD;
   }
-  //
-  // Append new vertex to the DS
-  BOPDS_ShapeInfo aSIn;
-  aSIn.SetShapeType(TopAbs_VERTEX);
-  aSIn.SetShape(aVn);
-  Standard_Integer n = myDS->Append(aSIn);
-  //
-  BOPDS_ShapeInfo& aSIDS = myDS->ChangeShapeInfo(n);
+  else {
+    // Append new vertex to the DS
+    BOPDS_ShapeInfo aSIn;
+    aSIn.SetShapeType(TopAbs_VERTEX);
+    aSIn.SetShape(aVn);
+    nV = myDS->Append(aSIn);
+  }
+  BOPDS_ShapeInfo& aSIDS = myDS->ChangeShapeInfo(nV);
   Bnd_Box& aBox = aSIDS.ChangeBox();
   BRepBndLib::Add(aVn, aBox);
   aBox.SetGap(aBox.GetGap() + Precision::Confusion());
   //
   // Fill ShapesSD
   BOPDS_VectorOfInterfVV& aVVs = myDS->InterfVV();
-  aVVs.SetIncrement(theVertIndices.Extent());
+  if (theAddInterfs)
+    aVVs.SetIncrement(theVertIndices.Extent());
   //
   aItLI.Initialize(theVertIndices);
   for (; aItLI.More(); aItLI.Next()) {
     Standard_Integer n1 = aItLI.Value();
-    myDS->AddShapeSD(n1, n);
+    myDS->AddShapeSD(n1, nV);
     //
-    BOPCol_ListIteratorOfListOfInteger aItLI2 = aItLI;
-    aItLI2.Next();
-    for (; aItLI2.More(); aItLI2.Next()) {
-      Standard_Integer n2 = aItLI2.Value();
-      //
-      myDS->AddInterf(n1, n2);
-      BOPDS_InterfVV& aVV = aVVs.Append1();
-      //
-      aVV.SetIndices(n1, n2);
-      aVV.SetIndexNew(n);
+    if (theAddInterfs) {
+      BOPCol_ListIteratorOfListOfInteger aItLI2 = aItLI;
+      aItLI2.Next();
+      for (; aItLI2.More(); aItLI2.Next()) {
+        Standard_Integer n2 = aItLI2.Value();
+        //
+        myDS->AddInterf(n1, n2);
+        BOPDS_InterfVV& aVV = aVVs.Append1();
+        //
+        aVV.SetIndices(n1, n2);
+        aVV.SetIndexNew(nV);
+      }
     }
   }
+  return nV;
 }
index 3e3e083..754fc47 100644 (file)
@@ -51,26 +51,22 @@ class BOPAlgo_VertexEdge : public BOPAlgo_Algo {
 
   BOPAlgo_VertexEdge() : 
     BOPAlgo_Algo(),
-    myIV(-1), myIE(-1), myIVx(-1), myFlag(-1), myT(-1.), myTolVNew(-1.) {
+    myIV(-1), myIE(-1), myFlag(-1), myT(-1.), myTolVNew(-1.) {
   };
   //
   virtual ~BOPAlgo_VertexEdge(){
   };
   //
   void SetIndices(const Standard_Integer nV,
-                  const Standard_Integer nE,
-                  const Standard_Integer nVx) {
+                  const Standard_Integer nE) {
     myIV=nV;
     myIE=nE;
-    myIVx=nVx;
   }
   //
   void Indices(Standard_Integer& nV,
-               Standard_Integer& nE,
-               Standard_Integer& nVx) const {
+               Standard_Integer& nE) const {
     nV=myIV;
     nE=myIE;
-    nVx=myIVx;
   }
   //
   void SetVertex(const TopoDS_Vertex& aV) {
@@ -111,13 +107,12 @@ class BOPAlgo_VertexEdge : public BOPAlgo_Algo {
   //
   virtual void Perform() {
     BOPAlgo_Algo::UserBreak();
-    myFlag=myContext->ComputeVE (myV, myE, myT, myTolVNew);
+    myFlag=myContext->ComputeVE (myV, myE, myT, myTolVNew, myFuzzyValue);
   };
   //
  protected:
   Standard_Integer myIV;
   Standard_Integer myIE;
-  Standard_Integer myIVx;
   Standard_Integer myFlag;
   Standard_Real myT;
   Standard_Real myTolVNew;
@@ -213,9 +208,10 @@ void BOPAlgo_PaveFiller::PerformVE()
     //
     BOPAlgo_VertexEdge& aVESolver=aVVE.Append1();
     //
-    aVESolver.SetIndices(nV, nE, nVx);
+    aVESolver.SetIndices(nV, nE);
     aVESolver.SetVertex(aV);
     aVESolver.SetEdge(aE);
+    aVESolver.SetFuzzyValue(myFuzzyValue);
     aVESolver.SetProgressIndicator(myProgressIndicator);
     //
   }// for (; myIterator->More(); myIterator->Next()) {
@@ -229,7 +225,7 @@ void BOPAlgo_PaveFiller::PerformVE()
     const BOPAlgo_VertexEdge& aVESolver=aVVE(k);
     iFlag=aVESolver.Flag();
     if (!iFlag) {
-      aVESolver.Indices(nV, nE, nVx);
+      aVESolver.Indices(nV, nE);
       aT=aVESolver.Parameter();
       // 
       // check if vertex hits beyond shrunk range, in such case create V-V interf
index 9940d80..e543b9a 100644 (file)
@@ -45,7 +45,6 @@
 #include <BRepBndLib.hxx>
 #include <BRepTools.hxx>
 #include <BRepAdaptor_Curve.hxx>
-#include <GeomAPI_ProjectPointOnCurve.hxx>
 #include <gp_Pnt.hxx>
 #include <IntTools_CommonPrt.hxx>
 #include <IntTools_Context.hxx>
@@ -99,6 +98,10 @@ class BOPAlgo_EdgeEdge :
     return myPB2;
   }
   // 
+  void SetFuzzyValue(const Standard_Real theFuzz) {
+    IntTools_EdgeEdge::SetFuzzyValue(theFuzz);
+  }
+  //
   virtual void Perform() {
     BOPAlgo_Algo::UserBreak();
     IntTools_EdgeEdge::Perform();
@@ -126,10 +129,23 @@ typedef BOPCol_Cnt
 //class    : BOPAlgo_TNV
 //purpose  : 
 //=======================================================================
+class BOPAlgo_TNV;
+typedef BOPCol_NCVector
+  <BOPAlgo_TNV> BOPAlgo_VectorOfTNV;
+//
+typedef BOPCol_Functor
+  <BOPAlgo_TNV,
+  BOPAlgo_VectorOfTNV> BOPAlgo_TNVFunctor;
+//
+typedef BOPCol_Cnt
+  <BOPAlgo_TNVFunctor,
+  BOPAlgo_VectorOfTNV> BOPAlgo_TNVCnt;
+//=======================================================================
 class BOPAlgo_TNV : public BOPCol_BoxBndTreeSelector{
  public:
   BOPAlgo_TNV() 
-    : BOPCol_BoxBndTreeSelector(), myTree(NULL) {
+    : BOPCol_BoxBndTreeSelector(),
+      myTol (0.), myFuzzyValue(0.), myTree(NULL), myVecTNV(NULL) {
   };
   //
   ~BOPAlgo_TNV(){
@@ -137,6 +153,7 @@ class BOPAlgo_TNV : public BOPCol_BoxBndTreeSelector{
   //
   void SetVertex(const TopoDS_Vertex& aV) {
     myV=aV;
+    myPnt = BRep_Tool::Pnt(myV);
   }
   //
   const TopoDS_Vertex& Vertex()const {
@@ -147,26 +164,50 @@ class BOPAlgo_TNV : public BOPCol_BoxBndTreeSelector{
     myTree=&aTree;
   }
   //
+  void SetTolerance(const Standard_Real theTol) {
+    myTol = theTol;
+  }
+  //
+  Standard_Real Tolerance() const {
+    return myTol;
+  }
+  //
+  const gp_Pnt& Pnt() const {
+    return myPnt;
+  }
+  //
+  void SetFuzzyValue(const Standard_Real theFuzzyValue) {
+    myFuzzyValue = theFuzzyValue;
+  }
+  //
+  void SetVectorOfTNV(const BOPAlgo_VectorOfTNV& theVec) {
+    myVecTNV = &theVec;
+  }
+  //
+  virtual Standard_Boolean Accept(const Standard_Integer& theIndex)
+  {
+    const BOPAlgo_TNV& aTNV = myVecTNV->Value(theIndex - 1);
+    Standard_Real aTolSum2 = myTol + aTNV.Tolerance() + myFuzzyValue;
+    aTolSum2 *= aTolSum2;
+    Standard_Real aD2 = myPnt.SquareDistance(aTNV.Pnt());
+    if (aD2 < aTolSum2)
+      return BOPCol_BoxBndTreeSelector::Accept(theIndex);
+    return Standard_False;
+  }
+  //
   void Perform() {
     myTree->Select(*this);
   }
   //
  protected:
+  Standard_Real myTol;
+  Standard_Real myFuzzyValue;
+  gp_Pnt        myPnt;
   TopoDS_Vertex myV;
   BOPCol_BoxBndTree *myTree;
+  const BOPAlgo_VectorOfTNV *myVecTNV;
 };
 //
-//=======================================================================
-typedef BOPCol_NCVector
-  <BOPAlgo_TNV> BOPAlgo_VectorOfTNV; 
-//
-typedef BOPCol_Functor 
-  <BOPAlgo_TNV,
-  BOPAlgo_VectorOfTNV> BOPAlgo_TNVFunctor;
-//
-typedef BOPCol_Cnt 
-  <BOPAlgo_TNVFunctor,
-  BOPAlgo_VectorOfTNV> BOPAlgo_TNVCnt;
 /////////////////////////////////////////////////////////////////////////
 //=======================================================================
 //class    : BOPAlgo_PVE
@@ -233,9 +274,13 @@ class BOPAlgo_PVE {
     return myContext;
   }
   //
+  void SetFuzzyValue(const Standard_Real theValue) {
+    myFuzzyValue = theValue;
+  }
+  //
   void Perform() {
     Standard_Real dummy;
-    myFlag = myContext->ComputeVE(myV, myE, myT, dummy);
+    myFlag = myContext->ComputeVE(myV, myE, myT, dummy, myFuzzyValue);
   };
   //
  protected:
@@ -243,6 +288,7 @@ class BOPAlgo_PVE {
   Standard_Integer myIE;
   Standard_Integer myFlag;
   Standard_Real myT;
+  Standard_Real myFuzzyValue;
   TopoDS_Vertex myV;
   TopoDS_Edge myE;
   Handle(BOPDS_PaveBlock) myPB;
@@ -362,6 +408,7 @@ void BOPAlgo_PaveFiller::PerformEE()
         //
         anEdgeEdge.SetEdge1(aE1, aT11, aT12);
         anEdgeEdge.SetEdge2(aE2, aT21, aT22);
+        anEdgeEdge.SetFuzzyValue(myFuzzyValue);
         anEdgeEdge.SetProgressIndicator(myProgressIndicator);
       }//for (; aIt2.More(); aIt2.Next()) {
     }//for (; aIt1.More(); aIt1.Next()) {
@@ -610,7 +657,7 @@ void BOPAlgo_PaveFiller::PerformEE()
     }
     else {
       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
-      myDS->UpdateCommonBlock(aCB);
+      myDS->UpdateCommonBlock(aCB, myFuzzyValue);
     }
   }
   //
@@ -728,6 +775,7 @@ Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEE
       aPVE.SetIndices(nVx, nE);
       aPVE.SetVertex(aVx);
       aPVE.SetEdge(aE);
+      aPVE.SetFuzzyValue(myFuzzyValue);
       aPVE.SetPaveBlock(aPB);
     }
   }
@@ -761,7 +809,7 @@ Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEE
     }
     else {
       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
-      myDS->UpdateCommonBlock(aCB);
+      myDS->UpdateCommonBlock(aCB, myFuzzyValue);
     }    
   }//for (; aItMPBLI.More(); aItMPBLI.Next()) {
   //
@@ -788,7 +836,7 @@ void BOPAlgo_PaveFiller::TreatNewVertices
                             Bnd_Box> aTreeFiller(aBBTree);
   BOPAlgo_VectorOfTNV aVTNV;
   //
-  Standard_Real aTolAdd = Precision::Confusion() / 2.;
+  Standard_Real aTolAdd = myFuzzyValue / 2.;
   aNbV = theMVCPB.Extent();
   for (i=1; i<=aNbV; ++i) {
     const TopoDS_Vertex& aV = *((TopoDS_Vertex*)&theMVCPB.FindKey(i));
@@ -804,6 +852,9 @@ void BOPAlgo_PaveFiller::TreatNewVertices
     aTNV.SetTree(aBBTree);
     aTNV.SetBox(aBox);
     aTNV.SetVertex(aV);
+    aTNV.SetTolerance(aTol);
+    aTNV.SetFuzzyValue(myFuzzyValue);
+    aTNV.SetVectorOfTNV(aVTNV);
   }
   //
   aTreeFiller.Fill();
@@ -948,7 +999,7 @@ void BOPAlgo_PaveFiller::ForceInterfVE(const Standard_Integer nV,
   const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nVx);
   const TopoDS_Edge&   aE = *(TopoDS_Edge*)  &myDS->Shape(nE);
   //
-  iFlag = myContext->ComputeVE(aV, aE, aT, aTolVNew);
+  iFlag = myContext->ComputeVE(aV, aE, aT, aTolVNew, myFuzzyValue);
   if (iFlag == 0 || iFlag == -4) {
     BOPDS_Pave aPave;
     //
index 902f525..356a43b 100644 (file)
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Vertex.hxx>
 
-//
-//
-//
-//
-//
 //=======================================================================
 //class    : BOPAlgo_VertexFace
 //purpose  : 
@@ -53,7 +48,7 @@ class BOPAlgo_VertexFace : public BOPAlgo_Algo {
 
   BOPAlgo_VertexFace() : 
     BOPAlgo_Algo(),
-    myIV(-1), myIF(-1), myIVx(-1), 
+    myIV(-1), myIF(-1),
     myFlag(-1), myT1(-1.),  myT2(-1.), myTolVNew(-1.) {
   }
   //
@@ -61,19 +56,15 @@ class BOPAlgo_VertexFace : public BOPAlgo_Algo {
   }
   //
   void SetIndices(const Standard_Integer nV,
-                  const Standard_Integer nF,
-                  const Standard_Integer nVx) {
+                  const Standard_Integer nF) {
     myIV=nV;
     myIF=nF;
-    myIVx=nVx;
   }
   //
   void Indices(Standard_Integer& nV,
-               Standard_Integer& nF,
-               Standard_Integer& nVx) const {
+               Standard_Integer& nF) const {
     nV=myIV;
     nF=myIF;
-    nVx=myIVx;
   }
   //
   void SetVertex(const TopoDS_Vertex& aV) {
@@ -116,13 +107,12 @@ class BOPAlgo_VertexFace : public BOPAlgo_Algo {
   //
   virtual void Perform() {
     BOPAlgo_Algo::UserBreak();
-    myFlag=myContext->ComputeVF(myV, myF, myT1, myT2, myTolVNew);
+    myFlag=myContext->ComputeVF(myV, myF, myT1, myT2, myTolVNew, myFuzzyValue);
   }
   //
  protected:
   Standard_Integer myIV;
   Standard_Integer myIF;
-  Standard_Integer myIVx;
   Standard_Integer myFlag;
   Standard_Real myT1;
   Standard_Real myT2;
@@ -186,10 +176,6 @@ void BOPAlgo_PaveFiller::PerformVF()
         nVx=nVSD;
       }
       //
-      if (myDS->HasInterf(nVx, nF)) {
-        continue;
-      }
-      //
       myDS->ChangeFaceInfo(nF);// !
       //
       const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nVx))); 
@@ -197,9 +183,10 @@ void BOPAlgo_PaveFiller::PerformVF()
       //
       BOPAlgo_VertexFace& aVertexFace=aVVF.Append1();
       //
-      aVertexFace.SetIndices(nV, nF, nVx);
+      aVertexFace.SetIndices(nV, nF);
       aVertexFace.SetVertex(aV);
       aVertexFace.SetFace(aF);
+      aVertexFace.SetFuzzyValue(myFuzzyValue);
       aVertexFace.SetProgressIndicator(myProgressIndicator);
     }//for (; myIterator->More(); myIterator->Next()) {
     //
@@ -216,18 +203,18 @@ void BOPAlgo_PaveFiller::PerformVF()
         continue;
       }
       //
-      aVertexFace.Indices(nV, nF, nVx);
+      aVertexFace.Indices(nV, nF);
       aVertexFace.Parameters(aT1, aT2);
       // 1
       BOPDS_InterfVF& aVF=aVFs.Append1();
-      aVF.SetIndices(nVx, nF);
+      aVF.SetIndices(nV, nF);
       aVF.SetUV(aT1, aT2);
       // 2
-      myDS->AddInterf(nVx, nF);
+      myDS->AddInterf(nV, nF);
       //
       // 3 update vertex V/F if necessary
       Standard_Real aTolVNew = aVertexFace.VertexNewTolerance();
-      nVx=UpdateVertex(nVx, aTolVNew);
+      nVx=UpdateVertex(nV, aTolVNew);
       //
       // 4
       if (myDS->IsNewShape(nVx)) {
@@ -315,7 +302,7 @@ void BOPAlgo_PaveFiller::TreatVerticesEE()
     if (!aMVOn.Contains(nV)) {
       const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&myDS->Shape(nV))); 
       const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF))); 
-      iFlag = myContext->ComputeVF(aV, aF, aT1, aT2, dummy);
+      iFlag = myContext->ComputeVF(aV, aF, aT1, aT2, dummy, myFuzzyValue);
       if (!iFlag) {
         // 1
         BOPDS_InterfVF& aVF=aVFs.Append1();
index 6867922..5cc8ed0 100644 (file)
@@ -103,6 +103,10 @@ class BOPAlgo_EdgeFace :
     return myPB;
   }
   //
+  void SetFuzzyValue(const Standard_Real theFuzz) {
+    IntTools_EdgeFace::SetFuzzyValue(theFuzz);
+  }
+  //
   virtual void Perform() {
     BOPAlgo_Algo::UserBreak();
     IntTools_EdgeFace::Perform();
@@ -227,8 +231,7 @@ void BOPAlgo_PaveFiller::PerformEF()
       //
       aEdgeFace.SetEdge (aE);
       aEdgeFace.SetFace (aF);
-      aEdgeFace.SetTolE (aTolE);
-      aEdgeFace.SetTolF (aTolF);
+      aEdgeFace.SetFuzzyValue(myFuzzyValue);
       aEdgeFace.SetDiscretize (aDiscretize);
       aEdgeFace.SetDeflection (aDeflection);
       aEdgeFace.UseQuickCoincidenceCheck(bExpressCompute);
@@ -263,8 +266,8 @@ void BOPAlgo_PaveFiller::PerformEF()
     const TopoDS_Edge& aE=aEdgeFace.Edge();
     const TopoDS_Face& aF=aEdgeFace.Face();
     //
-    aTolE=aEdgeFace.TolE();
-    aTolF=aEdgeFace.TolF();
+    aTolE=BRep_Tool::Tolerance(aE);
+    aTolF=BRep_Tool::Tolerance(aF);
     const IntTools_Range& anewSR=aEdgeFace.NewSR();
     Handle(BOPDS_PaveBlock)& aPB=aEdgeFace.PaveBlock();
     //
@@ -607,7 +610,7 @@ Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEF
       nVx=aItLI.Value();
       const TopoDS_Vertex& aVx=(*(TopoDS_Vertex *)(&myDS->Shape(nVx)));
       //
-      iFlag=myContext->ComputeVE (aVx, aE, aT, dummy);
+      iFlag=myContext->ComputeVE (aVx, aE, aT, dummy, myFuzzyValue);
       if (!iFlag) {
         aPave.SetIndex(nVx);
         aPave.SetParameter(aT);
@@ -625,7 +628,7 @@ Standard_Integer BOPAlgo_PaveFiller::PerformVerticesEF
     }
     else {
       const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
-      myDS->UpdateCommonBlock(aCB);
+      myDS->UpdateCommonBlock(aCB, myFuzzyValue);
     }    
   }//for (; aItMPBLI.More(); aItMPBLI.Next()) {
   // 
@@ -707,7 +710,7 @@ Standard_Boolean BOPAlgo_PaveFiller::ForceInterfVF
   const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
   const TopoDS_Face&   aF = *(TopoDS_Face*)  &myDS->Shape(nF);
   //
-  iFlag = myContext->ComputeVF(aV, aF, U, V, aTolVNew);
+  iFlag = myContext->ComputeVF(aV, aF, U, V, aTolVNew, myFuzzyValue);
   if (iFlag == 0 || iFlag == -2) {
     bRet=!bRet;
   //
index c805f06..591dd30 100644 (file)
@@ -19,7 +19,6 @@
 #include <BOPAlgo_PaveFiller.hxx>
 #include <BOPAlgo_SectionAttribute.hxx>
 #include <BOPAlgo_Tools.hxx>
-#include <BOPCol_DataMapOfIntegerReal.hxx>
 #include <BOPCol_DataMapOfShapeInteger.hxx>
 #include <BOPCol_ListOfInteger.hxx>
 #include <BOPCol_ListOfShape.hxx>
@@ -139,6 +138,10 @@ class BOPAlgo_FaceFace :
     return myTolFF;
   }
   //
+  void SetFuzzyValue(const Standard_Real theFuzz) {
+    IntTools_FaceFace::SetFuzzyValue(theFuzz);
+  }
+  //
   virtual void Perform() {
     BOPAlgo_Algo::UserBreak();
     IntTools_FaceFace::Perform(myF1, myF2);
@@ -249,6 +252,7 @@ void BOPAlgo_PaveFiller::PerformFF()
     }
     //
     aFaceFace.SetParameters(bApp, bCompC2D1, bCompC2D2, aApproxTol);
+    aFaceFace.SetFuzzyValue(myFuzzyValue);
     aFaceFace.SetProgressIndicator(myProgressIndicator);
   }//for (; myIterator->More(); myIterator->Next()) {
   //
@@ -369,7 +373,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
   Standard_Boolean bExist, bValid2D;
   Standard_Integer i, nF1, nF2, aNbC, aNbP, j;
   Standard_Integer nV1, nV2;
-  Standard_Real aTolR3D, aT1, aT2, aTol;
+  Standard_Real aTolR3D, aT1, aT2;
   Handle(NCollection_BaseAllocator) aAllocator;
   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
   TopoDS_Edge aES;
@@ -384,13 +388,14 @@ void BOPAlgo_PaveFiller::MakeBlocks()
                       aMVStick(100,aAllocator), aMVEF(100, aAllocator),
                       aMI(100, aAllocator), aMVBounds(100, aAllocator);
   BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator);
-  BOPDS_MapOfPaveBlock aMPBAdd(100, aAllocator);
+  BOPDS_MapOfPaveBlock aMPBAdd(100, aAllocator), aMPBCommon;
   BOPDS_ListOfPaveBlock aLPB(aAllocator);
   BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMSCPB(100, aAllocator); 
   BOPCol_DataMapOfShapeInteger aMVI(100, aAllocator);
   BOPDS_DataMapOfPaveBlockListOfPaveBlock aDMExEdges(100, aAllocator);
   BOPCol_DataMapOfIntegerReal aMVTol(100, aAllocator);
-  BOPCol_DataMapOfIntegerInteger aDMI(100, aAllocator);
+  BOPCol_DataMapOfIntegerInteger aDMNewSD(100, aAllocator);
+  BOPCol_DataMapOfIntegerListOfInteger aDMVLV;
   BOPCol_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator);
   BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItMV;
   BOPCol_IndexedMapOfShape aMicroEdges(100, aAllocator);
@@ -430,11 +435,12 @@ void BOPAlgo_PaveFiller::MakeBlocks()
     //
     aMVOnIn.Clear();
     aMPBOnIn.Clear();
+    aMPBCommon.Clear();
     aDMBV.Clear();
     aMVTol.Clear();
     aLSE.Clear();
     //
-    myDS->VerticesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn);
+    myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn, aMPBCommon);
     myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
     
     // 1. Treat Points
@@ -460,18 +466,27 @@ void BOPAlgo_PaveFiller::MakeBlocks()
     aMVEF.Clear();
     GetStickVertices(nF1, nF2, aMVStick, aMVEF, aMI);
     //
-    for (j=0; j<aNbC; ++j) {
-      BOPDS_Curve& aNC=aVC.ChangeValue(j);
-      const IntTools_Curve& aIC=aNC.Curve();
+    for (j = 0; j < aNbC; ++j) {
+      BOPDS_Curve& aNC = aVC.ChangeValue(j);
       // DEBt
       aNC.InitPaveBlock1();
       //
-      PutPavesOnCurve(aMVOnIn, aTolR3D, aNC, nF1, nF2, aMI, aMVEF, aMVTol);
+      PutPavesOnCurve(aMVOnIn, aTolR3D, aNC, nF1, nF2, aMI, aMVEF, aMVTol, aDMVLV);
+    }
+
+    // if some E-F vertex was put on a curve due to large E-F intersection range,
+    // and it also was put on another curve correctly then remove this vertex from
+    // the first curve. Detect such case if the distance to curve exceeds aTolR3D.
+    FilterPavesOnCurves(aVC, aTolR3D);
+
+    for (j = 0; j<aNbC; ++j) {
+      BOPDS_Curve& aNC=aVC.ChangeValue(j);
+      const IntTools_Curve& aIC=aNC.Curve();
       //
-      PutStickPavesOnCurve(aF1, aF2, aMI, aNC, aMVStick, aMVTol);
+      PutStickPavesOnCurve(aF1, aF2, aMI, aNC, aMVStick, aMVTol, aDMVLV);
       //904/F7
       if (aNbC == 1) {
-        PutEFPavesOnCurve(aNC, aMI, aMVEF, aMVTol);
+        PutEFPavesOnCurve(aNC, aMI, aMVEF, aMVTol, aDMVLV);
       }
       //
       if (aIC.HasBounds()) {
@@ -488,7 +503,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
         }
       }
     }//for (j=0; j<aNbC; ++j) {
-    //
+
     // Put closing pave if needed
     for (j=0; j<aNbC; ++j) {
       BOPDS_Curve& aNC=aVC.ChangeValue(j);
@@ -549,7 +564,7 @@ void BOPAlgo_PaveFiller::MakeBlocks()
         }
         //
         Standard_Real aTolNew;
-        bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aPBOut, aTolNew);
+        bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aMPBCommon, aPBOut, aTolNew);
         if (bExist) {
           if (aMPBAdd.Add(aPBOut)) {
             Standard_Boolean bInBothFaces = Standard_True;
@@ -604,23 +619,35 @@ void BOPAlgo_PaveFiller::MakeBlocks()
       //
       aLPBC.RemoveFirst();
     }//for (j=0; j<aNbC; ++j) {
+    //
     //back to previous tolerance values for unused vertices
+    //and forget about SD groups of such vertices
     aItMV.Initialize(aMVTol);
     for (; aItMV.More(); aItMV.Next()) {
       nV1 = aItMV.Key();
-      aTol = aItMV.Value();
+      Standard_Real aTol = aItMV.Value();
       //
       const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV1);
       const Handle(BRep_TVertex)& TV = 
         *((Handle(BRep_TVertex)*)&aV.TShape());
       TV->Tolerance(aTol);
+      // reset bnd box
+      BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV1);
+      Bnd_Box& aBoxDS=aSIDS.ChangeBox();
+      aBoxDS = Bnd_Box();
+      BRepBndLib::Add(aV, aBoxDS);
+      aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
+      //
+      if (aDMVLV.IsBound(nV1))
+        aDMVLV.UnBind(nV1);
     }
     //
     ProcessExistingPaveBlocks(i, aMPBOnIn, aDMBV, aMSCPB, aMVI, aMPBAdd);
   }//for (i=0; i<aNbFF; ++i) {
   // 
   // post treatment
-  myErrorStatus=PostTreatFF(aMSCPB, aMVI, aDMExEdges, aDMI, aMicroEdges, aAllocator);
+  MakeSDVerticesFF(aDMVLV, aDMNewSD);
+  myErrorStatus=PostTreatFF(aMSCPB, aMVI, aDMExEdges, aDMNewSD, aMicroEdges, aAllocator);
   if (myErrorStatus) {
     return;
   }
@@ -628,9 +655,9 @@ void BOPAlgo_PaveFiller::MakeBlocks()
   CorrectToleranceOfSE();
   //
   // update face info
-  UpdateFaceInfo(aDMExEdges, aDMI);
+  UpdateFaceInfo(aDMExEdges, aDMNewSD);
   //Update all pave blocks
-  UpdatePaveBlocks(aDMI);
+  UpdatePaveBlocks(aDMNewSD);
   //-----------------------------------------------------scope t
   aMF.Clear();
   aMVStick.Clear();
@@ -638,7 +665,31 @@ void BOPAlgo_PaveFiller::MakeBlocks()
   aMVOnIn.Clear();
   aDMExEdges.Clear();
   aMI.Clear();
-  aDMI.Clear();
+  aDMNewSD.Clear();
+}
+
+//=======================================================================
+//function : MakeSDVerticesFF
+//purpose  : 
+//=======================================================================
+void BOPAlgo_PaveFiller::MakeSDVerticesFF
+  (const BOPCol_DataMapOfIntegerListOfInteger& theDMVLV,
+   BOPCol_DataMapOfIntegerInteger& theDMNewSD)
+{
+  // Create a new SD vertex for each group of coinciding vertices
+  // and put new substitutions to theDMNewSD.
+  BOPCol_DataMapIteratorOfDataMapOfIntegerListOfInteger aItG(theDMVLV);
+  for (; aItG.More(); aItG.Next()) {
+    const BOPCol_ListOfInteger& aList = aItG.Value();
+    // make SD vertices w/o creation of interfs
+    Standard_Integer nSD = MakeSDVertices(aList, Standard_False);
+    // update theDMNewSD
+    BOPCol_ListIteratorOfListOfInteger aItL(aList);
+    for (; aItL.More(); aItL.Next()) {
+      Standard_Integer nV = aItL.Value();
+      theDMNewSD.Bind(nV, nSD);
+    }
+  }
 }
 
 //=======================================================================
@@ -649,7 +700,7 @@ Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
     (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
      BOPCol_DataMapOfShapeInteger& aMVI,
      BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
-     BOPCol_DataMapOfIntegerInteger& aDMI,
+     BOPCol_DataMapOfIntegerInteger& aDMNewSD,
      const BOPCol_IndexedMapOfShape& theMicroEdges,
      const Handle(NCollection_BaseAllocator)& theAllocator)
 {
@@ -797,18 +848,18 @@ Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
       if (!bIntersectionPoint) {
         // save SD connection
         nSx = aMVI.Find(aSx);
-        aDMI.Bind(nSx, iV);
+        aDMNewSD.Bind(nSx, iV);
         myDS->AddShapeSD(nSx, iV);
       }
       else {
       // update FF interference
-        const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
-        iX=aCPB.IndexInterf();
-        iP=aCPB.Index();
-        BOPDS_InterfFF& aFF=aFFs(iX);
-        BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
-        BOPDS_Point& aNP=aVNP(iP);
-        aNP.SetIndex(iV);
+      const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
+      iX=aCPB.IndexInterf();
+      iP=aCPB.Index();
+      BOPDS_InterfFF& aFF=aFFs(iX);
+      BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
+      BOPDS_Point& aNP=aVNP(iP);
+      aNP.SetIndex(iV);
       }
     }//if (aType==TopAbs_VERTEX) {
     //
@@ -918,7 +969,7 @@ Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
               const BOPDS_Pave& aP1 = !j ? aPB1->Pave1() : aPB1->Pave2();
               if (aP1.Parameter() == aPave[j].Parameter() && 
                   aP1.Index() != iV) {
-                aDMI.Bind(aP1.Index(), iV);
+                aDMNewSD.Bind(aP1.Index(), iV);
                 myDS->AddShapeSD(aP1.Index(), iV);
               }
               //
@@ -1120,10 +1171,12 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingVertex
 {
   Standard_Boolean bRet;
   Standard_Integer nV, iFlag;
+  Standard_Real aTolCheck;
   gp_Pnt aPV;
   Bnd_Box aBoxP;
   BOPCol_MapIteratorOfMapOfInteger aIt;
   //
+  aTolCheck = theTolR3D + myFuzzyValue;
   bRet=Standard_True;
   //
   aBoxP.Add(aP);
@@ -1137,7 +1190,7 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingVertex
     const Bnd_Box& aBoxV=aSIV.Box();
     //
     if (!aBoxP.IsOut(aBoxV)) {
-      iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP, theTolR3D);
+      iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP, aTolCheck);
       if (!iFlag) {
         return bRet;
       }
@@ -1160,7 +1213,7 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
     return !bRet;
   } 
   //
-  Standard_Real aT1, aT2, aTm, aTx, aTol, aDist;
+  Standard_Real aT1, aT2, aTm, aTx, aTolE, aTolCheck, aTol, aDist;
   Standard_Integer nE, iFlag, nV1, nV2;
   gp_Pnt aPm;
   Bnd_Box aBoxPm;
@@ -1189,8 +1242,9 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
     const Bnd_Box& aBoxE=aSIE.Box();
     if (!aBoxE.IsOut(aBoxPm)) {
       const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
-      const Standard_Real aTol1 = Max(BRep_Tool::Tolerance(aE), aTol);
-      iFlag=myContext->ComputePE(aPm, aTol1, aE, aTx, aDist);
+      aTolE = BRep_Tool::Tolerance(aE);
+      aTolCheck = Max(aTolE, aTol) + myFuzzyValue;
+      iFlag = myContext->ComputePE(aPm, aTolCheck, aE, aTx, aDist);
       if (!iFlag) {
         return bRet;
       }
@@ -1203,28 +1257,30 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
 //function : IsExistingPaveBlock
 //purpose  : 
 //=======================================================================
-  Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
+Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
     (const Handle(BOPDS_PaveBlock)& thePB,
      const BOPDS_Curve& theNC,
      const Standard_Real theTolR3D,
      const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn,
+     const BOPDS_MapOfPaveBlock& theMPBCommon,
      Handle(BOPDS_PaveBlock)& aPBOut,
      Standard_Real& theTolNew)
 {
   Standard_Boolean bRet;
-  Standard_Real aT1, aT2, aTm, aTx;
+  Standard_Real aT1, aT2, aTm, aTx, aTolCheck;
   Standard_Integer nSp, iFlag1, iFlag2, nV11, nV12, nV21, nV22, i, aNbPB;
   gp_Pnt aP1, aPm, aP2;
   Bnd_Box aBoxP1, aBoxPm, aBoxP2, aBoxTmp;
   //
   bRet=Standard_False;
+  aTolCheck = theTolR3D + myFuzzyValue;
   const IntTools_Curve& aIC=theNC.Curve();
   //
   thePB->Range(aT1, aT2);
   thePB->Indices(nV11, nV12);
   const Standard_Real aTolV11 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV11)));
   const Standard_Real aTolV12 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV12)));
-  const Standard_Real aTolV1 = Max(aTolV11, aTolV12);
+  const Standard_Real aTolV1 = Max(aTolV11, aTolV12) + myFuzzyValue;
 
   //first point
   aIC.D0(aT1, aP1);
@@ -1246,7 +1302,7 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
     aPB->Indices(nV21, nV22);
     const Standard_Real aTolV21 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV21)));
     const Standard_Real aTolV22 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV22)));
-    const Standard_Real aTolV2 = Max(aTolV21, aTolV22);
+    const Standard_Real aTolV2 = Max(aTolV21, aTolV22) + myFuzzyValue;
     nSp=aPB->Edge();
     if (nSp < 0)
       continue;
@@ -1261,9 +1317,16 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
     if (iFlag1 && iFlag2) {
       Standard_Real aDist = 0.;
 
-      const Standard_Real aRealTol = myDS->IsCommonBlock(aPB) ?
-                                     Max(aTolV1, aTolV2) : theTolR3D;
-
+      Standard_Real aRealTol = aTolCheck;
+      if (myDS->IsCommonBlock(aPB))
+      {
+        aRealTol = Max(aRealTol, Max(aTolV1, aTolV2));
+        if (theMPBCommon.Contains(aPB))
+          // for an edge, which is a common block with a face,
+          // increase the chance to coincide with section curve
+          aRealTol *= 2.;
+      }
+      
       aBoxTmp = aBoxPm;
       aBoxTmp.Enlarge(aRealTol);
 
@@ -1299,11 +1362,11 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
 //function : PutBoundPaveOnCurve
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
-                                               const TopoDS_Face& aF2,
-                                               const Standard_Real aTolR3D,
-                                               BOPDS_Curve& aNC,
-                                               BOPCol_ListOfInteger& aLVB)
+void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
+                                             const TopoDS_Face& aF2,
+                                             const Standard_Real aTolR3D,
+                                             BOPDS_Curve& aNC,
+                                             BOPCol_ListOfInteger& aLVB)
 {
   Standard_Boolean bVF;
   Standard_Integer nV, iFlag, nVn, j, aNbEP;
@@ -1402,7 +1465,7 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
 //function : PutPavesOnCurve
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_PaveFiller::PutPavesOnCurve
+void BOPAlgo_PaveFiller::PutPavesOnCurve
   (const BOPCol_MapOfInteger& aMVOnIn,
    const Standard_Real aTolR3D,
    BOPDS_Curve& aNC,
@@ -1410,7 +1473,8 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
    const Standard_Integer nF2,
    const BOPCol_MapOfInteger& aMI,
    const BOPCol_MapOfInteger& aMVEF,
-   BOPCol_DataMapOfIntegerReal& aMVTol)
+   BOPCol_DataMapOfIntegerReal& aMVTol,
+   BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
 {
   Standard_Boolean bInBothFaces;
   Standard_Integer nV;
@@ -1422,7 +1486,7 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
   aIt.Initialize(aMVEF);
   for (; aIt.More(); aIt.Next()) {
     nV=aIt.Value();
-    PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, 2);
+    PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 2);
   }
   //Put all other vertices
   aIt.Initialize(aMVOnIn);
@@ -1451,7 +1515,97 @@ Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
       }
     }
     //
-    PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, 1);
+    PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 1);
+  }
+}
+
+//=======================================================================
+//function : FilterPavesOnCurves
+//purpose  : 
+//=======================================================================
+namespace {
+  struct PaveBlockDist {
+    Handle(BOPDS_PaveBlock) PB;
+    Standard_Real Dist; // square distance from vertex to the paveblock
+    Standard_Real SinAngle; // sinus of angle between projection vector 
+    // and tangent at projection point
+  };
+}
+void BOPAlgo_PaveFiller::FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC,
+                                             const Standard_Real theTolR3D)
+{
+  Standard_Real aSqTol = theTolR3D * theTolR3D;
+
+  // For each vertex found in ExtPaves of pave blocks of section curves
+  // collect list of pave blocks with distance to the curve
+  NCollection_IndexedDataMap<Standard_Integer,NCollection_List<PaveBlockDist> > aIDMVertPBs;
+  Standard_Integer i;
+  const Standard_Real anEps = gp::Resolution();
+  for (i = 0; i < theVNC.Extent(); ++i)
+  {
+    const BOPDS_Curve& aNC = theVNC(i);
+    const IntTools_Curve& aIC = aNC.Curve();
+    GeomAdaptor_Curve aGAC(aIC.Curve());
+    const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
+    const BOPDS_ListOfPave& aPaves = aPB->ExtPaves();
+    BOPDS_ListOfPave::Iterator itPaves(aPaves);
+    for (; itPaves.More(); itPaves.Next())
+    {
+      const BOPDS_Pave& aPave = itPaves.Value();
+      Standard_Integer nV = aPave.Index();
+      const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
+      // compute distance from vertex to the point on curve with vertex parameter
+      gp_Pnt aPV = BRep_Tool::Pnt(aV);
+      Standard_Real aPar = aPave.Parameter();
+      gp_Pnt aPonC;
+      gp_Vec aD1;
+      aGAC.D1(aPar, aPonC, aD1);
+      gp_Vec aProjVec(aPV, aPonC);
+      Standard_Real aSqDist = aProjVec.SquareMagnitude();
+      Standard_Real aSqD1Mod = aD1.SquareMagnitude();
+      Standard_Real aSin = aProjVec.CrossSquareMagnitude(aD1);
+      if (aSqDist > anEps && aSqD1Mod > anEps)
+        aSin = sqrt(aSin / aSqDist / aSqD1Mod);
+      NCollection_List<PaveBlockDist>* pList = aIDMVertPBs.ChangeSeek(nV);
+      if (!pList)
+        pList = &aIDMVertPBs.ChangeFromIndex(aIDMVertPBs.Add(nV, NCollection_List<PaveBlockDist>()));
+      PaveBlockDist aPBD = { aPB, aSqDist, aSin };
+      pList->Append(aPBD);
+    }
+  }
+
+  // Process each vertex
+  const Standard_Real aSinAngleMin = 0.5; // angle below which projection is suspicious
+  for (i = 1; i <= aIDMVertPBs.Extent(); i++)
+  {
+    Standard_Integer nV = aIDMVertPBs.FindKey(i);
+    const NCollection_List<PaveBlockDist>& aList = aIDMVertPBs(i);
+    // Find a pave with minimal distance
+    Standard_Real aMinDist = RealLast();
+    Handle(BOPDS_PaveBlock) aPBMinDist;
+    NCollection_List<PaveBlockDist>::Iterator itL(aList);
+    for (; itL.More(); itL.Next())
+    {
+      const PaveBlockDist& aPBD = itL.Value();
+      if (aPBD.Dist < aMinDist)
+      {
+        aMinDist = aPBD.Dist;
+        aPBMinDist = aPBD.PB;
+      }
+    }
+    // Remove a vertex from a pave block if the distance is greater than the tolerance 
+    // and there are other pave blocks for which the distance is less than the current.
+    // Do not remove a vertex if it is projected on the curve with quite large angle
+    // (see test bugs modalg_6 bug27761).
+    Standard_Real aCheckDist = 100. * Max(aSqTol, aMinDist);
+    for (itL.Init(aList); itL.More(); itL.Next())
+    {
+      const PaveBlockDist& aPBD = itL.Value();
+      if (aPBD.Dist > aCheckDist && aPBD.SinAngle < aSinAngleMin)
+      {
+        aPBD.PB->RemoveExtPave(nV);
+      }
+    }
   }
 }
 
@@ -1595,14 +1749,15 @@ void BOPAlgo_PaveFiller::GetEFPnts
 }
 
 //=======================================================================
-//function : ProcessUnUsedVertices
+//function : PutEFPavesOnCurve
 //purpose  : 
 //=======================================================================
   void BOPAlgo_PaveFiller::PutEFPavesOnCurve
   (BOPDS_Curve& aNC,
    const BOPCol_MapOfInteger& aMI,
    const BOPCol_MapOfInteger& aMVEF,
-   BOPCol_DataMapOfIntegerReal& aMVTol)
+   BOPCol_DataMapOfIntegerReal& aMVTol,
+   BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
 {
   if (!aMVEF.Extent()) {
     return;
@@ -1640,7 +1795,7 @@ void BOPAlgo_PaveFiller::GetEFPnts
     Standard_Integer aNbPoints = aProjPT.NbPoints();
     if (aNbPoints) {
       aDist = aProjPT.LowerDistance();
-      PutPaveOnCurve(nV, aDist, aNC, aMI, aMVTol);
+      PutPaveOnCurve(nV, aDist, aNC, aMI, aMVTol, aDMVLV);
     }
   }
 }
@@ -1655,7 +1810,8 @@ void BOPAlgo_PaveFiller::GetEFPnts
    const BOPCol_MapOfInteger& aMI,
    BOPDS_Curve& aNC,
    const BOPCol_MapOfInteger& aMVStick,
-   BOPCol_DataMapOfIntegerReal& aMVTol)
+   BOPCol_DataMapOfIntegerReal& aMVTol,
+   BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
 {
   BOPCol_MapOfInteger aMV;
   aMV.Assign(aMVStick);
@@ -1718,7 +1874,7 @@ void BOPAlgo_PaveFiller::GetEFPnts
         // The intersection curve aIC is vanishing curve (the crease)
         aD=sqrt(aD2);
         //
-        PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol);
+        PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol, aDMVLV);
       }
     }//for (jVU=1; jVU=aNbVU; ++jVU) {
   }
@@ -1832,49 +1988,59 @@ void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC,
 //function : PutPaveOnCurve
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_PaveFiller::PutPaveOnCurve
+void BOPAlgo_PaveFiller::PutPaveOnCurve
   (const Standard_Integer nV,
    const Standard_Real aTolR3D,
-   BOPDS_Curve& aNC,
+   const BOPDS_Curve& aNC,
    const BOPCol_MapOfInteger& aMI,
    BOPCol_DataMapOfIntegerReal& aMVTol,
+   BOPCol_DataMapOfIntegerListOfInteger& aDMVLV,
    const Standard_Integer iCheckExtend)
 {
   Standard_Boolean bIsVertexOnLine;
-  Standard_Real aT, aTolV;
+  Standard_Real aT;
   //
   const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
-  Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
+  const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
   const IntTools_Curve& aIC = aNC.Curve();
   //
-  bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT);
+  Standard_Real aTolV = (aMVTol.IsBound(nV) ? aMVTol(nV) : BRep_Tool::Tolerance(aV));
+
+  bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT);
   if (!bIsVertexOnLine && iCheckExtend) {
-    aTolV = BRep_Tool::Tolerance(aV);
-    //
     ExtendedTolerance(nV, aMI, aTolV, iCheckExtend);
-    bIsVertexOnLine=myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D, aT);
+    bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT);
   }
   //
   if (bIsVertexOnLine) {
     // check if aPB contains the parameter aT
     Standard_Boolean bExist;
-    Standard_Integer nVToUpdate;
-    Standard_Real aPTol, aDist, aTolVNew, aTolV2, aDTol;
-    TopoDS_Vertex aVToUpdate;
-    gp_Pnt aP1, aP2;
+    Standard_Integer nVUsed;
+    Standard_Real aPTol, aDTol;
     //
-    aTolV2 = 0.;
     aDTol = 1.e-12;
     //
     GeomAdaptor_Curve aGAC(aIC.Curve());
     aPTol = aGAC.Resolution(aTolR3D);
     //
-    bExist = aPB->ContainsParameter(aT, aPTol, nVToUpdate);
+    bExist = aPB->ContainsParameter(aT, aPTol, nVUsed);
     if (bExist) {
       // use existing pave
-      aP1 = BRep_Tool::Pnt(aV);
-      aTolV2 = BRep_Tool::Tolerance(aV);
-      aVToUpdate = (*(TopoDS_Vertex *)(&myDS->Shape(nVToUpdate)));
+      BOPCol_ListOfInteger* pList = aDMVLV.ChangeSeek(nVUsed);
+      if (!pList) {
+        pList = aDMVLV.Bound(nVUsed, BOPCol_ListOfInteger());
+        pList->Append(nVUsed);
+        if (!aMVTol.IsBound(nVUsed)) {
+          const TopoDS_Vertex& aVUsed = (*(TopoDS_Vertex *)(&myDS->Shape(nVUsed)));
+          aTolV = BRep_Tool::Tolerance(aVUsed);
+          aMVTol.Bind(nVUsed, aTolV);
+        }
+      }
+      pList->Append(nV);
+      if (!aMVTol.IsBound(nV)) {
+        aTolV = BRep_Tool::Tolerance(aV);
+        aMVTol.Bind(nV, aTolV);
+      }
     }
     else {
       // add new pave
@@ -1883,34 +2049,28 @@ void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC,
       aPave.SetParameter(aT);
       aPB->AppendExtPave(aPave);
       //
-      aP1 = aGAC.Value(aT);
-      nVToUpdate = nV;
-      aVToUpdate = aV;
-    }
-    //
-    aTolV = BRep_Tool::Tolerance(aVToUpdate);
-    aP2 = BRep_Tool::Pnt(aVToUpdate);
-    aDist = aP1.Distance(aP2);
-    aTolVNew = Max(aDist - aTolV2, aTolR3D);
-    //
-    if (aTolVNew > aTolV) {
-      BRep_Builder aBB;
-      aBB.UpdateVertex(aVToUpdate, aTolVNew+aDTol);
-      //
-      if (!aMVTol.IsBound(nVToUpdate)) {
-        aMVTol.Bind(nVToUpdate, aTolV);
+      gp_Pnt aP1 = aGAC.Value(aT);
+      aTolV = BRep_Tool::Tolerance(aV);
+      gp_Pnt aP2 = BRep_Tool::Pnt(aV);
+      Standard_Real aDist = aP1.Distance(aP2);
+      if (aDist > aTolV) {
+        BRep_Builder().UpdateVertex(aV, aDist + aDTol);
+        //
+        if (!aMVTol.IsBound(nV)) {
+          aMVTol.Bind(nV, aTolV);
+        }
+        //
+        BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV);
+        Bnd_Box& aBoxDS=aSIDS.ChangeBox();
+        BRepBndLib::Add(aV, aBoxDS);
+        aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
       }
-      // 
-      BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nVToUpdate);
-      Bnd_Box& aBoxDS=aSIDS.ChangeBox();
-      BRepBndLib::Add(aVToUpdate, aBoxDS);
-      aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
     }
   }
 }
 
 //=======================================================================
-//function : ProcessOldPaveBlocks
+//function : ProcessExistingPaveBlocks
 //purpose  : 
 //=======================================================================
 void BOPAlgo_PaveFiller::ProcessExistingPaveBlocks
@@ -1977,7 +2137,7 @@ void BOPAlgo_PaveFiller::ProcessExistingPaveBlocks
         //
         const TopoDS_Edge& aE = *(TopoDS_Edge*)&aSIE.Shape();
         //
-        iFlag = myContext->ComputeVE(aV, aE, aT, dummy);
+        iFlag = myContext->ComputeVE(aV, aE, aT, dummy, myFuzzyValue);
         if (!iFlag) {
           aMPB.Add(aPB);
           PreparePostTreatFF(theInt, iC, aPB, aMSCPB, aMVI, aLPBC);
@@ -2096,24 +2256,20 @@ void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
   //    with the opposite face.
   //    In case of coincidence create common blocks
   Standard_Integer nF;
-  Standard_Real aTolE, aTolF;
   //
   nF = bIn1 ? nF2 : nF1;
   const TopoDS_Face& aF = *(TopoDS_Face*)&myDS->Shape(nF);
   BOPDS_IndexedMapOfPaveBlock& aMPBIn = bIn1 ? aMPBIn2 : aMPBIn1;
-  aTolF = BRep_Tool::Tolerance(aF);
   //
   aIt.Initialize(aLPB);
   for (; aIt.More(); aIt.Next()) {
     Handle(BOPDS_PaveBlock)& aPBChangeValue = aIt.ChangeValue();
     const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPBChangeValue->Edge());
-    aTolE = BRep_Tool::Tolerance(aE);
     //
     IntTools_EdgeFace anEF;
     anEF.SetEdge(aE);
     anEF.SetFace(aF);
-    anEF.SetTolE(aTolE);
-    anEF.SetTolF(aTolF);
+    anEF.SetFuzzyValue(myFuzzyValue);
     anEF.SetRange(aPBChangeValue->Pave1().Parameter(), aPBChangeValue->Pave2().Parameter());
     anEF.SetContext(myContext);
     anEF.Perform();
@@ -2267,9 +2423,9 @@ Standard_Boolean BOPAlgo_PaveFiller::CheckPlanes
 //purpose  : 
 //=======================================================================
 void BOPAlgo_PaveFiller::UpdatePaveBlocks
-(const BOPCol_DataMapOfIntegerInteger& aDMI)
+(const BOPCol_DataMapOfIntegerInteger& aDMNewSD)
 {
-  if (aDMI.IsEmpty()) {
+  if (aDMNewSD.IsEmpty()) {
     return;
   }
   //
@@ -2302,10 +2458,10 @@ void BOPAlgo_PaveFiller::UpdatePaveBlocks
         Standard_Boolean wasRegularEdge = (nV[0] != nV[1]);
         //
         for (j = 0; j < 2; ++j) {
-          if (aDMI.IsBound(nV[j])) {
+          if (aDMNewSD.IsBound(nV[j])) {
             BOPDS_Pave aPave;
             //
-            nV[j] = aDMI.Find(nV[j]);
+            nV[j] = aDMNewSD.Find(nV[j]);
             aPave.SetIndex(nV[j]);
             aPave.SetParameter(aT[j]);
             //
@@ -2594,20 +2750,20 @@ void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
     Standard_Real aTolR3D = aFF.TolR3D();
     Standard_Real aTolReal = aFF.TolReal();
     Standard_Boolean bToReduce = aTolReal < aTolR3D;
-    // tolerance of intersection has been increased, so process this intersection
+      // tolerance of intersection has been increased, so process this intersection
     BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
-    Standard_Integer aNbC = aVNC.Extent(), k;
-    for (k = 0; k < aNbC; ++k) {
+      Standard_Integer aNbC = aVNC.Extent(), k;
+      for (k = 0; k < aNbC; ++k) {
       BOPDS_Curve& aNC = aVNC(k);
       BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
-      BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
+        BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
       for (; aItLPB.More(); ) {
-        const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
-        Standard_Integer nE;
+          const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
+          Standard_Integer nE;
         if (!aPB->HasEdge(nE)) {
           aLPB.Remove(aItLPB);
-          continue;
-        }
+            continue;
+          }
         //
         Standard_Boolean bIsReduced = Standard_False;
         if (bToReduce && (aPB->OriginalEdge() < 0)) {
@@ -2620,13 +2776,13 @@ void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
           }
         }
         //
-        // fill in the map vertex index - pave blocks
-        for (Standard_Integer j=0; j < 2; j++) {
+          // fill in the map vertex index - pave blocks
+          for (Standard_Integer j=0; j < 2; j++) {
           Standard_Integer nV = (j == 0 ? aPB->Pave1().Index() : aPB->Pave2().Index());
-          BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV);
-          if (!pPBList) {
-            pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock()));
-          }
+            BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV);
+            if (!pPBList) {
+              pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock()));
+            }
           pPBList->Append(aPB);
           if (bIsReduced) {
             aMVIToReduce.Add(nV);
index 7ab29eb..308ceeb 100644 (file)
@@ -92,6 +92,9 @@ void BOPAlgo_PaveFiller::ProcessDE()
             //
             // 2.
             BOPDS_ListOfPaveBlock& aLPBD = myDS->ChangePaveBlocks(nE);
+            Standard_ASSERT_VOID(!aLPBD.IsEmpty(), "ListOfPaveBlock is unexpectedly empty");
+            if (aLPBD.IsEmpty())
+              continue;
             aPBD = aLPBD.First();
             //
             FillPaves(nV, nE, nF, aLPBOut, aPBD);
index 5d9dd3f..a6fc3a9 100644 (file)
@@ -56,7 +56,7 @@ class BOPAlgo_ShrunkRange : public IntTools_ShrunkRange {
   //
   virtual void Perform() {
     IntTools_ShrunkRange::Perform();
-  }
+    }
   //
  protected:
   Handle(BOPDS_PaveBlock) myPB;
@@ -153,6 +153,7 @@ void BOPAlgo_PaveFiller::FillShrunkData(const TopAbs_ShapeEnum aType1,
   BOPAlgo_ShrunkRangeCnt::Perform(myRunParallel, aVSD, myContext);
   //=============================================================
   //
+  Standard_Real aFuzz = myFuzzyValue / 2.;
   for (k=0; k < aNbVSD; ++k) {
     BOPAlgo_ShrunkRange& aSD=aVSD(k);
     if (!aSD.IsDone()) {
@@ -161,7 +162,8 @@ void BOPAlgo_PaveFiller::FillShrunkData(const TopAbs_ShapeEnum aType1,
     //
     Handle(BOPDS_PaveBlock)& aPB=aSD.PaveBlock();
     aSD.ShrunkRange(aTS1, aTS2);
-    const Bnd_Box& aBox=aSD.BndBox();
+    Bnd_Box aBox=aSD.BndBox();
+    aBox.SetGap(aBox.GetGap() + aFuzz);
     Standard_Boolean bIsSplittable = aSD.IsSplittable();
     //
     aPB->SetShrunkData(aTS1, aTS2, aBox, bIsSplittable);
index 199487f..8832187 100644 (file)
@@ -63,16 +63,6 @@ static
   Standard_Real ComputeParameter(const TopoDS_Vertex& aV,
                                  const TopoDS_Edge& aE);
 
-static 
-  void AddShapeAndSubShapes(const Standard_Integer nS,
-                            const BOPDS_ShapeInfo& theSI,
-                            BOPCol_MapOfInteger& theMI);
-
-static 
-  void CollectEdges(const BOPDS_DS& theDS,
-                    const Standard_Integer nF,
-                    BOPCol_MapOfInteger& theMI);
-
 //=======================================================================
 //function : 
 //purpose  : 
@@ -99,9 +89,7 @@ BOPDS_DS::BOPDS_DS()
   myInterfVZ(0, myAllocator),
   myInterfEZ(0, myAllocator),
   myInterfFZ(0, myAllocator),
-  myInterfZZ(0, myAllocator),
-  myFuzzyValue(0.),
-  myToleranceMap(100, myAllocator)
+  myInterfZZ(0, myAllocator)
 {
   myNbShapes=0;
   myNbSourceShapes=0;
@@ -132,9 +120,7 @@ BOPDS_DS::BOPDS_DS(const Handle(NCollection_BaseAllocator)& theAllocator)
   myInterfVZ(0, myAllocator),
   myInterfEZ(0, myAllocator),
   myInterfFZ(0, myAllocator),
-  myInterfZZ(0, myAllocator),
-  myFuzzyValue(0.),
-  myToleranceMap(100, myAllocator)
+  myInterfZZ(0, myAllocator)
 {
   myNbShapes=0;
   myNbSourceShapes=0;
@@ -155,7 +141,6 @@ void BOPDS_DS::Clear()
 {
   myNbShapes=0;
   myNbSourceShapes=0;
-  myFuzzyValue=0.;
   //
   myArguments.Clear();
   myRanges.Clear();
@@ -177,7 +162,6 @@ void BOPDS_DS::Clear()
   myInterfEZ.Clear();
   myInterfFZ.Clear();
   myInterfZZ.Clear();
-  myToleranceMap.Clear();
 }
 //=======================================================================
 //function : SetArguments
@@ -336,11 +320,11 @@ Standard_Integer BOPDS_DS::Index(const TopoDS_Shape& theS)const
 //function : Init
 //purpose  : 
 //=======================================================================
-void BOPDS_DS::Init()
+void BOPDS_DS::Init(const Standard_Real theFuzz)
 {
   Standard_Integer i1, i2, j, aI, aNb, aNbS, aNbE, aNbSx;
   Standard_Integer n1, n2, n3, nV, nW, nE, aNbF;
-  Standard_Real aTol, aFuzz, aTolAdd;
+  Standard_Real aTol, aTolAdd;
   TopAbs_ShapeEnum aTS;
   TopoDS_Iterator aItS;
   BOPCol_ListIteratorOfListOfInteger aIt1, aIt2, aIt3;
@@ -395,8 +379,7 @@ void BOPDS_DS::Init()
     i1=i2+1;
   }
   //
-  aFuzz = myFuzzyValue / 2.;
-  aTolAdd = Precision::Confusion();
+  aTolAdd = Max(theFuzz, Precision::Confusion()) * 0.5;
   myNbSourceShapes = NbShapes();
   //
   // 2 Bounding Boxes
@@ -413,15 +396,7 @@ void BOPDS_DS::Init()
       Bnd_Box& aBox=aSI.ChangeBox();
       const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&aS);
       const gp_Pnt& aP=BRep_Tool::Pnt(aV);
-      //
-      const Handle(BRep_TVertex)& TV = 
-        *((Handle(BRep_TVertex)*)&aV.TShape());
-      aTol = TV->Tolerance();
-      // TODO: non-destructive
-      myToleranceMap.Bind(j, aTol);
-      aTol += aFuzz;
-      TV->Tolerance(aTol);
-      //
+      aTol = BRep_Tool::Tolerance(aV);
       aBox.SetGap(aTol + aTolAdd);
       aBox.Add(aP);
     }
@@ -435,14 +410,7 @@ void BOPDS_DS::Init()
     if (aTS==TopAbs_EDGE) {
       const TopoDS_Shape& aS=aSI.Shape();
       const TopoDS_Edge& aE=*((TopoDS_Edge*)&aS);
-      //
-      const Handle(BRep_TEdge)& TE = 
-        *((Handle(BRep_TEdge)*)&aE.TShape());
-      aTol = TE->Tolerance();
-      // TODO: non-destructive
-      myToleranceMap.Bind(j, aTol);
-      aTol += aFuzz;
-      TE->Tolerance(aTol);
+      aTol = BRep_Tool::Tolerance(aE);
       //
       if (!BRep_Tool::Degenerated(aE)) {
         Standard_Boolean bInf1, bInf2;
@@ -519,15 +487,6 @@ void BOPDS_DS::Init()
     aTS=aSI.ShapeType();
     if (aTS==TopAbs_FACE) {
       const TopoDS_Shape& aS=aSI.Shape();
-      const TopoDS_Face& aF=*((TopoDS_Face*)&aS);
-      //
-      const Handle(BRep_TFace)& TF = 
-        *((Handle(BRep_TFace)*)&aF.TShape());
-      aTol = TF->Tolerance();
-      // TODO: non-destructive
-      myToleranceMap.Bind(j, aTol);
-      aTol += aFuzz;
-      TF->Tolerance(aTol);
       //
       Bnd_Box& aBox=aSI.ChangeBox();
       BRepBndLib::Add(aS, aBox);
@@ -928,7 +887,11 @@ void BOPDS_DS::InitPaveBlocks(const Standard_Integer theI)
       }
       aPave.SetIndex(nV);
       aPave.SetParameter(aT);
-      aPB->AppendExtPave(aPave);
+      if (aSI.HasFlag())
+        // for a degenerated edge append pave unconditionally
+        aPB->AppendExtPave1(aPave);
+      else
+        aPB->AppendExtPave(aPave);
     }
     //
     if (aNbV==1) {
@@ -1044,7 +1007,8 @@ void BOPDS_DS::UpdatePaveBlock(const Handle(BOPDS_PaveBlock)& thePB)
 //function : UpdateCommonBlock
 //purpose  : 
 //=======================================================================
-void BOPDS_DS::UpdateCommonBlock(const Handle(BOPDS_CommonBlock)& theCB)
+void BOPDS_DS::UpdateCommonBlock(const Handle(BOPDS_CommonBlock)& theCB,
+                                 const Standard_Real theFuzz)
 {
   Standard_Integer nE, iRef, n1, n2;
   BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB, aItPBN;
@@ -1117,7 +1081,7 @@ void BOPDS_DS::UpdateCommonBlock(const Handle(BOPDS_CommonBlock)& theCB)
         const Handle(BOPDS_PaveBlock)& aPBx=aItPB.Value();
         if (aLPBxN.Extent()) {
           const Handle(BOPDS_PaveBlock)& aPBCx = aLPBxN.First();
-          bCoinside = CheckCoincidence(aPBx, aPBCx);
+          bCoinside = CheckCoincidence(aPBx, aPBCx, theFuzz);
           if (bCoinside) {
             nE = aPBx->OriginalEdge();
             const TopoDS_Edge& aE = *(TopoDS_Edge*)&Shape(nE);
@@ -1522,11 +1486,12 @@ void BOPDS_DS::AloneVertices(const Standard_Integer theI,
 //function : VerticesOnIn
 //purpose  : 
 //=======================================================================
-void BOPDS_DS::VerticesOnIn
+void BOPDS_DS::SubShapesOnIn
   (const Standard_Integer nF1,
    const Standard_Integer nF2,
-   BOPCol_MapOfInteger& aMI,
-   BOPDS_IndexedMapOfPaveBlock& aMPB)const
+   BOPCol_MapOfInteger& theMVOnIn,
+   BOPDS_IndexedMapOfPaveBlock& thePBOnIn,
+   BOPDS_MapOfPaveBlock& theCommonPB)const
 {
   Standard_Integer i, j, nV, nV1, nV2, aNbPB;
   BOPCol_MapIteratorOfMapOfInteger aIt;
@@ -1544,10 +1509,14 @@ void BOPDS_DS::VerticesOnIn
     aNbPB = pMPB[i].Extent();
     for (j = 1; j <= aNbPB; ++j) {
       const Handle(BOPDS_PaveBlock)& aPB = pMPB[i](j);
-      aMPB.Add(aPB);
+      thePBOnIn.Add(aPB);
       aPB->Indices(nV1, nV2);
-      aMI.Add(nV1);
-      aMI.Add(nV2);
+      theMVOnIn.Add(nV1);
+      theMVOnIn.Add(nV2);
+      if (i < 2) {
+        if (pMPB[2].Contains(aPB) || pMPB[3].Contains(aPB))
+          theCommonPB.Add(aPB);
+      }
     }
   }
   //
@@ -1562,7 +1531,7 @@ void BOPDS_DS::VerticesOnIn
     for (; aIt.More(); aIt.Next()) {
       nV=aIt.Value();
       if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) {
-        aMI.Add(nV);
+        theMVOnIn.Add(nV);
       }
     }
   }
@@ -1705,7 +1674,8 @@ void BOPDS_DS::Dump()const
 //=======================================================================
 Standard_Boolean BOPDS_DS::CheckCoincidence
   (const Handle(BOPDS_PaveBlock)& aPB1,
-   const Handle(BOPDS_PaveBlock)& aPB2)
+   const Handle(BOPDS_PaveBlock)& aPB2,
+   const Standard_Real theFuzz)
 {
   Standard_Boolean bRet;
   Standard_Integer nE1, nE2, aNbPoints;
@@ -1734,7 +1704,7 @@ Standard_Boolean BOPDS_DS::CheckCoincidence
     aD=aPPC.LowerDistance();
     //
     aTol=BRep_Tool::Tolerance(aE1);
-    aTol=aTol+BRep_Tool::Tolerance(aE2) + Precision::Confusion();
+    aTol = aTol + BRep_Tool::Tolerance(aE2) + Max(theFuzz, Precision::Confusion());
     if (aD<aTol) {
       aT2x=aPPC.LowerDistanceParameter();
       if (aT2x>aT21 && aT2x<aT22) {
@@ -1897,19 +1867,22 @@ void BOPDS_DS::Paves(const Standard_Integer theEdge,
 // purpose:
 //=======================================================================
 void BOPDS_DS::UpdateEdgeTolerance(const Standard_Integer nE,
-                                   const Standard_Real aTol)
+                                   const Standard_Real aTol,
+                                   const Standard_Real theFuzz)
 {
   Standard_Integer nV;
   Standard_Real aTolV;
   BRep_Builder aBB;
   BOPCol_ListIteratorOfListOfInteger aIt;
   //
+  Standard_Real aTolAdd = Max(theFuzz, Precision::Confusion()) * 0.5;
+
   const TopoDS_Edge& aE = *(TopoDS_Edge*)&Shape(nE);
   aBB.UpdateEdge(aE, aTol);
   BOPDS_ShapeInfo& aSIE=ChangeShapeInfo(nE);
   Bnd_Box& aBoxE=aSIE.ChangeBox();
   BRepBndLib::Add(aE, aBoxE);
-  aBoxE.SetGap(aBoxE.GetGap() + Precision::Confusion());
+  aBoxE.SetGap(aBoxE.GetGap() + aTolAdd);
   //
   const BOPCol_ListOfInteger& aLI = aSIE.SubShapes();
   aIt.Initialize(aLI);
@@ -1922,7 +1895,7 @@ void BOPDS_DS::UpdateEdgeTolerance(const Standard_Integer nE,
       BOPDS_ShapeInfo& aSIV = ChangeShapeInfo(nV);
       Bnd_Box& aBoxV = aSIV.ChangeBox();
       BRepBndLib::Add(aV, aBoxV);
-      aBoxV.SetGap(aBoxV.GetGap() + Precision::Confusion());
+      aBoxV.SetGap(aBoxV.GetGap() + aTolAdd);
     }
   }
 }
@@ -2061,239 +2034,6 @@ void BOPDS_DS::BuildBndBoxSolid(const Standard_Integer theIndex,
 }
 
 //=======================================================================
-//function : DefaultTolerances
-//purpose  : 
-//=======================================================================
-void BOPDS_DS::SetDefaultTolerances()
-{
-  if (myFuzzyValue == 0.) {
-    return;
-  }
-  //
-  Standard_Boolean bAdd;
-  Standard_Integer i, j, n1, n2, nS, nSOp, nSs;
-  Standard_Integer anIntType, aNbFF, aNbFIn;
-  Standard_Real aTolDef;
-  TopAbs_ShapeEnum aTS1, aTS2;
-  BOPCol_MapOfInteger aMICh;
-  BOPCol_DataMapOfIntegerMapOfInteger aDMI;
-  BOPCol_ListIteratorOfListOfInteger aItLI;
-  BOPDS_MapIteratorMapOfPassKey aItPK;
-  BOPDS_ListIteratorOfListOfPaveBlock aItPB;
-  BOPCol_MapIteratorOfMapOfInteger aItMI;
-  BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItDMIR;
-  //
-  // 1. Collect interfered shapes
-  // 1.1. Interferences V/V, V/E, V/F, E/E and E/F
-  aItPK.Initialize(myInterfTB);
-  for (; aItPK.More(); aItPK.Next()) {
-    const BOPDS_PassKey& aPK = aItPK.Value();
-    aPK.Ids(n1, n2);
-    //
-    const BOPDS_ShapeInfo& aSI1 = ShapeInfo(n1);
-    const BOPDS_ShapeInfo& aSI2 = ShapeInfo(n2);
-    //
-    aTS1 = aSI1.ShapeType();
-    aTS2 = aSI2.ShapeType();
-    //
-    anIntType = BOPDS_Tools::TypeToInteger(aTS1, aTS2);
-    if (anIntType < 5) {
-      AddShapeAndSubShapes(n1, aSI1, aMICh);
-      AddShapeAndSubShapes(n2, aSI2, aMICh);
-    } // if (anIntType < 5) {
-  } // for (; aIt.More(); aIt.Next()) {
-  //
-  // 1.2 FaceInfo information
-  aNbFF = myFaceInfoPool.Extent();
-  for (i = 0; i < aNbFF; ++i) {
-    const BOPDS_FaceInfo& aFI = myFaceInfoPool(i);
-    nS = aFI.Index();
-    if (aMICh.Contains(nS)) {
-      continue;
-    }
-    //
-    aNbFIn = (aFI.PaveBlocksIn().Extent() + 
-              aFI.VerticesIn().Extent() +
-              aFI.PaveBlocksSc().Extent() +
-              aFI.VerticesSc().Extent());
-    if (aNbFIn > 0) {
-      AddShapeAndSubShapes(nS, ShapeInfo(nS), aMICh);
-    } // if (aNbFIn > 0) {
-  } // for (i = 0; i < aNbFF; ++i) {
-  //
-  // 1.3. Empty F/F interferences
-  aNbFF = myInterfFF.Extent();
-  for (i = 0; i < aNbFF; ++i) {
-    BOPDS_InterfFF& aFF = myInterfFF(i);
-    if ((aFF.Curves().Extent() == 0) &&
-        (aFF.Points().Extent() == 0)) {
-      aFF.Indices(n1, n2);
-      for (j = 0; j < 2; ++j) {
-        nS = !j ? n1 : n2;
-        if (aMICh.Contains(nS)) {
-          continue;
-        }
-        nSOp = !j ? n2 : n1;
-        //
-        BOPCol_MapOfInteger aME, aMEOp;
-        //
-        if (aDMI.IsBound(nS)) {
-          aME = aDMI.Find(nS);
-        } else {
-          CollectEdges(*this, nS, aME);
-          aDMI.Bind(nS, aME);
-        }
-        //
-        if (aDMI.IsBound(nSOp)) {
-          aMEOp = aDMI.Find(nSOp);
-        } else {
-          CollectEdges(*this, nSOp, aMEOp);
-          aDMI.Bind(nSOp, aMEOp);
-        }
-        //
-        bAdd = Standard_True;
-        aItMI.Initialize(aME);
-        for (; aItMI.More(); aItMI.Next()) {
-          nSs = aItMI.Value();
-          if (!aMEOp.Contains(nSs)) {
-            bAdd = Standard_False;
-            break;
-          }
-        }
-        //
-        if (bAdd) {
-          AddShapeAndSubShapes(nS, ShapeInfo(nS), aMICh);
-          if (j == 0) {
-            AddShapeAndSubShapes(nSOp, ShapeInfo(nSOp), aMICh);
-          }
-        } // if (bAdd) {
-      } // for (j = 0; j < 2; ++j) {
-    } //if ((aFF.Curves().Extent() == 0) &&
-  } // for (i = 0; i < aNbFF; ++i) {
-  //
-  // 2. Back to default tolerance values
-  aItDMIR.Initialize(myToleranceMap);
-  for (; aItDMIR.More(); aItDMIR.Next()) {
-    i = aItDMIR.Key();
-    //
-    if (aMICh.Contains(i)) {
-      continue;
-    }
-    //
-    const BOPDS_ShapeInfo& aSI = ShapeInfo(i);
-    aTolDef = aItDMIR.Value();
-    aTS1 = aSI.ShapeType();
-    switch (aTS1) {
-      case TopAbs_VERTEX: {
-        const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aSI.Shape();
-        const Handle(BRep_TVertex)& aTV = 
-          *((Handle(BRep_TVertex)*)&aV.TShape());
-        aTV->Tolerance(aTolDef);
-        break;
-      }
-      case TopAbs_EDGE: {
-        const TopoDS_Edge& aE = *(TopoDS_Edge*)&aSI.Shape();
-        const Handle(BRep_TEdge)& aTE = 
-          *((Handle(BRep_TEdge)*)&aE.TShape());
-        aTE->Tolerance(aTolDef);
-        //
-        const BOPDS_ListOfPaveBlock& aLPB = PaveBlocks(i);
-        aItPB.Initialize(aLPB);
-        for (; aItPB.More(); aItPB.Next()) {
-          const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
-          nS = aPB->Edge();
-          const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&Shape(nS);
-          const Handle(BRep_TEdge)& aTEIm = 
-          *((Handle(BRep_TEdge)*)&aEIm.TShape());
-          aTEIm->Tolerance(aTolDef);
-        }
-        break;
-      }
-      case TopAbs_FACE: {
-        const TopoDS_Face& aF = *(TopoDS_Face*)&aSI.Shape();
-        const Handle(BRep_TFace)& aTF = 
-          *((Handle(BRep_TFace)*)&aF.TShape());
-        aTF->Tolerance(aTolDef);
-        break;
-      }
-      default:
-        break;
-    } // switch (aTS1) {
-  } // for (; aItDMIR.More(); aItDMIR.Next()) {
-}
-
-//=======================================================================
-//function : AddShapeAndSubShapes
-//purpose  : 
-//=======================================================================
-void AddShapeAndSubShapes(const Standard_Integer nS,
-                          const BOPDS_ShapeInfo& theSI,
-                          BOPCol_MapOfInteger& theMI)
-{
-  Standard_Integer nSs;
-  if (theMI.Add(nS)) {
-    const BOPCol_ListOfInteger& aLI = theSI.SubShapes();
-    BOPCol_ListIteratorOfListOfInteger aItLI(aLI);
-    for (; aItLI.More(); aItLI.Next()) {
-      nSs = aItLI.Value();
-      theMI.Add(nSs);
-    }
-  }
-}
-
-//=======================================================================
-//function : CollectEdges
-//purpose  : 
-//=======================================================================
-void CollectEdges(const BOPDS_DS& theDS,
-                  const Standard_Integer nF,
-                  BOPCol_MapOfInteger& theMI)
-{
-  Standard_Integer i, j, aNbPB, nE, nEIm;
-  BOPCol_ListIteratorOfListOfInteger aItLI;
-  BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
-  //
-  // ON edges
-  const BOPDS_ShapeInfo& aSI = theDS.ShapeInfo(nF);
-  const BOPCol_ListOfInteger& aLI = aSI.SubShapes();
-  aItLI.Initialize(aLI);
-  for (; aItLI.More(); aItLI.Next()) {
-    nE = aItLI.Value();
-    const BOPDS_ShapeInfo& aSIE = theDS.ShapeInfo(nE);
-    if (aSIE.ShapeType() != TopAbs_EDGE) {
-      continue;
-    }
-    //
-    if (!aSIE.HasReference()) {
-      theMI.Add(nE);
-      continue;
-    }
-    //
-    const BOPDS_ListOfPaveBlock& aLPB = theDS.PaveBlocks(nE);
-    aItLPB.Initialize(aLPB);
-    for (; aItLPB.More(); aItLPB.Next()) {
-      const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
-      nEIm = aPB->Edge();
-      theMI.Add(nEIm);
-    }
-  }
-  // IN and SC edges
-  const BOPDS_FaceInfo& aFI = theDS.FaceInfo(nF);
-  const BOPDS_IndexedMapOfPaveBlock& aMPBIn = aFI.PaveBlocksIn();
-  const BOPDS_IndexedMapOfPaveBlock& aMPBSc = aFI.PaveBlocksSc();
-  //
-  for (i = 0; i < 2; ++i) {
-    const BOPDS_IndexedMapOfPaveBlock& aMPB = !i ? aMPBIn : aMPBSc;
-    aNbPB = aMPB.Extent();
-    for (j = 1; j <= aNbPB; ++j) {
-      const Handle(BOPDS_PaveBlock)& aPB = aMPB(j);
-      nE = aPB->Edge();
-      theMI.Add(nE);
-    }
-  }
-}
-
-//=======================================================================
 //function : UpdatePaveBlocksWithSDVertices
 //purpose  : 
 //=======================================================================
index 86985ea..a882896 100644 (file)
 #include <BOPDS_VectorOfInterfFZ.hxx>
 #include <BOPDS_VectorOfInterfZZ.hxx>
 #include <Standard_Real.hxx>
-#include <BOPCol_DataMapOfIntegerReal.hxx>
 #include <Standard_Boolean.hxx>
 #include <BOPDS_ListOfPaveBlock.hxx>
 #include <BOPDS_IndexedMapOfPaveBlock.hxx>
+#include <BOPDS_MapOfPaveBlock.hxx>
 #include <BOPCol_MapOfInteger.hxx>
 #include <BOPCol_ListOfInteger.hxx>
 #include <BOPDS_ListOfPave.hxx>
+#include <Precision.hxx>
 class BOPDS_IndexRange;
 class BOPDS_ShapeInfo;
 class TopoDS_Shape;
@@ -113,7 +114,7 @@ Standard_EXPORT virtual ~BOPDS_DS();
 
   //! Initializes the data structure for
   //! the arguments
-  Standard_EXPORT void Init();
+  Standard_EXPORT void Init(const Standard_Real theFuzz = Precision::Confusion());
   
 
   //! Selector
@@ -218,7 +219,8 @@ Standard_EXPORT virtual ~BOPDS_DS();
   
 
   //! Update the common block theCB
-  Standard_EXPORT void UpdateCommonBlock (const Handle(BOPDS_CommonBlock)& theCB);
+  Standard_EXPORT void UpdateCommonBlock (const Handle(BOPDS_CommonBlock)& theCB,
+                                          const Standard_Real theFuzz);
   
 
   //! Query
@@ -300,9 +302,15 @@ Standard_EXPORT virtual ~BOPDS_DS();
   Standard_EXPORT void RefineFaceInfoOn();
   
 
-  //! Returns the indices of vertices and pave blocks
-  //! that  are On/In for the faces with indices theF1, theF2
-  Standard_EXPORT void VerticesOnIn (const Standard_Integer theF1, const Standard_Integer theF2, BOPCol_MapOfInteger& theMI, BOPDS_IndexedMapOfPaveBlock& aMPB) const;
+  //! Returns information about ON/IN subshapes of the given faces.
+  //! @param theMVOnIn  the indices of ON/IN vertices from both faces
+  //! @param thePBOnIn  all On/In pave blocks from both faces
+  //! @param theCommonPB  the common pave blocks (that are shared by both faces).
+  Standard_EXPORT void SubShapesOnIn (const Standard_Integer theF1,
+                                      const Standard_Integer theF2,
+                                      BOPCol_MapOfInteger& theMVOnIn,
+                                      BOPDS_IndexedMapOfPaveBlock& thePBOnIn,
+                                      BOPDS_MapOfPaveBlock& theCommonPB) const;
   
 
   //! Returns the indices of edges that are  shared
@@ -439,26 +447,18 @@ Standard_EXPORT virtual ~BOPDS_DS();
   
 
   //! Updates tolerance of the sub-shapes of the shape with index <theIndex>.
-  Standard_EXPORT void UpdateEdgeTolerance (const Standard_Integer theIndex, const Standard_Real theTolerance);
+  Standard_EXPORT void UpdateEdgeTolerance (const Standard_Integer theIndex,
+                                            const Standard_Real theTolerance,
+                                            const Standard_Real theFuzz = Precision::Confusion());
 
+  //! Update the pave blocks for all shapes in data structure
   Standard_EXPORT void UpdatePaveBlocksWithSDVertices();
 
+  //! Update the pave block of the common block for all shapes in data structure
   Standard_EXPORT void UpdateCommonBlockWithSDVertices(const Handle(BOPDS_CommonBlock)& theCB);
 
   Standard_EXPORT void InitPaveBlocksForVertex(const Standard_Integer theNV);
 
-  //! Sets the extended tolerance
-    void SetFuzzyValue (const Standard_Real theFuzz);
-  
-  //! Returns the extended tolerance
-    Standard_Real FuzzyValue() const;
-  
-  //! Reverts the tolerance values of unchanged entities to default values.
-  Standard_EXPORT void SetDefaultTolerances();
-
-
-
-
 protected:
 
   
@@ -466,6 +466,7 @@ protected:
   //! Initializes the pave blocks for the shape with index theIndex
   Standard_EXPORT void InitPaveBlocks (const Standard_Integer theIndex);
 
+  //! Update the pave block for all shapes in data structure
   Standard_EXPORT void UpdatePaveBlockWithSDVertices(const Handle(BOPDS_PaveBlock)& thePB);
 
   //! Initializes the state of face with index theIndex
@@ -473,7 +474,9 @@ protected:
   
   Standard_EXPORT void InitShape (const Standard_Integer theIndex, const TopoDS_Shape& theS, const BOPCol_BaseAllocator& theAllocator, BOPCol_DataMapOfShapeInteger& theMSI);
   
-  Standard_EXPORT Standard_Boolean CheckCoincidence (const Handle(BOPDS_PaveBlock)& thePB1, const Handle(BOPDS_PaveBlock)& thePB2);
+  Standard_EXPORT Standard_Boolean CheckCoincidence (const Handle(BOPDS_PaveBlock)& thePB1,
+                                                     const Handle(BOPDS_PaveBlock)& thePB2,
+                                                     const Standard_Real theFuzz);
   
 
   //! Computes bouding box <theBox> for the solid with DS-index <theIndex>
@@ -503,8 +506,6 @@ protected:
   BOPDS_VectorOfInterfEZ myInterfEZ;
   BOPDS_VectorOfInterfFZ myInterfFZ;
   BOPDS_VectorOfInterfZZ myInterfZZ;
-  Standard_Real myFuzzyValue;
-  BOPCol_DataMapOfIntegerReal myToleranceMap;
 
 
 private:
index bf4ef9c..7f6f71f 100644 (file)
@@ -133,19 +133,3 @@ inline const BOPDS_MapOfPassKey& BOPDS_DS::Interferences()const
 {
   return myInterfTB;
 }
-//=======================================================================
-//function : SetFuzzyValue
-//purpose  : 
-//=======================================================================
-inline void BOPDS_DS::SetFuzzyValue(const Standard_Real theFuzz)
-{
-  myFuzzyValue = (theFuzz < 0.) ? 0. : theFuzz;
-}
-//=======================================================================
-//function : FuzzyValue
-//purpose  : 
-//=======================================================================
-inline Standard_Real BOPDS_DS::FuzzyValue() const
-{
-  return myFuzzyValue;
-}
index fa06f62..3f2ea71 100755 (executable)
@@ -212,6 +212,25 @@ IMPLEMENT_STANDARD_RTTIEXT(BOPDS_PaveBlock,MMgt_TShared)
   myExtPaves.Append(thePave);
 }
 //=======================================================================
+//function : RemoveExtPave
+//purpose  : 
+//=======================================================================
+void BOPDS_PaveBlock::RemoveExtPave(const Standard_Integer theVertNum)
+{
+  if (myMFence.Contains(theVertNum))
+  {
+    BOPDS_ListOfPave::Iterator itPaves(myExtPaves);
+    while (itPaves.More())
+    {
+      if (itPaves.Value().Index() == theVertNum)
+        myExtPaves.Remove(itPaves);
+      else
+        itPaves.Next();
+    }
+    myMFence.Remove(theVertNum);
+  }
+}
+//=======================================================================
 //function : ExtPaves
 //purpose  : 
 //=======================================================================
index 397ad80..b0ca607 100644 (file)
@@ -139,14 +139,17 @@ public:
   
 
   //! Modifier
-  //! Appends extra paves <theLP>
-  Standard_EXPORT void AppendExtPave (const BOPDS_Pave& theLP);
+  //! Appends extra paves <thePave>
+  Standard_EXPORT void AppendExtPave(const BOPDS_Pave& thePave);
   
 
   //! Modifier
   //! Appends extra pave <thePave>
   Standard_EXPORT void AppendExtPave1 (const BOPDS_Pave& thePave);
   
+  //! Modifier
+  //! Removes a pave with the given vertex number from extra paves
+  Standard_EXPORT void RemoveExtPave(const Standard_Integer theVertNum);
 
   //! Selector
   //! Returns the  extra paves
index 2a4f64a..fffb11c 100644 (file)
@@ -922,7 +922,8 @@ Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
 Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
   (const TopoDS_Face& theF1,
    const TopoDS_Face& theF2,
-   Handle(IntTools_Context)& theContext)
+   Handle(IntTools_Context)& theContext,
+   const Standard_Real theFuzz)
 {
   Standard_Boolean bFlag;
   Standard_Integer iErr;
@@ -932,6 +933,7 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
   TopoDS_Face aF1, aF2;
   TopoDS_Edge aE1;
   TopExp_Explorer aExp;
+  Standard_Real aFuzz1 = (theFuzz > Precision::Confusion() ? theFuzz : Precision::Confusion());
   //
   bFlag=Standard_False;
   //
@@ -947,12 +949,14 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
     aE1=(*(TopoDS_Edge*)(&aExp.Current()));
     if (!BRep_Tool::Degenerated(aE1)) {
       Standard_Real aTolE = BRep_Tool::Tolerance(aE1);
-      aTolF1 = (aTolE > aTolF1) ? aTolE : aTolF1;
+      if (aTolE > aTolF1) {
+        aTolF1 = aTolE;
+      }
     }
   }
   // 2
   aTolF2=BRep_Tool::Tolerance(aF2);
-  aTol = aTolF1 + aTolF2 + Precision::Confusion();
+  aTol = aTolF1 + aTolF2 + aFuzz1;
   //
   iErr = BOPTools_AlgoTools3D::PointInFace(aF1, aP, aP2D,
                                            theContext);
@@ -1420,23 +1424,16 @@ void BOPTools_AlgoTools::MakeEdge(const IntTools_Curve& theIC,
                                   const Standard_Real theTolR3D,
                                   TopoDS_Edge& theE)
 {
-  Standard_Real aTolV;
   BRep_Builder aBB;
+  Standard_Real aNeedTol = theTolR3D + 1e-12;
+  //
+  aBB.UpdateVertex(theV1, aNeedTol);
+  aBB.UpdateVertex(theV2, aNeedTol);
   //
   BOPTools_AlgoTools::MakeSectEdge (theIC, theV1, theT1, theV2, theT2, 
                                     theE);
   //
   aBB.UpdateEdge(theE, theTolR3D);
-  //
-  aTolV=BRep_Tool::Tolerance(theV1);
-  if (aTolV<theTolR3D) {
-    aBB.UpdateVertex(theV1, theTolR3D);
-  }
-  //
-  aTolV=BRep_Tool::Tolerance(theV2);
-  if (aTolV<theTolR3D) {
-    aBB.UpdateVertex(theV2, theTolR3D);
-  }
 }
 //=======================================================================
 // function: ComputeVV
@@ -1467,14 +1464,16 @@ Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1,
 // purpose: 
 //=======================================================================
 Standard_Integer BOPTools_AlgoTools::ComputeVV(const TopoDS_Vertex& aV1, 
-                                               const TopoDS_Vertex& aV2)
+                                               const TopoDS_Vertex& aV2,
+                                               const Standard_Real aFuzz)
 {
   Standard_Real aTolV1, aTolV2, aTolSum, aTolSum2, aD2;
   gp_Pnt aP1, aP2;
+  Standard_Real aFuzz1 = (aFuzz > Precision::Confusion() ? aFuzz : Precision::Confusion());
   //
   aTolV1=BRep_Tool::Tolerance(aV1);
   aTolV2=BRep_Tool::Tolerance(aV2);
-  aTolSum = aTolV1 + aTolV2 + Precision::Confusion();
+  aTolSum=aTolV1+aTolV2+aFuzz1;
   aTolSum2=aTolSum*aTolSum;
   //
   aP1=BRep_Tool::Pnt(aV1);
index 0fcc84f..033105c 100644 (file)
@@ -32,6 +32,7 @@
 #include <TopAbs_State.hxx>
 #include <BOPCol_IndexedMapOfShape.hxx>
 #include <BOPCol_BaseAllocator.hxx>
+#include <Precision.hxx>
 class TopoDS_Vertex;
 class gp_Pnt;
 class IntTools_Curve;
@@ -44,7 +45,6 @@ class IntTools_Range;
 class TopoDS_Shell;
 
 
-
 class BOPTools_AlgoTools 
 {
 public:
@@ -54,7 +54,9 @@ public:
   
   Standard_EXPORT static Standard_Integer ComputeVV (const TopoDS_Vertex& aV1, const gp_Pnt& aP2, const Standard_Real aTolP2);
   
-  Standard_EXPORT static Standard_Integer ComputeVV (const TopoDS_Vertex& aV1, const TopoDS_Vertex& aV2);
+  Standard_EXPORT static Standard_Integer ComputeVV (const TopoDS_Vertex& aV1, 
+                                                     const TopoDS_Vertex& aV2, 
+                                                     const Standard_Real theFuzz = Precision::Confusion());
   
   Standard_EXPORT static void MakeVertex (const BOPCol_ListOfShape& aLV, TopoDS_Vertex& aV);
   
@@ -79,7 +81,10 @@ public:
   
   Standard_EXPORT static Standard_Boolean IsSplitToReverse (const TopoDS_Edge& aE1, const TopoDS_Edge& aE2, Handle(IntTools_Context)& aContext);
   
-  Standard_EXPORT static Standard_Boolean AreFacesSameDomain (const TopoDS_Face& theF1, const TopoDS_Face& theF2, Handle(IntTools_Context)& theContext);
+  Standard_EXPORT static Standard_Boolean AreFacesSameDomain (const TopoDS_Face& theF1,
+                                         const TopoDS_Face& theF2, 
+                                         Handle(IntTools_Context)& theContext,
+                                         const Standard_Real theFuzz = Precision::Confusion());
   
   Standard_EXPORT static Standard_Boolean CheckSameGeom (const TopoDS_Face& theF1, const TopoDS_Face& theF2, Handle(IntTools_Context)& theContext);
   
@@ -299,26 +304,11 @@ public:
   Standard_EXPORT static Standard_Boolean ComputeTolerance (const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, Standard_Real& theMaxDist, Standard_Real& theMaxPar);
 
 
-
-
 protected:
 
 
-
-
-
 private:
 
-
-
-
-
 };
 
-
-
-
-
-
-
 #endif // _BOPTools_AlgoTools_HeaderFile
index c1d9bea..04141ba 100644 (file)
@@ -52,6 +52,7 @@
 #include <gp_Pnt2d.hxx>
 #include <IntRes2d_Domain.hxx>
 #include <IntRes2d_IntersectionPoint.hxx>
+#include <IntRes2d_IntersectionSegment.hxx>
 #include <IntTools_Context.hxx>
 #include <IntTools_Curve.hxx>
 #include <IntTools_Range.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
+
 static 
   void CheckEdge (const TopoDS_Edge& E,
                   const Standard_Real aMaxTol,
@@ -126,13 +112,11 @@ static
                    const BOPCol_IndexedMapOfShape& aMapToAvoid);
 
 static 
-  Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
-                                  const TopoDS_Face& aF,
-                                  const GeomAdaptor_Surface& aS,
-                                  const TopoDS_Edge& aE1,
-                                  const TopoDS_Edge& aE2);
-
-
+  Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
+                                  const TopoDS_Face& theF,
+                                  const Handle(Geom_Surface)& theS,
+                                  const TopoDS_Edge& theE1,
+                                  const TopoDS_Edge& theE2);
 
 //=======================================================================
 //class    : BOPTools_CPC
@@ -578,22 +562,17 @@ void CheckEdge (const TopoDS_Edge& Ed,
 void CorrectWires(const TopoDS_Face& aFx,
                   const BOPCol_IndexedMapOfShape& aMapToAvoid)
 {
-  Standard_Boolean bIsPeriodic; 
   Standard_Integer i, aNbV;
   Standard_Real aTol, aTol2, aD2, aD2max, aT1, aT2, aT;
   gp_Pnt aP, aPV;
   gp_Pnt2d aP2D;
   TopoDS_Face aF;
-  TopoDS_Vertex aV11, aV12, aV21, aV22;;
   TopTools_IndexedDataMapOfShapeListOfShape aMVE;
   TopTools_ListIteratorOfListOfShape aIt, aIt1;
   //
   aF=aFx;
   aF.Orientation(TopAbs_FORWARD);
   const Handle(Geom_Surface)& aS=BRep_Tool::Surface(aFx);
-  GeomAdaptor_Surface aGAS (aS);
-  //
-  bIsPeriodic=(aGAS.IsUPeriodic() || aGAS.IsVPeriodic()); 
   //
   TopExp::MapShapesAndAncestors(aF, 
                                 TopAbs_VERTEX, 
@@ -616,69 +595,60 @@ void CorrectWires(const TopoDS_Face& aFx,
       aT=BRep_Tool::Parameter(aV, aE);
       //
       aC2D->D0(aT, aP2D);
-      aGAS.D0(aP2D.X(), aP2D.Y(), aP);
+      aS->D0(aP2D.X(), aP2D.Y(), aP);
       aD2=aPV.SquareDistance(aP);
       if (aD2>aD2max) {
         aD2max=aD2;
       }
-      //check self interference
-      if (aNbV==2) {
-        continue;
-      }
-      //
-      if (bIsPeriodic) {
-        continue;
-      }
-      //
-      TopExp::Vertices(aE, aV11, aV12);
+    }
+    //
+    //check wires on self interference by intersecting 2d curves of the edges
+    aIt.Initialize(aLE);
+    for (; aIt.More(); aIt.Next()) {
+      const TopoDS_Edge& aE1 = *(TopoDS_Edge*)&aIt.Value();
       //
       aIt1 = aIt;
-      aIt1.Next();
-      for (; aIt1.More(); aIt1.Next()) {
-        const TopoDS_Edge& aE1=*(TopoDS_Edge*)(&aIt1.Value());
+      for (aIt1.Next(); aIt1.More(); aIt1.Next()) {
+        const TopoDS_Edge& aE2 = *(TopoDS_Edge*)&aIt1.Value();
         //
-        //do not perform check for edges that have two common vertices
-        TopExp::Vertices(aE1, aV21, aV22);
-        if ((aV11.IsSame(aV21) && aV12.IsSame(aV22)) ||
-            (aV12.IsSame(aV21) && aV11.IsSame(aV22))) {
+        if (aE1.IsSame(aE2)) {
           continue;
         }
         //
-        aD2=IntersectCurves2d(aPV, aF, aGAS, aE, aE1);
-        if (aD2>aD2max) {
-          aD2max=aD2;
+        aD2 = IntersectCurves2d(aV, aF, aS, aE1, aE2);
+        if (aD2 > aD2max) {
+          aD2max = aD2;
         }
-      }// for (; aIt1.More(); aIt1.Next()) {
-    }// for (; aIt.More(); aIt.Next()) {
+      }
+    }
+    //
     if (aD2max>aTol2) {
-      aTol=sqrt(aD2max);
+      aTol = 1.01 * sqrt(aD2max);
       UpdateShape(aV, aTol, aMapToAvoid);
     }
   }// for (i=1; i<=aNbV; ++i) {
 }
+
 //=======================================================================
 // Function : IntersectCurves2d
 // purpose  : Intersect 2d curves of edges
 //=======================================================================
-Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
-                                const TopoDS_Face& aF,
-                                const GeomAdaptor_Surface& aGAS,
-                                const TopoDS_Edge& aE1,
-                                const TopoDS_Edge& aE2)
+Standard_Real IntersectCurves2d(const TopoDS_Vertex& theV,
+                                const TopoDS_Face& theF,
+                                const Handle(Geom_Surface)& theS,
+                                const TopoDS_Edge& theE1,
+                                const TopoDS_Edge& theE2)
 {
-  Standard_Real aDist, aD, aT11, aT12, aT21, aT22, aTol2d, aT1, aT2;
-  Standard_Integer j, aNbPnt;
-  Geom2dInt_GInter aInter;
-  gp_Pnt aP;
-  gp_Pnt2d aP2D;
+  Standard_Real aT11, aT12, aT21, aT22, aTol2d, aMaxDist;
+  Geom2dInt_GInter anInter;
   //
-  aDist = 0.;
-  aTol2d = 1.e-10;//Precision::Confusion();
+  aMaxDist = 0.;
+  aTol2d = 1.e-10;
   //
   const Handle(Geom2d_Curve)& aC2D1=
-    BRep_Tool::CurveOnSurface(aE1, aF, aT11, aT12);
+    BRep_Tool::CurveOnSurface(theE1, theF, aT11, aT12);
   const Handle(Geom2d_Curve)& aC2D2=
-    BRep_Tool::CurveOnSurface(aE2, aF, aT21, aT22);
+    BRep_Tool::CurveOnSurface(theE2, theF, aT21, aT22);
   //
   Geom2dAdaptor_Curve aGAC1(aC2D1), aGAC2(aC2D2);
   IntRes2d_Domain aDom1(aC2D1->Value(aT11), aT11, aTol2d, 
@@ -686,35 +656,68 @@ Standard_Real IntersectCurves2d(const gp_Pnt& aPV,
   IntRes2d_Domain aDom2(aC2D2->Value(aT21), aT21, aTol2d, 
                         aC2D2->Value(aT22), aT22, aTol2d);
   //
-  aInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d);
-  if (aInter.IsDone()) {
-    if (aInter.NbSegments()) {
-      return aDist;
+  anInter.Perform(aGAC1, aDom1, aGAC2, aDom2, aTol2d, aTol2d);
+  if (!anInter.IsDone()) {
+    return aMaxDist;
+  }
+  //
+  Standard_Real aT1, aT2, aTint1, aTint2, aHalfR1, aHalfR2, aDist;
+  Standard_Integer i, aNb;
+  gp_Pnt aP, aPV;
+  gp_Pnt2d aP2d;
+  NCollection_List<IntRes2d_IntersectionPoint> aLP;
+  NCollection_List<IntRes2d_IntersectionPoint>::Iterator aItLP;
+  //
+  aPV = BRep_Tool::Pnt(theV);
+  aT1 = BRep_Tool::Parameter(theV, theE1);
+  aT2 = BRep_Tool::Parameter(theV, theE2);
+  //
+  aHalfR1 = (aT12 - aT11) / 2.;
+  aHalfR2 = (aT22 - aT21) / 2.;
+  //
+  aDist = 0.;
+  //
+  aNb = anInter.NbSegments();
+  for (i = 1; i <= aNb; ++i) {
+    const IntRes2d_IntersectionSegment& aSeg = anInter.Segment(i);
+    aLP.Append(aSeg.FirstPoint());
+    aLP.Append(aSeg.LastPoint());
+  }
+  //
+  aNb = anInter.NbPoints();
+  for (i = 1; i <= aNb; ++i) {
+    const IntRes2d_IntersectionPoint& aPnt = anInter.Point(i);
+    aLP.Append(aPnt);
+  }
+  //
+  aItLP.Initialize(aLP);
+  for (; aItLP.More(); aItLP.Next()) {
+    const IntRes2d_IntersectionPoint& aPnt = aItLP.Value();
+    //
+    aTint1 = aPnt.ParamOnFirst();
+    aTint2 = aPnt.ParamOnSecond();
+    //
+    if ((aTint1 < aT11 || aTint1 > aT12) ||
+        (aTint2 < aT21 || aTint2 > aT22)) {
+      // out of range;
+      continue;
     }
-    aNbPnt = aInter.NbPoints();
-    if (aNbPnt) {
-      aDist = -Precision::Infinite();
-      for (j = 1; j <= aNbPnt; ++j) {
-        const IntRes2d_IntersectionPoint& aPoint = aInter.Point(j);
-        //
-        aT1 = aPoint.ParamOnFirst();
-        aT2 = aPoint.ParamOnSecond();
-        //
-        if ((aT1 < aT11 || aT1 > aT12) ||
-            (aT2 < aT21 || aT2 > aT22)) {
-          continue;
-        }          
-        //
-        aP2D = aPoint.Value();
-        aGAS.D0(aP2D.X(), aP2D.Y(), aP);
-        aD=aPV.SquareDistance(aP);
-        if (aD > aDist) {
-          aDist = 1.01 * aD;
-        }
-      }
+    //
+    if (Abs(aTint1 - aT1) > aHalfR1 ||
+        Abs(aTint2 - aT2) > aHalfR2) {
+      // intersection on the other end of the closed edge
+      continue;
+    }
+    //
+    aP2d = aPnt.Value();
+    theS->D0(aP2d.X(), aP2d.Y(), aP);
+    aDist = aPV.SquareDistance(aP);
+    if (aDist > aMaxDist) {
+      aMaxDist = aDist;
     }
   }
-  return aDist;
+  //
+  return aMaxDist;
 }
 //=======================================================================
 // Function : CorrectEdgeTolerance
index 395b715..f92bec1 100644 (file)
@@ -200,7 +200,7 @@ IntTools_BeanFaceIntersector::IntTools_BeanFaceIntersector(const BRepAdaptor_Cur
 {
   myCurve = theCurve;
   
-  myCriteria = myBeanTolerance + myFaceTolerance + Precision::Confusion();
+  myCriteria = myBeanTolerance + myFaceTolerance;
   myCurveResolution = myCurve.Resolution(myCriteria);
 
   mySurface = theSurface;
@@ -243,7 +243,7 @@ void IntTools_BeanFaceIntersector::Init(const BRepAdaptor_Curve&   theCurve,
   myBeanTolerance = theBeanTolerance;
   myFaceTolerance = theFaceTolerance;
   
-  myCriteria = myBeanTolerance + myFaceTolerance + Precision::Confusion();
+  myCriteria = myBeanTolerance + myFaceTolerance;
   myCurveResolution = myCurve.Resolution(myCriteria);
   
   SetSurfaceParameters(mySurface.FirstUParameter(), mySurface.LastUParameter(), 
index 03250f8..a4d26b8 100644 (file)
@@ -514,24 +514,25 @@ Standard_Integer IntTools_Context::ComputePE
 //purpose  : 
 //=======================================================================
 Standard_Integer IntTools_Context::ComputeVE
-  (const TopoDS_Vertex& aV1, 
-   const TopoDS_Edge&   aE2,
-   Standard_Real& aParam,
-   Standard_Real& aTolVnew)
+  (const TopoDS_Vertex& theV, 
+   const TopoDS_Edge&   theE,
+   Standard_Real& theT,
+   Standard_Real& theTol,
+   const Standard_Real theFuzz)
 {
-  if (BRep_Tool::Degenerated(aE2)) {
+  if (BRep_Tool::Degenerated(theE)) {
     return -1;
   }
-  if (!BRep_Tool::IsGeometric(aE2)) { 
+  if (!BRep_Tool::IsGeometric(theE)) { 
     return -2;
   }
-  Standard_Real aDist, aTolV1, aTolE2, aTolSum;
+  Standard_Real aDist, aTolV, aTolE, aTolSum;
   Standard_Integer aNbProj;
   gp_Pnt aP;
   //
-  aP=BRep_Tool::Pnt(aV1);
+  aP=BRep_Tool::Pnt(theV);
   //
-  GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(aE2);
+  GeomAPI_ProjectPointOnCurve& aProjector=ProjPC(theE);
   aProjector.Perform(aP);
 
   aNbProj=aProjector.NbPoints();
@@ -541,13 +542,12 @@ Standard_Integer IntTools_Context::ComputeVE
   //
   aDist=aProjector.LowerDistance();
   //
-  aTolV1=BRep_Tool::Tolerance(aV1);
-  aTolE2=BRep_Tool::Tolerance(aE2);
-  aTolSum = aTolV1 + aTolE2 + Precision::Confusion();
+  aTolV=BRep_Tool::Tolerance(theV);
+  aTolE=BRep_Tool::Tolerance(theE);
+  aTolSum = aTolV + aTolE + Max(theFuzz, Precision::Confusion());
   //
-  aTolVnew=aDist+aTolE2;
-  //
-  aParam=aProjector.LowerDistanceParameter();
+  theTol = aDist + aTolE;
+  theT = aProjector.LowerDistanceParameter();
   if (aDist > aTolSum) {
     return -4;
   }
@@ -558,19 +558,20 @@ Standard_Integer IntTools_Context::ComputeVE
 //purpose  : 
 //=======================================================================
 Standard_Integer IntTools_Context::ComputeVF
-  (const TopoDS_Vertex& aV1, 
-   const TopoDS_Face&   aF2,
-   Standard_Real& U,
-   Standard_Real& V,
-   Standard_Real& aTolVnew)
+  (const TopoDS_Vertex& theVertex, 
+   const TopoDS_Face&   theFace,
+   Standard_Real& theU,
+   Standard_Real& theV,
+   Standard_Real& theTol,
+   const Standard_Real theFuzz)
 {
-  Standard_Real aTolV1, aTolF2, aTolSum, aDist;
+  Standard_Real aTolV, aTolF, aTolSum, aDist;
   gp_Pnt aP;
 
-  aP=BRep_Tool::Pnt(aV1);
+  aP = BRep_Tool::Pnt(theVertex);
   //
   // 1. Check if the point is projectable on the surface
-  GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(aF2);
+  GeomAPI_ProjectPointOnSurf& aProjector=ProjPS(theFace);
   aProjector.Perform(aP);
   //
   if (!aProjector.IsDone()) { // the point is not  projectable on the surface
@@ -579,22 +580,22 @@ Standard_Integer IntTools_Context::ComputeVF
   //
   // 2. Check the distance between the projection point and 
   //    the original point
-  aDist=aProjector.LowerDistance();
+  aDist = aProjector.LowerDistance();
   //
-  aTolV1=BRep_Tool::Tolerance(aV1);
-  aTolF2=BRep_Tool::Tolerance(aF2);
+  aTolV = BRep_Tool::Tolerance(theVertex);
+  aTolF = BRep_Tool::Tolerance(theFace);
   //
-  aTolSum = aTolV1 + aTolF2 + Precision::Confusion();
-  aTolVnew = aDist + aTolF2;
+  aTolSum = aTolV + aTolF + Max(theFuzz, Precision::Confusion());
+  theTol = aDist + aTolF;
+  aProjector.LowerDistanceParameters(theU, theV);
   //
   if (aDist > aTolSum) {
     // the distance is too large
     return -2;
   }
-  aProjector.LowerDistanceParameters(U, V);
   //
-  gp_Pnt2d aP2d(U, V);
-  Standard_Boolean pri=IsPointInFace (aF2, aP2d);
+  gp_Pnt2d aP2d(theU, theV);
+  Standard_Boolean pri = IsPointInFace (theFace, aP2d);
   if (!pri) {//  the point lays on the surface but out of the face 
     return -3;
   }
index d7ff8ad..03a1e23 100644 (file)
@@ -23,6 +23,7 @@
 #include <BOPCol_DataMapOfTransientAddress.hxx>
 #include <Standard_Integer.hxx>
 #include <Standard_Real.hxx>
+#include <Precision.hxx>
 #include <MMgt_TShared.hxx>
 #include <TopAbs_State.hxx>
 #include <Standard_Boolean.hxx>
@@ -111,37 +112,40 @@ Standard_EXPORT virtual  ~IntTools_Context();
   Standard_EXPORT Standard_Integer ComputePE (const gp_Pnt& theP, const Standard_Real theTolP,
                                               const TopoDS_Edge& theE, Standard_Real& theT,
                                               Standard_Real& theDist);
-  
+
 
   //! Computes parameter of the vertex aV on
-  //! the edge aE and new increased value of vertex tolerance.
+  //! the edge aE and correct tolerance value for 
+  //! the vertex on the edge.
   //! Returns zero if the distance between vertex
-  //! and edge is less than sum of tolerances,
+  //! and edge is less than sum of tolerances and the fuzzy value,
   //! otherwise and for following conditions returns
   //! negative value: <br>
   //! 1. the edge is degenerated (-1) <br>
   //! 2. the edge does not contain 3d curve and pcurves (-2) <br>
   //! 3. projection algorithm failed (-3)
-  Standard_EXPORT Standard_Integer ComputeVE (const TopoDS_Vertex& aV,
-                                              const TopoDS_Edge& aE,
-                                              Standard_Real& aParam,
-                                              Standard_Real& aTolVnew);
+  Standard_EXPORT Standard_Integer ComputeVE (const TopoDS_Vertex& theV,
+                                const TopoDS_Edge& theE, 
+                                Standard_Real& theT,
+                                Standard_Real& theTol,
+                                const Standard_Real theFuzz = Precision::Confusion());
 
 
   //! Computes UV parameters of the vertex aV on face aF
-  //! and new increased value of vertex tolerance.
+  //! and correct tolerance value for the vertex on the face.
   //! Returns zero if the distance between vertex and face is
-  //! less than or equal the sum of tolerances and the projection
-  //! point lays inside boundaries of the face.
+  //! less than or equal the sum of tolerances and the fuzzy value 
+  //! and the projection point lays inside boundaries of the face.
   //! For following conditions returns negative value <br>
   //! 1. projection algorithm failed (-1) <br>
   //! 2. distance is more than sum of tolerances (-2) <br>
   //! 3. projection point out or on the boundaries of face (-3)
-  Standard_EXPORT Standard_Integer ComputeVF (const TopoDS_Vertex& aV,
-                                              const TopoDS_Face& aF,
-                                              Standard_Real& U,
-                                              Standard_Real& V,
-                                              Standard_Real& aTolVnew);
+  Standard_EXPORT Standard_Integer ComputeVF (const TopoDS_Vertex& theVertex, 
+                                const TopoDS_Face& theFace, 
+                                Standard_Real& theU,
+                                Standard_Real& theV,
+                                Standard_Real& theTol,
+                                const Standard_Real theFuzz = Precision::Confusion());
 
 
   //! Returns the state of the point aP2D
@@ -226,7 +230,6 @@ Standard_EXPORT virtual  ~IntTools_Context();
 
 
 
-
   DEFINE_STANDARD_RTTIEXT(IntTools_Context,MMgt_TShared)
 
 protected:
@@ -251,14 +254,6 @@ private:
   //! Clears map of already cached projectors.
   Standard_EXPORT void clearCachedPOnSProjectors();
 
-
-
 };
 
-
-
-
-
-
-
 #endif // _IntTools_Context_HeaderFile
index a3bb33b..cdb1a76 100644 (file)
@@ -160,7 +160,7 @@ void IntTools_EdgeEdge::Prepare()
     mySwap = Standard_True;
   }
   //
-  Standard_Real aTolAdd = Precision::Confusion() / 2.;
+  Standard_Real aTolAdd = myFuzzyValue / 2.;
   myTol1 = myCurve1.Tolerance() + aTolAdd;
   myTol2 = myCurve2.Tolerance() + aTolAdd;
   myTol = myTol1 + myTol2;
index a9a432a..c55977c 100644 (file)
@@ -94,6 +94,10 @@ public:
   void SetRange2(const Standard_Real aT1, const Standard_Real aT2);
   
 
+  //! Sets the Fuzzy value
+  void SetFuzzyValue (const Standard_Real theFuzz);
+  
+  
   //! Performs the intersection between edges
   Standard_EXPORT void Perform();
   
@@ -102,6 +106,10 @@ public:
   Standard_Boolean IsDone() const;
   
 
+  //! Returns Fuzzy value
+  Standard_Real FuzzyValue() const;
+  
+  
   //! Returns common parts
   const IntTools_SequenceOfCommonPrts& CommonParts() const;
 
@@ -190,6 +198,7 @@ protected:
   Standard_Real myTol1;
   Standard_Real myTol2;
   Standard_Real myTol;
+  Standard_Real myFuzzyValue;
   Standard_Real myRes1;
   Standard_Real myRes2;
   Standard_Real myResCoeff1;
index 398afc7..24a76ec 100644 (file)
@@ -24,6 +24,7 @@ inline IntTools_EdgeEdge::IntTools_EdgeEdge()
   myTol1(0.),
   myTol2(0.),
   myTol(0.),
+  myFuzzyValue(Precision::Confusion()),
   myRes1(0.),
   myRes2(0.),
   myResCoeff1(0.),
@@ -49,6 +50,7 @@ inline IntTools_EdgeEdge::IntTools_EdgeEdge(const TopoDS_Edge&  theEdge1,
   myTol1(0.),
   myTol2(0.),
   myTol(0.),
+  myFuzzyValue(Precision::Confusion()),
   myRes1(0.),
   myRes2(0.),
   myResCoeff1(0.),
@@ -78,6 +80,7 @@ inline IntTools_EdgeEdge::IntTools_EdgeEdge(const TopoDS_Edge&  theEdge1,
   myTol1(0.),
   myTol2(0.),
   myTol(0.),
+  myFuzzyValue(Precision::Confusion()),
   myRes1(0.),
   myRes2(0.),
   myResCoeff1(0.),
@@ -173,6 +176,23 @@ inline void IntTools_EdgeEdge::SetEdge2(const TopoDS_Edge&  theEdge,
   SetRange2(aT1, aT2);
 }
 //=======================================================================
+//function : SetFuzzyValue
+//purpose  : 
+//=======================================================================
+inline void IntTools_EdgeEdge::SetFuzzyValue(const Standard_Real theFuzz)
+{
+  myFuzzyValue = Max(theFuzz, Precision::Confusion());
+}
+//=======================================================================
+//function : FuzzyValue
+//purpose  : 
+//=======================================================================
+inline Standard_Real IntTools_EdgeEdge::FuzzyValue() const
+{
+  return myFuzzyValue;
+}
+
+//=======================================================================
 //function : CommonParts
 //purpose  : 
 //=======================================================================
index 3d6749d..323ea0e 100644 (file)
@@ -72,9 +72,8 @@ static
 //=======================================================================
   IntTools_EdgeFace::IntTools_EdgeFace()
 {
-  myTolE=1.e-7;
-  myTolF=1.e-7;
-  myDiscret=30;
+  myFuzzyValue = Precision::Confusion();
+  myDiscret = 30;
   myEpsT   =1e-12;
   myDeflection=0.01;
   myIsDone=Standard_False;
@@ -115,22 +114,6 @@ void IntTools_EdgeFace::SetFace(const TopoDS_Face& aFace)
   myFace=aFace;
 }
 //=======================================================================
-//function : SetTolE
-//purpose  : 
-//=======================================================================
-void IntTools_EdgeFace::SetTolE(const Standard_Real aTol) 
-{
-  myTolE=aTol;
-} 
-//=======================================================================
-//function : SetTolF
-//purpose  : 
-//=======================================================================
-void IntTools_EdgeFace::SetTolF(const Standard_Real aTol) 
-{
-  myTolF=aTol;
-} 
-//=======================================================================
 //function : Edge
 //purpose  : 
 //=======================================================================
@@ -147,21 +130,13 @@ const TopoDS_Face& IntTools_EdgeFace::Face()const
   return myFace;
 }
 //=======================================================================
-//function : TolE
+//function : SetFuzzyValue
 //purpose  : 
 //=======================================================================
-Standard_Real IntTools_EdgeFace::TolE()const 
+void IntTools_EdgeFace::SetFuzzyValue(const Standard_Real theFuzz)
 {
-  return myTolE;
+  myFuzzyValue = Max(theFuzz, Precision::Confusion());
 }
- //=======================================================================
-//function : TolF
-//purpose  : 
-//=======================================================================
-Standard_Real IntTools_EdgeFace::TolF()const 
-{
-  return myTolF;
-} 
 //=======================================================================
 //function : SetDiscretize
 //purpose  : 
@@ -345,12 +320,15 @@ void IntTools_EdgeFace::Prepare()
   aCurveType=myC.GetType();
   //
   // 2.Prepare myCriteria
-  if (aCurveType==GeomAbs_BSplineCurve||
-    aCurveType==GeomAbs_BezierCurve) {
-    myCriteria=1.5*myTolE+myTolF;
+  Standard_Real aFuzz = myFuzzyValue / 2.;
+  Standard_Real aTolF = BRep_Tool::Tolerance(myFace) + aFuzz;
+  Standard_Real aTolE = BRep_Tool::Tolerance(myEdge) + aFuzz;
+  if (aCurveType == GeomAbs_BSplineCurve ||
+      aCurveType == GeomAbs_BezierCurve) {
+    myCriteria = 1.5*aTolE + aTolF;
   }
   else {
-    myCriteria = myTolE + myTolF + Precision::Confusion();
+    myCriteria = aTolE + aTolF;
   }
   // 2.a myTmin, myTmax
   aTmin=myRange.First();
@@ -820,19 +798,22 @@ void IntTools_EdgeFace::Perform()
   aCurveType=myC.GetType();
   //
   // Prepare myCriteria
-  if (aCurveType==GeomAbs_BSplineCurve||
+  Standard_Real aFuzz = myFuzzyValue / 2.;
+  Standard_Real aTolF = BRep_Tool::Tolerance(myFace) + aFuzz;
+  Standard_Real aTolE = BRep_Tool::Tolerance(myEdge) + aFuzz;
+  if (aCurveType == GeomAbs_BSplineCurve ||
       aCurveType==GeomAbs_BezierCurve) {
     //--- 5112
-    Standard_Real diff1 = (myTolE/myTolF);
-    Standard_Real diff2 = (myTolF/myTolE);
+    Standard_Real diff1 = (aTolE/aTolF);
+    Standard_Real diff2 = (aTolF/aTolE);
     if( diff1 > 100 || diff2 > 100 ) {
-      myCriteria = Max(myTolE,myTolF);
+      myCriteria = Max(aTolE,aTolF);
     }
     else //--- 5112
-      myCriteria=1.5*myTolE+myTolF;
+      myCriteria = 1.5*aTolE + aTolF;
   }
   else {
-    myCriteria = myTolE + myTolF + Precision::Confusion();
+    myCriteria = aTolE + aTolF;
   }
   
   myS.Initialize (myFace,Standard_True);
@@ -852,7 +833,7 @@ void IntTools_EdgeFace::Perform()
     }
   }
   //
-  IntTools_BeanFaceIntersector anIntersector(myC, myS, myTolE, myTolF);
+  IntTools_BeanFaceIntersector anIntersector(myC, myS, aTolE, aTolF);
   anIntersector.SetBeanParameters(myRange.First(), myRange.Last());
   //
   anIntersector.SetContext(myContext);
index 08458ff..e7cbd85 100644 (file)
@@ -61,18 +61,10 @@ public:
   Standard_EXPORT void SetEdge (const TopoDS_Edge& anEdge);
   
 
-  //! Initializes algorithm by edge tolerance
-  Standard_EXPORT void SetTolE (const Standard_Real aTolEdge1);
-  
-
   //! Initializes algorithm by the face aFace
   Standard_EXPORT void SetFace (const TopoDS_Face& aFace);
   
 
-  //! Initializes algorithm by face tolerance
-  Standard_EXPORT void SetTolF (const Standard_Real aTolFace);
-  
-
   //! Returns edge
   Standard_EXPORT const TopoDS_Edge& Edge() const;
   
@@ -81,14 +73,6 @@ public:
   Standard_EXPORT const TopoDS_Face& Face() const;
   
 
-  //! Returns  tolerance of the edge
-  Standard_EXPORT Standard_Real TolE() const;
-  
-
-  //! Returns  tolerance of the face
-  Standard_EXPORT Standard_Real TolF() const;
-  
-
   //! Initializes algorithm by discretization value
   Standard_EXPORT void SetDiscretize (const Standard_Integer aDiscret);
   
@@ -117,6 +101,14 @@ public:
   //! Gets the intersecton context
   Standard_EXPORT const Handle(IntTools_Context)& Context() const;
   
+  //! Sets the Fuzzy value
+  Standard_EXPORT void SetFuzzyValue(const Standard_Real theFuzz);
+
+  //! Returns Fuzzy value
+  Standard_Real FuzzyValue() const
+  {
+    return myFuzzyValue;
+  }
 
   //! Launches the process
   Standard_EXPORT void Perform();
@@ -184,8 +176,7 @@ private:
 
   TopoDS_Edge myEdge;
   TopoDS_Face myFace;
-  Standard_Real myTolE;
-  Standard_Real myTolF;
+  Standard_Real myFuzzyValue;
   Standard_Integer myDiscret;
   Standard_Real myEpsT;
   Standard_Real myDeflection;
index ce8f371..e3a2aed 100644 (file)
@@ -56,9 +56,9 @@
 #include <gp_Elips.hxx>
 
 static
-  void TolR3d(const TopoDS_Face& ,
-              const TopoDS_Face& ,
-              Standard_Real& );
+  void TolR3d(const Standard_Real aTolF1,
+              const Standard_Real aTolF2,
+              Standard_Real& myTolReached3d);
 
 static 
   void Parameters(const Handle(GeomAdaptor_HSurface)&,
@@ -84,6 +84,7 @@ static
                                           const TopoDS_Face&        theFace2,
                                           const Standard_Real       theOtherParameter,
                                           const Standard_Boolean    bIncreasePar,
+                                          const Standard_Real       theTol,
                                           Standard_Real&            theNewParameter,
                                           const Handle(IntTools_Context)& );
 
@@ -174,8 +175,11 @@ IntTools_FaceFace::IntTools_FaceFace()
   myTolReached2d=0.; 
   myTolReached3d=0.;
   myTolReal = 0.;
+  myTolF1 = 0.;
+  myTolF2 = 0.;
+  myTol = 0.;
+  myFuzzyValue = Precision::Confusion();
   SetParameters(Standard_True, Standard_True, Standard_True, 1.e-07);
-  
 }
 //=======================================================================
 //function : SetContext
@@ -283,6 +287,23 @@ void IntTools_FaceFace::SetParameters(const Standard_Boolean ToApproxC3d,
   myTolApprox = ApproximationTolerance;
 }
 //=======================================================================
+//function : SetFuzzyValue
+//purpose  : 
+//=======================================================================
+void IntTools_FaceFace::SetFuzzyValue(const Standard_Real theFuzz)
+{
+  myFuzzyValue = Max(theFuzz, Precision::Confusion());
+}
+//=======================================================================
+//function : FuzzyValue
+//purpose  : 
+//=======================================================================
+Standard_Real IntTools_FaceFace::FuzzyValue() const
+{
+  return myFuzzyValue;
+}
+
+//=======================================================================
 //function : SetList
 //purpose  : 
 //=======================================================================
@@ -293,12 +314,10 @@ void IntTools_FaceFace::SetList(IntSurf_ListOfPntOn2S& aListOfPnts)
 
 
 static Standard_Boolean isTreatAnalityc(const TopoDS_Face& theF1,
-                                        const TopoDS_Face& theF2)
+                                        const TopoDS_Face& theF2,
+                                        const Standard_Real theTol)
 {
   const Standard_Real Tolang = 1.e-8;
-  const Standard_Real aTolF1=BRep_Tool::Tolerance(theF1);
-  const Standard_Real aTolF2=BRep_Tool::Tolerance(theF2);
-  const Standard_Real aTolSum = aTolF1 + aTolF2 + Precision::Confusion();
   Standard_Real aHigh = 0.0;
 
   const BRepAdaptor_Surface aBAS1(theF1), aBAS2(theF2);
@@ -351,7 +370,7 @@ static Standard_Boolean isTreatAnalityc(const TopoDS_Face& theF1,
   }
 
   IntAna_QuadQuadGeo inter;
-  inter.Perform(aS1,aS2,Tolang,aTolSum, aHigh);
+  inter.Perform(aS1,aS2,Tolang,theTol, aHigh);
   if(inter.TypeInter() == IntAna_Ellipse)
   {
     const gp_Elips anEl = inter.Ellipse(1);
@@ -424,10 +443,12 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
   const Handle(Geom_Surface) S1=BRep_Tool::Surface(myFace1);
   const Handle(Geom_Surface) S2=BRep_Tool::Surface(myFace2);
 
-  const Standard_Real aTolF1=BRep_Tool::Tolerance(myFace1);
-  const Standard_Real aTolF2=BRep_Tool::Tolerance(myFace2);
+  Standard_Real aFuzz = myFuzzyValue / 2.;
+  myTolF1 = BRep_Tool::Tolerance(myFace1) + aFuzz;
+  myTolF2 = BRep_Tool::Tolerance(myFace2) + aFuzz;
+  myTol = myTolF1 + myTolF2;
 
-  Standard_Real TolArc = aTolF1 + aTolF2 + Precision::Confusion();
+  Standard_Real TolArc = myTol;
   Standard_Real TolTang = TolArc;
 
   const Standard_Boolean isFace1Quad = (aType1 == GeomAbs_Cylinder ||
@@ -452,7 +473,7 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
     Standard_Real TolAng = 1.e-8;
     //
     PerformPlanes(myHS1, myHS2, 
-                  aTolF1, aTolF2, TolAng, TolTang, 
+                  myTolF1, myTolF2, TolAng, TolTang, 
                   myApprox1, myApprox2, 
                   mySeqOfCurve, myTangentFaces, myTolReached3d);
     //
@@ -462,7 +483,7 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
       const Standard_Integer NbLinPP = mySeqOfCurve.Length();
       if(NbLinPP) {
         Standard_Real aTolFMax;
-        aTolFMax=Max(aTolF1, aTolF2);
+        aTolFMax=Max(myTolF1, myTolF2);
         myTolReal = Precision::Confusion();
         if (aTolFMax > myTolReal) {
           myTolReal = aTolFMax;
@@ -498,7 +519,7 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
     myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
     // F2
     BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
-    CorrectSurfaceBoundaries(myFace2, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
+    CorrectSurfaceBoundaries(myFace2, myTol * 2., umin, umax, vmin, vmax);
     myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
   }
   else if ((aType2==GeomAbs_Plane) && isFace1Quad)
@@ -506,7 +527,7 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
     Standard_Real umin, umax, vmin, vmax;
     //F1
     BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
-    CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
+    CorrectSurfaceBoundaries(myFace1, myTol * 2., umin, umax, vmin, vmax);
     myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
     // F2
     BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
@@ -517,10 +538,10 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
   {
     Standard_Real umin, umax, vmin, vmax;
     BRepTools::UVBounds(myFace1, umin, umax, vmin, vmax);
-    CorrectSurfaceBoundaries(myFace1, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
+    CorrectSurfaceBoundaries(myFace1, myTol * 2., umin, umax, vmin, vmax);
     myHS1->ChangeSurface().Load(S1, umin, umax, vmin, vmax);
     BRepTools::UVBounds(myFace2, umin, umax, vmin, vmax);
-    CorrectSurfaceBoundaries(myFace2, (aTolF1 + aTolF2) * 2., umin, umax, vmin, vmax);
+    CorrectSurfaceBoundaries(myFace2, myTol * 2., umin, umax, vmin, vmax);
     myHS2->ChangeSurface().Load(S2, umin, umax, vmin, vmax);
   }
 
@@ -605,7 +626,7 @@ void IntTools_FaceFace::Perform(const TopoDS_Face& aF1,
     }
 #endif
 
-  const Standard_Boolean isGeomInt = isTreatAnalityc(aF1, aF2);
+  const Standard_Boolean isGeomInt = isTreatAnalityc(aF1, aF2, myTol);
   myIntersector.Perform(myHS1, dom1, myHS2, dom2, TolArc, TolTang, 
                                   myListOfPnts, RestrictLine, isGeomInt);
 
@@ -909,7 +930,7 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
     //
     // myTolReached3d
     if (typl == IntPatch_Lin) {
-      TolR3d (myFace1, myFace2, myTolReached3d);
+      TolR3d (myTolF1, myTolF2, myTolReached3d);
     }
     //
     aNbParts=myLConstruct.NbParts();
@@ -928,12 +949,7 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
         Handle(Geom_TrimmedCurve) aCT3D=new Geom_TrimmedCurve(newc, fprm, lprm);
         aCurve.SetCurve(aCT3D);
         if (typl == IntPatch_Parabola) {
-          Standard_Real aTolF1, aTolF2, aTolBase;
-          
-          aTolF1 = BRep_Tool::Tolerance(myFace1);
-          aTolF2 = BRep_Tool::Tolerance(myFace2);
-          aTolBase=aTolF1+aTolF2;
-          myTolReached3d=IntTools_Tools::CurveTolerance(aCT3D, aTolBase);
+          myTolReached3d=IntTools_Tools::CurveTolerance(aCT3D, myTol);
         }
         //
         aCurve.SetCurve(new Geom_TrimmedCurve(newc, fprm, lprm));
@@ -1035,7 +1051,7 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
     }
     //
     // myTolReached3d
-    TolR3d (myFace1, myFace2, myTolReached3d);
+    TolR3d (myTolF1, myTolF2, myTolReached3d);
     //
     aNbParts=myLConstruct.NbParts();
     //
@@ -1060,14 +1076,14 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
         else {
           gp_Pnt P1 = newc->Value(fprm);
           gp_Pnt P2 = newc->Value(aPeriod);
-          Standard_Real aTolDist = BRep_Tool::Tolerance(myFace1) + BRep_Tool::Tolerance(myFace2);
+          Standard_Real aTolDist = myTol;
           aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
 
           if(P1.Distance(P2) > aTolDist) {
             Standard_Real anewpar = fprm;
 
             if(ParameterOutOfBoundary(fprm, newc, myFace1, myFace2, 
-                                      lprm, Standard_False, anewpar, myContext)) {
+                                      lprm, Standard_False, myTol, anewpar, myContext)) {
               fprm = anewpar;
             }
             aSeqFprm.Append(fprm);
@@ -1083,14 +1099,14 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
         else {
           gp_Pnt P1 = newc->Value(aNul);
           gp_Pnt P2 = newc->Value(lprm);
-          Standard_Real aTolDist = BRep_Tool::Tolerance(myFace1) + BRep_Tool::Tolerance(myFace2);
+          Standard_Real aTolDist = myTol;
           aTolDist = (myTolReached3d > aTolDist) ? myTolReached3d : aTolDist;
 
           if(P1.Distance(P2) > aTolDist) {
             Standard_Real anewpar = lprm;
 
             if(ParameterOutOfBoundary(lprm, newc, myFace1, myFace2, 
-                                      fprm, Standard_True, anewpar, myContext)) {
+                                      fprm, Standard_True, myTol, anewpar, myContext)) {
               lprm = anewpar;
             }
             aSeqFprm.Append(aNul);
@@ -1387,6 +1403,7 @@ void IntTools_FaceFace::MakeCurve(const Standard_Integer Index,
                              myFace2, 
                              myLConstruct, 
                              bAvoidLineConstructor, 
+                             myTol,
                              aSeqOfL, 
                              aReachedTol,
                              myContext);
@@ -2225,15 +2242,13 @@ Handle(Geom_Curve) MakeBSpline  (const Handle(IntPatch_WLine)& WL,
 //function : TolR3d
 //purpose  : 
 //=======================================================================
-void TolR3d(const TopoDS_Face& aF1,
-            const TopoDS_Face& aF2,
+void TolR3d(const Standard_Real aTolF1,
+            const Standard_Real aTolF2,
             Standard_Real& myTolReached3d)
 {
-  Standard_Real aTolF1, aTolF2, aTolFMax, aTolTresh;
+  Standard_Real aTolFMax, aTolTresh;
       
   aTolTresh=2.999999e-3;
-  aTolF1 = BRep_Tool::Tolerance(aF1);
-  aTolF2 = BRep_Tool::Tolerance(aF2);
   aTolFMax=Max(aTolF1, aTolF2);
   
   if (aTolFMax>aTolTresh) {
@@ -2252,6 +2267,7 @@ Standard_Boolean ParameterOutOfBoundary(const Standard_Real       theParameter,
                                         const TopoDS_Face&        theFace2,
                                         const Standard_Real       theOtherParameter,
                                         const Standard_Boolean    bIncreasePar,
+                                        const Standard_Real       theTol,
                                         Standard_Real&            theNewParameter,
                                         const Handle(IntTools_Context)& aContext)
 {
@@ -2261,7 +2277,7 @@ Standard_Boolean ParameterOutOfBoundary(const Standard_Real       theParameter,
   Standard_Real acurpar = theParameter;
   TopAbs_State aState = TopAbs_ON;
   Standard_Integer iter = 0;
-  Standard_Real asumtol = BRep_Tool::Tolerance(theFace1) + BRep_Tool::Tolerance(theFace2);
+  Standard_Real asumtol = theTol;
   Standard_Real adelta = asumtol * 0.1;
   adelta = (adelta < Precision::Confusion()) ? Precision::Confusion() : adelta;
   Handle(Geom_Surface) aSurf1 = BRep_Tool::Surface(theFace1);
index ba55735..6abf965 100644 (file)
@@ -110,7 +110,13 @@ public:
 
   //! Sets the intersecton context
   Standard_EXPORT void SetContext (const Handle(IntTools_Context)& aContext);
+
+  //! Sets the Fuzzy value
+  void SetFuzzyValue (const Standard_Real theFuzz);
+
   
+  //! Returns Fuzzy value
+  Standard_Real FuzzyValue() const;
 
   //! Gets the intersecton context
   Standard_EXPORT const Handle(IntTools_Context)& Context() const;
@@ -150,6 +156,10 @@ private:
   Standard_Boolean myApprox1;
   Standard_Boolean myApprox2;
   Standard_Real myTolApprox;
+  Standard_Real myTolF1;
+  Standard_Real myTolF2;
+  Standard_Real myTol;
+  Standard_Real myFuzzyValue;
   IntTools_SequenceOfCurves mySeqOfCurve;
   Standard_Boolean myTangentFaces;
   TopoDS_Face myFace1;
index a6b3975..19a8e87 100644 (file)
@@ -805,7 +805,7 @@ Standard_Boolean IntTools_Tools::ComputeTolerance
   //e.g. after trimming) we will be able to come
   //to the more precise minimum point. As result, this curve with the
   //tolerance computed earlier will become invalid.
-  const Standard_Real anEps = (1.0+1.0e-7);
+  const Standard_Real anEps = (1.0+1.0e-5);
   theMaxDist = anEps*aCS.MaxDistance();
   theMaxPar  = aCS.MaxParameter();
   //
index fc6b2f2..f36c788 100644 (file)
@@ -730,6 +730,7 @@ Standard_Boolean IntTools_WLineTool::
                        const TopoDS_Face&                             theFace2,
                        const GeomInt_LineConstructor&                 theLConstructor,
                        const Standard_Boolean                         theAvoidLConstructor,
+                       const Standard_Real                            theTol,
                        IntPatch_SequenceOfLine&                       theNewLines,
                        Standard_Real&                                 theReachedTol3d,
                        const Handle(IntTools_Context)& aContext) 
@@ -1206,7 +1207,7 @@ Standard_Boolean IntTools_WLineTool::
 
           if(found) {
             // check point
-            Standard_Real aCriteria = BRep_Tool::Tolerance(theFace1) + BRep_Tool::Tolerance(theFace2);
+            Standard_Real aCriteria = theTol;
             GeomAPI_ProjectPointOnSurf& aProjector = 
               (surfit == 0) ? aContext->ProjPS(theFace2) : aContext->ProjPS(theFace1);
             Handle(GeomAdaptor_HSurface) aSurface = (surfit == 0) ? theSurface1 : theSurface2;
index bfb9e69..a031857 100644 (file)
@@ -46,6 +46,7 @@ public:
                                         const TopoDS_Face&                             theFace2,
                                         const GeomInt_LineConstructor&                 theLConstructor,
                                         const Standard_Boolean                         theAvoidLConstructor,
+                                        const Standard_Real                            theTol,
                                         IntPatch_SequenceOfLine&                       theNewLines,
                                         Standard_Real&                                 theReachedTol3d,
                                         const Handle(IntTools_Context)& );
index 77bd9e2..7ca79ca 100644 (file)
@@ -1,3 +1,2 @@
-puts "TODO OCC26018 ALL: Faulty shapes in variables faulty_1 to faulty_"
 source [locate_data_file 51678_flame-sbr.prt.1.gdml.tcl]
 
index fa231d1..5a19d2f 100644 (file)
@@ -1,7 +1,3 @@
-puts "TODO ?OCC27052 ALL: Faulty shapes in variables faulty_1 to"
-puts "TODO OCC27052 Windows: Error : The command is not valid. The area is"
-puts "TODO OCC27052 ALL: Error : The area of result shape is"
-puts "TODO OCC26018 Linux: bopcheck failed"
 source [locate_data_file mos2014-asm-scf-final.asm.1.gdml.tcl]
 
 set bcheck [bopcheck result]
@@ -9,4 +5,4 @@ puts $bcheck
 if {![regexp {This shape seems to be OK.} $bcheck]} {
     puts "Error: bopcheck failed"
 }
-checkprops result -s 618615
\ No newline at end of file
+checkprops result -s 429157
\ No newline at end of file
index acd902c..9d1ca47 100644 (file)
@@ -1,7 +1,3 @@
-puts "TODO ?OCC27052 ALL: Faulty shapes in variables faulty_1 to"
-puts "TODO OCC27052 Windows: Error : The command is not valid. The area is"
-puts "TODO OCC27052 ALL: Error : The area of result shape is"
-puts "TODO OCC26018 Linux: bopcheck failed"
 source [locate_data_file mos2014-scf-final.prt.1.gdml.tcl]
 
 set bcheck [bopcheck result]
@@ -9,4 +5,4 @@ puts $bcheck
 if {![regexp {This shape seems to be OK.} $bcheck]} {
     puts "Error: bopcheck failed"
 }
-checkprops result -s 618615
\ No newline at end of file
+checkprops result -s 429157
\ No newline at end of file
index e7477a8..d1c71d0 100644 (file)
@@ -1,7 +1,7 @@
 # test script on make volume operation
 # plane sphere
 
-puts "TODO ?OCC26020 Windows: Faulty shapes in variables faulty_1 to faulty_"
+puts "TODO ?OCC26020 ALL: Faulty shapes in variables faulty_1 to faulty_"
 puts "TODO OCC26020 ALL: Error: bopcheck failed"
 puts "TODO OCC26020 ALL: Error : The area of result shape is"
 
index b928b99..46c66a0 100644 (file)
@@ -1,8 +1,6 @@
 # test script on make volume operation
 # cylinder plane
 
-puts "TODO OCC26737 ALL: Error: bopcheck failed"
-
 # planar face 
 plane pln_f1 0 515 1.1102230246251565e-015 0 -1 -1.1102230246251565e-016
 erase pln_f1
index b5bb4e4..4617ccd 100755 (executable)
@@ -1,6 +1,3 @@
-puts "TODO OCC12345 ALL: Faulty : TEST FAILED"
-#puts "TODO OCC12345 ALL: Error : The length of result shape is"
-
 puts "============"
 puts "PRO19653"
 puts "BREPALGO_BOOLEANOPERATION does not return result."
@@ -12,6 +9,14 @@ restore [locate_data_file pro19653a.brep] a
 checkshape a
 restore [locate_data_file pro19653b.brep] b
 checkshape b
+
+# There is a gap between shapes around the edge a_4. The tolerance
+# of the edge is 1e-7. The max gap width is about 2e-6. So, in order to 
+# get the whole edge as a section we need to set its tolerance to that value.
+# Otherwise, this test case will be unstable from version to version.
+explode a e
+settolerance a_4 2e-6
+
 bsection result a b
 
 explode result e
index d9c4171..8b07a20 100755 (executable)
@@ -20,19 +20,19 @@ pcylinder Cylinder006 1.600000023842 3.200000047684 180
 ttranslate Cylinder006 -15 50.1 2.35
 
 #Object Label: LeftHalfCyl
-bfuse to-Fusion-002-t to-Fusion-001-t Cylinder006
+#bfuse to-Fusion-002-t to-Fusion-001-t Cylinder006
 psphere Sphere001 1.600000023842 0 90 180
 trotate Sphere001 0 0 0 1 0 0 90
 ttranslate Sphere001 -15 -0.1 5.5
 
 #Object Label: RightSph
-bfuse to-Fusion-003-t to-Fusion-002-t Sphere001
+#bfuse to-Fusion-003-t to-Fusion-002-t Sphere001
 pcylinder Cylinder005 1.600000023842 3.200000047684 180
 trotate Cylinder005 0 0 0 0 0 1 180
 ttranslate Cylinder005 -15 -0.1 2.35
 
 #Object Label: RightHalfCyl
-bfuse to-Fusion-004-t to-Fusion-003-t Cylinder005
+#bfuse to-Fusion-004-t to-Fusion-003-t Cylinder005
 pcylinder Cylinder004 1.600000023842 50.200000762939 180
 trotate Cylinder004 0 0 0 0 0.7071067811865475 0.7071067811865475 180
 ttranslate Cylinder004 -15.000003814697 -0.100001335144 5.500000953674
diff --git a/tests/bugs/modalg_6/bug26738 b/tests/bugs/modalg_6/bug26738
new file mode 100644 (file)
index 0000000..c032911
--- /dev/null
@@ -0,0 +1,38 @@
+puts "============"
+puts "OCC26738"
+puts "============"
+puts ""
+#######################################################################
+# Make Boolean operations non-destructive when running with fuzzy option
+#######################################################################
+
+restore [locate_data_file bug26619_shell_ft81_h0.brep] h0
+restore [locate_data_file bug26619_the_face.brep] f0
+
+regexp {Tolerance +MAX=([-0-9.+eE]+)} [tolerance h0] full ExpectedMaxTol_h0
+regexp {Tolerance +MAX=([-0-9.+eE]+)} [tolerance f0] full ExpectedMaxTol_f0
+
+#turn on non-destructive mode of BOP and fuzzy value;
+#with this combination the test is fail before the fix 26738,
+#as tolerance of input shape is changed
+bnondestructive 1
+bfuzzyvalue 0.1
+
+bclearobjects
+bcleartools
+baddobjects h0
+baddtools f0
+bfillds
+bbop result 4
+
+regexp {Tolerance +MAX=([-0-9.+eE]+)} [tolerance h0] full MaxTol_h0
+regexp {Tolerance +MAX=([-0-9.+eE]+)} [tolerance f0] full MaxTol_f0
+
+set tol_abs_MaxTol 0.0001
+set tol_rel_MaxTol 0.0001
+checkreal "MaxTolerance h0" ${MaxTol_h0} ${ExpectedMaxTol_h0} ${tol_abs_MaxTol} ${tol_rel_MaxTol}
+checkreal "MaxTolerance f0" ${MaxTol_f0} ${ExpectedMaxTol_f0} ${tol_abs_MaxTol} ${tol_rel_MaxTol}
+
+checkprops result -l 150.23
+
+set 2dviewer 1
index 927a0e0..8ebde56 100644 (file)
@@ -17,6 +17,6 @@ baddtools b2
 bfillds
 bbop result 0
 
-checkprops result -s 42.131
+checkprops result -s 40.7799
 
 checkview -display result -2d -path ${imagedir}/${test_image}.png