#include <BRepClass_Intersector.hxx>
#include <ElCLib.hxx>
#include <Extrema_ExtPC2d.hxx>
+#include <GCE2d_MakeSegment.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_Line.hxx>
#include <Geom2dInt_GInter.hxx>
const Standard_Real aT,
Standard_Real& aTolZ);
+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);
+
+static
+void CheckSkip(Geom2dInt_GInter& theInter,
+ const gp_Lin2d& theL,
+ const BRepClass_Edge& theE,
+ const Handle(Geom2d_Curve)& theC2D,
+ 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);
+
+
//=======================================================================
//function : BRepClass_Intersector
//purpose :
//=======================================================================
-BRepClass_Intersector::BRepClass_Intersector()
+BRepClass_Intersector::BRepClass_Intersector() : myMaxTolerance(0.1)
+{
+}
+
+//=======================================================================
+//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)
{
+ Extrema_ExtPC2d anExtPC2d(theL.Location(), theCur);
+ Standard_Real aMinDist = RealLast();
+ Standard_Integer aMinInd = 0;
+ if (anExtPC2d.IsDone())
+ {
+ const Standard_Integer aNbPnts = anExtPC2d.NbExt();
+ for (Standard_Integer i = 1; i <= aNbPnts; ++i)
+ {
+ Standard_Real aDist = anExtPC2d.SquareDistance(i);
+
+ if (aDist < aMinDist)
+ {
+ aMinDist = aDist;
+ aMinInd = i;
+ }
+ }
+ }
+
+ if (aMinInd != 0) {
+ aMinDist = Sqrt(aMinDist);
+ }
+ if (aMinDist <= theTolZ) {
+ gp_Pnt2d aPntExact = (anExtPC2d.Point(aMinInd)).Value();
+ Standard_Real aPar = (anExtPC2d.Point(aMinInd)).Parameter();
+ //
+ RefineTolerance(theF, theCur, aPar, theTolZ);
+ //
+ if (aMinDist <= theTolZ) {
+ IntRes2d_Transition aTrOnLin(IntRes2d_Head);
+ IntRes2d_Position aPosOnCurve = IntRes2d_Middle;
+ if (Abs(aPar - theDeb) <= Precision::Confusion()) {
+ aPosOnCurve = IntRes2d_Head;
+ }
+ else if (Abs(aPar - theFin) <= Precision::Confusion()) {
+ aPosOnCurve = IntRes2d_End;
+ }
+ //
+ IntRes2d_Transition aTrOnCurve(aPosOnCurve);
+ thePntInter = IntRes2d_IntersectionPoint(aPntExact, 0., aPar,
+ aTrOnLin, aTrOnCurve,
+ Standard_False);
+ //
+ return Standard_True;
+ }
+ }
+ return Standard_False;
}
+//=======================================================================
+//function : CheckSkip
+//purpose :
+//=======================================================================
+void CheckSkip(Geom2dInt_GInter& theInter,
+ const gp_Lin2d& theL,
+ const BRepClass_Edge& theE,
+ const Handle(Geom2d_Curve)& theC2D,
+ 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)
+{
+ if (theE.Edge().IsNull() || theE.Face().IsNull())
+ {
+ return;
+ }
+ Standard_Boolean anIsLSkip = Standard_False;
+ TopoDS_Vertex aVl; // the last vertex of current edge
+
+ Handle(Geom2d_Curve) aSkipC2D;
+
+ aVl = TopExp::LastVertex(theE.Edge(), Standard_True);
+ if (aVl.IsNull())
+ {
+ return;
+ }
+ const TopoDS_Edge anEl = theE.NextEdge(); // the next edge
+ if (!(BRep_Tool::Tolerance(aVl) > theMaxTol) || theE.NextEdge().IsNull())
+ {
+ return;
+ }
+ Standard_Real aLdeb = 0.0, aLfin = 0.0;
+ Handle(Geom2d_Curve) aLC2D; // the next curve
+
+ aLC2D = BRep_Tool::CurveOnSurface(theE.NextEdge(), theE.Face(), aLdeb, aLfin);
+ if (aLC2D.IsNull())
+ {
+ return;
+ }
+ Standard_Real anA, aB, aC; // coefficients of the straight line
+ Standard_Real aX1, anY1, aX2, anY2; // coordinates of the ends of edges
+ gp_Pnt2d aP1, aP2; // the ends of edges
+
+ theL.Coefficients(anA, aB, aC);
+
+ Standard_Real at1 = theFin;
+ if (theE.Edge().Orientation() != TopAbs_FORWARD)
+ {
+ at1 = theDeb;
+ }
+
+ Standard_Real at2 = aLdeb;
+ if (theE.NextEdge().Orientation() != TopAbs_FORWARD)
+ {
+ at2 = aLfin;
+ }
+
+ aP1 = theC2D->Value(at1);
+ aP2 = aLC2D->Value(at2);
+
+ // Check if points belong to DL domain
+ Standard_Real aPar1 = ElCLib::Parameter(theL, aP1);
+ Standard_Real aPar2 = ElCLib::Parameter(theL, aP2);
+
+ if (!(aPar1 > theDL.FirstParameter() && aPar1 < theDL.LastParameter()) ||
+ !(aPar2 > theDL.FirstParameter() && aPar2 < theDL.LastParameter()))
+ {
+ return;
+ }
+ aX1 = aP1.X(); anY1 = aP1.Y(); aX2 = aP2.X(); anY2 = aP2.Y();
+ Standard_Real aFV = anA * aX1 + aB * anY1 + aC;
+ Standard_Real aSV = anA * aX2 + aB * anY2 + aC;
+
+ // Check for getting into vertex with high tolerance
+ if ((aFV * aSV) >= 0)
+ {
+ anIsLSkip = Standard_False;
+ }
+ else
+ {
+ anIsLSkip = Standard_True;
+ GCE2d_MakeSegment aMkSeg(aP1, aP2);
+ if (!aMkSeg.IsDone())
+ {
+ return;
+ }
+ aSkipC2D = aMkSeg.Value();
+
+ if (aSkipC2D.IsNull() || !anIsLSkip)
+ {
+ return;
+ }
+ // if we got
+ theCur.Load(aSkipC2D);
+ if (theCur.Curve().IsNull())
+ {
+ return;
+ }
+ Standard_Real atoldeb = 1.e-5, atolfin = 1.e-5;
+
+ theDeb = theCur.FirstParameter();
+ theFin = theCur.LastParameter();
+ theCur.D0(theDeb, thePdeb);
+ theCur.D0(theFin, thePfin);
+
+ IntRes2d_Domain aDE(thePdeb, theDeb, atoldeb, thePfin, theFin, atolfin);
+ // temporary periodic domain
+ if (theCur.Curve()->IsPeriodic())
+ {
+ aDE.SetEquivalentParameters(theCur.FirstParameter(),
+ theCur.FirstParameter() +
+ theCur.Curve()->LastParameter() -
+ theCur.Curve()->FirstParameter());
+ }
+
+ theInter = Geom2dInt_GInter(theCGA, theDL, theCur, aDE,
+ Precision::PConfusion(),
+ Precision::PIntersection());
+ }
+}
+
//=======================================================================
//function : Perform
//purpose :
//
// 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())
- {
- const Standard_Integer aNbPnts = anExtPC2d.NbExt();
- for (i = 1; i <= aNbPnts; ++i)
- {
- aDist = anExtPC2d.SquareDistance(i);
-
- if (aDist < MinDist)
- {
- MinDist = aDist;
- MinInd = i;
- }
- }
- }
+ Standard_Boolean aStatusOn = Standard_False;
+ IntRes2d_IntersectionPoint aPntInter;
- 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;
- }
- //
- 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;
- }
+ 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);
Precision::PConfusion(),
Precision::PIntersection());
//
+ // The check is for hitting the intersector to
+ // a vertex with high tolerance
+ if (Inter.IsEmpty())
+ {
+ CheckSkip(Inter, L, E, aC2D, DL,
+ C, CGA, fin, deb, MaxTolerance(), pdeb, pfin);
+ }
+
+ //
SetValues(Inter);
}