1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0027884: Modeling Algorithms - Possible improvement for 2d classifier

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
This commit is contained in:
abulyche 2021-07-14 23:40:32 +03:00 committed by bugmaster
parent fceeb82917
commit 715fcb5a92
14 changed files with 513 additions and 101 deletions

View File

@ -124,7 +124,7 @@ Standard_Integer b2dclassify (Draw_Interpretor& theDI,
const char** theArgVec) const char** theArgVec)
{ {
if (theArgNb < 3) { if (theArgNb < 3) {
theDI << " use b2dclassify Face Point2d [Tol]\n"; theDI << " use b2dclassify Face Point2d [Tol] [UseBox] [GapCheckTol]\n";
return 1; return 1;
} }
@ -144,9 +144,11 @@ Standard_Integer b2dclassify (Draw_Interpretor& theDI,
const TopoDS_Face& aF = TopoDS::Face(aS); const TopoDS_Face& aF = TopoDS::Face(aS);
const Standard_Real aTol = (theArgNb == 4) ? const Standard_Real aTol = (theArgNb == 4) ?
Draw::Atof (theArgVec[3]) : BRep_Tool::Tolerance (aF); 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; BRepClass_FaceClassifier aClassifier;
aClassifier.Perform(aF, aP, aTol); aClassifier.Perform(aF, aP, aTol, anUseBox, aGapCheckTol);
PrintState (theDI, aClassifier.State()); PrintState (theDI, aClassifier.State());
// //
return 0; return 0;

View File

@ -17,6 +17,7 @@
#include <BRepClass_Edge.hxx> #include <BRepClass_Edge.hxx>
#include <NCollection_IndexedDataMap.hxx> #include <NCollection_IndexedDataMap.hxx>
#include <Precision.hxx>
#include <TopoDS.hxx> #include <TopoDS.hxx>
#include <TopoDS_Vertex.hxx> #include <TopoDS_Vertex.hxx>
#include <TopExp.hxx> #include <TopExp.hxx>
@ -25,7 +26,7 @@
//function : BRepClass_Edge //function : BRepClass_Edge
//purpose : //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; return;
} }
const TopTools_ListOfShape* aListE = theMapVE.Seek(aVL); const TopTools_ListOfShape* aListE = theMapVE.Seek(aVL);
if ((*aListE).Extent() == 2) if (aListE->Extent() == 2)
{ {
for (TopTools_ListIteratorOfListOfShape anIt(*aListE); anIt.More(); anIt.Next()) 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, BRepClass_Edge::BRepClass_Edge(const TopoDS_Edge& E,
const TopoDS_Face& F) : const TopoDS_Face& F) :
myEdge(E), myEdge(E),
myFace(F) myFace(F),
myMaxTolerance(Precision::Infinite()),
myUseBndBox(Standard_False)
{ {
} }

View File

@ -57,6 +57,33 @@ const TopoDS_Face& Face() const;
//! Finds and sets the next Edge for the current //! Finds and sets the next Edge for the current
Standard_EXPORT void SetNextEdge(const TopTools_IndexedDataMapOfShapeListOfShape& theMapVE); 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: protected:
@ -71,6 +98,8 @@ private:
TopoDS_Edge myEdge; TopoDS_Edge myEdge;
TopoDS_Face myFace; TopoDS_Face myFace;
TopoDS_Edge myNextEdge; TopoDS_Edge myNextEdge;
Standard_Real myMaxTolerance;
Standard_Boolean myUseBndBox;
}; };

View File

@ -46,33 +46,41 @@ BRepClass_FaceClassifier::BRepClass_FaceClassifier(BRepClass_FaceExplorer& F,
//function : BRepClass_FaceClassifier //function : BRepClass_FaceClassifier
//purpose : //purpose :
//======================================================================= //=======================================================================
BRepClass_FaceClassifier::BRepClass_FaceClassifier(const TopoDS_Face& F, BRepClass_FaceClassifier::BRepClass_FaceClassifier(const TopoDS_Face& theF,
const gp_Pnt& P, const gp_Pnt& theP,
const Standard_Real Tol) 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 //function : BRepClass_FaceClassifier
//purpose : //purpose :
//======================================================================= //=======================================================================
BRepClass_FaceClassifier::BRepClass_FaceClassifier(const TopoDS_Face& F, BRepClass_FaceClassifier::BRepClass_FaceClassifier(const TopoDS_Face& theF,
const gp_Pnt2d& P, const gp_Pnt2d& theP,
const Standard_Real Tol) const Standard_Real theTol,
const Standard_Boolean theUseBndBox,
const Standard_Real theGapCheckTol)
{ {
Perform(F,P,Tol); Perform(theF, theP, theTol, theUseBndBox, theGapCheckTol);
} }
//======================================================================= //=======================================================================
//function : Perform //function : Perform
//purpose : //purpose :
//======================================================================= //=======================================================================
void BRepClass_FaceClassifier::Perform(const TopoDS_Face& F, void BRepClass_FaceClassifier::Perform(const TopoDS_Face& theF,
const gp_Pnt2d& P, const gp_Pnt2d& theP,
const Standard_Real Tol) const Standard_Real theTol,
const Standard_Boolean theUseBndBox,
const Standard_Real theGapCheckTol)
{ {
BRepClass_FaceExplorer Fex(F); BRepClass_FaceExplorer aFex(theF);
BRepClass_FClassifier::Perform(Fex,P,Tol); 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 //function : Perform
//purpose : //purpose :
//======================================================================= //=======================================================================
void BRepClass_FaceClassifier::Perform(const TopoDS_Face& aF, void BRepClass_FaceClassifier::Perform(const TopoDS_Face& theF,
const gp_Pnt& aP, const gp_Pnt& theP,
const Standard_Real aTol) const Standard_Real theTol,
const Standard_Boolean theUseBndBox,
const Standard_Real theGapCheckTol)
{ {
Standard_Integer aNbExt, aIndice, i; Standard_Integer aNbExt, aIndice, i;
Standard_Real aU1, aU2, aV1, aV2, aMaxDist, aD; Standard_Real aU1, aU2, aV1, aV2, aMaxDist, aD;
@ -96,14 +106,14 @@ void BRepClass_FaceClassifier::Perform(const TopoDS_Face& aF,
aMaxDist=RealLast(); aMaxDist=RealLast();
aIndice=0; aIndice=0;
// //
BRepAdaptor_Surface aSurf(aF, Standard_False); BRepAdaptor_Surface aSurf(theF, Standard_False);
BRepTools::UVBounds(aF, aU1, aU2, aV1, aV2); BRepTools::UVBounds(theF, aU1, aU2, aV1, aV2);
aExtrema.Initialize(aSurf, aU1, aU2, aV1, aV2, aTol, aTol); aExtrema.Initialize(aSurf, aU1, aU2, aV1, aV2, theTol, theTol);
// //
//modified by NIZNHY-PKV Wed Aug 13 11:28:47 2008f //modified by NIZNHY-PKV Wed Aug 13 11:28:47 2008f
rejected=Standard_True; rejected=Standard_True;
//modified by NIZNHY-PKV Wed Aug 13 11:28:49 2008t //modified by NIZNHY-PKV Wed Aug 13 11:28:49 2008t
aExtrema.Perform(aP); aExtrema.Perform(theP);
if(!aExtrema.IsDone()) { if(!aExtrema.IsDone()) {
return; return;
} }
@ -124,6 +134,6 @@ void BRepClass_FaceClassifier::Perform(const TopoDS_Face& aF,
if(aIndice) { if(aIndice) {
aExtrema.Point(aIndice).Parameter(aU1, aU2); aExtrema.Point(aIndice).Parameter(aU1, aU2);
aPuv.SetCoord(aU1, aU2); aPuv.SetCoord(aU1, aU2);
Perform(aF, aPuv, aTol); Perform(theF, aPuv, theTol, theUseBndBox, theGapCheckTol);
} }
} }

View File

@ -46,19 +46,31 @@ public:
//! Creates an algorithm to classify the Point P with //! Creates an algorithm to classify the Point P with
//! Tolerance <T> on the face <F>. //! 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 //! Classify the Point P with Tolerance <T> on the
//! face described by <F>. //! 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 //! Creates an algorithm to classify the Point P with
//! Tolerance <T> on the face <F>. //! 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 //! Classify the Point P with Tolerance <T> on the
//! face described by <F>. //! 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);

View File

@ -36,14 +36,17 @@ static const Standard_Real Probing_Step = 0.2111;
//purpose : //purpose :
//======================================================================= //=======================================================================
BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) : BRepClass_FaceExplorer::BRepClass_FaceExplorer(const TopoDS_Face& F) :
myFace(F), myFace(F),
myCurEdgeInd(1), myCurEdgeInd(1),
myCurEdgePar(Probing_Start), myCurEdgePar(Probing_Start),
myMaxTolerance(0.1),
myUseBndBox(Standard_False),
myUMin (Precision::Infinite()), myUMin (Precision::Infinite()),
myUMax (-Precision::Infinite()), myUMax (-Precision::Infinite()),
myVMin (Precision::Infinite()), myVMin (Precision::Infinite()),
myVMax (-Precision::Infinite()) myVMax (-Precision::Infinite())
{ {
myFace.Orientation(TopAbs_FORWARD); myFace.Orientation(TopAbs_FORWARD);
} }
@ -338,5 +341,7 @@ void BRepClass_FaceExplorer::CurrentEdge(BRepClass_Edge& E,
E.Face() = myFace; E.Face() = myFace;
Or = E.Edge().Orientation(); Or = E.Edge().Orientation();
E.SetNextEdge(myMapVE); E.SetNextEdge(myMapVE);
E.SetMaxTolerance(myMaxTolerance);
E.SetUseBndBox(myUseBndBox);
} }

View File

@ -94,6 +94,33 @@ public:
//! Current edge in current wire and its orientation. //! Current edge in current wire and its orientation.
Standard_EXPORT void CurrentEdge (BRepClass_Edge& E, TopAbs_Orientation& Or) const; 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; TopExp_Explorer myEExplorer;
Standard_Integer myCurEdgeInd; Standard_Integer myCurEdgeInd;
Standard_Real myCurEdgePar; Standard_Real myCurEdgePar;
Standard_Real myMaxTolerance;
Standard_Boolean myUseBndBox;
TopTools_IndexedDataMapOfShapeListOfShape myMapVE; TopTools_IndexedDataMapOfShapeListOfShape myMapVE;
Standard_Real myUMin; Standard_Real myUMin;

View File

@ -15,6 +15,8 @@
// commercial license or contractual agreement. // commercial license or contractual agreement.
#include <Bnd_Box2d.hxx>
#include <BndLib_Add2dCurve.hxx>
#include <BRep_Tool.hxx> #include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve2d.hxx> #include <BRepAdaptor_Curve2d.hxx>
#include <BRepAdaptor_Surface.hxx> #include <BRepAdaptor_Surface.hxx>
@ -53,10 +55,10 @@ static
Standard_Boolean CheckOn(IntRes2d_IntersectionPoint& thePntInter, Standard_Boolean CheckOn(IntRes2d_IntersectionPoint& thePntInter,
const TopoDS_Face& theF, const TopoDS_Face& theF,
const gp_Lin2d& theL, const gp_Lin2d& theL,
Geom2dAdaptor_Curve& theCur, const Geom2dAdaptor_Curve& theCur,
Standard_Real theTolZ, Standard_Real& theTolZ,
Standard_Real theFin, const Standard_Real theFin,
Standard_Real theDeb); const Standard_Real theDeb);
static static
void CheckSkip(Geom2dInt_GInter& theInter, void CheckSkip(Geom2dInt_GInter& theInter,
@ -66,22 +68,93 @@ void CheckSkip(Geom2dInt_GInter& theInter,
const IntRes2d_Domain& theDL, const IntRes2d_Domain& theDL,
Geom2dAdaptor_Curve& theCur, Geom2dAdaptor_Curve& theCur,
const Geom2dAdaptor_Curve& theCGA, const Geom2dAdaptor_Curve& theCGA,
Standard_Real theFin, Standard_Real& theFin,
Standard_Real theDeb, Standard_Real& theDeb,
Standard_Real theMaxTol, const Standard_Real theMaxTol,
gp_Pnt2d thePdeb, gp_Pnt2d& thePdeb,
gp_Pnt2d thePfin); 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 //function : BRepClass_Intersector
//purpose : //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 //function : CheckOn
//purpose : //purpose :
@ -89,10 +162,10 @@ BRepClass_Intersector::BRepClass_Intersector() : myMaxTolerance(0.1)
Standard_Boolean CheckOn(IntRes2d_IntersectionPoint& thePntInter, Standard_Boolean CheckOn(IntRes2d_IntersectionPoint& thePntInter,
const TopoDS_Face& theF, const TopoDS_Face& theF,
const gp_Lin2d& theL, const gp_Lin2d& theL,
Geom2dAdaptor_Curve& theCur, const Geom2dAdaptor_Curve& theCur,
Standard_Real theTolZ, Standard_Real& theTolZ,
Standard_Real theFin, const Standard_Real theFin,
Standard_Real theDeb) const Standard_Real theDeb)
{ {
Extrema_ExtPC2d anExtPC2d(theL.Location(), theCur); Extrema_ExtPC2d anExtPC2d(theL.Location(), theCur);
Standard_Real aMinDist = RealLast(); Standard_Real aMinDist = RealLast();
@ -153,11 +226,11 @@ void CheckSkip(Geom2dInt_GInter& theInter,
const IntRes2d_Domain& theDL, const IntRes2d_Domain& theDL,
Geom2dAdaptor_Curve& theCur, Geom2dAdaptor_Curve& theCur,
const Geom2dAdaptor_Curve& theCGA, const Geom2dAdaptor_Curve& theCGA,
Standard_Real theFin, Standard_Real& theFin,
Standard_Real theDeb, Standard_Real& theDeb,
Standard_Real theMaxTol, const Standard_Real theMaxTol,
gp_Pnt2d thePdeb, gp_Pnt2d& thePdeb,
gp_Pnt2d thePfin) gp_Pnt2d& thePfin)
{ {
if (theE.Edge().IsNull() || theE.Face().IsNull()) if (theE.Edge().IsNull() || theE.Face().IsNull())
{ {
@ -272,10 +345,10 @@ void CheckSkip(Geom2dInt_GInter& theInter,
//function : Perform //function : Perform
//purpose : //purpose :
//======================================================================= //=======================================================================
void BRepClass_Intersector::Perform(const gp_Lin2d& L, void BRepClass_Intersector::Perform(const gp_Lin2d& L,
const Standard_Real P, const Standard_Real P,
const Standard_Real Tol, const Standard_Real Tol,
const BRepClass_Edge& E) const BRepClass_Edge& E)
{ {
Standard_Real deb = 0.0, fin = 0.0, aTolZ = Tol; Standard_Real deb = 0.0, fin = 0.0, aTolZ = Tol;
Handle(Geom2d_Curve) aC2D; Handle(Geom2d_Curve) aC2D;
@ -284,69 +357,92 @@ void BRepClass_Intersector::Perform(const gp_Lin2d& L,
const TopoDS_Face& F = E.Face(); 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()) { if (aC2D.IsNull()) {
done = Standard_False; // !IsDone() done = Standard_False; // !IsDone()
return; 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(); Geom2dAdaptor_Curve C(aC2D, deb, fin);
fin = C.LastParameter();
// //
// Case of "ON": direct check of belonging to edge // Case of "ON": direct check of belonging to edge
// taking into account the tolerance // taking into account the tolerance
Standard_Boolean aStatusOn = Standard_False; if (!anUseBndBox || (anUseBndBox && !aBond.IsOut(aPntF)))
IntRes2d_IntersectionPoint aPntInter;
aStatusOn = CheckOn(aPntInter, F, L, C, aTolZ, fin, deb);
if (aStatusOn)
{ {
Append(aPntInter); Standard_Boolean aStatusOn = Standard_False;
done = Standard_True; IntRes2d_IntersectionPoint aPntInter;
return;
aStatusOn = CheckOn(aPntInter, F, L, C, aTolZ, fin, deb);
if (aStatusOn)
{
Append(aPntInter);
done = Standard_True;
return;
}
} }
//
// if (anUseBndBox)
gp_Pnt2d pdeb,pfin; {
C.D0(deb,pdeb); TopoDS_Vertex aVF, aVL;
C.D0(fin,pfin); 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; Standard_Real toldeb = 1.e-5, tolfin = 1.e-5;
IntRes2d_Domain DL; IntRes2d_Domain DL;
// //
if(P!=RealLast()) { if (P != RealLast()) {
DL.SetValues(L.Location(),0.,Precision::PConfusion(),ElCLib::Value(P,L),P,Precision::PConfusion()); DL.SetValues(L.Location(), 0., Precision::PConfusion(), ElCLib::Value(P, L), P, Precision::PConfusion());
} }
else { else {
DL.SetValues(L.Location(),0.,Precision::PConfusion(),Standard_True); 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 // temporary periodic domain
if (C.Curve()->IsPeriodic()) { if (C.Curve()->IsPeriodic()) {
DE.SetEquivalentParameters(C.FirstParameter(), DE.SetEquivalentParameters(C.FirstParameter(),
C.FirstParameter() + C.FirstParameter() +
C.Curve()->LastParameter() - C.Curve()->LastParameter() -
C.Curve()->FirstParameter()); C.Curve()->FirstParameter());
} }
Handle(Geom2d_Line) GL= new Geom2d_Line(L); Handle(Geom2d_Line) GL = new Geom2d_Line(L);
Geom2dAdaptor_Curve CGA(GL); Geom2dAdaptor_Curve CGA(GL);
Geom2dInt_GInter Inter(CGA,DL,C,DE, Geom2dInt_GInter Inter(CGA, DL, C, DE,
Precision::PConfusion(), Precision::PConfusion(),
Precision::PIntersection()); Precision::PIntersection());
// //
// The check is for hitting the intersector to // The check is for hitting the intersector to
// a vertex with high tolerance // a vertex with high tolerance
if (Inter.IsEmpty()) if (Inter.IsEmpty())
{ {
CheckSkip(Inter, L, E, aC2D, DL, CheckSkip(Inter, L, E, aC2D, DL,
C, CGA, fin, deb, MaxTolerance(), pdeb, pfin); C, CGA, fin, deb, E.MaxTolerance(), pdeb, pfin);
} }
// //
SetValues(Inter); SetValues(Inter);
} }

View File

@ -47,19 +47,6 @@ public:
//! <U>. //! <U>.
Standard_EXPORT void LocalGeometry (const BRepClass_Edge& E, const Standard_Real U, gp_Dir2d& T, gp_Dir2d& N, Standard_Real& C) const; 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: protected:
@ -71,7 +58,6 @@ protected:
private: private:
Standard_Real myMaxTolerance;
}; };

View File

@ -129,7 +129,7 @@ Standard_Boolean BRepClass3d_SolidExplorer::FindAPointInTheFace
{ {
T.SetCoord ( y, -x); T.SetCoord ( y, -x);
} }
Standard_Real ParamInit = RealLast(); Standard_Real ParamInit = Precision::Infinite();
Standard_Real TolInit = 0.00001; Standard_Real TolInit = 0.00001;
Standard_Boolean APointExist = Standard_False; Standard_Boolean APointExist = Standard_False;

View File

@ -18,7 +18,6 @@
#include <Bnd_Box2d.hxx> #include <Bnd_Box2d.hxx>
#include <gp.hxx> #include <gp.hxx>
#include <gp_Dir2d.hxx> #include <gp_Dir2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Trsf2d.hxx> #include <gp_Trsf2d.hxx>
#include <Standard_ConstructionError.hxx> #include <Standard_ConstructionError.hxx>
#include <Standard_Stream.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 //function : IsOut
//purpose : //purpose :

View File

@ -17,6 +17,7 @@
#ifndef _Bnd_Box2d_HeaderFile #ifndef _Bnd_Box2d_HeaderFile
#define _Bnd_Box2d_HeaderFile #define _Bnd_Box2d_HeaderFile
#include <gp_Lin2d.hxx>
#include <gp_Pnt2d.hxx> #include <gp_Pnt2d.hxx>
#include <Standard.hxx> #include <Standard.hxx>
#include <Standard_DefineAlloc.hxx> #include <Standard_DefineAlloc.hxx>
@ -182,7 +183,13 @@ public:
//! Returns True if the 2d pnt <P> is out <me>. //! Returns True if the 2d pnt <P> is out <me>.
Standard_EXPORT Standard_Boolean IsOut (const gp_Pnt2d& P) const; 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>. //! Returns True if <Box2d> is out <me>.
Standard_EXPORT Standard_Boolean IsOut (const Bnd_Box2d& Other) const; Standard_EXPORT Standard_Boolean IsOut (const Bnd_Box2d& Other) const;

View File

@ -2069,6 +2069,123 @@ static Standard_Integer OCC27875(Draw_Interpretor& theDI,
return 0; 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 <TDF_Tool.hxx>
#include <XCAFDoc_View.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("OCC26270", "OCC26270 shape result", __FILE__, OCC26270, group);
theCommands.Add ("OCC27552", "OCC27552", __FILE__, OCC27552, group); theCommands.Add ("OCC27552", "OCC27552", __FILE__, OCC27552, group);
theCommands.Add("OCC27875", "OCC27875 curve", __FILE__, OCC27875, 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("OCC28389", "OCC28389", __FILE__, OCC28389, group);
theCommands.Add("OCC28594", "OCC28594", __FILE__, OCC28594, group); theCommands.Add("OCC28594", "OCC28594", __FILE__, OCC28594, group);
theCommands.Add("OCC28784", "OCC28784 result shape", __FILE__, OCC28784, group); theCommands.Add("OCC28784", "OCC28784 result shape", __FILE__, OCC28784, group);

View File

@ -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"
}