0027884: Modeling Algorithms - Possible improvement for 2d classifier
authorabulyche <abulyche@opencascade.com>
Wed, 14 Jul 2021 20:40:32 +0000 (23:40 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 13 Aug 2021 17:22:41 +0000 (20:22 +0300)
Added the implementation of bndbox<->line and bndbox<->segment intersections for 2D to Bnd_Box2d
Added the speedup for 2d classification to BRepClass_Intersector.cxx
Added the test for our improvement

14 files changed:
src/BOPTest/BOPTest_LowCommands.cxx
src/BRepClass/BRepClass_Edge.cxx
src/BRepClass/BRepClass_Edge.hxx
src/BRepClass/BRepClass_FaceClassifier.cxx
src/BRepClass/BRepClass_FaceClassifier.hxx
src/BRepClass/BRepClass_FaceExplorer.cxx
src/BRepClass/BRepClass_FaceExplorer.hxx
src/BRepClass/BRepClass_Intersector.cxx
src/BRepClass/BRepClass_Intersector.hxx
src/BRepClass3d/BRepClass3d_SolidExplorer.cxx
src/Bnd/Bnd_Box2d.cxx
src/Bnd/Bnd_Box2d.hxx
src/QABugs/QABugs_20.cxx
tests/bugs/modalg_6/bug27884 [new file with mode: 0644]

index b863f41..4f032f0 100644 (file)
@@ -124,7 +124,7 @@ Standard_Integer b2dclassify (Draw_Interpretor& theDI,
                               const char**      theArgVec)
 {
   if (theArgNb < 3)  {
-    theDI << " use b2dclassify Face Point2d [Tol]\n";
+    theDI << " use b2dclassify Face Point2d [Tol] [UseBox] [GapCheckTol]\n";
     return 1;
   }
 
@@ -144,9 +144,11 @@ Standard_Integer b2dclassify (Draw_Interpretor& theDI,
   const TopoDS_Face&  aF   = TopoDS::Face(aS);
   const Standard_Real aTol = (theArgNb == 4) ? 
     Draw::Atof (theArgVec[3]) : BRep_Tool::Tolerance (aF);
-  
+  const Standard_Boolean anUseBox = (theArgNb == 5 && Draw::Atof(theArgVec[4]) == 0) ?
+    Standard_False : Standard_True;
+  const Standard_Real aGapCheckTol = (theArgNb == 6) ? Draw::Atof(theArgVec[5]) : 0.1;
   BRepClass_FaceClassifier aClassifier;
-  aClassifier.Perform(aF, aP, aTol);
+  aClassifier.Perform(aF, aP, aTol, anUseBox, aGapCheckTol);
   PrintState (theDI, aClassifier.State());
   //
   return 0;
index 0774105..102fb6d 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <BRepClass_Edge.hxx>
 #include <NCollection_IndexedDataMap.hxx>
+#include <Precision.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Vertex.hxx>
 #include <TopExp.hxx>
@@ -25,7 +26,7 @@
 //function : BRepClass_Edge
 //purpose  : 
 //=======================================================================
-BRepClass_Edge::BRepClass_Edge()
+BRepClass_Edge::BRepClass_Edge() : myMaxTolerance(Precision::Infinite()), myUseBndBox(Standard_False)
 {
 }
 
@@ -47,7 +48,7 @@ void BRepClass_Edge::SetNextEdge(const TopTools_IndexedDataMapOfShapeListOfShape
     return;
   }
   const TopTools_ListOfShape* aListE = theMapVE.Seek(aVL);
-  if ((*aListE).Extent() == 2)
+  if (aListE->Extent() == 2)
   {
     for (TopTools_ListIteratorOfListOfShape anIt(*aListE); anIt.More(); anIt.Next())
     {
@@ -68,7 +69,9 @@ void BRepClass_Edge::SetNextEdge(const TopTools_IndexedDataMapOfShapeListOfShape
 BRepClass_Edge::BRepClass_Edge(const TopoDS_Edge& E,
                               const TopoDS_Face& F) :
        myEdge(E),
-       myFace(F)
+       myFace(F),
+       myMaxTolerance(Precision::Infinite()),
+       myUseBndBox(Standard_False)
 {
 }
 
index fe742f3..a9e5b25 100644 (file)
@@ -57,6 +57,33 @@ const TopoDS_Face& Face() const;
   //! Finds and sets the next Edge for the current
   Standard_EXPORT void SetNextEdge(const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE);
 
+  //! Returns the maximum tolerance
+  Standard_Real MaxTolerance() const
+  {
+    return myMaxTolerance;
+  }
+
+  //! Sets the maximum tolerance at 
+  //! which to start checking in the intersector
+  void SetMaxTolerance(const Standard_Real theValue)
+  {
+    myMaxTolerance = theValue;
+  }
+
+  //! Returns true if we are using boxes
+  //! in the intersector
+  Standard_Boolean UseBndBox() const
+  {
+    return myUseBndBox;
+  }
+
+  //! Sets the status of whether we are
+  //! using boxes or not
+  void SetUseBndBox(const Standard_Boolean theValue)
+  {
+    myUseBndBox = theValue;
+  }
+
 
 protected:
 
@@ -71,6 +98,8 @@ private:
   TopoDS_Edge myEdge;
   TopoDS_Face myFace;
   TopoDS_Edge myNextEdge;
+  Standard_Real myMaxTolerance;
+  Standard_Boolean myUseBndBox;
 
 };
 
index e5ab500..65cc41f 100644 (file)
@@ -46,33 +46,41 @@ BRepClass_FaceClassifier::BRepClass_FaceClassifier(BRepClass_FaceExplorer& F,
 //function : BRepClass_FaceClassifier
 //purpose  : 
 //=======================================================================
-BRepClass_FaceClassifier::BRepClass_FaceClassifier(const TopoDS_Face& F, 
-                                                  const gp_Pnt& P, 
-                                                  const Standard_Real Tol)
+BRepClass_FaceClassifier::BRepClass_FaceClassifier(const TopoDS_Face& theF, 
+                                                  const gp_Pnt& theP, 
+                                                  const Standard_Real theTol,
+               const Standard_Boolean theUseBndBox,
+               const Standard_Real theGapCheckTol)
 {
-  Perform(F,P,Tol);
+  Perform(theF, theP, theTol, theUseBndBox, theGapCheckTol);
 }
 //=======================================================================
 //function : BRepClass_FaceClassifier
 //purpose  : 
 //=======================================================================
-BRepClass_FaceClassifier::BRepClass_FaceClassifier(const TopoDS_Face& F, 
-                                                  const gp_Pnt2d& P, 
-                                                  const Standard_Real Tol)
+BRepClass_FaceClassifier::BRepClass_FaceClassifier(const TopoDS_Face& theF, 
+                                                  const gp_Pnt2d& theP, 
+                                                  const Standard_Real theTol,
+               const Standard_Boolean theUseBndBox,
+               const Standard_Real theGapCheckTol)
 {
-  Perform(F,P,Tol);
+  Perform(theF, theP, theTol, theUseBndBox, theGapCheckTol);
 }
 
 //=======================================================================
 //function : Perform
 //purpose  : 
 //=======================================================================
-void  BRepClass_FaceClassifier::Perform(const TopoDS_Face& F, 
-                                       const gp_Pnt2d& P, 
-                                       const Standard_Real Tol)
+void  BRepClass_FaceClassifier::Perform(const TopoDS_Face& theF, 
+                                       const gp_Pnt2d& theP, 
+                                       const Standard_Real theTol,
+          const Standard_Boolean theUseBndBox,
+          const Standard_Real theGapCheckTol)
 {
-  BRepClass_FaceExplorer Fex(F);
-  BRepClass_FClassifier::Perform(Fex,P,Tol);
+  BRepClass_FaceExplorer aFex(theF);
+  aFex.SetMaxTolerance(theGapCheckTol);
+  aFex.SetUseBndBox(theUseBndBox);
+  BRepClass_FClassifier::Perform(aFex, theP, theTol);
 }
 
 
@@ -84,9 +92,11 @@ void  BRepClass_FaceClassifier::Perform(const TopoDS_Face& F,
 //function : Perform
 //purpose  : 
 //=======================================================================
-void  BRepClass_FaceClassifier::Perform(const TopoDS_Face& aF, 
-                                       const gp_Pnt& aP, 
-                                       const Standard_Real aTol)
+void  BRepClass_FaceClassifier::Perform(const TopoDS_Face& theF, 
+                                       const gp_Pnt& theP, 
+                                       const Standard_Real theTol,
+          const Standard_Boolean theUseBndBox,
+          const Standard_Real theGapCheckTol)
 {
   Standard_Integer aNbExt, aIndice, i; 
   Standard_Real aU1, aU2, aV1, aV2, aMaxDist, aD;
@@ -96,14 +106,14 @@ void  BRepClass_FaceClassifier::Perform(const TopoDS_Face& aF,
   aMaxDist=RealLast();
   aIndice=0;
   //
-  BRepAdaptor_Surface aSurf(aF, Standard_False);
-  BRepTools::UVBounds(aF, aU1, aU2, aV1, aV2);
-  aExtrema.Initialize(aSurf, aU1, aU2, aV1, aV2, aTol, aTol);
+  BRepAdaptor_Surface aSurf(theF, Standard_False);
+  BRepTools::UVBounds(theF, aU1, aU2, aV1, aV2);
+  aExtrema.Initialize(aSurf, aU1, aU2, aV1, aV2, theTol, theTol);
   //
   //modified by NIZNHY-PKV Wed Aug 13 11:28:47 2008f
   rejected=Standard_True;
   //modified by NIZNHY-PKV Wed Aug 13 11:28:49 2008t
-  aExtrema.Perform(aP);
+  aExtrema.Perform(theP);
   if(!aExtrema.IsDone()) {
     return;
   }
@@ -124,6 +134,6 @@ void  BRepClass_FaceClassifier::Perform(const TopoDS_Face& aF,
   if(aIndice) { 
     aExtrema.Point(aIndice).Parameter(aU1, aU2);
     aPuv.SetCoord(aU1, aU2);
-    Perform(aF, aPuv, aTol);
+    Perform(theF, aPuv, theTol, theUseBndBox, theGapCheckTol);
   }
 }
index 7bce028..e4382fb 100644 (file)
@@ -46,19 +46,31 @@ public:
   
   //! Creates an algorithm to classify the Point  P with
   //! Tolerance <T> on the face <F>.
-  Standard_EXPORT BRepClass_FaceClassifier(const TopoDS_Face& F, const gp_Pnt2d& P, const Standard_Real Tol);
-  
+  //! Recommended to use Bnd_Box if the number of edges > 10
+  //! and the geometry is mostly spline
+  Standard_EXPORT BRepClass_FaceClassifier(const TopoDS_Face& theF, const gp_Pnt2d& theP, const Standard_Real theTol, 
+                   const Standard_Boolean theUseBndBox = Standard_False, const Standard_Real theGapCheckTol = 0.1);
+
   //! Classify  the Point  P  with  Tolerance <T> on the
   //! face described by <F>.
-  Standard_EXPORT void Perform (const TopoDS_Face& F, const gp_Pnt2d& P, const Standard_Real Tol);
+  //! Recommended to use Bnd_Box if the number of edges > 10
+  //! and the geometry is mostly spline
+  Standard_EXPORT void Perform (const TopoDS_Face& theF, const gp_Pnt2d& theP, const Standard_Real theTol, 
+                   const Standard_Boolean theUseBndBox = Standard_False, const Standard_Real theGapCheckTol = 0.1);
   
   //! Creates an algorithm to classify the Point  P with
   //! Tolerance <T> on the face <F>.
-  Standard_EXPORT BRepClass_FaceClassifier(const TopoDS_Face& F, const gp_Pnt& P, const Standard_Real Tol);
+  //! Recommended to use Bnd_Box if the number of edges > 10
+  //! and the geometry is mostly spline
+  Standard_EXPORT BRepClass_FaceClassifier(const TopoDS_Face& theF, const gp_Pnt& theP, const Standard_Real theTol,
+                   const Standard_Boolean theUseBndBox = Standard_False, const Standard_Real theGapCheckTol = 0.1);
   
   //! Classify  the Point  P  with  Tolerance <T> on the
   //! face described by <F>.
-  Standard_EXPORT void Perform (const TopoDS_Face& F, const gp_Pnt& P, const Standard_Real Tol);
+  //! Recommended to use Bnd_Box if the number of edges > 10
+  //! and the geometry is mostly spline
+  Standard_EXPORT void Perform (const TopoDS_Face& theF, const gp_Pnt& theP, const Standard_Real theTol,
+                   const Standard_Boolean theUseBndBox = Standard_False, const Standard_Real theGapCheckTol = 0.1);
 
 
 
index 93ccbd9..88ad99a 100644 (file)
@@ -36,14 +36,17 @@ static const Standard_Real Probing_Step = 0.2111;
 //purpose  : 
 //=======================================================================
 
-BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) :
+BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) : 
        myFace(F),
        myCurEdgeInd(1),
        myCurEdgePar(Probing_Start),
+       myMaxTolerance(0.1),
+       myUseBndBox(Standard_False),
        myUMin (Precision::Infinite()),
        myUMax (-Precision::Infinite()),
        myVMin (Precision::Infinite()),
        myVMax (-Precision::Infinite())
+       
 {
   myFace.Orientation(TopAbs_FORWARD);
 }
@@ -338,5 +341,7 @@ void  BRepClass_FaceExplorer::CurrentEdge(BRepClass_Edge& E,
   E.Face() = myFace;
   Or = E.Edge().Orientation();
   E.SetNextEdge(myMapVE);
+  E.SetMaxTolerance(myMaxTolerance);
+  E.SetUseBndBox(myUseBndBox);
 }
 
index d075136..8866993 100644 (file)
@@ -94,6 +94,33 @@ public:
   //! Current edge in current wire and its orientation.
   Standard_EXPORT void CurrentEdge (BRepClass_Edge& E, TopAbs_Orientation& Or) const;
 
+  //! Returns the maximum tolerance
+  Standard_Real MaxTolerance() const
+  {
+    return myMaxTolerance;
+  }
+
+  //! Sets the maximum tolerance at 
+  //! which to start checking in the intersector
+  void SetMaxTolerance(const Standard_Real theValue)
+  {
+    myMaxTolerance = theValue;
+  }
+
+  //! Returns true if we are using boxes
+  //! in the intersector
+  Standard_Boolean UseBndBox() const
+  {
+    return myUseBndBox;
+  }
+
+  //! Sets the status of whether we are
+  //! using boxes or not
+  void SetUseBndBox(const Standard_Boolean theValue)
+  {
+    myUseBndBox = theValue;
+  }
+
 
 
 
@@ -112,6 +139,8 @@ private:
   TopExp_Explorer myEExplorer;
   Standard_Integer myCurEdgeInd;
   Standard_Real myCurEdgePar;
+  Standard_Real myMaxTolerance;
+  Standard_Boolean myUseBndBox;
   TopTools_IndexedDataMapOfShapeListOfShape myMapVE;
 
   Standard_Real myUMin;
index 8e0cf6d..dae1ef8 100644 (file)
@@ -15,6 +15,8 @@
 // commercial license or contractual agreement.
 
 
+#include <Bnd_Box2d.hxx>
+#include <BndLib_Add2dCurve.hxx>
 #include <BRep_Tool.hxx>
 #include <BRepAdaptor_Curve2d.hxx>
 #include <BRepAdaptor_Surface.hxx>
@@ -53,10 +55,10 @@ static
 Standard_Boolean CheckOn(IntRes2d_IntersectionPoint& thePntInter,
                          const TopoDS_Face& theF,
                          const gp_Lin2d& theL,
-                         Geom2dAdaptor_Curve& theCur,
-                         Standard_Real theTolZ,
-                         Standard_Real theFin,
-                         Standard_Real theDeb);
+                         const Geom2dAdaptor_Curve& theCur,
+                         Standard_Real& theTolZ,
+                         const Standard_Real theFin,
+                         const Standard_Real theDeb);
 
 static
 void CheckSkip(Geom2dInt_GInter& theInter,
@@ -66,22 +68,93 @@ void CheckSkip(Geom2dInt_GInter& theInter,
                const IntRes2d_Domain& theDL,
                Geom2dAdaptor_Curve& theCur,
                const Geom2dAdaptor_Curve& theCGA,
-               Standard_Real theFin,
-               Standard_Real theDeb,
-               Standard_Real theMaxTol,
-               gp_Pnt2d thePdeb,
-               gp_Pnt2d thePfin);
+               Standard_Real& theFin,
+               Standard_Real& theDeb,
+               const Standard_Real theMaxTol,
+               gp_Pnt2d& thePdeb,
+               gp_Pnt2d& thePfin);
 
+static
+Standard_Real MaxTol2DCurEdge(const TopoDS_Vertex& theV1,
+                              const TopoDS_Vertex& theV2,
+                              const TopoDS_Face& theF,
+                              const Standard_Real theTol);
+
+static
+Standard_Boolean IsInter(Bnd_Box2d& theBox,
+                         const gp_Lin2d& theL,
+                         const Standard_Real theP);
 
 //=======================================================================
 //function : BRepClass_Intersector
 //purpose  : 
 //=======================================================================
 
-BRepClass_Intersector::BRepClass_Intersector() : myMaxTolerance(0.1)
+BRepClass_Intersector::BRepClass_Intersector()
 {
 }
 
+//=======================================================================
+//function : MaxTol2DCurEdge
+//purpose  :
+//=======================================================================
+Standard_Real MaxTol2DCurEdge(const TopoDS_Vertex& theV1,
+                              const TopoDS_Vertex& theV2,
+                              const TopoDS_Face& theF,
+                              const Standard_Real theTol)
+{
+  Standard_Real aTolV3D1, aTolV3D2;
+  if (theV1.IsNull())
+  {
+    aTolV3D1 = 0.0;
+  }
+  else
+  {
+    aTolV3D1 = BRep_Tool::Tolerance(theV1);
+  }
+  if (theV2.IsNull())
+  {
+    aTolV3D2 = 0.0;
+  }
+  else
+  {
+    aTolV3D2 = BRep_Tool::Tolerance(theV2);
+  }
+  Standard_Real aTol2D, anUr, aVr;
+  Standard_Real aTolV3D = Max(aTolV3D1, aTolV3D2);
+  BRepAdaptor_Surface aS(theF, Standard_False);
+
+  anUr = aS.UResolution(aTolV3D);
+  aVr = aS.VResolution(aTolV3D);
+  aTol2D = Max(anUr, aVr);
+  //
+  aTol2D = Max(aTol2D, theTol);
+  return aTol2D;
+}
+
+//=======================================================================
+//function : IsInter
+//purpose  :
+//=======================================================================
+Standard_Boolean IsInter(Bnd_Box2d& theBox,
+                         const gp_Lin2d& theL,
+                         const Standard_Real theP)
+{
+  Standard_Boolean aStatusInter = Standard_True;
+  if (Precision::IsInfinite(theP))
+  {
+    aStatusInter = theBox.IsOut(theL);
+  }
+  else
+  {
+    gp_Pnt2d aPntF = theL.Location();
+    gp_Pnt2d aPntL = ElCLib::Value(theP, theL);
+    aStatusInter = theBox.IsOut(aPntF, aPntL);
+  }
+  return !aStatusInter;
+}
+
 //=======================================================================
 //function : CheckOn
 //purpose  :
@@ -89,10 +162,10 @@ BRepClass_Intersector::BRepClass_Intersector() : myMaxTolerance(0.1)
 Standard_Boolean CheckOn(IntRes2d_IntersectionPoint& thePntInter,
                          const TopoDS_Face& theF,
                          const gp_Lin2d& theL,
-                         Geom2dAdaptor_Curve& theCur,
-                         Standard_Real theTolZ,
-                         Standard_Real theFin,
-                         Standard_Real theDeb)
+                         const Geom2dAdaptor_Curve& theCur,
+                         Standard_Real& theTolZ,
+                         const Standard_Real theFin,
+                         const Standard_Real theDeb)
 {
   Extrema_ExtPC2d anExtPC2d(theL.Location(), theCur);
   Standard_Real aMinDist = RealLast();
@@ -153,11 +226,11 @@ void CheckSkip(Geom2dInt_GInter& theInter,
                const IntRes2d_Domain& theDL,
                Geom2dAdaptor_Curve& theCur,
                const Geom2dAdaptor_Curve& theCGA,
-               Standard_Real theFin,
-               Standard_Real theDeb,
-               Standard_Real theMaxTol,
-               gp_Pnt2d thePdeb,
-               gp_Pnt2d thePfin)
+               Standard_Real& theFin,
+               Standard_Real& theDeb,
+               const Standard_Real theMaxTol,
+               gp_Pnt2d& thePdeb,
+               gp_Pnt2d& thePfin)
 {
   if (theE.Edge().IsNull() || theE.Face().IsNull())
   {
@@ -272,10 +345,10 @@ void CheckSkip(Geom2dInt_GInter& theInter,
 //function : Perform
 //purpose  : 
 //=======================================================================
-void  BRepClass_Intersector::Perform(const gp_Lin2d& L, 
-                                     const Standard_Real P, 
-                                     const Standard_Real Tol, 
-                                     const BRepClass_Edge& E)
+void  BRepClass_Intersector::Perform(const gp_Lin2d& L,
+  const Standard_Real P,
+  const Standard_Real Tol,
+  const BRepClass_Edge& E)
 {
   Standard_Real deb = 0.0, fin = 0.0, aTolZ = Tol;
   Handle(Geom2d_Curve) aC2D;
@@ -284,69 +357,92 @@ void  BRepClass_Intersector::Perform(const gp_Lin2d& L,
   const TopoDS_Face& F = E.Face();
 
   //
-  aC2D=BRep_Tool::CurveOnSurface(EE, F, deb, fin);
+  aC2D = BRep_Tool::CurveOnSurface(EE, F, deb, fin);
   if (aC2D.IsNull()) {
     done = Standard_False; // !IsDone()
     return;
   }
   //
-  Geom2dAdaptor_Curve C(aC2D, deb, fin);
+  Bnd_Box2d aBond;
+  gp_Pnt2d aPntF;
+  Standard_Boolean anUseBndBox = E.UseBndBox();
+  if (anUseBndBox)
+  {
+    BndLib_Add2dCurve::Add(aC2D, deb, fin, 0., aBond);
+    aBond.SetGap(aTolZ);
+    aPntF = L.Location();
+  }
   //
-  deb = C.FirstParameter();
-  fin = C.LastParameter();
+  Geom2dAdaptor_Curve C(aC2D, deb, fin);
   //
   // Case of "ON": direct check of belonging to edge
   // taking into account the tolerance
-  Standard_Boolean aStatusOn = Standard_False;
-  IntRes2d_IntersectionPoint aPntInter;
+  if (!anUseBndBox || (anUseBndBox && !aBond.IsOut(aPntF)))
+  {
+    Standard_Boolean aStatusOn = Standard_False;
+    IntRes2d_IntersectionPoint aPntInter;
 
-  aStatusOn = CheckOn(aPntInter, F, L, C, aTolZ, fin, deb);
-  if (aStatusOn)
+    aStatusOn = CheckOn(aPntInter, F, L, C, aTolZ, fin, deb);
+    if (aStatusOn)
+    {
+      Append(aPntInter);
+      done = Standard_True;
+      return;
+    }
+  }
+  // 
+  if (anUseBndBox)
   {
-    Append(aPntInter);
-    done = Standard_True;
-    return;
+    TopoDS_Vertex aVF, aVL;
+    TopExp::Vertices(EE, aVF, aVL);
+
+    aTolZ = MaxTol2DCurEdge(aVF, aVL, F, Tol);
+    aBond.SetGap(aTolZ);
+
+    if (!IsInter(aBond, L, P))
+    {
+      done = Standard_False;
+      return;
+    }
   }
-  
-  //  
-  gp_Pnt2d pdeb,pfin;
-  C.D0(deb,pdeb);
-  C.D0(fin,pfin);
+  gp_Pnt2d pdeb, pfin;
+  C.D0(deb, pdeb);
+  C.D0(fin, pfin);
   Standard_Real toldeb = 1.e-5, tolfin = 1.e-5;
 
   IntRes2d_Domain DL;
   //
-  if(P!=RealLast()) {
-    DL.SetValues(L.Location(),0.,Precision::PConfusion(),ElCLib::Value(P,L),P,Precision::PConfusion());
+  if (P != RealLast()) {
+    DL.SetValues(L.Location(), 0., Precision::PConfusion(), ElCLib::Value(P, L), P, Precision::PConfusion());
   }
-  else { 
-    DL.SetValues(L.Location(),0.,Precision::PConfusion(),Standard_True);
+  else {
+    DL.SetValues(L.Location(), 0., Precision::PConfusion(), Standard_True);
   }
 
-  IntRes2d_Domain DE(pdeb,deb,toldeb,pfin,fin,tolfin);
+  IntRes2d_Domain DE(pdeb, deb, toldeb, pfin, fin, tolfin);
   // temporary periodic domain
   if (C.Curve()->IsPeriodic()) {
     DE.SetEquivalentParameters(C.FirstParameter(),
-      C.FirstParameter() + 
+      C.FirstParameter() +
       C.Curve()->LastParameter() -
       C.Curve()->FirstParameter());
   }
 
-  Handle(Geom2d_Line) GL= new Geom2d_Line(L);
+  Handle(Geom2d_Line) GL = new Geom2d_Line(L);
   Geom2dAdaptor_Curve CGA(GL);
-  Geom2dInt_GInter Inter(CGA,DL,C,DE,
+  Geom2dInt_GInter Inter(CGA, DL, C, DE,
     Precision::PConfusion(),
     Precision::PIntersection());
   //
   // The check is for hitting the intersector to
   // a vertex with high tolerance
-  if (Inter.IsEmpty()) 
+  if (Inter.IsEmpty())
   {
-    CheckSkip(Inter, L, E, aC2D, DL, 
-      C, CGA, fin, deb, MaxTolerance(), pdeb, pfin);
+    CheckSkip(Inter, L, E, aC2D, DL,
+      C, CGA, fin, deb, E.MaxTolerance(), pdeb, pfin);
   }
 
- // 
 // 
   SetValues(Inter);
 }
 
index 279b34c..05acbc2 100644 (file)
@@ -47,19 +47,6 @@ public:
   //! <U>.
   Standard_EXPORT void LocalGeometry (const BRepClass_Edge& E, const Standard_Real U, gp_Dir2d& T, gp_Dir2d& N, Standard_Real& C) const;
 
-  //! Returns the maximum tolerance
-  Standard_Real MaxTolerance()
-  {
-    return myMaxTolerance;
-  }
-
-  //! Sets the maximum tolerance at 
-  //! which to start checking in the intersector
-  void SetMaxTolerance(const Standard_Real theValue)
-  {
-    myMaxTolerance = theValue;
-  }
-
 
 
 protected:
@@ -71,7 +58,6 @@ protected:
 private:
 
 
-  Standard_Real myMaxTolerance;
 
 
 };
index 3b0aa63..07a45b6 100644 (file)
@@ -129,7 +129,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
     {
       T.SetCoord ( y, -x);
     }
-    Standard_Real ParamInit = RealLast();
+    Standard_Real ParamInit = Precision::Infinite();
     Standard_Real TolInit   = 0.00001;
     Standard_Boolean APointExist = Standard_False;
 
index f082dbc..de882d9 100644 (file)
@@ -18,7 +18,6 @@
 #include <Bnd_Box2d.hxx>
 #include <gp.hxx>
 #include <gp_Dir2d.hxx>
-#include <gp_Pnt2d.hxx>
 #include <gp_Trsf2d.hxx>
 #include <Standard_ConstructionError.hxx>
 #include <Standard_Stream.hxx>
@@ -251,6 +250,80 @@ Standard_Boolean Bnd_Box2d::IsOut (const gp_Pnt2d& P) const
   }
 }
 
+//=======================================================================
+//function : IsOut
+//purpose  :
+//=======================================================================
+
+Standard_Boolean Bnd_Box2d::IsOut(const gp_Lin2d& theL) const
+{
+  if (IsWhole())
+  {
+    return Standard_False;
+  }
+  if (IsVoid())
+  {
+    return Standard_True;
+  }
+  Standard_Real aXMin, aXMax, aYMin, aYMax;
+  Get(aXMin, aYMin, aXMax, aYMax);
+
+  gp_XY aCenter((aXMin + aXMax) / 2, (aYMin + aYMax) / 2);
+  gp_XY aHeigh(Abs(aXMax - aCenter.X()), Abs(aYMax - aCenter.Y()));
+
+  const Standard_Real aProd[3] = {
+    theL.Direction().XY() ^ (aCenter - theL.Location().XY()),
+    theL.Direction().X() * aHeigh.Y(),
+    theL.Direction().Y() * aHeigh.X()
+  };
+  Standard_Boolean aStatus = (Abs(aProd[0]) > (Abs(aProd[1]) + Abs(aProd[2])));
+  return aStatus;
+}
+
+//=======================================================================
+//function : IsOut
+//purpose  :
+//=======================================================================
+
+Standard_Boolean Bnd_Box2d::IsOut(const gp_Pnt2d& theP0, const gp_Pnt2d& theP1) const
+{
+  if (IsWhole())
+  {
+    return Standard_False;
+  }
+  if (IsVoid())
+  {
+    return Standard_True;
+  }
+  
+  Standard_Boolean aStatus = Standard_True;
+  Standard_Real aLocXMin, aLocXMax, aLocYMin, aLocYMax;
+  Get(aLocXMin, aLocYMin, aLocXMax, aLocYMax);
+
+  //// Intersect the line containing the segment.
+  const gp_XY aSegDelta(theP1.XY() - theP0.XY());
+
+  gp_XY aCenter((aLocXMin + aLocXMax) / 2, (aLocYMin + aLocYMax) / 2);
+  gp_XY aHeigh(Abs(aLocXMax - aCenter.X()), Abs(aLocYMax - aCenter.Y()));
+
+  const Standard_Real aProd[3] = {
+    aSegDelta ^ (aCenter - theP0.XY()),
+    aSegDelta.X() * aHeigh.Y(),
+    aSegDelta.Y() * aHeigh.X()
+  };
+
+  if((Abs(aProd[0]) <= (Abs(aProd[1]) + Abs(aProd[2]))))
+  {
+    // Intersection with line detected; check the segment as bounding box
+    const gp_XY aHSeg(0.5 * aSegDelta.X(), 0.5 * aSegDelta.Y());
+    const gp_XY aHSegAbs(Abs(aHSeg.X()), Abs(aHSeg.Y()));
+    aStatus = ((Abs((theP0.XY() + aHSeg - aCenter).X()) >
+      (aHeigh + aHSegAbs).X()) || (Abs((theP0.XY() + aHSeg - aCenter).Y()) >
+      (aHeigh + aHSegAbs).Y()));
+  }
+  return aStatus;
+}
+
 //=======================================================================
 //function : IsOut
 //purpose  : 
index 3e1ae44..02dd79d 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef _Bnd_Box2d_HeaderFile
 #define _Bnd_Box2d_HeaderFile
 
+#include <gp_Lin2d.hxx>
 #include <gp_Pnt2d.hxx>
 #include <Standard.hxx>
 #include <Standard_DefineAlloc.hxx>
@@ -182,7 +183,13 @@ public:
   
   //! Returns True if the 2d pnt <P> is out <me>.
   Standard_EXPORT Standard_Boolean IsOut (const gp_Pnt2d& P) const;
+
+  //! Returns True if the line doesn't intersect the box.
+  Standard_EXPORT Standard_Boolean IsOut(const gp_Lin2d& theL) const;
   
+  //! Returns True if the segment doesn't intersect the box.
+  Standard_EXPORT Standard_Boolean IsOut(const gp_Pnt2d& theP0, const gp_Pnt2d& theP1) const;
+
   //! Returns True if <Box2d> is out <me>.
   Standard_EXPORT Standard_Boolean IsOut (const Bnd_Box2d& Other) const;
   
index 67da0fa..d7098ec 100644 (file)
@@ -2069,6 +2069,123 @@ static Standard_Integer OCC27875(Draw_Interpretor& theDI,
   return 0;
 }
 
+#include <BRepClass_FaceClassifier.hxx>
+static Standard_Integer OCC27884(Draw_Interpretor& theDI,
+  Standard_Integer  theArgNb,
+  const char**      theArgVec)
+{
+  if (theArgNb != 4) {
+    return 0;
+  }
+  Standard_Real aCheck = Draw::Atof(theArgVec[3]);
+  Handle(Geom_Curve) aCur = DrawTrSurf::GetCurve(theArgVec[1]);
+
+  const Handle(Standard_Type)& aType = aCur->DynamicType();
+
+  Standard_Real aF = aCur->FirstParameter();
+  Standard_Real aL = aCur->LastParameter();
+
+  Standard_Real number_points = Draw::Atof(theArgVec[2]);
+  Standard_Real aSig = (aL - aF) / (number_points - 1);
+
+  TopTools_ListOfShape aLE;
+
+  gp_Pnt aP, aPF, aPL;
+  aPF = aCur->Value(aF);
+  aP = aPF;
+
+  for (Standard_Integer i = 1; i < number_points; i++)
+  {
+    TopoDS_Edge anE;
+    aL = aF + (i * aSig);
+    aPL = aCur->Value(aL);
+    if (aCheck == 2)
+    {
+      if (i % 2 == 1)
+      {
+        anE = BRepBuilderAPI_MakeEdge(aPF, aPL);
+      }
+      else
+      {
+        if (aType == STANDARD_TYPE(Geom_BSplineCurve))
+        {
+          Handle(Geom_BSplineCurve) aCurCopy = Handle(Geom_BSplineCurve)::DownCast(aCur->Copy());
+          aCurCopy->Segment(aL - aSig, aL);
+          anE = BRepBuilderAPI_MakeEdge(aCurCopy);
+        }
+        else
+        {
+          Handle(Geom_TrimmedCurve) aTCur = new Geom_TrimmedCurve(aCur, aL - aSig, aL);
+          anE = BRepBuilderAPI_MakeEdge(aTCur);
+        }
+      }
+      aPF = aPL;
+    }
+    else
+    {
+      if (aCheck == 0)
+      {
+        anE = BRepBuilderAPI_MakeEdge(aPF, aPL);
+        aPF = aPL;
+      }
+      if (aCheck == 1)
+      {
+        if (aType == STANDARD_TYPE(Geom_BSplineCurve))
+        {
+          Handle(Geom_BSplineCurve) aCurCopy = Handle(Geom_BSplineCurve)::DownCast(aCur->Copy());
+          aCurCopy->Segment(aL - aSig, aL);
+          anE = BRepBuilderAPI_MakeEdge(aCurCopy);
+        }
+        else
+        {
+          Handle(Geom_TrimmedCurve) aTCur = new Geom_TrimmedCurve(aCur, aL - aSig, aL);
+          anE = BRepBuilderAPI_MakeEdge(aTCur);
+        }
+      }
+    }
+    aLE.Append(anE);
+  }
+  if (!aCur->IsClosed())
+  {
+    TopoDS_Edge anE = BRepBuilderAPI_MakeEdge(aPL, aP);
+    aLE.Append(anE);
+  }
+
+  BRepBuilderAPI_MakeWire aWire;
+  aWire.Add(aLE);
+  TopoDS_Face aFace = BRepBuilderAPI_MakeFace(aWire.Wire());
+  
+  //
+  
+  Standard_Real anUMin, anUMax, aVMin, aVMax;
+  BRepTools::UVBounds(aFace, anUMin, anUMax, aVMin, aVMax);
+  gp_Pnt2d aP2d(anUMin - ((anUMax + anUMin) / 2), aVMin - ((aVMax + aVMin) / 2));
+  
+  const Standard_Real aTol = BRep_Tool::Tolerance(aFace);
+
+  BRepClass_FaceClassifier aClassifier;
+
+  OSD_Timer timer;
+  timer.Start();
+  for (Standard_Integer i = 1; i <= 100; i++)
+  {
+    aClassifier.Perform(aFace, aP2d, aTol, Standard_True);
+  }
+  timer.Stop();
+  Standard_Real aTimer1 = timer.UserTimeCPU();
+  timer.Reset();
+  timer.Start();
+  for (Standard_Integer i = 1; i <= 100; i++)
+  {
+    aClassifier.Perform(aFace, aP2d, aTol, Standard_False);
+  }
+  timer.Stop();
+  Standard_Real aTimer2 = timer.UserTimeCPU();
+  theDI << "Improving time: " << (aTimer2 - aTimer1) / aTimer2 * 100 << " %\n";
+
+  return 0;
+}
+
 
 #include <TDF_Tool.hxx>
 #include <XCAFDoc_View.hxx>
@@ -3901,6 +4018,7 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
   theCommands.Add("OCC26270", "OCC26270 shape result", __FILE__, OCC26270, group);
   theCommands.Add ("OCC27552", "OCC27552", __FILE__, OCC27552, group); 
   theCommands.Add("OCC27875", "OCC27875 curve", __FILE__, OCC27875, group);
+  theCommands.Add("OCC27884", "OCC27884: Possible improvement for 2d classifier", __FILE__, OCC27884, group);
   theCommands.Add("OCC28389", "OCC28389", __FILE__, OCC28389, group);
   theCommands.Add("OCC28594", "OCC28594", __FILE__, OCC28594, group);
   theCommands.Add("OCC28784", "OCC28784 result shape", __FILE__, OCC28784, group);
diff --git a/tests/bugs/modalg_6/bug27884 b/tests/bugs/modalg_6/bug27884
new file mode 100644 (file)
index 0000000..0127894
--- /dev/null
@@ -0,0 +1,42 @@
+puts "================================================================="
+puts "OCC27884: Modeling Algorithms - Possible improvement for 2d classifier"
+puts "================================================================="
+puts ""
+
+pload ALL
+pload QAcommands
+
+circle c 1 0 0 150
+
+set res1 [OCC27884 c 400 0]
+regexp {Improving time: +([-0-9.+eE]+) %} $res1 full time1
+
+if { $time1 <= 5 } {
+  puts "Error: algorithm slowed down"
+}
+
+
+set res2 [OCC27884 c 250 1]
+regexp {Improving time: +([-0-9.+eE]+) %} $res2 full time2
+
+if { $time2 <= 5 } {
+  puts "Error: algorithm slowed down"
+}
+
+
+convert c1 c
+
+set res3 [OCC27884 c1 350 2]
+regexp {Improving time: +([-0-9.+eE]+) %} $res3 full time3
+
+if { $time3 <= 15 } {
+  puts "Error: algorithm slowed down"
+}
+
+
+set res4 [OCC27884 c1 250 1]
+regexp {Improving time: +([-0-9.+eE]+) %} $res4 full time4
+
+if { $time4 <= 15 } {
+  puts "Error: algorithm slowed down"
+}