#include <BRep_Tool.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepClass_FaceClassifier.hxx>
+#include <BRepTopAdaptor_FClass2d.hxx>
#include <DBRep.hxx>
#include <Draw.hxx>
#include <DrawTrSurf.hxx>
const char* g = "BOPTest commands";
theCommands.Add("bclassify" , "use bclassify Solid Point [Tolerance=1.e-7]",
__FILE__, bclassify , g);
- theCommands.Add("b2dclassify" , "use b2dclassify Face Point2d [Tol] ",
+ theCommands.Add("b2dclassify", "Classifies the point relatively face. If no point is given, classifies the infinite point\n"
+ "Uses BRepClass_FaceClassifier for classification\n"
+ "Usage: b2dclassify Face [Point2d] [Tol]",
__FILE__, b2dclassify , g);
- theCommands.Add("b2dclassifx" , "use b2dclassifx Face Point2d [Tol] ",
+ theCommands.Add("b2dclassifx", "Classifies the point relatively face. If no point is given, classifies the infinite point\n"
+ "Uses IntTools_FClass2d for classification\n"
+ "Usage: b2dclassifx Face [Point2d] [Tol]",
__FILE__, b2dclassifx , g);
theCommands.Add("bhaspc" , "use bhaspc Edge Face [do]",
__FILE__, bhaspc , g);
//purpose :
//=======================================================================
Standard_Integer b2dclassifx (Draw_Interpretor& theDI,
- Standard_Integer theArgNb,
- const char** theArgVec)
+ Standard_Integer theArgc,
+ const char** theArgv)
{
- if (theArgNb < 3) {
- theDI << " use b2dclassifx Face Point2d [Tol]\n";
+ if (theArgc < 2)
+ {
+ theDI.PrintHelp (theArgv[0]);
return 1;
}
- TopoDS_Shape aS = DBRep::Get (theArgVec[1]);
- if (aS.IsNull()) {
- theDI << " Null Shape is not allowed here\n";
+ TopoDS_Shape aS = DBRep::Get (theArgv[1]);
+ if (aS.IsNull())
+ {
+ theDI << theArgv[1] << " is a null shape\n";
return 1;
}
- else if (aS.ShapeType() != TopAbs_FACE) {
- theDI << " Shape type must be FACE\n";
+
+ if (aS.ShapeType() != TopAbs_FACE)
+ {
+ theDI << theArgv[1] << " is a not a face\n";
return 1;
}
- TopAbs_State aState;
- gp_Pnt2d aP (8., 9.);
- //
- DrawTrSurf::GetPoint2d (theArgVec[2], aP);
- const TopoDS_Face& aF = TopoDS::Face(aS);
- const Standard_Real aTol = (theArgNb == 4) ?
- Draw::Atof (theArgVec[3]) : BRep_Tool::Tolerance (aF);
- //
- IntTools_FClass2d aClassifier(aF, aTol);
- aState=aClassifier.Perform(aP);
+
+ const TopoDS_Face& aF = TopoDS::Face (aS);
+ Standard_Real aTol = BRep_Tool::Tolerance (aF);
+
+ gp_Pnt2d aP;
+ Standard_Boolean isPoint = (theArgc > 2) && DrawTrSurf::GetPoint2d (theArgv[2], aP);
+
+ if (isPoint)
+ {
+ if (theArgc > 3)
+ aTol = Draw::Atof (theArgv[3]);
+ }
+ else if (theArgc > 2)
+ aTol = Draw::Atof (theArgv[2]);
+
+ IntTools_FClass2d aClassifier (aF, aTol);
+ TopAbs_State aState = isPoint ?
+ aClassifier.Perform (aP) :
+ aClassifier.PerformInfinitePoint ();
+
PrintState (theDI, aState);
- //
return 0;
}
//
//purpose :
//=======================================================================
Standard_Integer b2dclassify (Draw_Interpretor& theDI,
- Standard_Integer theArgNb,
- const char** theArgVec)
+ Standard_Integer theArgc,
+ const char** theArgv)
{
- if (theArgNb < 3) {
- theDI << " use b2dclassify Face Point2d [Tol]\n";
+ if (theArgc < 2)
+ {
+ theDI.PrintHelp (theArgv[0]);
return 1;
}
- TopoDS_Shape aS = DBRep::Get (theArgVec[1]);
- if (aS.IsNull()) {
- theDI << " Null Shape is not allowed here\n";
+ TopoDS_Shape aS = DBRep::Get (theArgv[1]);
+ if (aS.IsNull())
+ {
+ theDI << theArgv[1] << " is a null shape\n";
return 1;
}
- else if (aS.ShapeType() != TopAbs_FACE) {
- theDI << " Shape type must be FACE\n";
+
+ if (aS.ShapeType() != TopAbs_FACE)
+ {
+ theDI << theArgv[1] << " is a not a face\n";
return 1;
}
- //
- gp_Pnt2d aP (8., 9.);
- //
- DrawTrSurf::GetPoint2d (theArgVec[2], aP);
- const TopoDS_Face& aF = TopoDS::Face(aS);
- const Standard_Real aTol = (theArgNb == 4) ?
- Draw::Atof (theArgVec[3]) : BRep_Tool::Tolerance (aF);
-
- BRepClass_FaceClassifier aClassifier;
- aClassifier.Perform(aF, aP, aTol);
- PrintState (theDI, aClassifier.State());
- //
+
+ const TopoDS_Face& aF = TopoDS::Face (aS);
+ Standard_Real aTol = BRep_Tool::Tolerance (aF);
+
+ gp_Pnt2d aP;
+ Standard_Boolean isPoint = (theArgc > 2) && DrawTrSurf::GetPoint2d (theArgv[2], aP);
+
+ TopAbs_State aState = TopAbs_UNKNOWN;
+ if (isPoint)
+ {
+ if (theArgc > 3)
+ aTol = Draw::Atof (theArgv[3]);
+
+ BRepClass_FaceClassifier aClassifier;
+ aClassifier.Perform (aF, aP, aTol);
+ aState = aClassifier.State();
+ }
+ else
+ {
+ if (theArgc > 2)
+ aTol = Draw::Atof (theArgv[2]);
+
+ BRepTopAdaptor_FClass2d aClassifier (aF, aTol);
+ aState = aClassifier.PerformInfinitePoint();
+ }
+
+ PrintState (theDI, aState);
return 0;
}
#include <Precision.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Edge.hxx>
static const Standard_Real Probing_Start = 0.123;
static const Standard_Real Probing_End = 0.7;
static const Standard_Real Probing_Step = 0.2111;
+//=======================================================================
+//function : BRepClass_FExp_DistanceTool
+//purpose : Tool for checking the ON status of a point for the face
+// using the real tolerances of sub-shapes of the latter.
+//=======================================================================
+#include <BVH_BoxSet.hxx>
+#include <BVH_Distance.hxx>
+#include <BVH_Tools.hxx>
+#include <BVH_LinearBuilder.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <BRepBndLib.hxx>
+#include <TopExp.hxx>
+#include <Bnd_Box.hxx>
+#include <Bnd_Tools.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BndLib_Add3dCurve.hxx>
+
+class BRepClass_FExp_DistanceTool:
+ public BVH_Distance <Standard_Real, 3, NCollection_Vec3<Standard_Real>,
+ BVH_BoxSet<Standard_Real, 3, TopoDS_Shape> >
+{
+public:
+
+ //! Empty constructor
+ BRepClass_FExp_DistanceTool()
+ : BVH_Distance <Standard_Real, 3, NCollection_Vec3<Standard_Real>, BVH_BoxSet<Standard_Real, 3, TopoDS_Shape>>()
+ {
+ }
+
+public: //! @name Setters
+
+ void SetPoint (const gp_Pnt& thePoint)
+ {
+ SetObject (NCollection_Vec3<Standard_Real> (thePoint.X(), thePoint.Y(), thePoint.Z()));
+ }
+
+public: //! @name Setters
+
+ const TopoDS_Shape& GetOnShape() const
+ {
+ return myOnShape;
+ }
+
+public: //! @name Clearing the results
+
+ //! Returns the flag controlling the tree descend
+ virtual void Clear() Standard_OVERRIDE
+ {
+ myDistance = 0.0;
+ myIsDone = Standard_False;
+ myOnShape.Nullify();
+ }
+
+public: //! @name Definition of the rules for tree descend
+
+ // Computes the distance from the point to bounding box
+ virtual Standard_Boolean RejectNode (const BVH_Vec3d& theCMin,
+ const BVH_Vec3d& theCMax,
+ Standard_Real& theDistance) const Standard_OVERRIDE
+ {
+ theDistance = BVH_Tools<Standard_Real, 3>::PointBoxSquareDistance (myObject, theCMin, theCMax);
+ return RejectMetric (theDistance);
+ }
+
+ // Computes the distance from the point to triangle
+ virtual Standard_Boolean Accept (const Standard_Integer theIndex,
+ const Standard_Real&) Standard_OVERRIDE
+ {
+ if (myBVHSet->Box (theIndex).IsOut (myObject))
+ return Standard_False;
+
+ // Get the shape
+ const TopoDS_Shape& aS = myBVHSet->Element (theIndex);
+
+ if (aS.ShapeType() == TopAbs_VERTEX)
+ {
+ const TopoDS_Vertex& aV = TopoDS::Vertex (aS);
+ gp_XYZ aP = BRep_Tool::Pnt (aV).XYZ();
+ Standard_Real aTolV = BRep_Tool::Tolerance (aV);
+ Standard_Real aSqTol = aTolV * aTolV;
+
+ Standard_Real aSqDist = (aP - gp_XYZ (myObject.x(), myObject.y(), myObject.z())).SquareModulus();
+ if (aSqDist <= aSqTol)
+ {
+ myOnShape = aS;
+ return Standard_True;
+ }
+ }
+ else if (aS.ShapeType() == TopAbs_EDGE)
+ {
+ const TopoDS_Edge& aE = TopoDS::Edge (aS);
+ Standard_Real aFirst, aLast;
+ const Handle (Geom_Curve)& aC = BRep_Tool::Curve (aE, aFirst, aLast);
+ if (aC.IsNull())
+ return Standard_False;
+
+ GeomAPI_ProjectPointOnCurve aProjPC
+ (gp_Pnt (myObject.x(), myObject.y(), myObject.z()), aC, aFirst, aLast);
+ if (aProjPC.NbPoints() > 0)
+ {
+ if (aProjPC.LowerDistance() < BRep_Tool::Tolerance (aE))
+ {
+ myOnShape = aS;
+ return Standard_True;
+ }
+ }
+ }
+ return Standard_False;
+ }
+
+ //! Returns the flag controlling the tree descend
+ virtual Standard_Boolean Stop() const Standard_OVERRIDE
+ {
+ return !myOnShape.IsNull();
+ }
+
+private: //! @name Fields
+
+ TopoDS_Shape myOnShape;
+};
+
//=======================================================================
//function : BRepClass_FaceExplorer
//purpose :
Or = E.Edge().Orientation();
}
+//=======================================================================
+//function : IsPointOnFace
+//purpose :
+//=======================================================================
+const opencascade::handle<BVH_BoxSet<Standard_Real, 3, TopoDS_Shape>>&
+ BRepClass_FaceExplorer::BVHBoxSet (Standard_Boolean toBuild) const
+{
+ if (toBuild && myBVHSet.IsNull())
+ {
+ myBVHSet = new BVH_BoxSet<Standard_Real, 3, TopoDS_Shape> (new BVH_LinearBuilder<Standard_Real, 3>());
+
+ for (TopExp_Explorer anExpV (myFace, TopAbs_VERTEX); anExpV.More(); anExpV.Next())
+ {
+ const TopoDS_Vertex& aV = TopoDS::Vertex (anExpV.Current());
+ const TopAbs_Orientation aVOri = aV.Orientation();
+ if (aVOri == TopAbs_FORWARD || aVOri == TopAbs_REVERSED)
+ {
+ Bnd_Box aBox;
+ aBox.Add (BRep_Tool::Pnt (aV));
+ aBox.Enlarge (BRep_Tool::Tolerance (aV));
+ myBVHSet->Add (anExpV.Current(), Bnd_Tools::Bnd2BVH (aBox));
+ }
+ }
+
+ for (TopExp_Explorer anExpE (myFace, TopAbs_EDGE); anExpE.More(); anExpE.Next())
+ {
+ const TopoDS_Edge& aE = TopoDS::Edge (anExpE.Current());
+ const TopAbs_Orientation aEOri = aE.Orientation();
+ if (aEOri == TopAbs_FORWARD || aEOri == TopAbs_REVERSED)
+ {
+ BRepAdaptor_Curve aBAC (aE);
+ Bnd_Box aBox;
+ BndLib_Add3dCurve::Add (aBAC, aBAC.Tolerance(), aBox);
+ myBVHSet->Add (anExpE.Current(), Bnd_Tools::Bnd2BVH (aBox));
+ }
+ }
+ myBVHSet->Build();
+ }
+ return myBVHSet;
+}
+
+
+//=======================================================================
+//function : IsPointOnFace
+//purpose :
+//=======================================================================
+Standard_Boolean BRepClass_FaceExplorer::IsPointOnFace (const gp_Pnt2d& thePoint) const
+{
+ const Handle (Geom_Surface)& aSurface = BRep_Tool::Surface (myFace);
+ gp_Pnt aP3d = aSurface->Value (thePoint.X(), thePoint.Y());
+ return IsPointOnFace (aP3d);
+}
+
+//=======================================================================
+//function : IsPointOnFace
+//purpose :
+//=======================================================================
+Standard_Boolean BRepClass_FaceExplorer::IsPointOnFace (const gp_Pnt& thePoint) const
+{
+ BRepClass_FExp_DistanceTool aDistTool;
+ aDistTool.SetBVHSet (BVHBoxSet().get());
+ aDistTool.SetPoint (thePoint);
+ aDistTool.ComputeDistance();
+ return aDistTool.IsDone();
+}
#include <Standard_Real.hxx>
#include <Standard_Boolean.hxx>
#include <TopAbs_Orientation.hxx>
+#include <BVH_BoxSet.hxx>
class TopoDS_Face;
class gp_Pnt2d;
class gp_Lin2d;
//! Current edge in current wire and its orientation.
Standard_EXPORT void CurrentEdge (BRepClass_Edge& E, TopAbs_Orientation& Or) const;
+ //! Returns the cached BVH_BoxSet.
+ //! @param toBuild controls if the set should be constructed if it is null
+ Standard_EXPORT const opencascade::handle<BVH_BoxSet<Standard_Real, 3, TopoDS_Shape>>&
+ BVHBoxSet (Standard_Boolean toBuild = Standard_True) const;
+ //! Checks the On status of a point evaluated from surface for the face using the
+ //! real tolerances of the sub-shapes of the face
+ Standard_EXPORT Standard_Boolean IsPointOnFace (const gp_Pnt2d& thePoint) const;
+
+ //! Checks the On status of a point for the face using the
+ //! real tolerances of the sub-shapes of the face
+ Standard_EXPORT Standard_Boolean IsPointOnFace (const gp_Pnt& thePoint) const;
protected:
Standard_Real myUMax;
Standard_Real myVMin;
Standard_Real myVMax;
+
+ mutable opencascade::handle <BVH_BoxSet<Standard_Real, 3, TopoDS_Shape>> myBVHSet;
};
#include <Geom2d_Line.hxx>
#include <Geom2dInt_GInter.hxx>
#include <Geom2dLProp_CLProps2d.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Lin2d.hxx>
#include <IntRes2d_Domain.hxx>
#include <IntRes2d_Transition.hxx>
#include <Precision.hxx>
#include <TopExp.hxx>
+#include <TopoDS.hxx>
#include <TopoDS_Vertex.hxx>
static
//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_Edge& EE = E.Edge();
- const TopoDS_Face& F = E.Face();
+ const TopoDS_Edge& anEdge = E.Edge();
+ const TopoDS_Face& aFace = E.Face();
- //
- aC2D=BRep_Tool::CurveOnSurface(EE, F, deb, fin);
- if (aC2D.IsNull()) {
- done = Standard_False; // !IsDone()
+ Standard_Real aFirst, aLast;
+ Handle (Geom2d_Curve) aC2D = BRep_Tool::CurveOnSurface (anEdge, aFace, aFirst, aLast);
+ if (aC2D.IsNull())
+ {
+ done = Standard_False;
return;
}
- //
- Geom2dAdaptor_Curve C(aC2D, deb, fin);
- //
- deb = C.FirstParameter();
- fin = C.LastParameter();
- //
- // Case of "ON": direct check of belonging to edge
- // taking into account the tolerance
- Extrema_ExtPC2d anExtPC2d(L.Location(), C);
- Standard_Real MinDist = RealLast(), aDist;
- Standard_Integer MinInd = 0, i;
- if (anExtPC2d.IsDone())
+
+ Geom2dAdaptor_Curve C (aC2D, aFirst, aLast);
{
- const Standard_Integer aNbPnts = anExtPC2d.NbExt();
- for (i = 1; i <= aNbPnts; ++i)
+ Extrema_ExtPC2d anExtPC2d (L.Location(), C);
+ Standard_Real MinDist = RealLast(), aDist;
+ Standard_Integer MinInd = 0, i;
+ if (anExtPC2d.IsDone())
{
- aDist = anExtPC2d.SquareDistance(i);
-
- if (aDist < MinDist)
+ const Standard_Integer aNbPnts = anExtPC2d.NbExt();
+ for (i = 1; i <= aNbPnts; ++i)
{
- MinDist = aDist;
- MinInd = i;
+ aDist = anExtPC2d.SquareDistance(i);
+ if (aDist < MinDist)
+ {
+ MinDist = aDist;
+ MinInd = i;
+ }
}
}
- }
- if (MinInd) {
- MinDist = sqrt(MinDist);
- }
- if (MinDist <= aTolZ) {
- gp_Pnt2d pnt_exact = (anExtPC2d.Point(MinInd)).Value();
- Standard_Real par = (anExtPC2d.Point(MinInd)).Parameter();
- //
- RefineTolerance(F, C, par, aTolZ);
- //
- if (MinDist <= aTolZ) {
- IntRes2d_Transition tr_on_lin(IntRes2d_Head);
- IntRes2d_Position pos_on_curve = IntRes2d_Middle;
- if (Abs(par - deb) <= Precision::Confusion()) {
- pos_on_curve = IntRes2d_Head;
- }
- else if (Abs(par - fin) <= Precision::Confusion()) {
- pos_on_curve = IntRes2d_End;
+ if (MinInd)
+ MinDist = sqrt (MinDist);
+
+ if (MinDist <= Tol)
+ {
+ gp_Pnt2d aPnt = (anExtPC2d.Point (MinInd)).Value();
+ Standard_Real aPar = (anExtPC2d.Point (MinInd)).Parameter();
+
+ Standard_Real aTolZ = Tol;
+ RefineTolerance (aFace, C, aPar, aTolZ);
+
+ if (MinDist <= aTolZ)
+ {
+ IntRes2d_Position aPosOnCurve = IntRes2d_Middle;
+ if (Abs (aPar - aFirst) <= Tol)
+ aPosOnCurve = IntRes2d_Head;
+ else if (Abs (aPar - aLast) <= Tol)
+ aPosOnCurve = IntRes2d_End;
+
+ IntRes2d_IntersectionPoint pnt_inter (aPnt, 0., aPar,
+ IntRes2d_Transition (IntRes2d_Head),
+ IntRes2d_Transition (aPosOnCurve),
+ Standard_False);
+ Append (pnt_inter);
+ done = Standard_True;
+ return;
}
- //
- IntRes2d_Transition tr_on_curve(pos_on_curve);
- IntRes2d_IntersectionPoint pnt_inter(pnt_exact, 0., par,
- tr_on_lin, tr_on_curve,
- Standard_False);
- //
- Append(pnt_inter);
- done = Standard_True;
- return;
}
}
- //
- gp_Pnt2d pdeb,pfin;
- C.D0(deb,pdeb);
- C.D0(fin,pfin);
+
+ // Intersection of the edge with the line
+ gp_Pnt2d aPFirst = C.Value (aFirst),
+ aPLast = C.Value (aLast);
IntRes2d_Domain DL;
if (P != RealLast())
else
DL.SetValues (L.Location(), 0., Precision::PConfusion(), Standard_True);
- IntRes2d_Domain DE (pdeb, deb, Tol, pfin, fin, Tol);
+ IntRes2d_Domain DE (aPFirst, aFirst, Tol, aPLast, aLast, Tol);
// temporary periodic domain
if (C.Curve()->IsPeriodic()) {
DE.SetEquivalentParameters(C.FirstParameter(),
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Curve2d.hxx>
#include <BRepAdaptor_HSurface.hxx>
-#include <BRepClass_FaceClassifier.hxx>
+#include <BRepClass_FaceExplorer.hxx>
+#include <BRepClass_FClassifier.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <BRepTopAdaptor_FClass2d.hxx>
#include <CSLib_Class2d.hxx>
return(Perform(P,Standard_False));
}
-TopAbs_State BRepTopAdaptor_FClass2d::Perform(const gp_Pnt2d& _Puv,
- const Standard_Boolean RecadreOnPeriodic) const
+TopAbs_State BRepTopAdaptor_FClass2d::Perform (const gp_Pnt2d& _Puv,
+ const Standard_Boolean RecadreOnPeriodic,
+ const Standard_Boolean theUseFTolForOnCheck) const
{
#if LBRCOMPT
STAT.NbPerform++;
#endif
+
+ if (theUseFTolForOnCheck)
+ {
+ if (FExplorer().IsPointOnFace (_Puv))
+ return TopAbs_ON;
+ }
+
Standard_Integer dedans;
Standard_Integer nbtabclass = TabClass.Length();
}
}
if(dedans==0) {
- BRepClass_FaceClassifier aClassifier;
Standard_Real m_Toluv = (Toluv > 4.0) ? 4.0 : Toluv;
- //aClassifier.Perform(Face,Puv,Toluv);
- aClassifier.Perform(Face,Puv,m_Toluv);
- aStatus = aClassifier.State();
+ aStatus = ClassifyByInter (Puv, m_Toluv);
}
if(dedans == 1) {
aStatus = TopAbs_IN;
}
}
else { //-- TabOrien(1)=-1 False Wire
- BRepClass_FaceClassifier aClassifier;
- aClassifier.Perform(Face,Puv,Toluv);
- aStatus = aClassifier.State();
+ aStatus = ClassifyByInter (Puv, Toluv);
}
if (!RecadreOnPeriodic || (!IsUPer && !IsVPer))
}
}
else { //-- TabOrien(1)=-1 False Wire
- BRepClass_FaceClassifier aClassifier;
- aClassifier.Perform(Face,Puv,Tol);
- aStatus = aClassifier.State();
+ aStatus = ClassifyByInter (Puv, Tol);
}
if (!RecadreOnPeriodic || (!IsUPer && !IsVPer))
} //for (;;)
}
+//=======================================================================
+//function : FExplorer
+//purpose :
+//=======================================================================
+BRepClass_FaceExplorer& BRepTopAdaptor_FClass2d::FExplorer() const
+{
+ if (myFExplorer.get() == NULL)
+ myFExplorer.reset (new BRepClass_FaceExplorer (Face));
+ return *myFExplorer;
+}
+
+TopAbs_State BRepTopAdaptor_FClass2d::ClassifyByInter (const gp_Pnt2d& thePnt,
+ const Standard_Real theTolUV) const
+{
+ BRepClass_FClassifier aClassifier;
+ aClassifier.Perform (FExplorer(), thePnt, theTolUV);
+ return aClassifier.State();
+}
void BRepTopAdaptor_FClass2d::Destroy() {
#if LBRCOMPT
#include <TopoDS_Face.hxx>
#include <TopAbs_State.hxx>
#include <Standard_Boolean.hxx>
+#include <BRepClass_FaceExplorer.hxx>
+#include <memory>
+
class TopoDS_Face;
class gp_Pnt2d;
-
class BRepTopAdaptor_FClass2d
{
public:
Standard_EXPORT TopAbs_State PerformInfinitePoint() const;
- Standard_EXPORT TopAbs_State Perform (const gp_Pnt2d& Puv, const Standard_Boolean RecadreOnPeriodic = Standard_True) const;
+ Standard_EXPORT TopAbs_State Perform (const gp_Pnt2d& Puv,
+ const Standard_Boolean RecadreOnPeriodic = Standard_True,
+ const Standard_Boolean theUseFTolForOnCheck = Standard_False) const;
Standard_EXPORT void Destroy();
~BRepTopAdaptor_FClass2d()
//! (Caution: Internal use . see the code for more details)
Standard_EXPORT TopAbs_State TestOnRestriction (const gp_Pnt2d& Puv, const Standard_Real Tol, const Standard_Boolean RecadreOnPeriodic = Standard_True) const;
+ //! Returns FaceExplorer for myFace
+ Standard_EXPORT BRepClass_FaceExplorer& FExplorer() const;
+ //! Classifies the point by geometrical classifier
+ Standard_EXPORT TopAbs_State ClassifyByInter (const gp_Pnt2d& thePnt,
+ const Standard_Real theTolUV) const;
protected:
Standard_Real Vmin;
Standard_Real Vmax;
+#ifdef _MSC_VER
+#if _MSC_VER < 1600
+ mutable std::auto_ptr<BRepClass_FaceExplorer> myFExplorer;
+#else
+ mutable std::unique_ptr<BRepClass_FaceExplorer> myFExplorer;
+#endif
+#else
+ mutable std::unique_ptr<BRepClass_FaceExplorer> myFExplorer;
+#endif
};
-
-
-
-
-
-
#endif // _BRepTopAdaptor_FClass2d_HeaderFile
//! Computes the distance between object and BVH tree
NumType ComputeDistance()
{
+ Clear();
myIsDone = this->Select() > 0;
return myDistance;
}
//! Returns the computed distance
NumType Distance() const { return myDistance; }
+public: //! @name Clearing the results
+
+ //! Clears the data
+ virtual void Clear()
+ {
+ myDistance = std::numeric_limits<NumType>::max();
+ myIsDone = Standard_False;
+ }
+
public: //! @name Definition of the rules for tree descend
//! Compares the two metrics and chooses the best one
return FixOrientation(MapWires);
}
+static TopAbs_State classifyWire (const TopoDS_Wire& theWire,
+ const Bnd_Box2d& aBox1,
+ const BRepTopAdaptor_FClass2d& theClassifier,
+ const TopAbs_State theInfPntState,
+ const TopTools_SequenceOfShape& theAllSubShapes,
+ const NCollection_Array1<Bnd_Box2d>& theWireBoxes,
+ const TopoDS_Face& theFace,
+ const Handle(ShapeAnalysis_Surface)& theSurf,
+ const Standard_Boolean theUClosed,
+ const Standard_Boolean theVClosed,
+ const Standard_Real theURange,
+ const Standard_Real theVRange,
+ TopTools_DataMapOfShapeInteger& theSI,
+ TopTools_ListOfShape& theIntWires,
+ const Standard_Boolean theUseToler)
+{
+ Standard_Boolean CheckShift = Standard_True;
+ TopAbs_State sta = TopAbs_OUT;
+ Standard_Integer aWireIt = 0;
+ const Standard_Integer nbAll = theAllSubShapes.Length();
+ for (Standard_Integer j = 1; j <= nbAll; j++)
+ {
+ aWireIt++;
+ //if(i==j) continue;
+ TopoDS_Shape aSh2 = theAllSubShapes.Value (j);
+ if (theWire == aSh2)
+ continue;
+ TopAbs_State stb = TopAbs_UNKNOWN;
+ if (aSh2.ShapeType () == TopAbs_VERTEX) {
+ aWireIt--;
+ gp_Pnt aP = BRep_Tool::Pnt (TopoDS::Vertex (aSh2));
+ gp_Pnt2d p2d = theSurf->ValueOfUV (aP, Precision::Confusion ());
+ stb = theClassifier.Perform (p2d, Standard_False, theUseToler);
+ if (stb == theInfPntState && (theUClosed || theVClosed)) {
+ gp_Pnt2d p2d1;
+ if (theUClosed) {
+ p2d1.SetCoord (p2d.X () + theURange, p2d.Y ());
+ stb = theClassifier.Perform (p2d1, Standard_False, theUseToler);
+ }
+ if (stb == theInfPntState && theVClosed) {
+ p2d1.SetCoord (p2d.X (), p2d.Y () + theVRange);
+ stb = theClassifier.Perform (p2d1, Standard_False, theUseToler);
+ }
+ }
+ }
+ else if (aSh2.ShapeType () == TopAbs_WIRE) {
+ CheckShift = Standard_True;
+ TopoDS_Wire bw = TopoDS::Wire (aSh2);
+ //Standard_Integer numin =0;
+ Bnd_Box2d aBox2 = theWireBoxes.Value (aWireIt);
+ if (aBox2.IsOut (aBox1))
+ continue;
+
+ TopoDS_Iterator ew (bw);
+ for (; ew.More (); ew.Next ()) {
+ TopoDS_Edge ed = TopoDS::Edge (ew.Value ());
+ Standard_Real cf, cl;
+ Handle (Geom2d_Curve) cw = BRep_Tool::CurveOnSurface (ed, theFace, cf, cl);
+ if (cw.IsNull ()) continue;
+ gp_Pnt2d unp = cw->Value ((cf + cl) / 2.);
+ TopAbs_State ste = theClassifier.Perform (unp, Standard_False, theUseToler);
+ std::cout << (ste == TopAbs_ON ? "ON" : (ste == TopAbs_IN ? "IN" : "OUT")) << std::endl;
+ if (ste == TopAbs_OUT || ste == TopAbs_IN) {
+ if (stb == TopAbs_UNKNOWN) {
+ stb = ste;
+ }
+ else {
+ if (!(stb == ste)) {
+ sta = TopAbs_UNKNOWN;
+ theSI.Bind (theWire, 0);
+ break;
+ }
+ }
+ }
+
+ Standard_Boolean found = Standard_False;
+ gp_Pnt2d unp1;
+ if (stb == theInfPntState && CheckShift) {
+ CheckShift = Standard_False;
+ if (theUClosed) {
+ unp1.SetCoord (unp.X () + theURange, unp.Y ());
+ found = (theInfPntState != theClassifier.Perform (unp1, Standard_False, theUseToler));
+ if (!found) {
+ unp1.SetX (unp.X () - theURange);
+ found = (theInfPntState != theClassifier.Perform (unp1, Standard_False, theUseToler));
+ }
+ }
+ if (theVClosed && !found) {
+ unp1.SetCoord (unp.X (), unp.Y () + theVRange);
+ found = (theInfPntState != theClassifier.Perform (unp1, Standard_False, theUseToler));
+ if (!found) {
+ unp1.SetY (unp.Y () - theVRange);
+ found = (theInfPntState != theClassifier.Perform (unp1, Standard_False, theUseToler));
+ }
+ }
+ // Additional check of diagonal steps for toroidal surfaces
+ if (!found && theUClosed && theVClosed)
+ {
+ for (Standard_Real dX = -1.0; dX <= 1.0 && !found; dX += 2.0)
+ for (Standard_Real dY = -1.0; dY <= 1.0 && !found; dY += 2.0)
+ {
+ unp1.SetCoord (unp.X () + theURange * dX, unp.Y () + theVRange * dY);
+ found = (theInfPntState != theClassifier.Perform (unp1, Standard_False, theUseToler));
+ }
+ }
+ }
+ if (found) {
+ if (stb == TopAbs_IN) stb = TopAbs_OUT;
+ else stb = TopAbs_IN;
+ Shift2dWire (bw, theFace, unp1.XY () - unp.XY (), theSurf);
+ }
+ }
+ if (ew.More())
+ break;
+ }
+ if (stb == theInfPntState) {
+ sta = TopAbs_IN;
+ }
+ else {
+ theIntWires.Append (aSh2);
+ }
+ }
+ return sta;
+}
//=======================================================================
//function : FixOrientation
TopTools_DataMapOfShapeListOfShape MW;
TopTools_DataMapOfShapeInteger SI;
TopTools_MapOfShape MapIntWires;
- MW.Clear();
- SI.Clear();
- MapIntWires.Clear();
Standard_Integer NbOuts=0;
Standard_Integer i;
Bnd_Box2d aBox1 = aWireBoxes.Value(i);
TopoDS_Shape dummy = myFace.EmptyCopied();
TopoDS_Face af = TopoDS::Face ( dummy );
-// B.MakeFace (af,mySurf->Surface(),::Precision::Confusion());
af.Orientation ( TopAbs_FORWARD );
B.Add (af,aw);
// PTV OCC945 06.11.2002 files ie_exhaust-A.stp (entities 3782, 3787)
// tolerance is too big. It is seems that to identify placement of 2d point
// it is enough Precision::PConfusion(), cause wea re know that 2d point in TopAbs_ON
// BRepTopAdaptor_FClass2d clas (af,toluv);
- Standard_Boolean CheckShift = Standard_True;
BRepTopAdaptor_FClass2d clas (af,::Precision::PConfusion());
- TopAbs_State sta = TopAbs_OUT;
TopAbs_State staout = clas.PerformInfinitePoint();
+
TopTools_ListOfShape IntWires;
- Standard_Integer aWireIt = 0;
- for ( Standard_Integer j = 1; j <= nbAll; j ++) {
- aWireIt++;
- //if(i==j) continue;
- TopoDS_Shape aSh2 = allSubShapes.Value(j);
- if(aw == aSh2)
- continue;
- TopAbs_State stb = TopAbs_UNKNOWN;
- if(aSh2.ShapeType() == TopAbs_VERTEX) {
- aWireIt--;
- gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aSh2));
- gp_Pnt2d p2d = mySurf->ValueOfUV(aP,Precision::Confusion());
- stb = clas.Perform (p2d,Standard_False);
- if(stb == staout && (uclosed || vclosed)) {
- gp_Pnt2d p2d1;
- if(uclosed) {
- p2d1.SetCoord(p2d.X()+uRange, p2d.Y());
- stb = clas.Perform (p2d1,Standard_False);
-
- }
- if(stb == staout && vclosed) {
- p2d1.SetCoord(p2d.X(), p2d.Y()+ vRange);
- stb = clas.Perform (p2d1,Standard_False);
- }
- }
- }
- else if (aSh2.ShapeType() == TopAbs_WIRE) {
- CheckShift = Standard_True;
- TopoDS_Wire bw = TopoDS::Wire (aSh2);
- //Standard_Integer numin =0;
- Bnd_Box2d aBox2 = aWireBoxes.Value(aWireIt);
- if (aBox2.IsOut(aBox1))
- continue;
+ TopTools_DataMapOfShapeInteger SILoc;
+ TopAbs_State sta = classifyWire (aw, aBox1, clas, staout,
+ allSubShapes, aWireBoxes,
+ myFace, mySurf,
+ uclosed, vclosed, uRange, vRange,
+ SILoc, IntWires, Standard_False);
+ if (sta == TopAbs_UNKNOWN)
+ {
+ IntWires.Clear();
+ SILoc.Clear();
+ sta = classifyWire (aw, aBox1, clas, staout,
+ allSubShapes, aWireBoxes,
+ myFace, mySurf,
+ uclosed, vclosed, uRange, vRange,
+ SILoc, IntWires, Standard_True);
+ }
+ {
+ for (TopTools_ListOfShape::Iterator itIW (IntWires); itIW.More(); itIW.Next())
+ MapIntWires.Add (itIW.Value());
- TopoDS_Iterator ew (bw);
- for(;ew.More(); ew.Next()) {
- TopoDS_Edge ed = TopoDS::Edge (ew.Value());
- Standard_Real cf,cl;
- Handle(Geom2d_Curve) cw = BRep_Tool::CurveOnSurface (ed,myFace,cf,cl);
- if (cw.IsNull()) continue;
- gp_Pnt2d unp = cw->Value ((cf+cl)/2.);
- TopAbs_State ste = clas.Perform (unp,Standard_False);
- if( ste==TopAbs_OUT || ste==TopAbs_IN ) {
- if(stb==TopAbs_UNKNOWN) {
- stb = ste;
- }
- else {
- if(!(stb==ste)) {
- sta = TopAbs_UNKNOWN;
- SI.Bind(aw,0);
- j=nb;
- break;
- }
- }
- }
-
- Standard_Boolean found = Standard_False;
- gp_Pnt2d unp1;
- if( stb == staout && CheckShift ) {
- CheckShift = Standard_False;
- if(uclosed) {
- unp1.SetCoord(unp.X()+uRange, unp.Y());
- found = (staout != clas.Perform (unp1,Standard_False));
- if(!found) {
- unp1.SetX(unp.X()-uRange);
- found = (staout != clas.Perform (unp1,Standard_False));
- }
- }
- if(vclosed&&!found) {
- unp1.SetCoord(unp.X(), unp.Y()+vRange);
- found = (staout != clas.Perform (unp1,Standard_False));
- if(!found) {
- unp1.SetY(unp.Y()-vRange);
- found = (staout != clas.Perform (unp1,Standard_False));
- }
- }
- // Additional check of diagonal steps for toroidal surfaces
- if (!found && uclosed && vclosed)
- {
- for (Standard_Real dX = -1.0; dX <= 1.0 && !found; dX += 2.0)
- for (Standard_Real dY = -1.0; dY <= 1.0 && !found; dY += 2.0)
- {
- unp1.SetCoord(unp.X() + uRange * dX, unp.Y() + vRange * dY);
- found = (staout != clas.Perform(unp1, Standard_False));
- }
- }
- }
- if(found) {
- if(stb==TopAbs_IN) stb = TopAbs_OUT;
- else stb = TopAbs_IN;
- Shift2dWire(bw,myFace,unp1.XY()-unp.XY(), mySurf);
- }
- }
- }
- if(stb==staout) {
- sta = TopAbs_IN;
- }
- else {
- IntWires.Append(aSh2);
- MapIntWires.Add(aSh2);
- }
+ for (TopTools_DataMapOfShapeInteger::Iterator itSI (SILoc); itSI.More(); itSI.Next())
+ SI.Bind (itSI.Key(), itSI.Value());
}
+ //
+ //Standard_Boolean CheckShift = Standard_True;
+ //
+ //TopAbs_State staout = clas.PerformInfinitePoint();
+ //TopTools_ListOfShape IntWires;
+ //Standard_Integer aWireIt = 0;
+ //for ( Standard_Integer j = 1; j <= nbAll; j ++) {
+ // aWireIt++;
+ // //if(i==j) continue;
+ // TopoDS_Shape aSh2 = allSubShapes.Value(j);
+ // if(aw == aSh2)
+ // continue;
+ // TopAbs_State stb = TopAbs_UNKNOWN;
+ // if(aSh2.ShapeType() == TopAbs_VERTEX) {
+ // aWireIt--;
+ // gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aSh2));
+ // gp_Pnt2d p2d = mySurf->ValueOfUV(aP,Precision::Confusion());
+ // stb = clas.Perform (p2d,Standard_False);
+ // if(stb == staout && (uclosed || vclosed)) {
+ // gp_Pnt2d p2d1;
+ // if(uclosed) {
+ // p2d1.SetCoord(p2d.X()+uRange, p2d.Y());
+ // stb = clas.Perform (p2d1,Standard_False);
+ //
+ // }
+ // if(stb == staout && vclosed) {
+ // p2d1.SetCoord(p2d.X(), p2d.Y()+ vRange);
+ // stb = clas.Perform (p2d1,Standard_False);
+ // }
+ // }
+ // }
+ // else if (aSh2.ShapeType() == TopAbs_WIRE) {
+ // CheckShift = Standard_True;
+ // TopoDS_Wire bw = TopoDS::Wire (aSh2);
+ // //Standard_Integer numin =0;
+ // Bnd_Box2d aBox2 = aWireBoxes.Value(aWireIt);
+ // if (aBox2.IsOut(aBox1))
+ // continue;
+ //
+ // TopoDS_Iterator ew (bw);
+ // for(;ew.More(); ew.Next()) {
+ // TopoDS_Edge ed = TopoDS::Edge (ew.Value());
+ // Standard_Real cf,cl;
+ // Handle(Geom2d_Curve) cw = BRep_Tool::CurveOnSurface (ed,myFace,cf,cl);
+ // if (cw.IsNull()) continue;
+ // gp_Pnt2d unp = cw->Value ((cf+cl)/2.);
+ // TopAbs_State ste = clas.Perform (unp,Standard_False);
+ // std::cout << (ste == TopAbs_ON ? "ON" : (ste == TopAbs_IN ? "IN" : "OUT")) << std::endl;
+ // if( ste==TopAbs_OUT || ste==TopAbs_IN ) {
+ // if(stb==TopAbs_UNKNOWN) {
+ // stb = ste;
+ // }
+ // else {
+ // if(!(stb==ste)) {
+ // sta = TopAbs_UNKNOWN;
+ // SI.Bind(aw,0);
+ // j=nb;
+ // break;
+ // }
+ // }
+ // }
+ //
+ // Standard_Boolean found = Standard_False;
+ // gp_Pnt2d unp1;
+ // if( stb == staout && CheckShift ) {
+ // CheckShift = Standard_False;
+ // if(uclosed) {
+ // unp1.SetCoord(unp.X()+uRange, unp.Y());
+ // found = (staout != clas.Perform (unp1,Standard_False));
+ // if(!found) {
+ // unp1.SetX(unp.X()-uRange);
+ // found = (staout != clas.Perform (unp1,Standard_False));
+ // }
+ // }
+ // if(vclosed&&!found) {
+ // unp1.SetCoord(unp.X(), unp.Y()+vRange);
+ // found = (staout != clas.Perform (unp1,Standard_False));
+ // if(!found) {
+ // unp1.SetY(unp.Y()-vRange);
+ // found = (staout != clas.Perform (unp1,Standard_False));
+ // }
+ // }
+ // // Additional check of diagonal steps for toroidal surfaces
+ // if (!found && uclosed && vclosed)
+ // {
+ // for (Standard_Real dX = -1.0; dX <= 1.0 && !found; dX += 2.0)
+ // for (Standard_Real dY = -1.0; dY <= 1.0 && !found; dY += 2.0)
+ // {
+ // unp1.SetCoord(unp.X() + uRange * dX, unp.Y() + vRange * dY);
+ // found = (staout != clas.Perform(unp1, Standard_False));
+ // }
+ // }
+ // }
+ // if(found) {
+ // if(stb==TopAbs_IN) stb = TopAbs_OUT;
+ // else stb = TopAbs_IN;
+ // Shift2dWire(bw,myFace,unp1.XY()-unp.XY(), mySurf);
+ // }
+ // }
+ // }
+ // if(stb==staout) {
+ // sta = TopAbs_IN;
+ // }
+ // else {
+ // IntWires.Append(aSh2);
+ // MapIntWires.Add(aSh2);
+ // }
+ //}
+
if (sta == TopAbs_UNKNOWN) { // ERREUR
SendWarning ( aw, Message_Msg ( "FixAdvFace.FixOrientation.MSG11" ) );// Cannot orient wire
}