]> OCCT Git - occt.git/commitdiff
0028490: Point located outside the solid is classified as inside
authorifv <ifv@opencascade.com>
Fri, 3 Mar 2017 12:34:11 +0000 (15:34 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 22 Jun 2017 08:31:00 +0000 (11:31 +0300)
New method for building surface polyhedron (class IntCurveSurface_Polyhedron), which takes in account intervals of discontinuity of surface is added for constructor IntCurvesFace_Intersector.

Bug in methods NbU(V)Intervals and U(V)Intervals for Offset surfaces is fixed.

src/GeomAdaptor/GeomAdaptor_Surface.cxx
src/IntCurvesFace/IntCurvesFace_Intersector.cxx
tests/bugs/modalg_6/bug28490_1 [new file with mode: 0644]
tests/bugs/modalg_6/bug28490_2 [new file with mode: 0644]
tests/bugs/step/bug24055

index 24e054270b5e23d129b8baaf43b830085e7fad13..04a7b35a6c31c6047dff630e73d633f1b0bb6570 100644 (file)
@@ -353,7 +353,7 @@ Standard_Integer GeomAdaptor_Surface::NbUIntervals(const GeomAbs_Shape S) const
         case GeomAbs_CN: break;
       }
       Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface);
-      GeomAdaptor_Surface Sur(myOffSurf->BasisSurface());
+      GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast);
       return Sur.NbUIntervals(BaseS);
     }
     case GeomAbs_Plane:
@@ -406,7 +406,7 @@ Standard_Integer GeomAdaptor_Surface::NbVIntervals(const GeomAbs_Shape S) const
         case GeomAbs_CN: break;
       }
       Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface);
-      GeomAdaptor_Surface Sur(myOffSurf->BasisSurface());
+      GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast);
       return Sur.NbVIntervals(BaseS);
     }
     case GeomAbs_Plane:
@@ -465,7 +465,7 @@ void GeomAdaptor_Surface::UIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shap
         case GeomAbs_CN: break;
       }
       Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface);
-      GeomAdaptor_Surface Sur(myOffSurf->BasisSurface());
+      GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast);
       myNbUIntervals = Sur.NbUIntervals(BaseS);
       Sur.UIntervals(T, BaseS);
     }
@@ -528,7 +528,7 @@ void GeomAdaptor_Surface::VIntervals(TColStd_Array1OfReal& T, const GeomAbs_Shap
         case GeomAbs_CN: break;
       }
       Handle(Geom_OffsetSurface) myOffSurf = Handle(Geom_OffsetSurface)::DownCast(mySurface);
-      GeomAdaptor_Surface Sur(myOffSurf->BasisSurface());
+      GeomAdaptor_Surface Sur(myOffSurf->BasisSurface(), myUFirst, myULast, myVFirst, myVLast);
       myNbVIntervals = Sur.NbVIntervals(BaseS);
       Sur.VIntervals(T, BaseS);
     }
index b43438ab3bca31d842729d0fe3d7f2bac43c6df4..02417ea2314971327fd6b5f731a4f3fb66c1d498 100644 (file)
 #include <BRep_Tool.hxx>
 #include <TopoDS.hxx>
 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
+//
+static void ComputeSamplePars(const Handle(Adaptor3d_HSurface)& Hsurface, 
+                              const Standard_Integer nbsu,
+                              const Standard_Integer nbsv,
+                              Handle(TColStd_HArray1OfReal)& UPars, 
+                              Handle(TColStd_HArray1OfReal)& VPars)
+{
+  Standard_Integer NbUInts = Hsurface->NbUIntervals(GeomAbs_C2);
+  Standard_Integer NbVInts = Hsurface->NbVIntervals(GeomAbs_C2);
+  TColStd_Array1OfReal UInts(1, NbUInts + 1);
+  TColStd_Array1OfReal VInts(1, NbVInts + 1);
+  Hsurface->UIntervals(UInts, GeomAbs_C2);
+  Hsurface->VIntervals(VInts, GeomAbs_C2);
+  //
+  TColStd_Array1OfInteger NbUSubInts(1, NbUInts);
+  TColStd_Array1OfInteger NbVSubInts(1, NbVInts);
+  //
+  Standard_Integer i, j, ind, NbU, NbV;
+  Standard_Real t, dt;
+  t = UInts(NbUInts + 1) - UInts(1);
+  t = 1. / t;
+  NbU = 0;
+  for(i = 1; i <= NbUInts; ++i)
+  {
+    dt = (UInts(i+1) - UInts(i));
+    NbUSubInts(i) = RealToInt(nbsu * dt * t) + 1;
+    NbU += NbUSubInts(i);
+  }
+  t = VInts(NbVInts + 1) - VInts(1);
+  t = 1. / t;
+  NbV = 0;
+  for(i = 1; i <= NbVInts; ++i)
+  {
+    dt = (VInts(i+1) - VInts(i));
+    NbVSubInts(i) = RealToInt(nbsv * dt * t) + 1;
+    NbV += NbVSubInts(i);
+  }
+  UPars = new TColStd_HArray1OfReal(1, NbU + 1);
+  VPars = new TColStd_HArray1OfReal(1, NbV + 1);
+  //
+  ind = 1;
+  for(i = 1; i <= NbUInts; ++i)
+  {
+    UPars->SetValue(ind++, UInts(i));
+    dt = (UInts(i+1) - UInts(i)) / NbUSubInts(i);
+    t = UInts(i);
+    for(j = 1; j < NbUSubInts(i); ++j)
+    {
+      t += dt;
+      UPars->SetValue(ind++, t);
+    }
+  }
+  UPars->SetValue(ind, UInts(NbUInts + 1));
+  //
+  ind = 1;
+  for(i = 1; i <= NbVInts; ++i)
+  {
+    VPars->SetValue(ind++, VInts(i));
+    dt = (VInts(i+1) - VInts(i)) / NbVSubInts(i);
+    t = VInts(i);
+    for(j = 1; j < NbVSubInts(i); ++j)
+    {
+      t += dt;
+      VPars->SetValue(ind++, t);
+    }
+  }
+  VPars->SetValue(ind, VInts(NbVInts + 1));
+}
+//
 //=======================================================================
 //function : SurfaceType
 //purpose  : 
@@ -86,24 +155,28 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
     U1 = Hsurface->LastUParameter();
     V0 = Hsurface->FirstVParameter();
     V1 = Hsurface->LastVParameter();
-
+    //
+    nbsu = myTopolTool->NbSamplesU();
+    nbsv = myTopolTool->NbSamplesV();
+    //
     Standard_Real aURes = Hsurface->UResolution(1.0);
     Standard_Real aVRes = Hsurface->VResolution(1.0);
 
     // Checking correlation between number of samples and length of the face along each axis
     const Standard_Real aTresh = 100.0;
-    const Standard_Integer aMinSamples = 10;
+    Standard_Integer aMinSamples = 20;
     const Standard_Integer aMaxSamples = 40;
     const Standard_Integer aMaxSamples2 = aMaxSamples * aMaxSamples;
     Standard_Real dU = (U1 - U0) / aURes;
     Standard_Real dV = (V1 - V0) / aVRes;
-    nbsu = myTopolTool->NbSamplesU();
-    nbsv = myTopolTool->NbSamplesV();
+    if (nbsu < aMinSamples) nbsu = aMinSamples;
+    if (nbsv < aMinSamples) nbsv = aMinSamples;
     if (nbsu > aMaxSamples) nbsu = aMaxSamples;
     if (nbsv > aMaxSamples) nbsv = aMaxSamples;
 
     if (Max(dU, dV) > Min(dU, dV) * aTresh)
     {
+      aMinSamples = 10;
       nbsu = (Standard_Integer)(Sqrt(dU / dV) * aMaxSamples);
       if (nbsu < aMinSamples) nbsu = aMinSamples;
       nbsv = aMaxSamples2 / nbsu;
@@ -113,8 +186,23 @@ IntCurvesFace_Intersector::IntCurvesFace_Intersector(const TopoDS_Face& Face,
         nbsu = aMaxSamples2 / aMinSamples;
       }
     }
-    PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *)
+
+    Standard_Integer NbUOnS = Hsurface->NbUIntervals(GeomAbs_C2);
+    Standard_Integer NbVOnS = Hsurface->NbVIntervals(GeomAbs_C2);
+
+    if(NbUOnS > 1 || NbVOnS > 1)
+    {
+      Handle(TColStd_HArray1OfReal) UPars, VPars;
+      ComputeSamplePars(Hsurface, nbsu, nbsv, UPars, VPars);
+      PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *)
+        new IntCurveSurface_ThePolyhedronOfHInter(Hsurface, UPars->ChangeArray1(), 
+                                                            VPars->ChangeArray1());
+    }
+    else 
+    {
+      PtrOnPolyhedron = (IntCurveSurface_ThePolyhedronOfHInter *)
         new IntCurveSurface_ThePolyhedronOfHInter(Hsurface,nbsu,nbsv,U0,V0,U1,V1);
+    }
   }
 }
 //=======================================================================
diff --git a/tests/bugs/modalg_6/bug28490_1 b/tests/bugs/modalg_6/bug28490_1
new file mode 100644 (file)
index 0000000..c83c93b
--- /dev/null
@@ -0,0 +1,21 @@
+puts "========"
+puts "OCC28490"
+puts "========"
+puts ""
+###########################################################
+# Point located outside the solid is classified as inside
+###########################################################
+
+restore [locate_data_file bug28490_solid_vertex1.brep] a
+explode a
+mkpoint p a_2
+set case_output [string trim [bclassify a_1 p]]
+
+if {$case_output != "The point is OUT of shape"} {
+  puts "ERROR: OCC28490 is reproduced. Point is classified as INNER."
+}
+
+smallview
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_6/bug28490_2 b/tests/bugs/modalg_6/bug28490_2
new file mode 100644 (file)
index 0000000..cb4e119
--- /dev/null
@@ -0,0 +1,21 @@
+puts "========"
+puts "OCC28490"
+puts "========"
+puts ""
+###########################################################
+# Point located outside the solid is classified as inside
+###########################################################
+
+restore [locate_data_file bug28490_solid_vertex2.brep] a
+explode a
+mkpoint p a_2
+set case_output [string trim [bclassify a_1 p]]
+
+if {$case_output != "The point is OUT of shape"} {
+  puts "ERROR: OCC28490 is reproduced. Point is classified as INNER."
+}
+
+smallview
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
index 88a1105022a48ec4d4fbe46987ce739be8a938bd..dda9296c0231bcc48b41f09d4d147c21747e257c 100644 (file)
@@ -1,5 +1,3 @@
-puts "TODO OCC25555 ALL: Faulty shapes in variables faulty_1 to faulty_"
-
 puts "============"
 puts "OCC24055"
 puts "============"