]> OCCT Git - occt.git/commitdiff
0029606: [Regression vs 7.0] BRepClass3d_SolidClassifier classifies the point as...
authorifv <ifv@opencascade.com>
Wed, 28 Mar 2018 14:00:50 +0000 (17:00 +0300)
committerbugmaster <bugmaster@opencascade.com>
Mon, 2 Apr 2018 13:36:31 +0000 (16:36 +0300)
Simple treatment of some analytical cases when curve is parallel or belongs surface is added in curve - face/surface intersection algorithm
Treatment such cases is added in classifier algorithm
Test case added

src/BRepClass3d/BRepClass3d_SClassifier.cxx
src/IntCurveSurface/IntCurveSurface_Inter.gxx
src/IntCurveSurface/IntCurveSurface_Intersection.cxx
src/IntCurveSurface/IntCurveSurface_Intersection.hxx
src/IntCurvesFace/IntCurvesFace_Intersector.cxx
src/IntCurvesFace/IntCurvesFace_Intersector.hxx
src/IntCurvesFace/IntCurvesFace_Intersector.lxx
tests/bugs/modalg_7/bug29606 [new file with mode: 0644]

index 451336da096a87822101d94869ad4fc7d827f51f..9db128ccb45f17b20da788fe0748d1e7150e5ff4 100644 (file)
@@ -33,6 +33,8 @@
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopExp.hxx>
+#include <BRepAdaptor_Surface.hxx>
+#include <Extrema_ExtPS.hxx>
 
 #include <vector>
 
@@ -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 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;
index d83d57cf4d9a71e34690fe4c34e01b237e4da635..02da3925398582d030085f916f3af2677496ffd6 100644 (file)
@@ -1252,9 +1252,11 @@ void IntCurveSurface_Inter::AppendIntAna(const TheCurve& curve,
   if(intana_ConicQuad.IsDone()) { 
     if(intana_ConicQuad.IsInQuadric()) { 
       //-- cout<<" Courbe Dans la Quadrique !!! Non Traite !!!"<<endl;
+      myIsParallel = Standard_True;
     }
     else if(intana_ConicQuad.IsParallel()) { 
       //-- cout<<" Courbe // a la Quadrique !!! Non Traite !!!"<<endl;
+      myIsParallel = Standard_True;
     }
     else { 
       Standard_Integer nbp = intana_ConicQuad.NbPoints();
index a8da4f39b5f810c833ab2a030092041176e8f7d1..e3f8e9ce688069e5271ca7578fd7c1e6dcd832bf 100644 (file)
 #define PARAMEQUAL(a,b) (Abs((a)-(b))< (1e-8))
 
 //================================================================================
-IntCurveSurface_Intersection::IntCurveSurface_Intersection(): done(Standard_False) { 
+IntCurveSurface_Intersection::IntCurveSurface_Intersection(): 
+done(Standard_False),
+myIsParallel(Standard_False)
+{ 
 }
 //================================================================================
 Standard_Boolean IntCurveSurface_Intersection::IsDone() const { return(done); } 
 //================================================================================
+Standard_Boolean IntCurveSurface_Intersection::IsParallel() const 
+{ 
+  return(myIsParallel); 
+}
+//================================================================================
 Standard_Integer IntCurveSurface_Intersection::NbPoints() const { 
   if (!done) {throw StdFail_NotDone();}
   return lpnt.Length();
@@ -116,6 +124,7 @@ void IntCurveSurface_Intersection::ResetFields() {
     lseg.Clear();
     lpnt.Clear();
     done=Standard_False;
+    myIsParallel = Standard_False;
   }
 }
 //================================================================================
index a81d4cbaeb87d843e35b98a86f1a621d61c96250..7b9f3064f05d38ad7fc96ef6f3ad4b33bd1daed2 100644 (file)
@@ -64,7 +64,12 @@ public:
   //! the computation has not been done
   //! raises OutOfRange if Index is not in the range <1..NbSegment>
   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:
index 11c1d84d376acbfb2b4e617f6299dd9769ffd7e4..28936081f2021fd57f78322652004a7a3175b913 100644 (file)
@@ -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
index 3a4ddd7ea378fc245701c9978d16bb47e0ab9cdb..c5843541bfefb29122712dfe23314548fd0bb73e 100644 (file)
@@ -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, ...)
 
 
 };
index 1bfdfb04eed4a53bc3dc11c160b74c80c2be0b1f..5724e88f16771c9ec0c6d78b6bfe8714f002b731 100644 (file)
@@ -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 (file)
index 0000000..dbdfccd
--- /dev/null
@@ -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"
+}
+