diff --git a/src/BOPTest/BOPTest_LowCommands.cxx b/src/BOPTest/BOPTest_LowCommands.cxx index b863f411d1..4f032f001f 100644 --- a/src/BOPTest/BOPTest_LowCommands.cxx +++ b/src/BOPTest/BOPTest_LowCommands.cxx @@ -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; diff --git a/src/BRepClass/BRepClass_Edge.cxx b/src/BRepClass/BRepClass_Edge.cxx index 0774105f1e..102fb6dcc5 100644 --- a/src/BRepClass/BRepClass_Edge.cxx +++ b/src/BRepClass/BRepClass_Edge.cxx @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -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) { } diff --git a/src/BRepClass/BRepClass_Edge.hxx b/src/BRepClass/BRepClass_Edge.hxx index fe742f363c..a9e5b25643 100644 --- a/src/BRepClass/BRepClass_Edge.hxx +++ b/src/BRepClass/BRepClass_Edge.hxx @@ -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; }; diff --git a/src/BRepClass/BRepClass_FaceClassifier.cxx b/src/BRepClass/BRepClass_FaceClassifier.cxx index e5ab5006f4..65cc41fc0c 100644 --- a/src/BRepClass/BRepClass_FaceClassifier.cxx +++ b/src/BRepClass/BRepClass_FaceClassifier.cxx @@ -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); } } diff --git a/src/BRepClass/BRepClass_FaceClassifier.hxx b/src/BRepClass/BRepClass_FaceClassifier.hxx index 7bce0288a3..e4382fb6e2 100644 --- a/src/BRepClass/BRepClass_FaceClassifier.hxx +++ b/src/BRepClass/BRepClass_FaceClassifier.hxx @@ -46,19 +46,31 @@ public: //! Creates an algorithm to classify the Point P with //! Tolerance on the face . - 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 on the //! face described by . - 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 on the face . - 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 on the //! face described by . - 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); diff --git a/src/BRepClass/BRepClass_FaceExplorer.cxx b/src/BRepClass/BRepClass_FaceExplorer.cxx index 93ccbd95ad..88ad99afb8 100644 --- a/src/BRepClass/BRepClass_FaceExplorer.cxx +++ b/src/BRepClass/BRepClass_FaceExplorer.cxx @@ -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); } diff --git a/src/BRepClass/BRepClass_FaceExplorer.hxx b/src/BRepClass/BRepClass_FaceExplorer.hxx index d075136069..8866993bc2 100644 --- a/src/BRepClass/BRepClass_FaceExplorer.hxx +++ b/src/BRepClass/BRepClass_FaceExplorer.hxx @@ -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; diff --git a/src/BRepClass/BRepClass_Intersector.cxx b/src/BRepClass/BRepClass_Intersector.cxx index 8e0cf6d81c..dae1ef8b12 100644 --- a/src/BRepClass/BRepClass_Intersector.cxx +++ b/src/BRepClass/BRepClass_Intersector.cxx @@ -15,6 +15,8 @@ // commercial license or contractual agreement. +#include +#include #include #include #include @@ -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; - - aStatusOn = CheckOn(aPntInter, F, L, C, aTolZ, fin, deb); - if (aStatusOn) + if (!anUseBndBox || (anUseBndBox && !aBond.IsOut(aPntF))) { - Append(aPntInter); - done = Standard_True; - return; + Standard_Boolean aStatusOn = Standard_False; + IntRes2d_IntersectionPoint aPntInter; + + aStatusOn = CheckOn(aPntInter, F, L, C, aTolZ, fin, deb); + if (aStatusOn) + { + Append(aPntInter); + done = Standard_True; + return; + } } - - // - gp_Pnt2d pdeb,pfin; - C.D0(deb,pdeb); - C.D0(fin,pfin); + // + if (anUseBndBox) + { + 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); 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); } diff --git a/src/BRepClass/BRepClass_Intersector.hxx b/src/BRepClass/BRepClass_Intersector.hxx index 279b34c97a..05acbc2e63 100644 --- a/src/BRepClass/BRepClass_Intersector.hxx +++ b/src/BRepClass/BRepClass_Intersector.hxx @@ -47,19 +47,6 @@ public: //! . 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; }; diff --git a/src/BRepClass3d/BRepClass3d_SolidExplorer.cxx b/src/BRepClass3d/BRepClass3d_SolidExplorer.cxx index 3b0aa638f5..07a45b616d 100644 --- a/src/BRepClass3d/BRepClass3d_SolidExplorer.cxx +++ b/src/BRepClass3d/BRepClass3d_SolidExplorer.cxx @@ -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; diff --git a/src/Bnd/Bnd_Box2d.cxx b/src/Bnd/Bnd_Box2d.cxx index f082dbc494..de882d94bb 100644 --- a/src/Bnd/Bnd_Box2d.cxx +++ b/src/Bnd/Bnd_Box2d.cxx @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -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 : diff --git a/src/Bnd/Bnd_Box2d.hxx b/src/Bnd/Bnd_Box2d.hxx index 3e1ae44a5e..02dd79dc09 100644 --- a/src/Bnd/Bnd_Box2d.hxx +++ b/src/Bnd/Bnd_Box2d.hxx @@ -17,6 +17,7 @@ #ifndef _Bnd_Box2d_HeaderFile #define _Bnd_Box2d_HeaderFile +#include #include #include #include @@ -182,7 +183,13 @@ public: //! Returns True if the 2d pnt

is out . 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 is out . Standard_EXPORT Standard_Boolean IsOut (const Bnd_Box2d& Other) const; diff --git a/src/QABugs/QABugs_20.cxx b/src/QABugs/QABugs_20.cxx index 67da0fa80f..d7098ec4bf 100644 --- a/src/QABugs/QABugs_20.cxx +++ b/src/QABugs/QABugs_20.cxx @@ -2069,6 +2069,123 @@ static Standard_Integer OCC27875(Draw_Interpretor& theDI, return 0; } +#include +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 #include @@ -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 index 0000000000..0127894c05 --- /dev/null +++ b/tests/bugs/modalg_6/bug27884 @@ -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" +}