0022818: Wrong triangulation of Revolution surface with slice angle <= 180 degree
authoroan <oan@opencascade.com>
Fri, 22 Mar 2013 13:44:31 +0000 (17:44 +0400)
committeroan <oan@opencascade.com>
Fri, 22 Mar 2013 13:44:31 +0000 (17:44 +0400)
Take face attributes into account to calculate 2d tolerance
Adding test cases for this fix
Correction according additional bug CR23832

src/BRepMesh/BRepMesh_FastDiscret.cxx
src/BRepMesh/BRepMesh_FastDiscretFace.cdl
src/BRepMesh/BRepMesh_FastDiscretFace.cxx
tests/bugs/modalg_2/bug22818_1
tests/bugs/modalg_2/bug22818_2
tests/bugs/modalg_2/bug22818_3 [new file with mode: 0755]
tests/bugs/modalg_2/bug22818_4 [new file with mode: 0755]

index a2e543a..c6fd0ef 100755 (executable)
@@ -905,7 +905,12 @@ void BRepMesh_FastDiscret::Add( const TopoDS_Edge&                  theEdge,
     }
     myVertices.Bind(pBegin, ipf);
   }
-  theUV = BRepMesh_FastDiscretFace::FindUV(pBegin, uvFirst, ipf, theGFace, mindist, myLocation2d);
+
+  Handle(BRepMesh_FaceAttribute) aFaceAttribute;
+  GetFaceAttribute ( theFace, aFaceAttribute );
+  theUV = BRepMesh_FastDiscretFace::FindUV(pBegin, uvFirst, 
+    ipf, theGFace, mindist, aFaceAttribute, myLocation2d);
+
   BRepMesh_Vertex vf(theUV, ipf, BRepMesh_Frontier);
   Standard_Integer ivf = myStructure->AddNode(vf);
 
@@ -936,7 +941,10 @@ void BRepMesh_FastDiscret::Add( const TopoDS_Edge&                  theEdge,
       myVertices.Bind(pEnd,ipl);
     }
   }
-  theUV = BRepMesh_FastDiscretFace::FindUV(pEnd, uvLast, ipl, theGFace, mindist, myLocation2d);
+
+  theUV = BRepMesh_FastDiscretFace::FindUV(pEnd, uvLast, ipl, 
+    theGFace, mindist, aFaceAttribute, myLocation2d);
+
   BRepMesh_Vertex vl(theUV, ipl, BRepMesh_Frontier);
   Standard_Integer ivl= myStructure->AddNode(vl);
 
@@ -1395,7 +1403,12 @@ Standard_Boolean BRepMesh_FastDiscret::Update(const TopoDS_Edge&          theEdg
           myVertices.Bind(pBegin,ipf);
         }
         NewNodInStruct(1) = ipf;
-        theUV = BRepMesh_FastDiscretFace::FindUV(pBegin, uvFirst, ipf, gFace, mindist, myLocation2d);
+
+        Handle(BRepMesh_FaceAttribute) aFaceAttribute;
+        GetFaceAttribute ( theFace, aFaceAttribute );
+        theUV = BRepMesh_FastDiscretFace::FindUV(pBegin, uvFirst, ipf, 
+          gFace, mindist, aFaceAttribute, myLocation2d);
+
         BRepMesh_Vertex vf(theUV,ipf,BRepMesh_Frontier);
         iv1 = myStructure->AddNode(vf);
         isv1 = myVemap.FindIndex(iv1);
@@ -1432,7 +1445,9 @@ Standard_Boolean BRepMesh_FastDiscret::Update(const TopoDS_Edge&          theEdg
           }
         }
         NewNodInStruct(nbnodes) = ipl;
-        theUV = BRepMesh_FastDiscretFace::FindUV(pEnd, uvLast, ipl, gFace, mindist, myLocation2d);
+        theUV = BRepMesh_FastDiscretFace::FindUV(pEnd, uvLast, ipl, 
+          gFace, mindist, aFaceAttribute, myLocation2d);
+
         BRepMesh_Vertex vl(theUV,ipl,BRepMesh_Frontier);
         
         ivl = myStructure->AddNode(vl);
index b35e17f..f0e7ac1 100755 (executable)
@@ -112,7 +112,8 @@ is
                 theXY           : Pnt2d                             from gp;
                 theIp           : Integer                           from Standard; 
                 theSFace        : HSurface                          from BRepAdaptor; 
-                theMinDist      : Real                              from  Standard;
+                theMinDist      : Real                              from Standard;
+                theFaceAttribute: FaceAttribute                     from BRepMesh;
                 theLocation2dMap: in out DataMapOfIntegerListOfXY   from BRepMesh)
           returns XY from gp;
 
index f02445e..58247f7 100755 (executable)
@@ -421,7 +421,7 @@ Standard_Boolean BRepMesh_FastDiscretFace::RestoreStructureFromTriangulation
   if (mindist < BRep_Tool::Tolerance(pBegin) ||
       mindist < BRep_Tool::Tolerance(pEnd) ) mindist = theDefEdge;
   
-  anUV = FindUV(pBegin, uvFirst, ipf, theSurf, mindist, myLocation2d);
+  anUV = FindUV(pBegin, uvFirst, ipf, theSurf, mindist, myAttrib, myLocation2d);
   Standard_Integer iv1, isv1;
   BRepMesh_Vertex vf(anUV, ipf, BRepMesh_Frontier);
   iv1 = myStructure->AddNode(vf);
@@ -462,7 +462,7 @@ Standard_Boolean BRepMesh_FastDiscretFace::RestoreStructureFromTriangulation
     }
   }
 
-  anUV = FindUV(pEnd, uvLast, ipl, theSurf, mindist, myLocation2d);
+  anUV = FindUV(pEnd, uvLast, ipl, theSurf, mindist, myAttrib, myLocation2d);
   BRepMesh_Vertex vl(anUV, ipl, BRepMesh_Frontier);
   
   Standard_Integer isvl;
@@ -1710,12 +1710,13 @@ const gp_Pnt& BRepMesh_FastDiscretFace::Pnt(const Standard_Integer Index) const
 //purpose  : 
 //=======================================================================
 
-gp_XY BRepMesh_FastDiscretFace::FindUV(const TopoDS_Vertex&                 theV,
-                                       const gp_Pnt2d&                      theXY,
-                                       const Standard_Integer               theIp,
-                                       const Handle(BRepAdaptor_HSurface)&  theSFace,
-                                       const Standard_Real                  theMinDist,
-                                       BRepMesh_DataMapOfIntegerListOfXY&   theLocation2dMap)
+gp_XY BRepMesh_FastDiscretFace::FindUV(const TopoDS_Vertex&                  theV,
+                                       const gp_Pnt2d&                       theXY,
+                                       const Standard_Integer                theIp,
+                                       const Handle(BRepAdaptor_HSurface)&   theSFace,
+                                       const Standard_Real                   theMinDist,
+                                       const Handle(BRepMesh_FaceAttribute)& theFaceAttribute,
+                                       BRepMesh_DataMapOfIntegerListOfXY&    theLocation2dMap)
 {
   gp_XY anUV;
   if (theLocation2dMap.IsBound(theIp))
@@ -1740,8 +1741,21 @@ gp_XY BRepMesh_FastDiscretFace::FindUV(const TopoDS_Vertex&                 theV
 
     const Standard_Real tol = Min(2. * BRep_Tool::Tolerance(theV), theMinDist);
 
-    const Standard_Real Utol2d = .5 * (theSFace->LastUParameter() - theSFace->FirstUParameter());
-    const Standard_Real Vtol2d = .5 * (theSFace->LastVParameter() - theSFace->FirstVParameter());
+    Standard_Real aDiffU, aDiffV;
+    
+    if ( theFaceAttribute.IsNull() )
+    {
+      aDiffU = theSFace->LastUParameter() - theSFace->FirstUParameter();
+      aDiffV = theSFace->LastVParameter() - theSFace->FirstVParameter();
+    }
+    else
+    {
+      aDiffU = theFaceAttribute->GetUMax() - theFaceAttribute->GetUMin();
+      aDiffV = theFaceAttribute->GetVMax() - theFaceAttribute->GetVMin();
+    }
+
+    const Standard_Real Utol2d = .5 * aDiffU;
+    const Standard_Real Vtol2d = .5 * aDiffV;
 
     const gp_Pnt p1 = theSFace->Value(anUV.X(), anUV.Y());
     const gp_Pnt p2 = theSFace->Value(theXY.X(), theXY.Y());
@@ -1811,7 +1825,7 @@ void BRepMesh_FastDiscretFace::Add(const TopoDS_Vertex&                theVert,
   }
   Standard_Real mindist = BRep_Tool::Tolerance(theVert);
   // gp_Pnt2d uvXY = BRep_Tool::Parameters(theVert,theFace);
-  gp_XY anUV = FindUV(theVert, uvXY, indVert, thegFace, mindist, myLocation2d);
+  gp_XY anUV = FindUV(theVert, uvXY, indVert, thegFace, mindist, myAttrib, myLocation2d);
   BRepMesh_Vertex vf(anUV, indVert, BRepMesh_Fixed);
   Standard_Integer ivff = myStructure->AddNode(vf);
   Standard_Integer isvf = myVemap.FindIndex(ivff);
index 25e8195..255991a 100755 (executable)
@@ -1,3 +1,5 @@
+puts "TODO OCC23832 ALL: Error   : area by triangles differs from the actual area by"
+
 puts "================"
 puts "OCC22818"
 puts "================"
@@ -33,4 +35,24 @@ set nb_compsol_good 0
 set nb_compound_good 0
 set nb_shape_good 21
 
-set 3dviewer 1
+vinit
+vdisplay result
+vsetdispmode 1
+vfit
+vzfit
+
+# relative tolerance (%)
+set rel_tol 1
+set area_eps 0
+#
+puts "\nChecking triangulation area (triarea command)..."
+set rel_err [expr abs([CheckTriArea result $area_eps])]
+if { $rel_err > $rel_tol } {
+   puts "Error   : area by triangles differs from the actual area by $rel_err %"
+} else {
+   if { $rel_tol > 1 && $rel_tol < 100 } {
+      puts "Error: Improvement: The current area difference is $rel_err instead of $rel_tol"
+   }
+}
+
+set only_screen 1
index 2b8995b..04a84a4 100755 (executable)
@@ -1,3 +1,5 @@
+puts "TODO OCC23832 ALL: Error   : area by triangles differs from the actual area by"
+
 puts "================"
 puts "OCC22818"
 puts "================"
@@ -34,4 +36,24 @@ set nb_compsol_good 0
 set nb_compound_good 0
 set nb_shape_good 21
 
-set 3dviewer 1
+vinit
+vdisplay result
+vsetdispmode 1
+vfit
+vzfit
+
+# relative tolerance (%)
+set rel_tol 1
+set area_eps 0
+#
+puts "\nChecking triangulation area (triarea command)..."
+set rel_err [expr abs([CheckTriArea result $area_eps])]
+if { $rel_err > $rel_tol } {
+   puts "Error   : area by triangles differs from the actual area by $rel_err %"
+} else {
+   if { $rel_tol > 1 && $rel_tol < 100 } {
+      puts "Error: Improvement: The current area difference is $rel_err instead of $rel_tol"
+   }
+}
+
+set only_screen 1
diff --git a/tests/bugs/modalg_2/bug22818_3 b/tests/bugs/modalg_2/bug22818_3
new file mode 100755 (executable)
index 0000000..596714c
--- /dev/null
@@ -0,0 +1,47 @@
+puts "================"
+puts "OCC22818"
+puts "================"
+puts ""
+#######################################################################################
+# Wrong triangulation of Revolution surface with slice angle <= 180 degree
+######################################################################################
+
+set BugNumber OCC22818
+
+pcone result 10 0 10 180
+
+checkshape result
+
+set square 479.224
+
+set nb_v_good 4
+set nb_e_good 7
+set nb_w_good 4
+set nb_f_good 4
+set nb_sh_good 1
+set nb_sol_good 1
+set nb_compsol_good 0
+set nb_compound_good 0
+set nb_shape_good 21
+
+vinit
+vdisplay result
+vsetdispmode 1
+vfit
+vzfit
+
+# relative tolerance (%)
+set rel_tol 1
+set area_eps 0
+#
+puts "\nChecking triangulation area (triarea command)..."
+set rel_err [expr abs([CheckTriArea result $area_eps])]
+if { $rel_err > $rel_tol } {
+   puts "Error   : area by triangles differs from the actual area by $rel_err %"
+} else {
+   if { $rel_tol > 1 && $rel_tol < 100 } {
+      puts "Error: Improvement: The current area difference is $rel_err instead of $rel_tol"
+   }
+}
+
+set only_screen 1
diff --git a/tests/bugs/modalg_2/bug22818_4 b/tests/bugs/modalg_2/bug22818_4
new file mode 100755 (executable)
index 0000000..d96171a
--- /dev/null
@@ -0,0 +1,50 @@
+puts "================"
+puts "OCC22818"
+puts "================"
+puts ""
+#######################################################################################
+# Wrong triangulation of Revolution surface with slice angle <= 180 degree
+######################################################################################
+
+set BugNumber OCC22818
+
+pcone result 10 0 20 180
+incmesh result 0.1
+triangles result
+isos result 0
+
+checkshape result
+
+set square 708.32
+
+set nb_v_good 4
+set nb_e_good 7
+set nb_w_good 4
+set nb_f_good 4
+set nb_sh_good 1
+set nb_sol_good 1
+set nb_compsol_good 0
+set nb_compound_good 0
+set nb_shape_good 21
+
+vinit
+vdisplay result
+vsetdispmode 1
+vfit
+vzfit
+
+# relative tolerance (%)
+set rel_tol 1
+set area_eps 0
+#
+puts "\nChecking triangulation area (triarea command)..."
+set rel_err [expr abs([CheckTriArea result $area_eps])]
+if { $rel_err > $rel_tol } {
+   puts "Error   : area by triangles differs from the actual area by $rel_err %"
+} else {
+   if { $rel_tol > 1 && $rel_tol < 100 } {
+      puts "Error: Improvement: The current area difference is $rel_err instead of $rel_tol"
+   }
+}
+
+set only_screen 1