#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopExp.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <Extrema_ExtPS.hxx>
#include <vector>
{
if(SolidExplorer.RejectShell(L) == Standard_False)
{
- for(SolidExplorer.InitFace();
- SolidExplorer.MoreFace() && !isFaultyLine;
- SolidExplorer.NextFace())
+ for (SolidExplorer.InitFace();
+ SolidExplorer.MoreFace() && !isFaultyLine;
+ SolidExplorer.NextFace())
{
- if(SolidExplorer.RejectFace(L) == Standard_False)
+ if (SolidExplorer.RejectFace(L) == Standard_False)
+ {
+ TopoDS_Shape aLocalShape = SolidExplorer.CurrentFace();
+ TopoDS_Face f = TopoDS::Face(aLocalShape);
+ IntCurvesFace_Intersector& Intersector3d = SolidExplorer.Intersector(f);
+
+ // Prolong segment, since there are cases when
+ // the intersector does not find intersection points with the original
+ // segment due to rough triangulation of a parameterized surface.
+ Standard_Real addW = Max(10 * Tol, 0.01*Par);
+ Standard_Real AddW = addW;
+
+ Bnd_Box aBoxF = Intersector3d.Bounding();
+
+ // The box must be finite in order to correctly prolong the segment to its bounds.
+ if (!aBoxF.IsVoid() && !aBoxF.IsWhole())
{
- TopoDS_Shape aLocalShape = SolidExplorer.CurrentFace();
- TopoDS_Face f = TopoDS::Face(aLocalShape);
- IntCurvesFace_Intersector& Intersector3d = SolidExplorer.Intersector(f);
+ Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
+ aBoxF.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
- // Prolong segment, since there are cases when
- // the intersector does not find intersection points with the original
- // segment due to rough triangulation of a parameterized surface.
- Standard_Real addW = Max(10*Tol, 0.01*Par);
- Standard_Real AddW = addW;
-
- Bnd_Box aBoxF = Intersector3d.Bounding();
-
- // The box must be finite in order to correctly prolong the segment to its bounds.
- if (!aBoxF.IsVoid() && !aBoxF.IsWhole())
- {
- Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
- aBoxF.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
-
- Standard_Real boxaddW = GetAddToParam(L,Par,aBoxF);
- addW = Max(addW,boxaddW);
- }
+ Standard_Real boxaddW = GetAddToParam(L, Par, aBoxF);
+ addW = Max(addW, boxaddW);
+ }
- Standard_Real minW = -AddW;
- Standard_Real maxW = Min(Par*10,Par+addW);
- Intersector3d.Perform(L,minW,maxW);
- if(Intersector3d.IsDone())
+ Standard_Real minW = -AddW;
+ Standard_Real maxW = Min(Par * 10, Par + addW);
+ Intersector3d.Perform(L, minW, maxW);
+ if (Intersector3d.IsDone())
+ {
+ if (Intersector3d.NbPnt() == 0)
{
- for (Standard_Integer i = 1; i <= Intersector3d.NbPnt(); i++)
+ if (Intersector3d.IsParallel())
{
- if(Abs(Intersector3d.WParameter(i)) < Abs(parmin) - Precision::PConfusion())
+ //Check distance between surface and point
+ BRepAdaptor_Surface aBAS(f, Standard_False);
+ Extrema_ExtPS aProj(P, aBAS, Precision::PConfusion(), Precision::PConfusion());
+ if (aProj.IsDone() && aProj.NbExt() > 0)
{
- parmin = Intersector3d.WParameter(i);
- TopAbs_State aState = Intersector3d.State(i);
- if(Abs(parmin)<=Tol)
- {
- myState = 2;
- myFace = f;
+ Standard_Integer i, indmin = 0;
+ Standard_Real d = RealLast();
+ for (i = 1; i <= aProj.NbExt(); ++i)
+ {
+ if (aProj.SquareDistance(i) < d)
+ {
+ d = aProj.SquareDistance(i);
+ indmin = i;
+ }
}
- // Treatment of case TopAbs_ON separately.
- else if(aState==TopAbs_IN)
+ if (indmin > 0)
{
- //-- The intersection point between the line and a face F
- // -- of the solid is in the face F
-
- IntCurveSurface_TransitionOnCurve tran = Intersector3d.Transition(i);
- if (tran == IntCurveSurface_Tangent)
+ if (d <= Tol * Tol)
{
- #ifdef OCCT_DEBUG
- cout<<"*Problem ds BRepClass3d_SClassifier.cxx"<<endl;
- #endif
- continue; // ignore this point
+ const Extrema_POnSurf& aPonS = aProj.Point(indmin);
+ Standard_Real anU, anV;
+ aPonS.Parameter(anU, anV);
+ gp_Pnt2d aP2d(anU, anV);
+ TopAbs_State aSt = Intersector3d.ClassifyUVPoint(aP2d);
+ if (aSt == TopAbs_IN || aSt == TopAbs_ON)
+ {
+ myState = 2;
+ myFace = f;
+ parmin = 0.;
+ break;
+ }
}
-
- Trans(parmin, tran, myState);
- myFace = f;
}
- // If the state is TopAbs_ON, it is necessary to chose
- // another line and to repeat the whole procedure.
- else if(aState==TopAbs_ON)
+ }
+ }
+ }
+ for (Standard_Integer i = 1; i <= Intersector3d.NbPnt(); i++)
+ {
+ if (Abs(Intersector3d.WParameter(i)) < Abs(parmin) - Precision::PConfusion())
+ {
+ parmin = Intersector3d.WParameter(i);
+ TopAbs_State aState = Intersector3d.State(i);
+ if (Abs(parmin) <= Tol)
+ {
+ myState = 2;
+ myFace = f;
+ break;
+ }
+ // Treatment of case TopAbs_ON separately.
+ else if (aState == TopAbs_IN)
+ {
+ //-- The intersection point between the line and a face F
+ // -- of the solid is in the face F
+
+ IntCurveSurface_TransitionOnCurve tran = Intersector3d.Transition(i);
+ if (tran == IntCurveSurface_Tangent)
{
- isFaultyLine = Standard_True;
- break;
+#ifdef OCCT_DEBUG
+ cout<<"*Problem ds BRepClass3d_SClassifier.cxx"<<endl;
+#endif
+ continue; // ignore this point
}
+
+ Trans(parmin, tran, myState);
+ myFace = f;
}
- else
+ // If the state is TopAbs_ON, it is necessary to chose
+ // another line and to repeat the whole procedure.
+ else if (aState == TopAbs_ON)
{
- //-- No point has been found by the Intersector3d.
- //-- Or a Point has been found with a greater parameter.
+ isFaultyLine = Standard_True;
+ break;
}
- } //-- loop by intersection points
- } //-- Face has not been rejected
- else
- myState = 1;
- }
- } //-- Exploration of the faces
+ }
+ else
+ {
+ //-- No point has been found by the Intersector3d.
+ //-- Or a Point has been found with a greater parameter.
+ }
+ } //-- loop by intersection points
+ if (myState == 2)
+ {
+ break;
+ }
+ } //-- Face has not been rejected
+ else
+ myState = 1;
+ }
+ }//-- Exploration of the faces
+ if (myState == 2)
+ {
+ break;
+ }
} //-- Shell has not been rejected
else
myState = 1;