diff --git a/src/BRepClass3d/BRepClass3d_SClassifier.cxx b/src/BRepClass3d/BRepClass3d_SClassifier.cxx index 451336da09..9db128ccb4 100644 --- a/src/BRepClass3d/BRepClass3d_SClassifier.cxx +++ b/src/BRepClass3d/BRepClass3d_SClassifier.cxx @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include @@ -338,87 +340,136 @@ void BRepClass3d_SClassifier::Perform(BRepClass3d_SolidExplorer& SolidExplorer, { 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 minW = -AddW; - Standard_Real maxW = Min(Par*10,Par+addW); - Intersector3d.Perform(L,minW,maxW); - if(Intersector3d.IsDone()) - { - 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; - } - // 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) - { - #ifdef OCCT_DEBUG - cout<<"*Problem ds BRepClass3d_SClassifier.cxx"< 0) + { + 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; + } + } + if (indmin > 0) + { + if (d <= Tol * Tol) + { + 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; + } + } + } + } + } + } + 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) + { +#ifdef OCCT_DEBUG + cout<<"*Problem ds BRepClass3d_SClassifier.cxx"< Standard_EXPORT const IntCurveSurface_IntersectionSegment& Segment (const Standard_Integer Index) const; - + + //! Returns true if curve is parallel or belongs surface + //! This case is recognized only for some pairs + //! of analytical curves and surfaces (plane - line, ...) + Standard_EXPORT Standard_Boolean IsParallel() const; + //! Dump all the fields. Standard_EXPORT void Dump() const; @@ -101,6 +106,9 @@ protected: Standard_Boolean done; + Standard_Boolean myIsParallel; //Curve is "parallel" surface + //This case is recognized only for some pairs + //of analytical curves and surfaces (plane - line, ...) private: diff --git a/src/IntCurvesFace/IntCurvesFace_Intersector.cxx b/src/IntCurvesFace/IntCurvesFace_Intersector.cxx index 11c1d84d37..28936081f2 100644 --- a/src/IntCurvesFace/IntCurvesFace_Intersector.cxx +++ b/src/IntCurvesFace/IntCurvesFace_Intersector.cxx @@ -135,7 +135,8 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face, nbpnt(0), PtrOnPolyhedron(NULL), PtrOnBndBounding(NULL), - myUseBoundTol (UseBToler) + myUseBoundTol (UseBToler), + myIsParallel(Standard_False) { BRepAdaptor_Surface surface; face = Face; @@ -336,6 +337,10 @@ void IntCurvesFace_Intersector::InternalCall(const IntCurveSurface_HInter &HICS, } //-- classifier state is IN or ON } //-- Loop on Intersection points. } //-- HICS.IsDone() + else if (HICS.IsDone()) + { + myIsParallel = HICS.IsParallel(); + } } //======================================================================= //function : Perform diff --git a/src/IntCurvesFace/IntCurvesFace_Intersector.hxx b/src/IntCurvesFace/IntCurvesFace_Intersector.hxx index 3a4ddd7ea3..c5843541bf 100644 --- a/src/IntCurvesFace/IntCurvesFace_Intersector.hxx +++ b/src/IntCurvesFace/IntCurvesFace_Intersector.hxx @@ -113,7 +113,12 @@ public: //! or TopAbs_ON //! ( the point is on a boudary of the face). TopAbs_State State (const Standard_Integer I) const; - + + //! Returns true if curve is parallel or belongs face surface + //! This case is recognized only for some pairs + //! of analytical curves and surfaces (plane - line, ...) + Standard_Boolean IsParallel() const; + //! Returns the significant face used to determine //! the intersection. const TopoDS_Face& Face() const; @@ -160,6 +165,9 @@ private: Standard_Address PtrOnPolyhedron; Standard_Address PtrOnBndBounding; Standard_Boolean myUseBoundTol; + Standard_Boolean myIsParallel; //Curve is "parallel" face surface + //This case is recognized only for some pairs + //of analytical curves and surfaces (plane - line, ...) }; diff --git a/src/IntCurvesFace/IntCurvesFace_Intersector.lxx b/src/IntCurvesFace/IntCurvesFace_Intersector.lxx index 1bfdfb04ee..5724e88f16 100644 --- a/src/IntCurvesFace/IntCurvesFace_Intersector.lxx +++ b/src/IntCurvesFace/IntCurvesFace_Intersector.lxx @@ -58,7 +58,10 @@ inline TopAbs_State IntCurvesFace_Intersector::State(const Standard_Integer i) c } // Modified by skv - Wed Sep 3 15:34:20 2003 OCC578 End //============================================================================ -inline const TopoDS_Face& IntCurvesFace_Intersector::Face() const { +inline Standard_Boolean IntCurvesFace_Intersector::IsParallel() const { + return myIsParallel; +} +inline const TopoDS_Face& IntCurvesFace_Intersector::Face() const { return(face); } //============================================================================ diff --git a/tests/bugs/modalg_7/bug29606 b/tests/bugs/modalg_7/bug29606 new file mode 100644 index 0000000000..dbdfccd957 --- /dev/null +++ b/tests/bugs/modalg_7/bug29606 @@ -0,0 +1,17 @@ +puts "========" +puts "OCC29606" +puts "========" +puts "" +####################################################### +#0029606: [Regression vs 7.0] BRepClass3d_SolidClassifier +#classifies the point as IN while it is ON +####################################################### + +restore [locate_data_file bug29606.brep] s + +point p1 621.05410336809734 47.416378469999998 111.25010709375 + +if {![regexp "The point is ON" [bclassify s p1]]} { + puts "Error: The Solid classification algorithm fails to classify the point" +} +