0027929: Methods D0 and D1 for trimmed offset surface return different values if...
authornbv <nbv@opencascade.com>
Wed, 5 Oct 2016 11:36:33 +0000 (14:36 +0300)
committerapn <apn@opencascade.com>
Thu, 6 Oct 2016 09:27:40 +0000 (12:27 +0300)
Using osculating surface is forbidden if the normal to basis (for offset) surface is well defined.

Creation of test case for this issue.
Adjusting test cases according to their new behavior.

src/GeomEvaluator/GeomEvaluator_OffsetSurface.cxx
tests/bugs/modalg_4/bug8842_8
tests/bugs/modalg_6/bug27929 [new file with mode: 0644]

index f190f3f..0484659 100644 (file)
@@ -258,12 +258,6 @@ void GeomEvaluator_OffsetSurface::CalculateD1(
   Standard_Boolean isOpposite = Standard_False;
   Standard_Boolean AlongU = Standard_False;
   Standard_Boolean AlongV = Standard_False;
-  if (!myOscSurf.IsNull())
-  {
-    AlongU = myOscSurf->UOscSurf(theU, theV, isOpposite, L);
-    AlongV = myOscSurf->VOscSurf(theU, theV, isOpposite, L);
-  }
-  const Standard_Real aSign = ((AlongV || AlongU) && isOpposite) ? -1. : 1.;
 
   // Normalize derivatives before normal calculation because it gives more stable result.
   // There will be normalized only derivatives greater than 1.0 to avoid differences in last significant digit
@@ -276,48 +270,58 @@ void GeomEvaluator_OffsetSurface::CalculateD1(
   if (aD1VNorm2 > 1.0)
     aD1V /= Sqrt(aD1VNorm2);
 
+  Standard_Boolean isSingular = Standard_False;
   Standard_Integer MaxOrder = 0;
   gp_Vec aNorm = aD1U.Crossed(aD1V);
-  if (aNorm.SquareMagnitude() > MagTol * MagTol)
+  if (aNorm.SquareMagnitude() <= MagTol * MagTol)
   {
-    if (!AlongV && !AlongU)
+    if (!myOscSurf.IsNull())
     {
-      // AlongU or AlongV leads to more complex D1 computation
-      // Try to compute D0 and D1 much simpler
-      aNorm.Normalize();
-      theValue.SetXYZ(theValue.XYZ() + myOffset * aSign * aNorm.XYZ());
-
-      gp_Vec aN0(aNorm.XYZ()), aN1U, aN1V;
-      Standard_Real aScale = (theD1U^theD1V).Dot(aN0);
-      aN1U.SetX(theD2U.Y() * theD1V.Z() + theD1U.Y() * theD2UV.Z()
-        - theD2U.Z() * theD1V.Y() - theD1U.Z() * theD2UV.Y());
-      aN1U.SetY((theD2U.X() * theD1V.Z() + theD1U.X() * theD2UV.Z()
-        - theD2U.Z() * theD1V.X() - theD1U.Z() * theD2UV.X()) * -1.0);
-      aN1U.SetZ(theD2U.X() * theD1V.Y() + theD1U.X() * theD2UV.Y()
-        - theD2U.Y() * theD1V.X() - theD1U.Y() * theD2UV.X());
-      Standard_Real aScaleU = aN1U.Dot(aN0);
-      aN1U.Subtract(aScaleU * aN0);
-      aN1U /= aScale;
-
-      aN1V.SetX(theD2UV.Y() * theD1V.Z() + theD2V.Z() * theD1U.Y()
-        - theD2UV.Z() * theD1V.Y() - theD2V.Y() * theD1U.Z());
-      aN1V.SetY((theD2UV.X() * theD1V.Z() + theD2V.Z() * theD1U.X()
-        - theD2UV.Z() * theD1V.X() - theD2V.X() * theD1U.Z()) * -1.0);
-      aN1V.SetZ(theD2UV.X() * theD1V.Y() + theD2V.Y() * theD1U.X()
-        - theD2UV.Y() * theD1V.X() - theD2V.X() * theD1U.Y());
-      Standard_Real aScaleV = aN1V.Dot(aN0);
-      aN1V.Subtract(aScaleV * aN0);
-      aN1V /= aScale;
-
-      theD1U += myOffset * aSign * aN1U;
-      theD1V += myOffset * aSign * aN1V;
-
-      return;
+      AlongU = myOscSurf->UOscSurf(theU, theV, isOpposite, L);
+      AlongV = myOscSurf->VOscSurf(theU, theV, isOpposite, L);
     }
-  }
-  else
+
     MaxOrder = 3;
+    isSingular = Standard_True;
+  }
 
+  const Standard_Real aSign = ((AlongV || AlongU) && isOpposite) ? -1. : 1.;
+  
+  if (!isSingular)
+  {
+    // AlongU or AlongV leads to more complex D1 computation
+    // Try to compute D0 and D1 much simpler
+    aNorm.Normalize();
+    theValue.SetXYZ(theValue.XYZ() + myOffset * aSign * aNorm.XYZ());
+
+    gp_Vec aN0(aNorm.XYZ()), aN1U, aN1V;
+    Standard_Real aScale = (theD1U^theD1V).Dot(aN0);
+    aN1U.SetX(theD2U.Y() * theD1V.Z() + theD1U.Y() * theD2UV.Z()
+      - theD2U.Z() * theD1V.Y() - theD1U.Z() * theD2UV.Y());
+    aN1U.SetY((theD2U.X() * theD1V.Z() + theD1U.X() * theD2UV.Z()
+      - theD2U.Z() * theD1V.X() - theD1U.Z() * theD2UV.X()) * -1.0);
+    aN1U.SetZ(theD2U.X() * theD1V.Y() + theD1U.X() * theD2UV.Y()
+      - theD2U.Y() * theD1V.X() - theD1U.Y() * theD2UV.X());
+    Standard_Real aScaleU = aN1U.Dot(aN0);
+    aN1U.Subtract(aScaleU * aN0);
+    aN1U /= aScale;
+
+    aN1V.SetX(theD2UV.Y() * theD1V.Z() + theD2V.Z() * theD1U.Y()
+      - theD2UV.Z() * theD1V.Y() - theD2V.Y() * theD1U.Z());
+    aN1V.SetY((theD2UV.X() * theD1V.Z() + theD2V.Z() * theD1U.X()
+      - theD2UV.Z() * theD1V.X() - theD2V.X() * theD1U.Z()) * -1.0);
+    aN1V.SetZ(theD2UV.X() * theD1V.Y() + theD2V.Y() * theD1U.X()
+      - theD2UV.Y() * theD1V.X() - theD2V.X() * theD1U.Y());
+    Standard_Real aScaleV = aN1V.Dot(aN0);
+    aN1V.Subtract(aScaleV * aN0);
+    aN1V /= aScale;
+
+    theD1U += myOffset * aSign * aN1U;
+    theD1V += myOffset * aSign * aN1V;
+
+    return;
+  }
+  
   Standard_Integer OrderU, OrderV;
   TColgp_Array2OfVec DerNUV(0, MaxOrder + 1, 0, MaxOrder + 1);
   TColgp_Array2OfVec DerSurf(0, MaxOrder + 2, 0, MaxOrder + 2);
@@ -400,7 +404,7 @@ void GeomEvaluator_OffsetSurface::CalculateD2(
   Standard_Boolean isOpposite = Standard_False;
   Standard_Boolean AlongU = Standard_False;
   Standard_Boolean AlongV = Standard_False;
-  if (!myOscSurf.IsNull())
+  if ((NStatus != CSLib_Defined) && !myOscSurf.IsNull())
   {
     AlongU = myOscSurf->UOscSurf(theU, theV, isOpposite, L);
     AlongV = myOscSurf->VOscSurf(theU, theV, isOpposite, L);
@@ -475,7 +479,7 @@ void GeomEvaluator_OffsetSurface::CalculateD3(
   Standard_Boolean isOpposite = Standard_False;
   Standard_Boolean AlongU = Standard_False;
   Standard_Boolean AlongV = Standard_False;
-  if (!myOscSurf.IsNull())
+  if ((NStatus != CSLib_Defined) && !myOscSurf.IsNull())
   {
     AlongU = myOscSurf->UOscSurf(theU, theV, isOpposite, L);
     AlongV = myOscSurf->VOscSurf(theU, theV, isOpposite, L);
@@ -555,7 +559,7 @@ gp_Vec GeomEvaluator_OffsetSurface::CalculateDN(
   Standard_Boolean isOpposite = Standard_False;
   Standard_Boolean AlongU = Standard_False;
   Standard_Boolean AlongV = Standard_False;
-  if (!myOscSurf.IsNull())
+  if ((NStatus != CSLib_Defined) && !myOscSurf.IsNull())
   {
     AlongU = myOscSurf->UOscSurf(theU, theV, isOpposite, L);
     AlongV = myOscSurf->VOscSurf(theU, theV, isOpposite, L);
index 1c23a88..eac4f7a 100755 (executable)
@@ -1,7 +1,3 @@
-puts "TODO OCC27929 ALL: Error : The area of result shape is"
-puts "TODO OCC27929 ALL: Error :  is WRONG because number of "
-
-
 puts "============"
 puts "OCC8842"
 puts "============"
diff --git a/tests/bugs/modalg_6/bug27929 b/tests/bugs/modalg_6/bug27929
new file mode 100644 (file)
index 0000000..88f4450
--- /dev/null
@@ -0,0 +1,79 @@
+puts "============"
+puts "OCC27929"
+puts "============"
+puts ""
+######################################################
+# Methods D0 and D1 for trimmed offset surface return different values if the surface has osculating surface
+######################################################
+
+set Toler 1.0e-14
+
+restore [locate_data_file bug27929_f1.brep] f1
+mksurface os1 f1
+svalue os1 0.5 0.5 x1 y1 z1
+svalue os1 0.5 0.5 x2 y2 z2 d1ux d1uy d1uz d1vx d1vy d1vz
+vertex v1 x1 y1 z1
+vertex v2 x2 y2 z2
+distmini di12 v1 v2
+
+if { [dval di12_val] > $Toler } {
+  puts "Error: Methods D0 and D1 return different result."
+} else {
+  puts "OK: Methods D0 and D1 return equal result."
+}
+
+smallview
+don f1 v1 v2
+fit
+
+checkview -screenshot -2d -path ${imagedir}/${test_image}.png
+
+# Check result of D2 method
+svalue os1 0.5 0.5 x3 y3 z3 d2ux d2uy d2uz d2vx d2vy d2vz DD2UX DD2UY DD2UZ DD2VX DD2VY DD2VZ DD2UVX DD2UVY DD2UVZ
+vertex v3 x3 y3 z3
+distmini di13 v1 v3
+
+if { [dval di13_val] > $Toler } {
+  puts "Error: Methods D0 and D2 return different result."
+} else {
+  puts "OK: Methods D0 and D2 return equal result."
+}
+
+if { [expr abs([dval d1ux-d2ux])] > $Toler } {
+  puts "Error: Methods D1 and D2 return different result."
+} else {
+  puts "OK: Methods D1 and D2 return equal result."  
+}
+
+if { [expr abs([dval d1uy-d2uy])] > $Toler } {
+  puts "Error: Methods D1 and D2 return different result."
+} else {
+  puts "OK: Methods D1 and D2 return equal result."  
+}
+
+if { [expr abs([dval d1uz-d2uz])] > $Toler } {
+  puts "Error: Methods D1 and D2 return different result."
+} else {
+  puts "OK: Methods D1 and D2 return equal result."  
+}
+
+if { [expr abs([dval d1vx-d2vx])] > $Toler } {
+  puts "Error: Methods D1 and D2 return different result."
+} else {
+  puts "OK: Methods D1 and D2 return equal result."  
+}
+
+if { [expr abs([dval d1vy-d2vy])] > $Toler } {
+  puts "Error: Methods D1 and D2 return different result."
+} else {
+  puts "OK: Methods D1 and D2 return equal result."  
+}
+
+if { [expr abs([dval d1vz-d2vz])] > $Toler } {
+  puts "Error: Methods D1 and D2 return different result."
+} else {
+  puts "OK: Methods D1 and D2 return equal result."  
+}
+
+
+