From 2f5512515694d024da5ad0afa8854592732ccb7b Mon Sep 17 00:00:00 2001 From: faizhaque <149001570+faizhaque@users.noreply.github.com> Date: Thu, 3 Oct 2024 19:46:33 -0400 Subject: [PATCH] Update PyImathEuler.cpp Make some changes by converting the Boost.python bindings for the Imath::Euler class to pybind11. Replaced boost.python headers and other changes. Signed-off-by: faizhaque <149001570+faizhaque@users.noreply.github.com> --- src/python/PyImath/PyImathEuler.cpp | 951 +++------------------------- 1 file changed, 79 insertions(+), 872 deletions(-) diff --git a/src/python/PyImath/PyImathEuler.cpp b/src/python/PyImath/PyImathEuler.cpp index ff1fceae..182117ed 100644 --- a/src/python/PyImath/PyImathEuler.cpp +++ b/src/python/PyImath/PyImathEuler.cpp @@ -3,876 +3,83 @@ // Copyright Contributors to the OpenEXR Project. // -// clang-format off - -#include -#define BOOST_BIND_GLOBAL_PLACEHOLDERS -#include -#include -#include +#include "PyBindImath.h" +#include #include -#include "PyImath.h" -#include "PyImathMathExc.h" -#include "PyImathEuler.h" -#include "PyImathDecorators.h" -#include "PyImathExport.h" -#include "PyImathOperators.h" - -// XXX incomplete array wrapping, docstrings missing - -namespace PyImath { -template<> const char *PyImath::EulerfArray::name() { return "EulerfArray"; } -template<> const char *PyImath::EulerdArray::name() { return "EulerdArray"; } -} - -namespace PyImath { -using namespace boost::python; -using namespace IMATH_NAMESPACE; - -template struct EulerName { static const char *value; }; -template<> const char *EulerName::value = "Eulerf"; -template<> const char *EulerName::value = "Eulerd"; - -template -static std::string nameOfOrder(typename IMATH_NAMESPACE::Euler::Order order) -{ - switch(order) - { - case IMATH_NAMESPACE::Euler::XYZ: - return "EULER_XYZ"; - case IMATH_NAMESPACE::Euler::XZY: - return "EULER_XZY"; - case IMATH_NAMESPACE::Euler::YZX: - return "EULER_YZX"; - case IMATH_NAMESPACE::Euler::YXZ: - return "EULER_YXZ"; - case IMATH_NAMESPACE::Euler::ZXY: - return "EULER_ZXY"; - case IMATH_NAMESPACE::Euler::ZYX: - return "EULER_ZYX"; - case IMATH_NAMESPACE::Euler::XZX: - return "EULER_XZX"; - case IMATH_NAMESPACE::Euler::XYX: - return "EULER_XYX"; - case IMATH_NAMESPACE::Euler::YXY: - return "EULER_YXY"; - case IMATH_NAMESPACE::Euler::YZY: - return "EULER_YZY"; - case IMATH_NAMESPACE::Euler::ZYZ: - return "EULER_ZYZ"; - case IMATH_NAMESPACE::Euler::ZXZ: - return "EULER_ZXZ"; - case IMATH_NAMESPACE::Euler::XYZr: - return "EULER_XYZr"; - case IMATH_NAMESPACE::Euler::XZYr: - return "EULER_XZYr"; - case IMATH_NAMESPACE::Euler::YZXr: - return "EULER_YZXr"; - case IMATH_NAMESPACE::Euler::YXZr: - return "EULER_YXZr"; - case IMATH_NAMESPACE::Euler::ZXYr: - return "EULER_ZXYr"; - case IMATH_NAMESPACE::Euler::ZYXr: - return "EULER_ZYXr"; - case IMATH_NAMESPACE::Euler::XZXr: - return "EULER_XZXr"; - case IMATH_NAMESPACE::Euler::XYXr: - return "EULER_XYXr"; - case IMATH_NAMESPACE::Euler::YXYr: - return "EULER_YXYr"; - case IMATH_NAMESPACE::Euler::YZYr: - return "EULER_YZYr"; - case IMATH_NAMESPACE::Euler::ZYZr: - return "EULER_ZYZr"; - case IMATH_NAMESPACE::Euler::ZXZr: - return "EULER_ZXZr"; - default: - break; - } - - return ""; -} - -template -static std::string Euler_str(const Euler &e) -{ - std::stringstream stream; - stream << EulerName::value << "(" << e.x << ", " << e.y << ", " << e.z << ", " - << nameOfOrder (e.order()) << ")"; - return stream.str(); -} - -// Non-specialized repr is same as str -template -static std::string Euler_repr(const Euler &e) -{ - return Euler_str(e); -} - -// Specialization for float to full precision -template <> -std::string Euler_repr(const Euler &e) -{ - return (boost::format("%s(%.9g, %.9g, %.9g, %s)") - % EulerName::value - % e.x % e.y % e.z - % nameOfOrder(e.order()).c_str()).str(); -} - -// Specialization for double to full precision -template <> -std::string Euler_repr(const Euler &e) -{ - return (boost::format("%s(%.17g, %.17g, %.17g, %s)") - % EulerName::value - % e.x % e.y % e.z - % nameOfOrder(e.order()).c_str()).str(); -} - - -template -static bool -equal(const Euler &e0, const Euler &e1) -{ - if(e0.x == e1.x && e0.y == e1.y && e0.z == e1.z && (e0.order())==(e1.order())) - return true; - else - return false; -} - -template -static bool -notequal(const Euler &e0, const Euler &e1) -{ - if(e0.x != e1.x || e0.y != e1.y || e0.z != e1.z || (e0.order()) != (e1.order())) - { - return true; - } - else - return false; -} - -template -static IMATH_NAMESPACE::Vec3 getAngleOrder(Euler &euler) -{ - int i, j, k; - euler.angleOrder(i, j, k); - return IMATH_NAMESPACE::Vec3 (i, j, k); -} - -template -static void -setXYZTuple(Euler &euler, const tuple &t) -{ - MATH_EXC_ON; - Vec3 v; - if(t.attr("__len__")() == 3) - { - v.x = extract(t[0]); - v.y = extract(t[1]); - v.z = extract(t[2]); - - euler.setXYZVector(v); - } - else - throw std::invalid_argument ("Euler expects tuple of length 3"); -} - -// needed to convert Eulerf::Order to Euler::Order -template -static typename Euler::Order interpretOrder(typename IMATH_NAMESPACE::Eulerf::Order order) -{ - typename Euler::Order o = Euler::XYZ; - switch(order) - { - case IMATH_NAMESPACE::Eulerf::XYZ: - { - o = Euler::XYZ; - }break; - case IMATH_NAMESPACE::Eulerf::XZY: - { - o = Euler::XZY; - }break; - case IMATH_NAMESPACE::Eulerf::YZX: - { - o = Euler::YZX; - }break; - case IMATH_NAMESPACE::Eulerf::YXZ: - { - o = Euler::YXZ; - }break; - case IMATH_NAMESPACE::Eulerf::ZXY: - { - o = Euler::ZXY; - }break; - case IMATH_NAMESPACE::Eulerf::ZYX: - { - o = Euler::ZYX; - }break; - case IMATH_NAMESPACE::Eulerf::XZX: - { - o = Euler::XZX; - }break; - case IMATH_NAMESPACE::Eulerf::XYX: - { - o = Euler::XYX; - }break; - case IMATH_NAMESPACE::Eulerf::YXY: - { - o = Euler::YXY; - }break; - case IMATH_NAMESPACE::Eulerf::YZY: - { - o = Euler::YZY; - }break; - case IMATH_NAMESPACE::Eulerf::ZYZ: - { - o = Euler::ZYZ; - }break; - case IMATH_NAMESPACE::Eulerf::ZXZ: - { - o = Euler::ZXZ; - }break; - case IMATH_NAMESPACE::Eulerf::XYZr: - { - o = Euler::XYZr; - }break; - case IMATH_NAMESPACE::Eulerf::XZYr: - { - o = Euler::XZYr; - }break; - case IMATH_NAMESPACE::Eulerf::YZXr: - { - o = Euler::YZXr; - }break; - case IMATH_NAMESPACE::Eulerf::YXZr: - { - o = Euler::YXZr; - }break; - case IMATH_NAMESPACE::Eulerf::ZXYr: - { - o = Euler::ZXYr; - }break; - case IMATH_NAMESPACE::Eulerf::ZYXr: - { - o = Euler::ZYXr; - }break; - case IMATH_NAMESPACE::Eulerf::XZXr: - { - o = Euler::XZXr; - }break; - case IMATH_NAMESPACE::Eulerf::XYXr: - { - o = Euler::XYXr; - }break; - case IMATH_NAMESPACE::Eulerf::YXYr: - { - o = Euler::YXYr; - }break; - case IMATH_NAMESPACE::Eulerf::YZYr: - { - o = Euler::YZYr; - }break; - case IMATH_NAMESPACE::Eulerf::ZYZr: - { - o = Euler::ZYZr; - }break; - case IMATH_NAMESPACE::Eulerf::ZXZr: - { - o = Euler::ZXZr; - }break; - default: - break; - } - - return o; -} - -// needed to convert Eulerf::InputLayout to Euler::InputLayout -template -static typename Euler::InputLayout interpretInputLayout(typename IMATH_NAMESPACE::Eulerf::InputLayout layout) -{ - if (layout == IMATH_NAMESPACE::Eulerf::XYZLayout) - return Euler::XYZLayout; - return Euler::IJKLayout; -} - -// needed to convert Eulerf::Axis to Euler::Axis -template -static typename Euler::Axis interpretAxis(typename IMATH_NAMESPACE::Eulerf::Axis axis) -{ - if (axis == IMATH_NAMESPACE::Eulerf::X) - return Euler::X; - else if (axis == IMATH_NAMESPACE::Eulerf::Y) - return Euler::Y; - else - return Euler::Z; -} - -template -static Euler * -eulerConstructor1(const Vec3 &v, - typename IMATH_NAMESPACE::Eulerf::Order order, - typename IMATH_NAMESPACE::Eulerf::InputLayout layout = IMATH_NAMESPACE::Eulerf::IJKLayout) -{ - typename Euler::Order o = interpretOrder(order); - typename Euler::InputLayout l = interpretInputLayout(layout); - return new Euler(v, o, l); -} - -template -static Euler * -eulerConstructor1a(const Vec3 &v) -{ - return eulerConstructor1 (v, IMATH_NAMESPACE::Eulerf::Default); -} - -template -static Euler * -eulerConstructor1b(const Vec3 &v, int iorder) -{ - typename Euler::Order o = typename Euler::Order (iorder); - return new Euler(v, o); -} - -// - -template -static Euler * -eulerConstructor1d(const Euler& e, int iorder) -{ - typename Euler::Order o = typename Euler::Order (iorder); - return new Euler(e, o); -} - -template -static Euler * -eulerConstructor1e(const Euler& e, int iorder, int layout) -{ - typename Euler::Order o = typename Euler::Order (iorder); - typename Euler::InputLayout l = typename Euler::InputLayout (layout); - return new Euler(e, o, l); -} - - -template -static Euler * -eulerConstructor2(T i, T j, T k, - typename IMATH_NAMESPACE::Eulerf::Order order, - typename IMATH_NAMESPACE::Eulerf::InputLayout layout = IMATH_NAMESPACE::Eulerf::IJKLayout) -{ - typename Euler::Order o = interpretOrder(order); - typename Euler::InputLayout l = interpretInputLayout(layout); - return new Euler(i, j, k, o, l); -} - -template -static Euler * -eulerConstructor2a(T i, T j, T k) -{ - return eulerConstructor2 (i, j, k, IMATH_NAMESPACE::Eulerf::Default); -} - -template -static Euler * -eulerConstructor2b(T i, T j, T k, int iorder) -{ - typename Euler::Order o = typename Euler::Order (iorder); - return new Euler(i, j, k, o); -} - -template -static Euler * -eulerConstructor3(const Matrix33 &mat, typename IMATH_NAMESPACE::Eulerf::Order order) -{ - typename Euler::Order o = interpretOrder(order); - return new Euler(mat, o); -} - -template -static Euler * -eulerConstructor3a(const Matrix33 &mat) -{ - return eulerConstructor3 (mat, IMATH_NAMESPACE::Eulerf::Default); -} - -template -static Euler * -eulerConstructor3b(const Matrix33 &mat, int iorder) -{ - typename Euler::Order o = typename Euler::Order (iorder); - return new Euler(mat, o); -} - -template -static Euler * -eulerConstructor4(const Matrix44 &mat, typename IMATH_NAMESPACE::Eulerf::Order order) -{ - typename Euler::Order o = interpretOrder(order); - return new Euler(mat, o); -} - -template -static Euler * -eulerConstructor4a(const Matrix44 &mat) -{ - return eulerConstructor4 (mat, IMATH_NAMESPACE::Eulerf::Default); -} - -template -static Euler * -eulerConstructor4b(const Matrix44 &mat, int iorder) -{ - typename Euler::Order o = typename Euler::Order (iorder); - return new Euler(mat, o); -} - -template -static Euler * -eulerConstructor5(typename IMATH_NAMESPACE::Eulerf::Order order) -{ - typename Euler::Order o = interpretOrder(order); - return new Euler(o); -} - -template -static Euler * -eulerConstructor5a() -{ - typename Euler::Order o = interpretOrder(IMATH_NAMESPACE::Eulerf::Default); - return new Euler(o); -} - -template -static Euler * -eulerConstructor5b(int iorder) -{ - typename Euler::Order o = typename Euler::Order (iorder); - return new Euler(o); -} - -template -static Euler * -eulerConstructor6(T x, T y, T z) -{ - return new Euler(Vec3(x,y,z)); -} - -template -static Euler * -eulerConstructor7(const Quat &quat, typename IMATH_NAMESPACE::Eulerf::Order order) -{ - Euler *e = eulerConstructor5(order); - e->extract(quat); - return e; -} - -template -static Euler * -eulerConstructor7a(const Quat &quat) -{ - return eulerConstructor7(quat, IMATH_NAMESPACE::Eulerf::Default); -} - -template -static Euler * -eulerConstructor7b(const Quat &quat, int iorder) -{ - Euler *e = eulerConstructor5b(iorder); - e->extract(quat); - return e; -} - -template -static Euler * -eulerConversionConstructor(const Euler &euler) -{ - MATH_EXC_ON; - Euler *e = new Euler; - *e = euler; - return e; -} - -template -static void -eulerMakeNear(Euler &euler, Euler &target) -{ - MATH_EXC_ON; - euler.makeNear (target); -} - -template -static void -eulerSetOrder(Euler &euler, typename IMATH_NAMESPACE::Eulerf::Order order) -{ - typename Euler::Order o = interpretOrder(order); - euler.setOrder (o); -} - -template -static void -eulerSet(Euler &euler, IMATH_NAMESPACE::Eulerf::Axis axis, int relative, int parityEven, int firstRepeats) -{ - MATH_EXC_ON; - typename Euler::Axis a = interpretAxis(axis); - euler.set (a, relative, parityEven, firstRepeats); -} - -template -static void -extract1(Euler &euler, const Matrix33 &m) -{ - MATH_EXC_ON; - euler.extract(m); -} - -template -static void -extract2(Euler &euler, const Matrix44 &m) -{ - MATH_EXC_ON; - euler.extract(m); -} - -template -static void -extract3(Euler &euler, const Quat &q) -{ - MATH_EXC_ON; - euler.extract(q); -} - -template -static Matrix33 -toMatrix33(Euler &euler) -{ - MATH_EXC_ON; - return euler.toMatrix33(); -} - -template -static Matrix44 -toMatrix44(Euler &euler) -{ - MATH_EXC_ON; - return euler.toMatrix44(); -} - -template -static Quat -toQuat(Euler &euler) -{ - MATH_EXC_ON; - return euler.toQuat(); -} - -template -static Vec3 -toXYZVector(Euler &euler) -{ - MATH_EXC_ON; - return euler.toXYZVector(); -} - -template -class_,bases > > -register_Euler() -{ - class_,bases > > euler_class(EulerName::value,EulerName::value,init >("copy construction")); - euler_class - .def(init<>("imath Euler default construction")) - .def("__init__", make_constructor(eulerConstructor1)) - .def("__init__", make_constructor(eulerConstructor1a)) - .def("__init__", make_constructor(eulerConstructor1b)) - .def("__init__", make_constructor(eulerConstructor1d)) - .def("__init__", make_constructor(eulerConstructor1e)) - .def("__init__", make_constructor(eulerConstructor2)) - .def("__init__", make_constructor(eulerConstructor2a)) - .def("__init__", make_constructor(eulerConstructor2b)) - .def("__init__", make_constructor(eulerConstructor3), - "Euler-from-matrix construction assumes, but does\n" - "not verify, that the matrix includes no shear or\n" - "non-uniform scaling. If necessary, you can fix\n" - "the matrix by calling the removeScalingAndShear()\n" - "function.\n") - .def("__init__", make_constructor(eulerConstructor3a)) - .def("__init__", make_constructor(eulerConstructor3b)) - .def("__init__", make_constructor(eulerConstructor4)) - .def("__init__", make_constructor(eulerConstructor4a)) - .def("__init__", make_constructor(eulerConstructor4b)) - .def("__init__", make_constructor(eulerConstructor5)) - .def("__init__", make_constructor(eulerConstructor5a)) - .def("__init__", make_constructor(eulerConstructor5b)) - .def("__init__", make_constructor(eulerConstructor6)) - .def("__init__", make_constructor(eulerConstructor7)) - .def("__init__", make_constructor(eulerConstructor7a)) - .def("__init__", make_constructor(eulerConstructor7b)) - .def("__init__", make_constructor(eulerConversionConstructor)) - .def("__init__", make_constructor(eulerConversionConstructor)) - - .def("angleOrder", &getAngleOrder, "angleOrder() set the angle order") - - .def("frameStatic", &Euler::frameStatic, - "e.frameStatic() -- returns true if the angles of e\n" - "are measured relative to a set of fixed axes,\n" - "or false if the angles of e are measured relative to\n" - "each other\n") - - .def("initialAxis", &Euler::initialAxis, - "e.initialAxis() -- returns the initial rotation\n" - "axis of e (EULER_X_AXIS, EULER_Y_AXIS, EULER_Z_AXIS)") - - .def("initialRepeated", &Euler::initialRepeated, - "e.initialRepeated() -- returns 1 if the initial\n" - "rotation axis of e is repeated (for example,\n" - "e.order() == EULER_XYX); returns 0 if the initial\n" - "rotation axis is not repeated.\n") - - .def("makeNear", &eulerMakeNear, - "e.makeNear(t) -- adjusts Euler e so that it\n" - "represents the same rotation as before, but the\n" - "individual angles of e differ from the angles of\n" - "t by as little as possible.\n" - "This method might not make sense if e.order()\n" - "and t.order() are different\n") - - .def("order", &Euler::order, - "e.order() -- returns the rotation order in e\n" - "(EULER_XYZ, EULER_XZY, ...)") - - .def("parityEven", &Euler::parityEven, - "e.parityEven() -- returns the parity of the\n" - "axis permutation of e\n") - - .def("set", &eulerSet, - "e.set(i,r,p,f) -- sets the rotation order in e\n" - "according to the following flags:\n" - "\n" - " i initial axis (EULER_X_AXIS,\n" - " EULER_Y_AXIS or EULER_Z_AXIS)\n" - "\n" - " r rotation angles are measured relative\n" - " to each other (r == 1), or relative to a\n" - " set of fixed axes (r == 0)\n" - "\n" - " p parity of axis permutation is even (r == 1)\n" - " or odd (r == 0)\n" - "\n" - " f first rotation axis is repeated (f == 1)\n" - " or not repeated (f == 0)\n") - - .def("setOrder", &eulerSetOrder, - "e.setOrder(o) -- sets the rotation order in e\n" - "to o (EULER_XYZ, EULER_XZY, ...)") - - .def("setXYZVector", &Euler::setXYZVector, - "e.setXYZVector(v) -- sets the three rotation\n" - "angles in e to v[0], v[1], v[2]") - .def("setXYZVector", &setXYZTuple) - - .def("extract", &extract1, - "e.extract(m) -- extracts the rotation component\n" - "from 3x3 matrix m and stores the result in e.\n" - "Assumes that m does not contain shear or non-\n" - "uniform scaling. If necessary, you can fix m\n" - "by calling m.removeScalingAndShear().") - - .def("extract", &extract2, - "e.extract(m) -- extracts the rotation component\n" - "from 4x4 matrix m and stores the result in e.\n" - "Assumes that m does not contain shear or non-\n" - "uniform scaling. If necessary, you can fix m\n" - "by calling m.removeScalingAndShear().") - - .def("extract", &extract3, - "e.extract(q) -- extracts the rotation component\n" - "from quaternion q and stores the result in e") - - .def("toMatrix33", &toMatrix33, "e.toMatrix33() -- converts e into a 3x3 matrix\n") - - .def("toMatrix44", &toMatrix44, "e.toMatrix44() -- converts e into a 4x4 matrix\n") - - .def("toQuat", &toQuat, "e.toQuat() -- converts e into a quaternion\n") - - .def("toXYZVector", &toXYZVector, - "e.toXYZVector() -- converts e into an XYZ\n" - "rotation vector") - .def("__str__", &Euler_str) - .def("__repr__", &Euler_repr) - - .def("__eq__", &equal) - .def("__ne__", ¬equal) - ; - - // fill in the Euler scope - { - scope euler_scope(euler_class); - enum_::Order> euler_order("Order"); - euler_order - .value("XYZ",Euler::XYZ) - .value("XZY",Euler::XZY) - .value("YZX",Euler::YZX) - .value("YXZ",Euler::YXZ) - .value("ZXY",Euler::ZXY) - .value("ZYX",Euler::ZYX) - .value("XZX",Euler::XZX) - .value("XYX",Euler::XYX) - .value("YXY",Euler::YXY) - .value("YZY",Euler::YZY) - .value("ZYZ",Euler::ZYZ) - .value("ZXZ",Euler::ZXZ) - .value("XYZr",Euler::XYZr) - .value("XZYr",Euler::XZYr) - .value("YZXr",Euler::YZXr) - .value("YXZr",Euler::YXZr) - .value("ZXYr",Euler::ZXYr) - .value("ZYXr",Euler::ZYXr) - .value("XZXr",Euler::XZXr) - .value("XYXr",Euler::XYXr) - .value("YXYr",Euler::YXYr) - .value("YZYr",Euler::YZYr) - .value("ZYZr",Euler::ZYZr) - .value("ZXZr",Euler::ZXZr) - - // don't export these, they're not really part of the public interface - //.value("Legal",Euler::Legal) - //.value("Min",Euler::Min) - //.value("Max",Euler::Max) - - // handle Default seperately since boost sets up a 1-1 mapping for enum values - //.value("Default",Euler::Default) - .export_values() - ; - // just set it to the XYZ value manually - euler_scope.attr("Default") = euler_scope.attr("XYZ"); - - enum_::Axis>("Axis") - .value("X",Euler::X) - .value("Y",Euler::Y) - .value("Z",Euler::Z) - .export_values() - ; - - enum_::InputLayout>("InputLayout") - .value("XYZLayout",Euler::XYZLayout) - .value("IJKLayout",Euler::IJKLayout) - .export_values() - ; - } - - decoratecopy(euler_class); - - return euler_class; -} - -// XXX fixme - template this -// really this should get generated automatically... - -/* -template -static FixedArray -EulerArray_get(FixedArray > &qa) -{ - return FixedArray( &(qa[0].r)+index, qa.len(), 4*qa.stride()); -} -*/ - -template -static FixedArray > * -EulerArray_eulerConstructor7a(const FixedArray > &q) -{ - MATH_EXC_ON; - size_t len = q.len(); - FixedArray >* result = new FixedArray >(len); - for (size_t i = 0; i < len; ++i) { - (*result)[i].extract(q[i]); - } - return result; -} - -template -static FixedArray > * -EulerArray_eulerConstructor8a(const FixedArray >& v) -{ - MATH_EXC_ON; - size_t len = v.len(); - FixedArray >* result = new FixedArray >(len); - - for (size_t i = 0; i < len; ++i) - (*result)[i] = Euler(v[i]); - - return result; -} - -template -static FixedArray > * -EulerArray_eulerConstructor9a(const FixedArray >& v, typename IMATH_NAMESPACE::Eulerf::Order order) -{ - MATH_EXC_ON; - size_t len = v.len(); - FixedArray >* result = new FixedArray >(len); - - typename Euler::Order o = interpretOrder(order); - for (size_t i = 0; i < len; ++i) - (*result)[i] = Euler(v[i], o); - - return result; -} - -template -static FixedArray > -EulerArray_toXYZVector(const FixedArray >& e) -{ - MATH_EXC_ON; - size_t len = e.len(); - FixedArray > result(len, UNINITIALIZED); - for (size_t i = 0; i < len; ++i) - result[i] = e[i].toXYZVector(); - return result; -} - -template -static FixedArray > -EulerArray_toQuat(const FixedArray >& e) -{ - MATH_EXC_ON; - size_t len = e.len(); - FixedArray > result(len, UNINITIALIZED); - for (size_t i = 0; i < len; ++i) - result[i] = e[i].toQuat(); - return result; -} - - -template -class_ > > -register_EulerArray() -{ - class_ > > eulerArray_class = FixedArray >::register_("Fixed length array of IMATH_NAMESPACE::Euler"); - eulerArray_class - //.add_property("x",&EulerArray_get) - //.add_property("y",&EulerArray_get) - //.add_property("z",&EulerArray_get) - .def("__init__", make_constructor(EulerArray_eulerConstructor7a)) - .def("__init__", make_constructor(EulerArray_eulerConstructor8a)) - .def("__init__", make_constructor(EulerArray_eulerConstructor9a)) - .def("toXYZVector", EulerArray_toXYZVector) - .def("toQuat", EulerArray_toQuat) - ; - - add_comparison_functions(eulerArray_class); - PyImath::add_explicit_construction_from_type >(eulerArray_class); - PyImath::add_explicit_construction_from_type >(eulerArray_class); - return eulerArray_class; -} - -template PYIMATH_EXPORT class_,bases > > register_Euler(); -template PYIMATH_EXPORT class_,bases > > register_Euler(); - -template PYIMATH_EXPORT class_ > > register_EulerArray(); -template PYIMATH_EXPORT class_ > > register_EulerArray(); - -template<> PYIMATH_EXPORT IMATH_NAMESPACE::Euler FixedArrayDefaultValue >::value() { return IMATH_NAMESPACE::Euler(); } -template<> PYIMATH_EXPORT IMATH_NAMESPACE::Euler FixedArrayDefaultValue >::value() { return IMATH_NAMESPACE::Euler(); } - -} // namespace PyImath +#include + +namespace PyBindImath { + +// Function to register the Euler class methods +template +void register_euler_methods(pybind11::class_, Imath::Vec3>& c) { + c.def(pybind11::init<>()) + .def(pybind11::init&, typename Imath::Euler::Order>(), pybind11::arg("v"), pybind11::arg("order") = Imath::Euler::XYZ) + .def(pybind11::init::Order>(), pybind11::arg("x"), pybind11::arg("y"), pybind11::arg("z"), pybind11::arg("order") = Imath::Euler::XYZ) + .def(pybind11::self == pybind11::self) + .def(pybind11::self != pybind11::self) + .def("toMatrix33", &Imath::Euler::toMatrix33) + .def("toMatrix44", &Imath::Euler::toMatrix44) + .def("toQuat", &Imath::Euler::toQuat) + .def("order", &Imath::Euler::order) + .def("setOrder", &Imath::Euler::setOrder) + .def("makeNear", &Imath::Euler::makeNear) + .def("extract", pybind11::overload_cast&>(&Imath::Euler::extract)) + .def("extract", pybind11::overload_cast&>(&Imath::Euler::extract)) + .def("extract", pybind11::overload_cast&>(&Imath::Euler::extract)) + .def("toXYZVector", &Imath::Euler::toXYZVector) + .def("__str__", [](const Imath::Euler& e) { + std::stringstream stream; + stream << "Euler(" << e.x << ", " << e.y << ", " << e.z << ", " << e.order() << ")"; + return stream.str(); + }) + .def("__repr__", [](const Imath::Euler& e) { + std::stringstream stream; + stream << "Euler(" << e.x << ", " << e.y << ", " << e.z << ", " << e.order() << ")"; + return stream.str(); + }); +} + +// Function to register the Euler class in the module +template +void register_euler(pybind11::module& m, const char* name) { + pybind11::class_, Imath::Vec3> c(m, name); + register_euler_methods(c); +} + +// Function to register the Euler types for float and double +void register_imath_euler(pybind11::module& m) { + register_euler(m, "Eulerf"); + register_euler(m, "Eulerd"); + + // Enums for Euler Orders + pybind11::enum_::Order>(m, "Order") + .value("XYZ", Imath::Euler::XYZ) + .value("XZY", Imath::Euler::XZY) + .value("YZX", Imath::Euler::YZX) + .value("YXZ", Imath::Euler::YXZ) + .value("ZXY", Imath::Euler::ZXY) + .value("ZYX", Imath::Euler::ZYX) + .value("XZX", Imath::Euler::XZX) + .value("XYX", Imath::Euler::XYX) + .value("YXY", Imath::Euler::YXY) + .value("YZY", Imath::Euler::YZY) + .value("ZYZ", Imath::Euler::ZYZ) + .value("ZXZ", Imath::Euler::ZXZ) + .export_values(); + + // Enums for Axis + pybind11::enum_::Axis>(m, "Axis") + .value("X", Imath::Euler::X) + .value("Y", Imath::Euler::Y) + .value("Z", Imath::Euler::Z) + .export_values(); + + // Enums for InputLayout + pybind11::enum_::InputLayout>(m, "InputLayout") + .value("XYZLayout", Imath::Euler::XYZLayout) + .value("IJKLayout", Imath::Euler::IJKLayout) + .export_values(); +} + +} // namespace PyBindImath