]> OCCT Git - occt.git/commitdiff
0029406: Foundation Classes - gp_Ax3 fails setting direction
authorisn <isn@opencascade.com>
Thu, 11 Jan 2018 16:03:03 +0000 (19:03 +0300)
committersmoskvin <smoskvin@opencascade.com>
Fri, 26 Nov 2021 15:50:18 +0000 (18:50 +0300)
Avoid exception in gp_Ax3::SetDirection(), SetAxis(): check if XDir of Ax3 is parallel to newly given direction.

src/QABugs/QABugs_20.cxx
src/gp/gp_Ax3.hxx
tests/bugs/fclasses/bug29406 [new file with mode: 0644]

index 227b295fe28f1dc54b457d9f314cd6a86a968a1b..ece17e6ebe07950f4939a9cdf9df4c95a81dd78a 100644 (file)
@@ -4025,6 +4025,130 @@ static Standard_Integer QANullifyShape(Draw_Interpretor& di,
   return 0;
 }
 
+static void CheckAx3Dir(gp_Ax3& theAxis, const gp_Dir& theDir)
+{
+  Standard_Boolean bDirect = theAxis.Direct();
+  theAxis.SetDirection (theDir);
+  if (bDirect != theAxis.Direct())
+  {
+    std::cout << "Error: coordinate system is reversed\n";
+  }
+  if (!theDir.IsEqual(theAxis.Direction(), Precision::Angular()))
+  {
+    std::cout << "Error: main dir was not set properly\n";
+  }
+}
+
+static void CheckAx3DirX(gp_Ax3& theAxis, const gp_Dir& theDir)
+{
+  Standard_Boolean bDirect = theAxis.Direct();
+  theAxis.SetXDirection (theDir);
+  if (bDirect != theAxis.Direct())
+  {
+    std::cout << "Error: coordinate system is reversed\n";
+  }
+  gp_Dir aGoodY = theAxis.Direction().Crossed(theDir);
+  if (theAxis.Direct())
+  {
+    if (!aGoodY.IsEqual(theAxis.YDirection(), Precision::Angular()))
+    {
+      std::cout << "Error: X dir was not set properly\n";
+    }
+  }
+  else
+  {
+    if (!aGoodY.IsOpposite(theAxis.YDirection(), Precision::Angular()))
+    {
+      std::cout << "Error: X dir was not set properly\n";
+    }
+  }
+}
+
+static void CheckAx3DirY(gp_Ax3& theAxis, const gp_Dir& theDir)
+{
+  Standard_Boolean bDirect = theAxis.Direct();
+  theAxis.SetYDirection (theDir);
+  if (bDirect != theAxis.Direct())
+  {
+    std::cout << "Error: coordinate system is reversed\n";
+  }
+  gp_Dir aGoodX = theAxis.Direction().Crossed(theDir);
+  if (theAxis.Direct())
+  {
+    if (!aGoodX.IsOpposite(theAxis.XDirection(), Precision::Angular()))
+    {
+      std::cout << "Error: Y dir was not set properly\n";
+    }
+  }
+  else
+  {
+    if (!aGoodX.IsEqual(theAxis.XDirection(), Precision::Angular()))
+    {
+      std::cout << "Error: Y dir was not set properly\n";
+    }
+  }
+}
+
+static void CheckAx3Ax1(gp_Ax3& theAx, const gp_Ax1& theAx0)
+{
+  Standard_Boolean bDirect = theAx.Direct();
+  theAx.SetAxis (theAx0);
+  if (bDirect != theAx.Direct())
+  {
+    std::cout << "Error: coordinate system is reversed\n";
+  }
+  if (!theAx0.Direction().IsEqual(theAx.Direction(), Precision::Angular()))
+  {
+    std::cout << "Error: main dir was not set properly\n";
+  }
+}
+
+
+static Standard_Integer OCC29406 (Draw_Interpretor&, Standard_Integer, const char**)
+{
+  // Main (Z) direction
+  {
+   // gp_Ax3::SetDirection() test
+    gp_Ax3 anAx1, anAx2, anAx3, anAx4, anAx5, anAx6;
+    anAx3.ZReverse();
+    anAx4.ZReverse();    
+    CheckAx3Dir(anAx1,  gp::DX());
+    CheckAx3Dir(anAx2, -gp::DX());
+    CheckAx3Dir(anAx3,  gp::DX());
+    CheckAx3Dir(anAx4, -gp::DX());
+    // gp_Ax3::SetAxis() test
+    gp_Ax1 anAx0_1 (gp::Origin(),  gp::DX());
+    gp_Ax1 anAx0_2 (gp::Origin(), -gp::DX());
+    CheckAx3Ax1(anAx5, anAx0_1);
+    CheckAx3Ax1(anAx6, anAx0_2);
+  }
+  // X direction
+  {
+    // gp_Ax3::SetXDirection() test
+    gp_Ax3 anAx1, anAx2, anAx3, anAx4;
+    anAx3.XReverse();
+    anAx4.XReverse();
+    CheckAx3DirX(anAx1,  gp::DZ());
+    CheckAx3DirX(anAx2, -gp::DZ());
+    CheckAx3DirX(anAx3,  gp::DZ());
+    CheckAx3DirX(anAx4, -gp::DZ());
+  }
+  // Y direction
+  {
+    // gp_Ax3::SetYDirection() test
+    gp_Ax3 anAx1, anAx2, anAx3, anAx4;
+    anAx3.YReverse();
+    anAx4.YReverse();
+    CheckAx3DirY(anAx1,  gp::DZ());
+    CheckAx3DirY(anAx2, -gp::DZ());
+    CheckAx3DirY(anAx3,  gp::DZ());
+    CheckAx3DirY(anAx4, -gp::DZ());
+  }
+
+  return 0;
+}
+
+
 void QABugs::Commands_20(Draw_Interpretor& theCommands) {
   const char *group = "QABugs";
 
@@ -4107,5 +4231,8 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
                   "Nullify shape. Usage: QANullifyShape shape",
                   __FILE__, QANullifyShape, group);
 
+  theCommands.Add ("OCC29406", 
+                   "Tests the case when newly set axis for gp_Ax3 is parallel to one of current axis", 
+                   __FILE__, OCC29406, group);
   return;
 }
index d7f69a083187ce4441f3268c0ddc1cfb6e569190..5398e5483c03fb2add8f3058eea7189e83f6a102 100644 (file)
@@ -348,37 +348,45 @@ inline gp_Ax2  gp_Ax3::Ax2()const
 // function : SetAxis
 // purpose  :
 // =======================================================================
-inline void  gp_Ax3::SetAxis (const gp_Ax1& theA1)
+inline void  gp_Ax3::SetAxis(const gp_Ax1& theA1)
 {
-  Standard_Boolean isDirect = Direct();
-  axis = theA1;
-  vxdir = axis.Direction().CrossCrossed (vxdir, axis.Direction());
-  if (isDirect)
-  {
-    vydir = axis.Direction().Crossed (vxdir);
-  }
-  else
-  {
-    vydir = vxdir.Crossed (axis.Direction());
-  }
+  axis.SetLocation(theA1.Location());
+  SetDirection(theA1.Direction());
 }
 
 // =======================================================================
 // function : SetDirection
 // purpose  :
 // =======================================================================
-inline void  gp_Ax3::SetDirection (const gp_Dir& theV)
+inline void  gp_Ax3::SetDirection(const gp_Dir& theV)
 {
-  Standard_Boolean isDirect = Direct();
-  axis.SetDirection (theV);
-  vxdir = theV.CrossCrossed (vxdir, theV);
-  if (isDirect)
+  Standard_Real aDot = theV.Dot(vxdir);
+  if(1. - Abs(aDot) <= Precision::Angular())
   {
-    vydir = theV.Crossed (vxdir);
+    if(aDot > 0)
+    {
+      vxdir = vydir;
+      vydir = axis.Direction();
+    }
+    else
+    {
+      vxdir = axis.Direction();
+    }
+    axis.SetDirection(theV);
   }
   else
-  {
-    vydir = vxdir.Crossed (theV);
+  { 
+    Standard_Boolean direct = Direct();
+    axis.SetDirection (theV);
+    vxdir = theV.CrossCrossed (vxdir, theV);
+    if (direct)
+    { 
+      vydir = theV.Crossed (vxdir); 
+    }
+    else        
+    { 
+      vydir = vxdir.Crossed (theV); 
+    }
   }
 }
 
@@ -388,15 +396,32 @@ inline void  gp_Ax3::SetDirection (const gp_Dir& theV)
 // =======================================================================
 inline void  gp_Ax3::SetXDirection (const gp_Dir& theVx)
 {
-  Standard_Boolean isDirect = Direct();
-  vxdir = axis.Direction().CrossCrossed (theVx, axis.Direction());
-  if (isDirect)
+  Standard_Real aDot = theVx.Dot(axis.Direction());
+  if (1. - Abs(aDot) <= Precision::Angular())
   {
-    vydir = axis.Direction().Crossed (vxdir);
+    if (aDot > 0)
+    {
+      axis.SetDirection(vxdir);
+      vydir = -vydir;
+    }
+    else
+    {
+      axis.SetDirection(vxdir);
+    }
+    vxdir = theVx;
   }
   else
   {
-    vydir = vxdir.Crossed (axis.Direction());
+    Standard_Boolean direct = Direct();
+    vxdir = axis.Direction().CrossCrossed(theVx, axis.Direction());
+    if (direct)
+    {
+      vydir = axis.Direction().Crossed(vxdir);
+    }
+    else
+    {
+      vydir = vxdir.Crossed(axis.Direction());
+    }
   }
 }
 
@@ -406,12 +431,29 @@ inline void  gp_Ax3::SetXDirection (const gp_Dir& theVx)
 // =======================================================================
 inline void  gp_Ax3::SetYDirection (const gp_Dir& theVy)
 {
-  Standard_Boolean isDirect = Direct();
-  vxdir = theVy.Crossed (axis.Direction());
-  vydir = (axis.Direction()).Crossed (vxdir);
-  if (!isDirect)
+  Standard_Real aDot = theVy.Dot(axis.Direction());
+  if (1. - Abs(aDot) <= Precision::Angular())
   {
-    vxdir.Reverse();
+    if (aDot > 0)
+    {
+      axis.SetDirection(vydir);
+      vxdir = -vxdir;
+    }
+    else
+    {
+      axis.SetDirection(vydir);
+    }
+    vydir = theVy;
+  }
+  else
+  {
+    Standard_Boolean isDirect = Direct();
+    vxdir = theVy.Crossed(axis.Direction());
+    vydir = (axis.Direction()).Crossed(vxdir);
+    if (!isDirect)
+    {
+      vxdir.Reverse();
+    }
   }
 }
 
diff --git a/tests/bugs/fclasses/bug29406 b/tests/bugs/fclasses/bug29406
new file mode 100644 (file)
index 0000000..950c8d4
--- /dev/null
@@ -0,0 +1,7 @@
+puts "============"
+puts "0029406: Foundation Classes - gp_Ax3 fails setting direction"
+puts "============"
+puts ""
+
+pload QAcommands
+OCC29406