]> OCCT Git - occt-copy.git/commitdiff
Fix for regressions for case infinite box ( case 46)
authorgka <gka@opencascade.com>
Thu, 30 Oct 2014 16:03:55 +0000 (19:03 +0300)
committernbv <nbv@opencascade.com>
Mon, 2 Feb 2015 14:03:59 +0000 (17:03 +0300)
Test cases

src/BOPAlgo/BOPAlgo.cdl
src/BOPAlgo/BOPAlgo_BuilderFace.cxx
src/BOPAlgo/BOPAlgo_BuilderSolid.cxx
src/IntCurvesFace/IntCurvesFace_Intersector.cxx
tests/bugs/modalg_5/bug25416_1 [new file with mode: 0644]
tests/bugs/modalg_5/bug25697_1 [new file with mode: 0644]
tests/bugs/modalg_5/bug25697_2 [new file with mode: 0644]

index f4097cd6fcdea44662e6a92f45c1da50af6ac515..8cd289d2d296c37f0fd9e9cd2424a77e233b7be6 100644 (file)
@@ -74,6 +74,7 @@ is
     class CheckerSI; 
     class ArgumentAnalyzer; 
     class CheckResult;
+    class ShellSplitter;
     --
     --  pointers
     --
index f2d3b3e9a0e0dc4ddf6738da0480a87ce473d358..784f39db95f62f5655ee349df27cd4575cc581e7 100644 (file)
@@ -57,6 +57,8 @@
 #include <BOPCol_DataMapOfShapeShape.hxx>
 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
 #include <BOPCol_MapOfShape.hxx>
+#include <BRepBndLib.hxx>
+#include <Bnd_Box.hxx>
 
 
 static
@@ -444,6 +446,7 @@ TopAbs_Orientation BOPAlgo_BuilderFace::Orientation()const
   }
   //
   // 2. Find outer growth shell that is most close to each hole shell
+  BOPCol_ListOfShape anUnUsedHoles;
   aIt2.Initialize(aHoleWires);
   for (; aIt2.More(); aIt2.Next()) {
     const TopoDS_Shape& aHole = aIt2.Value();
@@ -481,8 +484,26 @@ TopAbs_Orientation BOPAlgo_BuilderFace::Orientation()const
         aMSH.Bind(aF, aLH);
       }
     }
+    else {
+      anUnUsedHoles.Append(aHole);
+    }
   }// for (; aIt2.More(); aIt2.Next())
   //
+  if (anUnUsedHoles.Extent()) {
+    // add the infinite face to new faces
+    Bnd_Box aBox;
+    BRepBndLib::Add(myFace, aBox);
+    if (aBox.IsOpenXmin() || aBox.IsOpenXmax() ||
+        aBox.IsOpenYmin() || aBox.IsOpenYmax() ||
+        aBox.IsOpenZmin() || aBox.IsOpenZmax()) {
+      TopoDS_Face aFace;
+      aBB.MakeFace(aFace, aS, aLoc, aTol);
+      //
+      aNewFaces.Append(aFace);
+      aMSH.Bind(aFace, anUnUsedHoles);
+    }
+  }
+  //
   // 3. Add aHoles to Faces
   aItMSH.Initialize(aMSH);
   for (; aItMSH.More(); aItMSH.Next()) {
index 1f44fd484948e7db15d832b137771c7b0d65e954..ff11819486ad09cf9fe59b4535119a8e820ec273 100644 (file)
@@ -6,29 +6,35 @@
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and / or modify it
-// under the terms of the GNU Lesser General Public version 2.1 as published
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
 // by the Free Software Foundation, with special exception defined in the file
 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
 // distribution for complete text of the license and disclaimer of any warranty.
 //
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
-
+//
 #include <BOPAlgo_BuilderSolid.ixx>
-
+//
+#include <NCollection_List.hxx>
+#include <NCollection_DataMap.hxx>
+#include <NCollection_UBTreeFiller.hxx>
+//
 #include <gp_Pnt2d.hxx>
 #include <gp_Pln.hxx>
 #include <gp_Vec.hxx>
 #include <gp_Dir.hxx>
 #include <gp_Pnt.hxx>
-
+//
+#include <TColStd_MapIntegerHasher.hxx>
+//
 #include <Geom_Curve.hxx>
 #include <Geom_Surface.hxx>
 #include <Geom2d_Curve.hxx>
-
+//
 #include <TopAbs.hxx>
-
+//
 #include <TopoDS_Iterator.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Shape.hxx>
 
 #include <BRep_Builder.hxx>
 #include <BRep_Tool.hxx>
-#include <BRepTools.hxx>
-#include <BRepClass3d_SolidClassifier.hxx>
-
+//
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 //
-#include <BOPTools_AlgoTools.hxx>
+#include <BRepBndLib.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
+//
 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
-#include <BOPTools.hxx>
 #include <BOPCol_ListOfShape.hxx>
 #include <BOPCol_MapOfOrientedShape.hxx>
-//
-#include <NCollection_List.hxx> 
-//
 #include <BOPCol_DataMapOfShapeShape.hxx>
 #include <BOPCol_DataMapOfShapeListOfShape.hxx>
-#include <BOPInt_Context.hxx>
-#include <BOPTools_CoupleOfShape.hxx>
 #include <BOPCol_MapOfShape.hxx>
+#include <BOPCol_ListOfInteger.hxx>
+//
+#include <BOPDS_BoxBndTree.hxx>
+
+#include <BOPTools.hxx>
+#include <BOPTools_CoupleOfShape.hxx>
+#include <BOPTools_AlgoTools.hxx>
+#include <BOPTools_AlgoTools3D.hxx>
+//
+#include <BOPInt_Context.hxx>
+//
+#include <BOPAlgo_ShellSplitter.hxx>
+#include <BOPCol_DataMapOfIntegerShape.hxx>
 
 static
   Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
@@ -74,14 +87,63 @@ static
   void MakeInternalShells(const BOPCol_MapOfShape& ,
                           BOPCol_ListOfShape& );
 
-static
-  Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell);
-
+//=======================================================================
+//class     : BOPAlgo_BuilderSolid_ShapeBox
+//purpose   : Auxiliary class
+//=======================================================================
+class BOPAlgo_BuilderSolid_ShapeBox {
+ public:
+  BOPAlgo_BuilderSolid_ShapeBox() {
+    myIsHole=Standard_False;
+  };
+  //
+  ~BOPAlgo_BuilderSolid_ShapeBox() {
+  };
+  //
+  void SetShape(const TopoDS_Shape& aS) {
+    myShape=aS;
+  };
+  //
+  const TopoDS_Shape& Shape()const {
+    return myShape;
+  };
+  //
+  void SetBox(const Bnd_Box& aBox) {
+    myBox=aBox;
+  };
+  //
+  const Bnd_Box& Box()const {
+    return myBox;
+  };
+  //
+  void SetIsHole(const Standard_Boolean bFlag) {
+    myIsHole=bFlag;
+  };
+  //
+  Standard_Boolean IsHole()const {
+    return myIsHole;
+  };
+  //
+ protected:
+  Standard_Boolean myIsHole;
+  TopoDS_Shape myShape;
+  Bnd_Box myBox;
+};
+//
+typedef NCollection_DataMap
+  <Standard_Integer, 
+  BOPAlgo_BuilderSolid_ShapeBox, 
+  TColStd_MapIntegerHasher> BOPAlgo_DataMapOfIntegerBSSB; 
+//
+typedef BOPAlgo_DataMapOfIntegerBSSB::Iterator 
+  BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB; 
+//
+//
 //=======================================================================
 //function : 
 //purpose  : 
 //=======================================================================
-  BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid()
+BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid()
 :
   BOPAlgo_BuilderArea()
 {
@@ -90,7 +152,8 @@ static
 //function : 
 //purpose  : 
 //=======================================================================
-  BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid(const Handle(NCollection_BaseAllocator)& theAllocator)
+BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid
+  (const Handle(NCollection_BaseAllocator)& theAllocator)
 :
   BOPAlgo_BuilderArea(theAllocator)
 {
@@ -99,20 +162,18 @@ static
 //function : ~
 //purpose  : 
 //=======================================================================
-  BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid()
+BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid()
 {
 }
 //=======================================================================
 //function : Perform
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_BuilderSolid::Perform()
+void BOPAlgo_BuilderSolid::Perform()
 {
   myErrorStatus=0;
   //
   if (myContext.IsNull()) {
-    //myErrorStatus=11;// Null Context
-    //return;
     myContext=new BOPInt_Context;
   }
   //
@@ -127,7 +188,6 @@ static
     aBB.Add(aC, aF);
   }
   //
-  //
   PerformShapesToAvoid();
   if (myErrorStatus) {
     return;
@@ -137,10 +197,12 @@ static
   if (myErrorStatus) {
     return;
   }
+  //
   PerformAreas();
   if (myErrorStatus) {
     return;
   }
+  //
   PerformInternalShapes();
   if (myErrorStatus) {
     return;
@@ -150,7 +212,7 @@ static
 //function :PerformShapesToAvoid
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
+void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
 {
   Standard_Boolean bFound;
   Standard_Integer i, iCnt, aNbE, aNbF;
@@ -171,7 +233,10 @@ static
     for (; aIt.More(); aIt.Next()) {
       const TopoDS_Shape& aF=aIt.Value();
       if (!myShapesToAvoid.Contains(aF)) {
-        BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
+        BOPTools::MapShapesAndAncestors(aF, 
+                                        TopAbs_EDGE, 
+                                        TopAbs_FACE, 
+                                        aMEF);
       }
     }
     aNbE=aMEF.Extent();
@@ -221,153 +286,53 @@ static
       break;
     }
     //
-  }//while (1) 
+  }//for(;;) {
 }  
 //=======================================================================
 //function : PerformLoops
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_BuilderSolid::PerformLoops()
+void BOPAlgo_BuilderSolid::PerformLoops()
 {
-  myErrorStatus=0;
-  //
-  myLoops.Clear();
-  //
-  Standard_Integer aNbLF, aNbOff, aNbFP, aNbFA;
-  Standard_Integer i;
-  TopAbs_Orientation anOr;
-  TopoDS_Edge aEL;
-  BRep_Builder aBB;
+  Standard_Integer iErr;
+  BOPCol_ListIteratorOfListOfShape aIt;
   TopoDS_Iterator aItS;
-  //
-  BOPCol_ListIteratorOfListOfShape aItF, aIt;
   BOPCol_MapIteratorOfMapOfOrientedShape aItM;
-  BOPTools_CoupleOfShape aCSOff;
-  //
-  BOPCol_MapOfOrientedShape AddedFacesMap;
-  BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
-  //
-  //=================================================
+  BOPAlgo_ShellSplitter aSSp;
+  // 
+  myErrorStatus=0;
+  myLoops.Clear();
   //
   // 1. Shells Usual
+  aIt.Initialize (myShapes);
+  for (; aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aF=aIt.Value();
+    if (!myShapesToAvoid.Contains(aF)) {
+      aSSp.AddStartElement(aF);
+    }
+  }
   //
-  aItF.Initialize (myShapes);
-  for (; aItF.More(); aItF.Next()) {
-    const TopoDS_Shape& aFF = aItF.Value();
-    BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
+  aSSp.Perform();
+  iErr=aSSp.ErrorStatus();
+  if (iErr) {
+    return;
   }
   //
-  aItF.Initialize (myShapes);
-  for (i=1; aItF.More(); aItF.Next(), ++i) {
-    const TopoDS_Shape& aFF = aItF.Value();
-    if (myShapesToAvoid.Contains(aFF)) {
-      continue;
-    }
-    if (!AddedFacesMap.Add(aFF)) {
-      continue;
-    }
-    //
-    // make a new shell
-    TopoDS_Shell aShell;
-    aBB.MakeShell(aShell);
-    aBB.Add(aShell, aFF);
-    //
-    aMEFP.Clear();
-    BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
-    //
-    // loop on faces added to Shell; add their neighbor faces to Shell and so on
-    TopoDS_Iterator aItAddedF (aShell);
-    for (; aItAddedF.More(); aItAddedF.Next()) {
-      const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value()));
-      //
-      // loop on edges of aF; find a good neighbor face of aF by aE
-      TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
-      for (; aEdgeExp.More(); aEdgeExp.Next()) {
-        const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
-        //
-        //1
-        if (aMEFP.Contains(aE)) {
-          const BOPCol_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
-          aNbFP=aLFP.Extent();
-          if (aNbFP>1) { 
-            continue;
-          }
-        }
-        //2
-        anOr=aE.Orientation();
-        if (anOr==TopAbs_INTERNAL) {
-          continue;
-        }
-        //3
-        if (BRep_Tool::Degenerated(aE)) {
-          continue;
-        }
-        //
-        // candidate faces list
-        const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
-        aNbLF=aLF.Extent();
-        if (!aNbLF) {
-          continue;
-        }
-        //
-        // try to select one of neighbors
-        // check if a face already added to Shell shares E
-        Standard_Boolean bFound;
-        BOPCol_ListIteratorOfListOfShape aItLF;
-        BOPTools_ListOfCoupleOfShape aLCSOff;
-        //
-        aItLF.Initialize(aLF);
-        for (; aItLF.More(); aItLF.Next()) { 
-          const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
-          if (myShapesToAvoid.Contains(aFL)) {
-            continue;
-          }
-          if (aF.IsSame(aFL)) {
-            continue;
-          } 
-          if (AddedFacesMap.Contains(aFL)){
-            continue;
-          }
-          //
-          bFound=BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL);
-          if (!bFound) {
-            continue;
-          }
-          //
-          aCSOff.SetShape1(aEL);
-          aCSOff.SetShape2(aFL);
-          aLCSOff.Append(aCSOff);
-        }//for (; aItLF.More(); aItLF.Next()) { 
-        //
-        aNbOff=aLCSOff.Extent();
-        if (!aNbOff){
-          continue;
-        }
-        //
-        TopoDS_Face aSelF;
-        if (aNbOff==1) {
-          aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
-        }
-        else if (aNbOff>1){
-          BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, myContext);
-          }
-        //
-        if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) { 
-          aBB.Add(aShell, aSelF);
-          BOPTools::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
-        }
-      } // for (; aEdgeExp.More(); aEdgeExp.Next()) { 
-    } //for (; aItAddedF.More(); aItAddedF.Next()) {
-    //
-    if (IsClosedShell(aShell)) {
-      myLoops.Append(aShell);
-    }
-  } // for (; aItF.More(); aItF.Next()) {
-  
+  const BOPCol_ListOfShape& aLSh=aSSp.Shells();
+  aIt.Initialize (aLSh);
+  for (; aIt.More(); aIt.Next()) {
+    const TopoDS_Shape& aSh=aIt.Value();
+    myLoops.Append(aSh);
+  }
+  //=================================================
   //
-  // Post Treatment
+  // 2. Post Treatment
+  Standard_Integer aNbFA;
+  BRep_Builder aBB;
+  BOPCol_MapOfOrientedShape AddedFacesMap;
+  BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
   BOPCol_MapOfOrientedShape aMP;
-  // 
+  //
   // a. collect all edges that are in loops
   aIt.Initialize (myLoops);
   for (; aIt.More(); aIt.Next()) {
@@ -396,8 +361,7 @@ static
   }
   //=================================================
   //
-  // 2.Internal Shells
-  //
+  // 3.Internal Shells
   myLoopsInternal.Clear();
   //
   aEFMap.Clear();
@@ -408,7 +372,9 @@ static
   aItM.Initialize(myShapesToAvoid);
   for (; aItM.More(); aItM.Next()) {
     const TopoDS_Shape& aFF=aItM.Key();
-    BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
+    BOPTools::MapShapesAndAncestors(aFF, 
+        TopAbs_EDGE, TopAbs_FACE, 
+        aEFMap);
   }
   //
   aItM.Initialize(myShapesToAvoid);
@@ -431,15 +397,16 @@ static
       for (; aEdgeExp.More(); aEdgeExp.Next()) {
         const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
         const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
-        aItF.Initialize(aLF);
-        for (; aItF.More(); aItF.Next()) { 
-          const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItF.Value()));
+        aIt.Initialize(aLF);
+        for (; aIt.More(); aIt.Next()) { 
+          const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aIt.Value()));
           if (AddedFacesMap.Add(aFL)){
             aBB.Add(aShell, aFL);
           }
         }
       }
     }
+    aShell.Closed (BRep_Tool::IsClosed (aShell));
     myLoopsInternal.Append(aShell);
   }
 }
@@ -447,131 +414,185 @@ static
 //function : PerformAreas
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_BuilderSolid::PerformAreas()
+void BOPAlgo_BuilderSolid::PerformAreas()
 {
-  myErrorStatus=0;
-  //
-  Standard_Boolean bIsGrowthShell, bIsHole;
+  Standard_Boolean bIsGrowth, bIsHole;
+  Standard_Integer k,aNbHoles;
   BRep_Builder aBB; 
-  TopoDS_Shape anInfinitePointShape;
-  BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
-  BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
-  //
+  BOPCol_ListIteratorOfListOfShape aItLS;
   BOPCol_ListOfShape aNewSolids, aHoleShells; 
   BOPCol_DataMapOfShapeShape aInOutMap;
-  BOPCol_DataMapOfShapeListOfShape aMSH;
   BOPCol_IndexedMapOfShape aMHF;
+  BOPCol_ListIteratorOfListOfInteger aItLI;
+  BOPDS_BoxBndTreeSelector aSelector;
+  BOPDS_BoxBndTree aBBTree;
+  NCollection_UBTreeFiller 
+    <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
+  BOPAlgo_DataMapOfIntegerBSSB aDMISB(100);
+  BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB;
+  BOPCol_DataMapOfShapeListOfShape aMSH;
+  BOPCol_DataMapIteratorOfDataMapOfShapeShape aItDMSS;
+  BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
+  //
+  myErrorStatus=0;
   //
   myAreas.Clear();
   //
   //  Draft solids [aNewSolids]
-  aShellIt.Initialize(myLoops);
-  for ( ; aShellIt.More(); aShellIt.Next()) {
-    const TopoDS_Shape& aShell = aShellIt.Value();
+  aItLS.Initialize(myLoops);
+  for (k=0; aItLS.More(); aItLS.Next(), ++k) {
+    TopoDS_Solid aSolid;
+    Bnd_Box aBox;
+    BOPAlgo_BuilderSolid_ShapeBox aSB;
+    //
+    const TopoDS_Shape& aShell = aItLS.Value();
+    aSB.SetShape(aShell);
     //
-    bIsGrowthShell=IsGrowthShell(aShell, aMHF);
-    if (bIsGrowthShell) {
+    BRepBndLib::Add(aShell, aBox);
+    bIsHole=Standard_False;
+    //
+    bIsGrowth=IsGrowthShell(aShell, aMHF);
+    if (bIsGrowth) {
       // make a growth solid from a shell
-      TopoDS_Solid Solid;
-      aBB.MakeSolid(Solid);
-      aBB.Add (Solid, aShell);
+      aBB.MakeSolid(aSolid);
+      aBB.Add (aSolid, aShell);
       //
-      aNewSolids.Append (Solid);
+      aNewSolids.Append (aSolid);
+      aSB.SetShape(aSolid);
     }
     else{
       // check if a shell is a hole
-      //XX
       bIsHole=IsHole(aShell, myContext);
-      //XX
       if (bIsHole) {
         aHoleShells.Append(aShell);
         BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
+        aSB.SetShape(aShell);
       }
       else {
         // make a growth solid from a shell
-        TopoDS_Solid Solid;
-        aBB.MakeSolid(Solid);
-        aBB.Add (Solid, aShell);
+        aBB.MakeSolid(aSolid);
+        aBB.Add (aSolid, aShell);
         //
-        aNewSolids.Append (Solid);
+        aNewSolids.Append (aSolid);
+        aSB.SetShape(aSolid);
       }
     }
+    //
+    aSB.SetBox(aBox);
+    aSB.SetIsHole(bIsHole);
+    aDMISB.Bind(k, aSB);
+  }  
+  //
+  // 2. Prepare TreeFiller
+  aItDMISB.Initialize(aDMISB);
+  for (; aItDMISB.More(); aItDMISB.Next()) {
+    k=aItDMISB.Key();
+    const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
+    //
+    bIsHole=aSB.IsHole();
+    if (bIsHole) {
+      const Bnd_Box& aBox=aSB.Box();
+      aTreeFiller.Add(k, aBox);
+    }
   }
   //
-  // 2. Find outer growth shell that is most close to each hole shell
-  aShellIt.Initialize(aHoleShells);
-  for (; aShellIt.More(); aShellIt.Next()) {
-    const TopoDS_Shape& aHole = aShellIt.Value();
+  // 3. Shake TreeFiller
+  aTreeFiller.Fill();
+  //
+  // 4. Find outer growth shell that is most close 
+  //    to each hole shell
+  aItDMISB.Initialize(aDMISB);
+  for (; aItDMISB.More(); aItDMISB.Next()) {
+    k=aItDMISB.Key();
+    const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
+    bIsHole=aSB.IsHole();
+    if (bIsHole) {
+      continue;
+    }
     //
-    aSolidIt.Initialize(aNewSolids);
-    for ( ; aSolidIt.More(); aSolidIt.Next())    {
-      const TopoDS_Shape& aSolid = aSolidIt.Value();
+    const TopoDS_Shape aSolid=aSB.Shape();
+    const Bnd_Box& aBoxSolid=aSB.Box();
+    //
+    aSelector.Clear();
+    aSelector.SetBox(aBoxSolid);
+    //
+    aNbHoles=aBBTree.Select(aSelector);
+    //
+    const BOPCol_ListOfInteger& aLI=aSelector.Indices();
+    //
+    aItLI.Initialize(aLI);
+    for (; aItLI.More(); aItLI.Next()) {
+      k=aItLI.Value();
+      const BOPAlgo_BuilderSolid_ShapeBox& aSBk=aDMISB.Find(k);
+      const TopoDS_Shape& aHole=aSBk.Shape();
       //
       if (!IsInside(aHole, aSolid, myContext)){
         continue;
       }
       //
-      if ( aInOutMap.IsBound (aHole)){
-        const TopoDS_Shape& aSolid2 = aInOutMap(aHole);
-        if (IsInside(aSolid, aSolid2, myContext)) {
+      if (aInOutMap.IsBound (aHole)){
+        const TopoDS_Shape& aHole2=aInOutMap(aHole);
+        if (IsInside(aHole, aHole2, myContext)) {
           aInOutMap.UnBind(aHole);
           aInOutMap.Bind (aHole, aSolid);
         }
       }
       else{
-        aInOutMap.Bind (aHole, aSolid);
+        aInOutMap.Bind(aHole, aSolid);
       }
     }
+  }//for (; aItDMISB.More(); aItDMISB.Next()) {
+  //
+  // 5. Map [Solid/Holes] -> aMSH 
+  aItDMSS.Initialize(aInOutMap);
+  for (; aItDMSS.More(); aItDMSS.Next()) {
+    const TopoDS_Shape& aHole=aItDMSS.Key();
+    const TopoDS_Shape& aSolid=aItDMSS.Value();
     //
-    // Add aHole to a map Solid/ListOfHoles [aMSH]
-    if (aInOutMap.IsBound(aHole)){
-      const TopoDS_Shape& aSolid=aInOutMap(aHole);
-      if (aMSH.IsBound(aSolid)) {
-        BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
-        aLH.Append(aHole);
-      }
-      else {
-        BOPCol_ListOfShape aLH;
-        aLH.Append(aHole);
-        aMSH.Bind(aSolid, aLH);
-      }
-      //aBB.Add (aSolid, aHole);
+    if (aMSH.IsBound(aSolid)) {
+      BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
+      aLH.Append(aHole);
+    }
+    else {
+      BOPCol_ListOfShape aLH;
+      aLH.Append(aHole);
+      aMSH.Bind(aSolid, aLH);
     }
-  }// for (; aShellIt.More(); aShellIt.Next()) {
+  }
   //
-  // 3. Add aHoles to Solids
+  // 6. Add aHoles to Solids
   aItMSH.Initialize(aMSH);
   for (; aItMSH.More(); aItMSH.Next()) {
     TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&aItMSH.Key()));
     //
     const BOPCol_ListOfShape& aLH=aItMSH.Value();
-    aShellIt.Initialize(aLH);
-    for (; aShellIt.More(); aShellIt.Next()) {
-      const TopoDS_Shape& aHole = aShellIt.Value();
+    aItLS.Initialize(aLH);
+    for (; aItLS.More(); aItLS.Next()) {
+      const TopoDS_Shape& aHole = aItLS.Value();
       aBB.Add (aSolid, aHole);
     }
     //
     // update classifier
-    BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid);
+    BRepClass3d_SolidClassifier& aSC=
+      myContext->SolidClassifier(aSolid);
     aSC.Load(aSolid);
     //
   }
   //
-  // These aNewSolids are draft solids that 
+  // 7. These aNewSolids are draft solids that 
   // do not contain any internal shapes
-  //
-  aShellIt.Initialize(aNewSolids);
-  for ( ; aShellIt.More(); aShellIt.Next()) {
-    const TopoDS_Shape& aSx = aShellIt.Value();
+  aItLS.Initialize(aNewSolids);
+  for ( ; aItLS.More(); aItLS.Next()) {
+    const TopoDS_Shape& aSx=aItLS.Value();
     myAreas.Append(aSx);
   }
-
   // Add holes that outside the solids to myAreas
-  aShellIt.Initialize(aHoleShells);
-  for (; aShellIt.More(); aShellIt.Next()) {
-    const TopoDS_Shape& aHole = aShellIt.Value();
+  aItLS.Initialize(aHoleShells);
+  for (; aItLS.More(); aItLS.Next()) {
+    const TopoDS_Shape& aHole = aItLS.Value();
     if (!aInOutMap.IsBound(aHole)){
       TopoDS_Solid aSolid;
+      //
       aBB.MakeSolid(aSolid);
       aBB.Add (aSolid, aHole);
       //
@@ -583,7 +604,7 @@ static
 //function : PerformInternalShapes
 //purpose  : 
 //=======================================================================
-  void BOPAlgo_BuilderSolid::PerformInternalShapes()
+void BOPAlgo_BuilderSolid::PerformInternalShapes()
 {
   myErrorStatus=0;
   //
@@ -592,95 +613,169 @@ static
     return;
   }
   // 
+  Standard_Integer k, aNbVFS, aNbSLF, aNbF, aNbA;
   BRep_Builder aBB;
   TopoDS_Iterator aIt;
-  BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
-  BOPCol_MapIteratorOfMapOfShape aItMF;
-  //
-  BOPCol_MapOfShape aMF, aMFP, aMFx;
-  BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
+  TopExp_Explorer aExp;
+  BOPCol_ListIteratorOfListOfShape  aItLS;
+  BOPCol_MapOfShape aMFs;
   BOPCol_ListOfShape aLSI;
-  //
-  // 1. All internal faces
-  aShellIt.Initialize(myLoopsInternal);
-  for (; aShellIt.More(); aShellIt.Next()) {
-    const TopoDS_Shape& aShell=aShellIt.Value();
+  BOPCol_ListIteratorOfListOfInteger aItLI;
+  BOPDS_BoxBndTreeSelector aSelector;
+  BOPDS_BoxBndTree aBBTree;
+  NCollection_UBTreeFiller 
+    <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
+  BOPCol_DataMapOfIntegerShape aDMIS;
+  //
+  aNbA=myAreas.Extent();
+  //
+  // 1. Prepare tree filler
+  k = 0;
+  aItLS.Initialize(myLoopsInternal);
+  for (; aItLS.More(); aItLS.Next()) {
+    const TopoDS_Shape& aShell=aItLS.Value();
     aIt.Initialize(aShell);
     for (; aIt.More(); aIt.Next()) {
-      const TopoDS_Shape& aF=aIt.Value();
-      aMF.Add(aF);
+      const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
+      //
+      if (aMFs.Add(aF)) {
+        if (aNbA) {
+          Bnd_Box aBox;
+          BRepBndLib::Add(aF, aBox);
+          aDMIS.Bind(k, aF);
+          aTreeFiller.Add(k++, aBox);
+        }
+      }
     }
   }
-  aNbFI=aMF.Extent();
   //
-  // 2 Process solids
-  aSolidIt.Initialize(myAreas);
-  for ( ; aSolidIt.More(); aSolidIt.Next()) {
-    TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aSolidIt.Value()));
+  if (!aNbA) {
+    // 7b. "Rest" faces treatment
+    TopoDS_Solid aSolid;
+    aBB.MakeSolid(aSolid);
     //
-    TopExp_Explorer anExpSol(aSolid, TopAbs_FACE);;
-    for (; anExpSol.More(); anExpSol.Next()) {
-      const TopoDS_Shape& aF = anExpSol.Current();
-      TopoDS_Shape aFF=aF;
-      //
-      aFF.Orientation(TopAbs_FORWARD);
-      aMFx.Add(aFF);
-      aFF.Orientation(TopAbs_REVERSED);
-      aMFx.Add(aFF);
+    MakeInternalShells(aMFs, aLSI);
+    //
+    aItLS.Initialize(aLSI);
+    for (; aItLS.More(); aItLS.Next()) {
+      const TopoDS_Shape& aSI=aItLS.Value();
+       aBB.Add (aSolid, aSI);
     }
-    aMEF.Clear();
-    BOPTools::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
-    //
-    // 2.1 Separate faces to process aMFP
-    aMFP.Clear();
-    aItMF.Initialize(aMF);
-    for (; aItMF.More(); aItMF.Next()) {
-      const TopoDS_Face& aF=(*(TopoDS_Face*)(&aItMF.Key()));
-      if (!aMFx.Contains(aF)) {
-        if (BOPTools_AlgoTools::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext)) {
-          aMFP.Add(aF);
+    myAreas.Append(aSolid);
+    //
+    return; // =>
+  }//if (!aNbA) {
+  //
+  //2. fill tree filler
+  aTreeFiller.Fill();
+  //
+  // 3. Face/Solid candidates: aVFS
+  BOPCol_IndexedDataMapOfShapeListOfShape aMSLF;
+  BOPCol_MapOfShape aMFProcessed;
+  //
+  aItLS.Initialize(myAreas);
+  for (; aItLS.More(); aItLS.Next()) {
+    Bnd_Box aBox;
+    //
+    TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aItLS.Value()));
+    BRepBndLib::Add(aSolid, aBox);
+    //
+    aMFs.Clear();
+    aExp.Init(aSolid, TopAbs_FACE);
+    for (; aExp.More(); aExp.Next()) {
+      const TopoDS_Shape& aFs=aExp.Current();
+      aMFs.Add(aFs);
+    }
+    //
+    aSelector.Clear();
+    aSelector.SetBox(aBox);
+    //
+    aNbF=aBBTree.Select(aSelector);
+    //
+    const BOPCol_ListOfInteger& aLI=aSelector.Indices();
+    aItLI.Initialize(aLI);
+    for (; aItLI.More(); aItLI.Next()) {
+      k=aItLI.Value();
+      const TopoDS_Face& aF = *(TopoDS_Face*)&aDMIS.Find(k);
+      if (aMFs.Contains(aF)) {
+        continue;
+      }
+      //
+      gp_Pnt aP;
+      gp_Pnt2d aP2D;
+      //
+      BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2D, myContext);
+      //
+      TopAbs_State aState=BOPTools_AlgoTools::ComputeState(aP, aSolid,
+                                                           Precision::Confusion(),
+                                                           myContext);
+      if (aState==TopAbs_IN) {
+        if (aMSLF.Contains(aSolid)) {
+          BOPCol_ListOfShape& aLF=aMSLF.ChangeFromKey(aSolid);
+          aLF.Append(aF);
+        }
+        else {
+          BOPCol_ListOfShape aLF;
+          //
+          aLF.Append(aF);
+          aMSLF.Add(aSolid, aLF);
         }
       }
     }
-    aMFx.Clear();
+  }// for (k=0; k < aNbVE; ++k) {
+  //
+  // 6. Update Solids by internal Faces
+  aNbSLF=aMSLF.Extent();
+  for (k=1; k <= aNbSLF; ++k) {
+    const TopoDS_Shape& aSolid=aMSLF.FindKey(k);
+    TopoDS_Shape *pSolid=(TopoDS_Shape*)&aSolid;
     //
-    // 2.2 Make Internal Shells
-    aLSI.Clear();
-    MakeInternalShells(aMFP, aLSI);
+    const BOPCol_ListOfShape& aLF=aMSLF(k);
     //
-    // 2.3 Add them to aSolid
-    aShellIt.Initialize(aLSI);
-    for (; aShellIt.More(); aShellIt.Next()) {
-      const TopoDS_Shape& aSI=aShellIt.Value();
-      aBB.Add (aSolid, aSI);
+    aMFs.Clear();
+    aItLS.Initialize(aLF);
+    for (; aItLS.More(); aItLS.Next()) {
+      const TopoDS_Shape& aF=aItLS.Value();
+      aMFs.Add(aF);
+      aMFProcessed.Add(aF);
     }
     //
-    // 2.4 Remove faces aMFP from aMF
-    aItMF.Initialize(aMFP);
-    for (; aItMF.More(); aItMF.Next()) {
-      const TopoDS_Shape& aF=aItMF.Key();
-      aMF.Remove(aF);
-    }
+    aLSI.Clear();
+    MakeInternalShells(aMFs, aLSI);
     //
-    aNbFI=aMF.Extent();
-    if (!aNbFI) {
-      break;
+    aItLS.Initialize(aLSI);
+    for (; aItLS.More(); aItLS.Next()) {
+      const TopoDS_Shape& aSI=aItLS.Value();
+      aBB.Add (*pSolid, aSI);
     }
-  } //for ( ; aSolidIt.More(); aSolidIt.Next()) {
+  }
+  // 
+  // 7. "Rest" faces treatment (if there are)
+  aMFs.Clear();
+  aNbVFS = aDMIS.Extent();
+  for (k=0; k < aNbVFS; ++k) {
+    const TopoDS_Face& aF=*(TopoDS_Face*)&aDMIS.Find(k);
+    if (!aMFProcessed.Contains(aF)) {
+      aMFs.Add(aF);
+    }
+  }
+  //
+  aNbFI=aMFs.Extent();
   if (aNbFI) {
     TopoDS_Solid aSolid;
     aBB.MakeSolid(aSolid);
     //
-    MakeInternalShells(aMF, aLSI);
-    aShellIt.Initialize(aLSI);
-    for (; aShellIt.More(); aShellIt.Next()) {
-      const TopoDS_Shape& aSI=aShellIt.Value();
+    aLSI.Clear();
+    MakeInternalShells(aMFs, aLSI);
+    //
+    aItLS.Initialize(aLSI);
+    for (; aItLS.More(); aItLS.Next()) {
+      const TopoDS_Shape& aSI=aItLS.Value();
       aBB.Add (aSolid, aSI);
     }
     myAreas.Append(aSolid);
   }
 }
-
 //=======================================================================
 //function : MakeInternalShells
 //purpose  : 
@@ -698,7 +793,9 @@ void MakeInternalShells(const BOPCol_MapOfShape& theMF,
   aItM.Initialize(theMF);
   for (; aItM.More(); aItM.Next()) {
     const TopoDS_Shape& aF=aItM.Key();
-    BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
+    BOPTools::MapShapesAndAncestors(aF, 
+        TopAbs_EDGE, TopAbs_FACE, 
+        aMEF);
   }
   //
   aItM.Initialize(theMF);
@@ -732,6 +829,7 @@ void MakeInternalShells(const BOPCol_MapOfShape& theMF,
         }
       }
     }
+    aShell.Closed (BRep_Tool::IsClosed (aShell));
     theShells.Append(aShell);
   }
 }
@@ -772,7 +870,9 @@ Standard_Boolean IsInside(const TopoDS_Shape& theS1,
     BOPCol_IndexedMapOfShape aBounds;
     BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds);
     const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current()));
-    aState=BOPTools_AlgoTools::ComputeState(aF, *pS2, 1.e-14, aBounds, theContext);
+    aState=BOPTools_AlgoTools::ComputeState(aF, *pS2,
+                                            Precision::Confusion(),
+                                            aBounds, theContext);
   }
   return (aState==TopAbs_IN);
 }
@@ -798,42 +898,3 @@ Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
   }
   return bRet;
 }
-//=======================================================================
-//function : IsClosedShell
-//purpose  : 
-//=======================================================================
-Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
-{
-  Standard_Integer aNbE;
-  Standard_Boolean bRet;
-  TopoDS_Iterator aIt;
-  TopExp_Explorer aExp;
-  //
-  BOPCol_MapOfShape aM;
-  // 
-  bRet=Standard_False;
-  aIt.Initialize(theShell);
-  for(; aIt.More(); aIt.Next()) {
-    const TopoDS_Face& aF=(*(TopoDS_Face*)(&aIt.Value()));
-    aExp.Init(aF, TopAbs_EDGE);
-    for (; aExp.More(); aExp.Next()) {
-      const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
-      if (BRep_Tool::Degenerated(aE)) {
-        continue;
-      }
-      //
-      if (aE.Orientation()==TopAbs_INTERNAL) {
-        continue;
-      }
-      if (!aM.Add(aE)) {
-        aM.Remove(aE);
-      }
-    }
-  }
-  //
-  aNbE=aM.Extent();
-  if (!aNbE) {
-    bRet=!bRet;
-  }
-  return bRet;
-}
index 8be816ceebdec5d144301046a5b8805846f3514e..16e39da299e74ab89e5199dfe427d8866e9d67fc 100644 (file)
@@ -65,8 +65,8 @@ GeomAbs_SurfaceType IntCurvesFace_Intersector::SurfaceType() const
 //purpose  : 
 //=======================================================================
 IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
-                                                    const Standard_Real aTol)
-: 
+                                                     const Standard_Real aTol)
+     
   Tol(aTol),
   done(Standard_False),
   nbpnt(0),
@@ -95,7 +95,7 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
     Standard_Boolean bFlag;
     //
     {
-      Standard_Real dU, dV, dA, dB, aR, aTresh; 
+      Standard_Real dU, dV, dA, dB, aTresh; 
       bFlag=Standard_True;
       //
       aTresh=100.;
@@ -104,18 +104,12 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
       dA=dU;
       dB=dV;
       if (dV>dU) {
-       dA=dV;
-       dB=dU;
+        dA=dV;
+        dB=dU;
       }
       //
-      aR=dA/dB;
-      if (dB<Precision::PConfusion()) {
-       bFlag=!bFlag;
-      }
-      else {
-       if (aR>aTresh) {
-         bFlag=!bFlag;
-       }
+      if (dB < Precision::PConfusion() || dA > dB * aTresh) {
+        bFlag=!bFlag;
       }
     }
     //
@@ -125,7 +119,7 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
       if(nbsu>40) nbsu = 40;
       if(nbsv>40) nbsv = 40;
       PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *) 
-       new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
+        new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
     }
     //
     /*
diff --git a/tests/bugs/modalg_5/bug25416_1 b/tests/bugs/modalg_5/bug25416_1
new file mode 100644 (file)
index 0000000..b0abf57
--- /dev/null
@@ -0,0 +1,124 @@
+puts "================"
+puts "OCC25416"
+puts "================"
+puts ""
+#######################################################################
+# Face/Face intersection algorithm gives different results for different order of the arguments
+#######################################################################
+
+# Check if list of xdistcs-command is valid
+proc checkList {List Tolerance D_good Limit_Tol} {
+   set L1 [llength ${List}]
+   set L2 10
+   set L3 5
+   set N [expr (${L1} - ${L2})/${L3} + 1]
+
+   for {set i 1} {${i} <= ${N}} {incr i} {
+      set j1 [expr ${L2} + (${i}-1)*${L3}]
+      set j2 [expr ${j1} + 2]
+      set T [lindex ${List} ${j1}]
+      set D [lindex ${List} ${j2}]
+      #puts "i=${i} j1=${j1} j2=${j2} T=${T} D=${D}"
+      if { [expr abs(${D} - ${D_good})] > ${Tolerance} } {
+         puts "Error: T=${T} D=${D}"
+      }
+      
+      if { ${Tolerance} > ${Limit_Tol} } {
+        if { [expr abs(${D} - ${D_good})] > ${Limit_Tol} 
+             && [expr abs(${D} - ${D_good})] <= ${Tolerance} } {
+           puts "Attention (critical value of tolerance) : T=${T} D=${D}"
+        }
+      }
+   }
+}
+
+
+puts "##############################"
+puts "#!!!Search \"Attention\" keyword on this web-page for additional checking!!!"
+puts "##############################"
+puts ""
+puts ""
+
+# bopcurves command
+
+restore [locate_data_file bug25416_f1.brep] f1
+restore [locate_data_file bug25416_f2.brep] f2
+
+#############################
+set log [bopcurves f1 f2 -2d]
+#############################
+
+regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv
+
+#This value must be equal to the analogical value in bug25292_31 and bug25292_32 of "bugs modalg_5" testgrid. 
+set MaxTol 1.e-7
+
+#This value must be equal to the analogical value in bug25292_31 and bug25292_32 of "bugs modalg_5" testgrid. 
+set GoodNbCurv 1
+
+if {${Toler} > ${MaxTol}} {
+  puts "Error: Tolerance is too big!"
+}
+if {${NbCurv} != ${GoodNbCurv}} {
+  puts "Error: Curve Number is bad!"
+}
+
+#-------------
+
+mksurface s1 f1
+mksurface s2 f2
+
+erase s1 s2
+
+for {set i 1} {$i <= ${NbCurv}} {incr i} {
+  set log [dump c_$i]
+  set dumptrimres [regexp {Trimmed curve\nParameters : +([-0-9.+eE]+) +([-0-9.+eE]+)} ${log} full U1 U2]
+  
+  if {${dumptrimres} == 0} {
+    regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles
+    
+    puts "Degree=${Degree}"
+    puts "Poles=${Poles}"
+    puts "KnotsPoles=${KnotsPoles}"
+    puts ""
+    
+    set Knot 1
+    set exp_string "Knots :\n\n +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
+    regexp ${exp_string} ${log} full U1 Mult1
+    
+    set Knot ${KnotsPoles}
+    set exp_string " +${Knot} :  +(\[-0-9.+eE\]+) +(\[-0-9.+eE\]+)"
+    regexp ${exp_string} ${log} full U2 Mult2
+  }
+  
+  puts "U1=${U1}"
+  puts "U2=${U2}"
+  
+  if {[expr {$U2 - $U1}] < 1.0e-20} {
+    puts "Error: Wrong curve's range!"
+  }
+
+  dlog reset
+  dlog on
+  xdistcs c_$i s1 ${U1} ${U2} 10
+  set Log2 [dlog get]
+  set List2 [split ${Log2} {TD= \t\n}]
+  set Tolerance 1.0e-7
+  set Limit_Tol 1.0e-7
+  set D_good 0.
+  checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol}
+
+  dlog reset
+  dlog on
+  xdistcs c_$i s2 ${U1} ${U2} 10
+  set Log2 [dlog get]
+  set List2 [split ${Log2} {TD= \t\n}]
+  set Tolerance 1.0e-7
+  set Limit_Tol 1.0e-7
+  set D_good 0.
+  checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol}
+}
+
+smallview
+fit
+set only_screen_axo 1
diff --git a/tests/bugs/modalg_5/bug25697_1 b/tests/bugs/modalg_5/bug25697_1
new file mode 100644 (file)
index 0000000..a0c7d87
--- /dev/null
@@ -0,0 +1,20 @@
+puts "==========="
+puts "OCC25697"
+puts "==========="
+puts ""
+##########################################################################################
+# Regression : Section obtained after command "bsection" in Test Harness is incorrect.
+##########################################################################################
+
+restore [locate_data_file bug25697_shell_for_seam.brep] s1
+restore [locate_data_file bug25697_prism.brep] p1
+bsection result s1 p1 -n2d2
+
+regexp {nb alone Vertices : +([-0-9.+eE]+)} [checksection result] full nb_alone_Vertices
+if { ${nb_alone_Vertices} == 2 } {
+  puts "OK: Good result done by Boolean Operation algorithm"
+} else {
+  puts "Error: Wrong result done by Boolean Operation algorithm"
+}
+
+set length 107.503
diff --git a/tests/bugs/modalg_5/bug25697_2 b/tests/bugs/modalg_5/bug25697_2
new file mode 100644 (file)
index 0000000..a41b690
--- /dev/null
@@ -0,0 +1,63 @@
+puts "=========="
+puts "OCC25697"
+puts "=========="
+puts ""
+########################################################################################
+# Regression : Section obtained after command "bsection" in Test Harness is incorrect.
+########################################################################################
+
+restore [locate_data_file bug25697_shell_for_seam.brep] b1
+restore [locate_data_file bug25697_prism.brep] b2
+explode b1 f
+copy b1_1 b1
+explode b2 f
+copy b2_1 b2
+
+#################################
+set log [bopcurves b1 b2 -2d1]
+#################################
+
+regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv
+
+set MaxTol 1.e-7
+set GoodNbCurv 3
+
+if { ${Toler} > ${MaxTol} } {
+  puts "Error: Tolerance is too big!"
+}
+
+if { ${NbCurv} != ${GoodNbCurv} } {
+  puts "Error: Curve Number is bad!"
+}
+
+#---------------
+mksurface s1 b1
+mksurface s2 b2
+
+for {set i 1} {$i <= ${NbCurv}} {incr i} {
+  bounds c_$i u1 u2
+  dump u1 u2
+  dlog reset
+  dlog on
+  xdistcs c_$i s1 u1 u2 10
+  set Log2 [dlog get]
+  set List2 [split ${Log2} {TD= \t\n}]
+  set Tolerance 1.0e-7
+  set Limit_Tol 1.0e-7
+  set D_good 0.
+  checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol}
+
+  dlog reset
+  dlog on
+  xdistcs c_$i s2 u1 u2 10
+  set Log2 [dlog get]
+  set List2 [split ${Log2} {TD= \t\n}]
+  set Tolerance 1.0e-7
+  set Limit_Tol 1.0e-7
+  set D_good 0.
+  checkList ${List2} ${Tolerance} ${D_good} ${Limit_Tol}
+}
+
+smallview
+fit
+set only_screen_axo 1