From 58c0958b5005beb81268afbc58cbb8116d84227b Mon Sep 17 00:00:00 2001 From: isn Date: Thu, 11 Jan 2018 19:03:03 +0300 Subject: [PATCH] 0029406: Foundation Classes - gp_Ax3 fails setting direction Avoid exception in gp_Ax3::SetDirection(), SetAxis(): check if XDir of Ax3 is parallel to newly given direction. --- src/QABugs/QABugs_20.cxx | 127 +++++++++++++++++++++++++++++++++++ src/gp/gp_Ax3.hxx | 102 +++++++++++++++++++--------- tests/bugs/fclasses/bug29406 | 7 ++ 3 files changed, 206 insertions(+), 30 deletions(-) create mode 100644 tests/bugs/fclasses/bug29406 diff --git a/src/QABugs/QABugs_20.cxx b/src/QABugs/QABugs_20.cxx index 227b295fe2..ece17e6ebe 100644 --- a/src/QABugs/QABugs_20.cxx +++ b/src/QABugs/QABugs_20.cxx @@ -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; } diff --git a/src/gp/gp_Ax3.hxx b/src/gp/gp_Ax3.hxx index d7f69a0831..5398e5483c 100644 --- a/src/gp/gp_Ax3.hxx +++ b/src/gp/gp_Ax3.hxx @@ -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 index 0000000000..950c8d4c3c --- /dev/null +++ b/tests/bugs/fclasses/bug29406 @@ -0,0 +1,7 @@ +puts "============" +puts "0029406: Foundation Classes - gp_Ax3 fails setting direction" +puts "============" +puts "" + +pload QAcommands +OCC29406