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
const char** theArgVec)
{
if (theArgNb < 3) {
- theDI << " use b2dclassify Face Point2d [Tol]\n";
+ theDI << " use b2dclassify Face Point2d [Tol] [UseBox] [GapCheckTol]\n";
return 1;
}
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;
#include <BRepClass_Edge.hxx>
#include <NCollection_IndexedDataMap.hxx>
+#include <Precision.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopExp.hxx>
//function : BRepClass_Edge
//purpose :
//=======================================================================
-BRepClass_Edge::BRepClass_Edge()
+BRepClass_Edge::BRepClass_Edge() : myMaxTolerance(Precision::Infinite()), myUseBndBox(Standard_False)
{
}
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())
{
BRepClass_Edge::BRepClass_Edge(const TopoDS_Edge& E,
const TopoDS_Face& F) :
myEdge(E),
- myFace(F)
+ myFace(F),
+ myMaxTolerance(Precision::Infinite()),
+ myUseBndBox(Standard_False)
{
}
//! 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:
TopoDS_Edge myEdge;
TopoDS_Face myFace;
TopoDS_Edge myNextEdge;
+ Standard_Real myMaxTolerance;
+ Standard_Boolean myUseBndBox;
};
//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);
}
//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;
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;
}
if(aIndice) {
aExtrema.Point(aIndice).Parameter(aU1, aU2);
aPuv.SetCoord(aU1, aU2);
- Perform(aF, aPuv, aTol);
+ Perform(theF, aPuv, theTol, theUseBndBox, theGapCheckTol);
}
}
//! 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);
//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);
}
E.Face() = myFace;
Or = E.Edge().Orientation();
E.SetNextEdge(myMapVE);
+ E.SetMaxTolerance(myMaxTolerance);
+ E.SetUseBndBox(myUseBndBox);
}
//! 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;
+ }
+
TopExp_Explorer myEExplorer;
Standard_Integer myCurEdgeInd;
Standard_Real myCurEdgePar;
+ Standard_Real myMaxTolerance;
+ Standard_Boolean myUseBndBox;
TopTools_IndexedDataMapOfShapeListOfShape myMapVE;
Standard_Real myUMin;
// 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>
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,
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 :
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();
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())
{
//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;
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);
}
//! <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:
private:
- Standard_Real myMaxTolerance;
};
{
T.SetCoord ( y, -x);
}
- Standard_Real ParamInit = RealLast();
+ Standard_Real ParamInit = Precision::Infinite();
Standard_Real TolInit = 0.00001;
Standard_Boolean APointExist = Standard_False;
#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>
}
}
+//=======================================================================
+//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 :
#ifndef _Bnd_Box2d_HeaderFile
#define _Bnd_Box2d_HeaderFile
+#include <gp_Lin2d.hxx>
#include <gp_Pnt2d.hxx>
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
//! 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;
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>
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);
--- /dev/null
+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"
+}