0029405: Modeling Algorithms - Check normal define status in HLRBRep_Data
authorvkuzin <vkuzin@opencascade.com>
Fri, 13 Aug 2021 11:43:22 +0000 (14:43 +0300)
committersmoskvin <smoskvin@opencascade.com>
Fri, 8 Oct 2021 17:51:13 +0000 (20:51 +0300)
Fixed exception when trying to calculate line and edge normal in methods HLRBRep_Data::OrientOutLine and HLRBRep_Data::OrientOthEdge, added a check for the existence of the normal before subsequent calculations. A correct check for zero derivative, correction of floating point error and division by zero determinant directly in HLRBRep_EdgeFaceTool::CurvatureValue was set.

src/HLRBRep/HLRBRep_Data.cxx
src/HLRBRep/HLRBRep_EdgeFaceTool.cxx
tests/bugs/modalg_7/bug29405 [new file with mode: 0644]

index 72b0fdf..2cebfec 100644 (file)
@@ -1543,43 +1543,45 @@ Standard_Boolean HLRBRep_Data::OrientOutLine (const Standard_Integer I, HLRBRep_
            V = gp_Dir(0,0,-1);
          }
          V.Transform(TI);
-         Standard_Real curv = HLRBRep_EdgeFaceTool::CurvatureValue
-           (iFaceGeom,pu,pv,V);
-         gp_Vec Nm = mySLProps.Normal();
-         if (curv == 0) {
+         if (mySLProps.IsNormalDefined()) {
+           Standard_Real curv = HLRBRep_EdgeFaceTool::CurvatureValue
+             (iFaceGeom,pu,pv,V);
+           gp_Vec Nm = mySLProps.Normal();
+           if (curv == 0) {
 #ifdef OCCT_DEBUG
-           std::cout << "HLRBRep_Data::OrientOutLine " << I;
-           std::cout << " Edge " << myFE << " : ";
-           std::cout << "CurvatureValue == 0." << std::endl;
+             std::cout << "HLRBRep_Data::OrientOutLine " << I;
+             std::cout << " Edge " << myFE << " : ";
+             std::cout << "CurvatureValue == 0." << std::endl;
 #endif
-         }
-         if (curv > 0)
-           Nm.Reverse();
-         Tg.Transform(T);
-         Pt.Transform(T);
-         Nm.Transform(T);
-         Nm.Cross(Tg);
-         if (Tg.Magnitude() < gp::Resolution()) {
+           }
+           if (curv > 0)
+             Nm.Reverse();
+           Tg.Transform(T);
+           Pt.Transform(T);
+           Nm.Transform(T);
+           Nm.Cross(Tg);
+           if (Tg.Magnitude() < gp::Resolution()) {
 #ifdef OCCT_DEBUG
-           std::cout << "HLRBRep_Data::OrientOutLine " << I;
-           std::cout << " Edge " << myFE << " : ";
-           std::cout << "Tg.Magnitude() == 0." << std::endl;
+             std::cout << "HLRBRep_Data::OrientOutLine " << I;
+             std::cout << " Edge " << myFE << " : ";
+             std::cout << "Tg.Magnitude() == 0." << std::endl;
 #endif  
-         }
-         if (myProj.Perspective())
-           r = Nm.Z() * myProj.Focus() - 
-             ( Nm.X() * Pt.X() + Nm.Y() * Pt.Y() + Nm.Z() * Pt.Z() );
-         else
-           r = Nm.Z();
-         myFEOri = (r > 0) ? TopAbs_FORWARD : TopAbs_REVERSED;
-         if (!FD.Cut() && FD.Closed() && FirstInversion) {
-           if ((eb1->Orientation(ie1) == myFEOri) != 
+           }
+           if (myProj.Perspective())
+             r = Nm.Z() * myProj.Focus() -
+             (Nm.X() * Pt.X() + Nm.Y() * Pt.Y() + Nm.Z() * Pt.Z());
+           else
+             r = Nm.Z();
+           myFEOri = (r > 0) ? TopAbs_FORWARD : TopAbs_REVERSED;
+           if (!FD.Cut() && FD.Closed() && FirstInversion) {
+             if ((eb1->Orientation(ie1) == myFEOri) !=
                (FD.Orientation() == TopAbs_FORWARD)) {
-             FirstInversion = Standard_False;
-             inverted = Standard_True;
+               FirstInversion = Standard_False;
+               inverted = Standard_True;
+             }
            }
+           eb1->Orientation(ie1, myFEOri);
          }
-         eb1->Orientation(ie1,myFEOri);
        }
        else {
 #ifdef OCCT_DEBUG
@@ -1627,19 +1629,21 @@ void HLRBRep_Data::OrientOthEdge (const Standard_Integer I,
        if (HLRBRep_EdgeFaceTool::UVPoint(p,myFEGeom,iFaceGeom,pu,pv)) {
          gp_Pnt Pt = EC.Value3D(p);
          mySLProps.SetParameters(pu,pv);
-         gp_Vec Nm = mySLProps.Normal();
-         Pt.Transform(T);
-         Nm.Transform(T);
-         if (myProj.Perspective()) {
-           r = Nm.Z() * myProj.Focus() - 
-             ( Nm.X() * Pt.X() + Nm.Y() * Pt.Y() + Nm.Z() * Pt.Z() );
-         }
-         else {
-           r = Nm.Z();
-         }
-         if (r < 0) {
-           myFEOri = TopAbs::Reverse(myFEOri);
-           eb1->Orientation(ie1,myFEOri);
+         if (mySLProps.IsNormalDefined()) {
+           gp_Vec Nm = mySLProps.Normal();
+           Pt.Transform(T);
+           Nm.Transform(T);
+           if (myProj.Perspective()) {
+             r = Nm.Z() * myProj.Focus() -
+               (Nm.X() * Pt.X() + Nm.Y() * Pt.Y() + Nm.Z() * Pt.Z());
+           }
+           else {
+             r = Nm.Z();
+           }
+           if (r < 0) {
+             myFEOri = TopAbs::Reverse(myFEOri);
+             eb1->Orientation(ie1, myFEOri);
+           }
          }
        }
 #ifdef OCCT_DEBUG
index 5bbaf5f..f589eed 100644 (file)
@@ -45,17 +45,17 @@ Standard_Real HLRBRep_EdgeFaceTool::CurvatureValue
   Standard_Real nmu2   = D1U*D1U;
   Standard_Real nmv2   = D1V*D1V;
   Standard_Real det = nmu2 * nmv2 - d1ud1v * d1ud1v;
-  Standard_Real alfa = ( d1ut * nmv2 - d1vt * d1ud1v ) / det;
-  Standard_Real beta = ( d1vt * nmu2 - d1ut * d1ud1v ) / det;
-  gp_Vec Nm = D1U ^ D1V;
-  if (Nm.Magnitude() > gp::Resolution()) {
+  if (det > gp::Resolution()) {
+    Standard_Real alfa = (d1ut * nmv2 - d1vt * d1ud1v) / det;
+    Standard_Real beta = (d1vt * nmu2 - d1ut * d1ud1v) / det;
+    Standard_Real alfa2 = alfa * alfa;
+    Standard_Real beta2 = beta * beta;
+    Standard_Real alfabeta = alfa * beta;
+    gp_Vec Nm = D1U ^ D1V;
     Nm.Normalize();
-    Standard_Real alfa2 = alfa*alfa;
-    Standard_Real beta2 = beta*beta;
-    Standard_Real alfabeta = alfa*beta;
-    Standard_Real N = (Nm*D2U)*alfa2  + 2*(Nm*D2UV)*alfabeta + (Nm*D2V)*beta2;
-    Standard_Real D = nmu2    *alfa2  + 2*d1ud1v   *alfabeta + nmv2    *beta2;
-    return N/D;
+    Standard_Real N = (Nm * D2U) * alfa2 + 2 * (Nm * D2UV) * alfabeta + (Nm * D2V) * beta2;
+    Standard_Real D = nmu2 * alfa2 + 2 * d1ud1v * alfabeta + nmv2 * beta2;
+    return N / D;
   }
   return 0.;
 }
diff --git a/tests/bugs/modalg_7/bug29405 b/tests/bugs/modalg_7/bug29405
new file mode 100644 (file)
index 0000000..0e6537b
--- /dev/null
@@ -0,0 +1,9 @@
+puts "============================================"
+puts "OCC29405: Modeling Algorithms - Check normal define status in HLRBRep_Data"
+puts "============================================"
+puts ""
+
+pload ALL
+ptorus t 17.37 17.37 [dval 2.35*180/pi]
+vdisplay t
+vcomputehlr t t2 -algotype algo 0 50 0 0 -50 0 0 0 1
\ No newline at end of file