]> OCCT Git - occt.git/commitdiff
0025519: BRepMesh can break mesh regularity for BSpline surfaces
authoroan <oan@opencascade.com>
Thu, 11 Dec 2014 13:19:31 +0000 (16:19 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 11 Dec 2014 13:20:31 +0000 (16:20 +0300)
Compute parameters to produce regular grid and add new internal points according to calculated values.
Use intervals as an additional parameters to determine regular grid for BSpline surfaces.

Test case for issue CR25519

Correction of test case for issue CR25519

Correction of test cases for issue CR25519

src/BRepMesh/BRepMesh_FastDiscretFace.cxx
tests/bugs/mesh/bug25519 [new file with mode: 0755]
tests/mesh/data/advanced/B6

index ad1471c3dfad1ec42b9d5be9b9b4894000cf9147..f1d9d50ce2fc6786d79e9bbb4317cc5ff263f44e 100644 (file)
@@ -186,9 +186,10 @@ void BRepMesh_FastDiscretFace::initDataStructure()
   // Check the necessity to fill the map of parameters
   const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface();
   GeomAbs_SurfaceType thetype = gFace->GetType();
-  const Standard_Boolean useUVParam = (thetype == GeomAbs_Torus         ||
-                                       thetype == GeomAbs_BezierSurface ||
-                                       thetype == GeomAbs_BSplineSurface);
+  const Standard_Boolean isBSpline = (thetype == GeomAbs_BezierSurface ||
+                                      thetype == GeomAbs_BSplineSurface);
+  const Standard_Boolean useUVParam = (thetype == GeomAbs_Torus ||isBSpline);
+
   myUParam.Clear(); 
   myVParam.Clear();
 
@@ -217,6 +218,40 @@ void BRepMesh_FastDiscretFace::initDataStructure()
   }
   aBoundaryNodes.Nullify();
 
+  if (isBSpline)
+  {
+    const Standard_Real aRange[2][2] = {
+      {myAttribute->GetUMin(), myAttribute->GetUMax()},
+      {myAttribute->GetVMin(), myAttribute->GetVMax()}
+    };
+
+    const GeomAbs_Shape aContinuity = GeomAbs_CN;
+    for (Standard_Integer i = 0; i < 2; ++i)
+    {
+      const Standard_Boolean isU = (i == 0);
+      const Standard_Integer aIntervalsNb = isU ?
+        gFace->NbUIntervals(aContinuity) :
+        gFace->NbVIntervals(aContinuity);
+
+      BRepMesh::IMapOfReal& aParams = isU ? myUParam : myVParam;
+      if (aIntervalsNb < aParams.Size())
+        continue;
+
+      TColStd_Array1OfReal aIntervals(1, aIntervalsNb + 1);
+      if (isU)
+        gFace->UIntervals(aIntervals, aContinuity);
+      else
+        gFace->VIntervals(aIntervals, aContinuity);
+
+      for (Standard_Integer j = 1; j <= aIntervals.Upper(); ++j)
+      {
+        const Standard_Real aParam = aIntervals(j);
+        if (aParam > aRange[i][0] && aParam < aRange[i][1])
+          aParams.Add(aParam);
+      }
+    }
+  }
+
   //////////////////////////////////////////////////////////// 
   //add internal vertices after self-intersection check
   if ( myInternalVerticesMode )
@@ -914,25 +949,30 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesBSpline(
           {
             aPrevParam2 = aParam2;
             aPrevPnt2   = aPnt2;
-
-            if (!isU && j < aParams2.Length())
-            {
-              // Update point parameter.
-              aStPnt1.SetX(aPrevParam2);
-
-              // Classify intersection point
-              if (aClassifier->Perform(aStPnt1) == TopAbs_IN)
-              {
-                insertVertex(aPrevPnt2, aStPnt1.Coord(), theNewVertices);
-              }
-            }
-
             ++j;
           }
         }
       }
     }
   }
+
+  // insert nodes of the regular grid
+  for (Standard_Integer i = 1; i <= aParams[0].Length(); ++i)
+  {
+    const Standard_Real aParam1 = aParams[0].Value(i);
+    for (Standard_Integer j = 1; j <= aParams[1].Length(); ++j)
+    {
+      gp_Pnt2d aPnt2d(aParam1, aParams[1].Value(j));
+
+      // Classify intersection point
+      if (aClassifier->Perform(aPnt2d) == TopAbs_IN)
+      {
+        gp_Pnt aPnt;
+        gFace->D0(aPnt2d.X(), aPnt2d.Y(), aPnt);
+        insertVertex(aPnt, aPnt2d.Coord(), theNewVertices);
+      }
+    }
+  }
 }
 
 //=======================================================================
diff --git a/tests/bugs/mesh/bug25519 b/tests/bugs/mesh/bug25519
new file mode 100755 (executable)
index 0000000..02c79e9
--- /dev/null
@@ -0,0 +1,45 @@
+puts "================"
+puts "CR25519"
+puts "================"
+puts ""
+###############################################
+## BRepMesh can break mesh regularity for BSpline surfaces
+###############################################
+
+restore [locate_data_file bug25519_testtriangulation.brep] a
+
+tclean a
+incmesh a 0.01
+front
+fit
+isos a 0
+triangles a
+
+set trinfo_s [trinfo a]
+regexp {([0-9]+) triangles} ${trinfo_s} str nbtri_s
+regexp {([0-9]+) nodes} ${trinfo_s} str nbnod_s
+regexp {deflection ([0-9.+e-]+)} ${trinfo_s} str defl_s
+
+set good_nbtri 2721
+set good_nbnod 1405
+set good_defl 0.082010129769776202
+
+set good_percent 5
+
+set nbtri_percent [expr abs (${good_nbtri} - ${nbtri_s}) / double (${nbtri_s}) * 100 ]
+set nbnod_percent [expr abs (${good_nbnod} - ${nbnod_s}) / double (${nbnod_s}) * 100 ]
+set defl_percent  [expr abs (${good_defl} - ${defl_s}) / ${defl_s} * 100 ]
+
+if { ${nbtri_percent} > ${good_percent} } {
+  puts "Error: triangle number is bad, it has changed to ${nbtri_percent} %"
+}
+
+if { ${nbnod_percent} > ${good_percent} } {
+  puts "Error: node number is bad, it has changed to ${nbnod_percent} %"
+}
+
+if { ${defl_percent} > ${good_percent} } {
+  puts "Error: deflection is bad, it has changed to ${defl_percent} %"
+}
+
+set only_screen_axo 1
index 9da4deb93dfaad528f80070278fb03a0befa75ce..fec0a49b85a617147d33b1956b3270722166f3e0 100755 (executable)
@@ -1 +1,7 @@
 set TheFileName OCC22247.brep
+if { [string compare $command "incmesh"] == 0 ||
+     [string compare $command "mesh"] == 0 ||
+     [string compare $command "incmesh_parallel"] == 0 } {
+  set bug_area "OCC25519"
+  set rel_tol 1.3654
+}