807 lines
25 KiB
C++
807 lines
25 KiB
C++
|
///////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Copyright (c) 1998-2011, Industrial Light & Magic, a division of Lucas
|
||
|
// Digital Ltd. LLC
|
||
|
//
|
||
|
// All rights reserved.
|
||
|
//
|
||
|
// Redistribution and use in source and binary forms, with or without
|
||
|
// modification, are permitted provided that the following conditions are
|
||
|
// met:
|
||
|
// * Redistributions of source code must retain the above copyright
|
||
|
// notice, this list of conditions and the following disclaimer.
|
||
|
// * Redistributions in binary form must reproduce the above
|
||
|
// copyright notice, this list of conditions and the following disclaimer
|
||
|
// in the documentation and/or other materials provided with the
|
||
|
// distribution.
|
||
|
// * Neither the name of Industrial Light & Magic nor the names of
|
||
|
// its contributors may be used to endorse or promote products derived
|
||
|
// from this software without specific prior written permission.
|
||
|
//
|
||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#include <PyImathEuler.h>
|
||
|
#include "PyImathDecorators.h"
|
||
|
#include "PyImathExport.h"
|
||
|
#include <Python.h>
|
||
|
#include <boost/python.hpp>
|
||
|
#include <boost/python/make_constructor.hpp>
|
||
|
#include <boost/format.hpp>
|
||
|
#include <PyImath.h>
|
||
|
#include <PyImathMathExc.h>
|
||
|
#include <ImathVec.h>
|
||
|
#include <Iex.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 <class T> struct EulerName { static const char *value; };
|
||
|
template<> const char *EulerName<float>::value = "Eulerf";
|
||
|
template<> const char *EulerName<double>::value = "Eulerd";
|
||
|
|
||
|
template <class T>
|
||
|
static std::string nameOfOrder(typename IMATH_NAMESPACE::Euler<T>::Order order)
|
||
|
{
|
||
|
switch(order)
|
||
|
{
|
||
|
case IMATH_NAMESPACE::Euler<T>::XYZ:
|
||
|
return "EULER_XYZ";
|
||
|
case IMATH_NAMESPACE::Euler<T>::XZY:
|
||
|
return "EULER_XZY";
|
||
|
case IMATH_NAMESPACE::Euler<T>::YZX:
|
||
|
return "EULER_YZX";
|
||
|
case IMATH_NAMESPACE::Euler<T>::YXZ:
|
||
|
return "EULER_YXZ";
|
||
|
case IMATH_NAMESPACE::Euler<T>::ZXY:
|
||
|
return "EULER_ZXY";
|
||
|
case IMATH_NAMESPACE::Euler<T>::ZYX:
|
||
|
return "EULER_ZYX";
|
||
|
case IMATH_NAMESPACE::Euler<T>::XZX:
|
||
|
return "EULER_XZX";
|
||
|
case IMATH_NAMESPACE::Euler<T>::XYX:
|
||
|
return "EULER_XYX";
|
||
|
case IMATH_NAMESPACE::Euler<T>::YXY:
|
||
|
return "EULER_YXY";
|
||
|
case IMATH_NAMESPACE::Euler<T>::YZY:
|
||
|
return "EULER_YZY";
|
||
|
case IMATH_NAMESPACE::Euler<T>::ZYZ:
|
||
|
return "EULER_ZYZ";
|
||
|
case IMATH_NAMESPACE::Euler<T>::ZXZ:
|
||
|
return "EULER_ZXZ";
|
||
|
case IMATH_NAMESPACE::Euler<T>::XYZr:
|
||
|
return "EULER_XYZr";
|
||
|
case IMATH_NAMESPACE::Euler<T>::XZYr:
|
||
|
return "EULER_XZYr";
|
||
|
case IMATH_NAMESPACE::Euler<T>::YZXr:
|
||
|
return "EULER_YZXr";
|
||
|
case IMATH_NAMESPACE::Euler<T>::YXZr:
|
||
|
return "EULER_YXZr";
|
||
|
case IMATH_NAMESPACE::Euler<T>::ZXYr:
|
||
|
return "EULER_ZXYr";
|
||
|
case IMATH_NAMESPACE::Euler<T>::ZYXr:
|
||
|
return "EULER_ZYXr";
|
||
|
case IMATH_NAMESPACE::Euler<T>::XZXr:
|
||
|
return "EULER_XZXr";
|
||
|
case IMATH_NAMESPACE::Euler<T>::XYXr:
|
||
|
return "EULER_XYXr";
|
||
|
case IMATH_NAMESPACE::Euler<T>::YXYr:
|
||
|
return "EULER_YXYr";
|
||
|
case IMATH_NAMESPACE::Euler<T>::YZYr:
|
||
|
return "EULER_YZYr";
|
||
|
case IMATH_NAMESPACE::Euler<T>::ZYZr:
|
||
|
return "EULER_ZYZr";
|
||
|
case IMATH_NAMESPACE::Euler<T>::ZXZr:
|
||
|
return "EULER_ZXZr";
|
||
|
}
|
||
|
|
||
|
return "";
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static std::string Euler_str(const Euler<T> &e)
|
||
|
{
|
||
|
std::stringstream stream;
|
||
|
stream << EulerName<T>::value << "(" << e.x << ", " << e.y << ", " << e.z << ", "
|
||
|
<< nameOfOrder<T> (e.order()) << ")";
|
||
|
return stream.str();
|
||
|
}
|
||
|
|
||
|
// Non-specialized repr is same as str
|
||
|
template <class T>
|
||
|
static std::string Euler_repr(const Euler<T> &e)
|
||
|
{
|
||
|
return Euler_str(e);
|
||
|
}
|
||
|
|
||
|
// Specialization for float to full precision
|
||
|
template <>
|
||
|
std::string Euler_repr(const Euler<float> &e)
|
||
|
{
|
||
|
return (boost::format("%s(%.9g, %.9g, %.9g, %s)")
|
||
|
% EulerName<float>::value
|
||
|
% e.x % e.y % e.z
|
||
|
% nameOfOrder<float>(e.order()).c_str()).str();
|
||
|
}
|
||
|
|
||
|
// Specialization for double to full precision
|
||
|
template <>
|
||
|
std::string Euler_repr(const Euler<double> &e)
|
||
|
{
|
||
|
return (boost::format("%s(%.17g, %.17g, %.17g, %s)")
|
||
|
% EulerName<double>::value
|
||
|
% e.x % e.y % e.z
|
||
|
% nameOfOrder<double>(e.order()).c_str()).str();
|
||
|
}
|
||
|
|
||
|
|
||
|
template <class T>
|
||
|
static bool
|
||
|
equal(const Euler<T> &e0, const Euler<T> &e1)
|
||
|
{
|
||
|
if(e0.x == e1.x && e0.y == e1.y && e0.z == e1.z && (e0.order())==(e1.order()))
|
||
|
return true;
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static bool
|
||
|
notequal(const Euler<T> &e0, const Euler<T> &e1)
|
||
|
{
|
||
|
if(e0.x != e1.x || e0.y != e1.y || e0.z != e1.z || (e0.order()) != (e1.order()))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static IMATH_NAMESPACE::Vec3 <int> getAngleOrder(Euler <T> &euler)
|
||
|
{
|
||
|
int i, j, k;
|
||
|
euler.angleOrder(i, j, k);
|
||
|
return IMATH_NAMESPACE::Vec3 <int> (i, j, k);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static void
|
||
|
setXYZTuple(Euler<T> &euler, const tuple &t)
|
||
|
{
|
||
|
MATH_EXC_ON;
|
||
|
Vec3<T> v;
|
||
|
if(t.attr("__len__")() == 3)
|
||
|
{
|
||
|
v.x = extract<T>(t[0]);
|
||
|
v.y = extract<T>(t[1]);
|
||
|
v.z = extract<T>(t[2]);
|
||
|
|
||
|
euler.setXYZVector(v);
|
||
|
}
|
||
|
else
|
||
|
THROW(IEX_NAMESPACE::LogicExc, "Color3 expects tuple of length 3");
|
||
|
}
|
||
|
|
||
|
// needed to convert Eulerf::Order to Euler<T>::Order
|
||
|
template <class T>
|
||
|
static typename Euler<T>::Order interpretOrder(typename IMATH_NAMESPACE::Eulerf::Order order)
|
||
|
{
|
||
|
typename Euler<T>::Order o = Euler<T>::XYZ;
|
||
|
switch(order)
|
||
|
{
|
||
|
case IMATH_NAMESPACE::Eulerf::XYZ:
|
||
|
{
|
||
|
o = Euler<T>::XYZ;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::XZY:
|
||
|
{
|
||
|
o = Euler<T>::XZY;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::YZX:
|
||
|
{
|
||
|
o = Euler<T>::YZX;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::YXZ:
|
||
|
{
|
||
|
o = Euler<T>::YXZ;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::ZXY:
|
||
|
{
|
||
|
o = Euler<T>::ZXY;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::ZYX:
|
||
|
{
|
||
|
o = Euler<T>::ZYX;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::XZX:
|
||
|
{
|
||
|
o = Euler<T>::XZX;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::XYX:
|
||
|
{
|
||
|
o = Euler<T>::XYX;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::YXY:
|
||
|
{
|
||
|
o = Euler<T>::YXY;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::YZY:
|
||
|
{
|
||
|
o = Euler<T>::YZY;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::ZYZ:
|
||
|
{
|
||
|
o = Euler<T>::ZYZ;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::ZXZ:
|
||
|
{
|
||
|
o = Euler<T>::ZXZ;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::XYZr:
|
||
|
{
|
||
|
o = Euler<T>::XYZr;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::XZYr:
|
||
|
{
|
||
|
o = Euler<T>::XZYr;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::YZXr:
|
||
|
{
|
||
|
o = Euler<T>::YZXr;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::YXZr:
|
||
|
{
|
||
|
o = Euler<T>::YXZr;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::ZXYr:
|
||
|
{
|
||
|
o = Euler<T>::ZXYr;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::ZYXr:
|
||
|
{
|
||
|
o = Euler<T>::ZYXr;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::XZXr:
|
||
|
{
|
||
|
o = Euler<T>::XZXr;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::XYXr:
|
||
|
{
|
||
|
o = Euler<T>::XYXr;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::YXYr:
|
||
|
{
|
||
|
o = Euler<T>::YXYr;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::YZYr:
|
||
|
{
|
||
|
o = Euler<T>::YZYr;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::ZYZr:
|
||
|
{
|
||
|
o = Euler<T>::ZYZr;
|
||
|
}break;
|
||
|
case IMATH_NAMESPACE::Eulerf::ZXZr:
|
||
|
{
|
||
|
o = Euler<T>::ZXZr;
|
||
|
}break;
|
||
|
}
|
||
|
|
||
|
return o;
|
||
|
}
|
||
|
|
||
|
// needed to convert Eulerf::Axis to Euler<T>::Axis
|
||
|
template <class T>
|
||
|
static typename Euler<T>::Axis interpretAxis(typename IMATH_NAMESPACE::Eulerf::Axis axis)
|
||
|
{
|
||
|
if (axis == IMATH_NAMESPACE::Eulerf::X)
|
||
|
return Euler<T>::X;
|
||
|
else if (axis == IMATH_NAMESPACE::Eulerf::Y)
|
||
|
return Euler<T>::Y;
|
||
|
else
|
||
|
return Euler<T>::Z;
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor1(const Vec3<T> &v, typename IMATH_NAMESPACE::Eulerf::Order order)
|
||
|
{
|
||
|
typename Euler<T>::Order o = interpretOrder<T>(order);
|
||
|
return new Euler<T>(v, o);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor1a(const Vec3<T> &v)
|
||
|
{
|
||
|
return eulerConstructor1 (v, IMATH_NAMESPACE::Eulerf::Default);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor1b(const Vec3<T> &v, int iorder)
|
||
|
{
|
||
|
typename Euler<T>::Order o = typename Euler<T>::Order (iorder);
|
||
|
return new Euler<T>(v, o);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor2(T i, T j, T k, typename IMATH_NAMESPACE::Eulerf::Order order)
|
||
|
{
|
||
|
typename Euler<T>::Order o = interpretOrder<T>(order);
|
||
|
return new Euler<T>(i, j, k, o);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor2a(T i, T j, T k)
|
||
|
{
|
||
|
return eulerConstructor2 (i, j, k, IMATH_NAMESPACE::Eulerf::Default);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor2b(T i, T j, T k, int iorder)
|
||
|
{
|
||
|
typename Euler<T>::Order o = typename Euler<T>::Order (iorder);
|
||
|
return new Euler<T>(i, j, k, o);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor3(const Matrix33<T> &mat, typename IMATH_NAMESPACE::Eulerf::Order order)
|
||
|
{
|
||
|
typename Euler<T>::Order o = interpretOrder<T>(order);
|
||
|
return new Euler<T>(mat, o);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor3a(const Matrix33<T> &mat)
|
||
|
{
|
||
|
return eulerConstructor3 (mat, IMATH_NAMESPACE::Eulerf::Default);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor3b(const Matrix33<T> &mat, int iorder)
|
||
|
{
|
||
|
typename Euler<T>::Order o = typename Euler<T>::Order (iorder);
|
||
|
return new Euler<T>(mat, o);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor4(const Matrix44<T> &mat, typename IMATH_NAMESPACE::Eulerf::Order order)
|
||
|
{
|
||
|
typename Euler<T>::Order o = interpretOrder<T>(order);
|
||
|
return new Euler<T>(mat, o);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor4a(const Matrix44<T> &mat)
|
||
|
{
|
||
|
return eulerConstructor4 (mat, IMATH_NAMESPACE::Eulerf::Default);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor4b(const Matrix44<T> &mat, int iorder)
|
||
|
{
|
||
|
typename Euler<T>::Order o = typename Euler<T>::Order (iorder);
|
||
|
return new Euler<T>(mat, o);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor5(typename IMATH_NAMESPACE::Eulerf::Order order)
|
||
|
{
|
||
|
typename Euler<T>::Order o = interpretOrder<T>(order);
|
||
|
return new Euler<T>(o);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor5a()
|
||
|
{
|
||
|
typename Euler<T>::Order o = interpretOrder<T>(IMATH_NAMESPACE::Eulerf::Default);
|
||
|
return new Euler<T>(o);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor5b(int iorder)
|
||
|
{
|
||
|
typename Euler<T>::Order o = typename Euler<T>::Order (iorder);
|
||
|
return new Euler<T>(o);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor6(T x, T y, T z)
|
||
|
{
|
||
|
return new Euler<T>(Vec3<T>(x,y,z));
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor7(const Quat<T> &quat, typename IMATH_NAMESPACE::Eulerf::Order order)
|
||
|
{
|
||
|
Euler<T> *e = eulerConstructor5<T>(order);
|
||
|
e->extract(quat);
|
||
|
return e;
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor7a(const Quat<T> &quat)
|
||
|
{
|
||
|
return eulerConstructor7(quat, IMATH_NAMESPACE::Eulerf::Default);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Euler<T> *
|
||
|
eulerConstructor7b(const Quat<T> &quat, int iorder)
|
||
|
{
|
||
|
Euler<T> *e = eulerConstructor5b<T>(iorder);
|
||
|
e->extract(quat);
|
||
|
return e;
|
||
|
}
|
||
|
|
||
|
template <class T, class S>
|
||
|
static Euler<T> *
|
||
|
eulerConversionConstructor(const Euler<S> &euler)
|
||
|
{
|
||
|
MATH_EXC_ON;
|
||
|
Euler<T> *e = new Euler<T>;
|
||
|
*e = euler;
|
||
|
return e;
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static void
|
||
|
eulerMakeNear(Euler<T> &euler, Euler<T> &target)
|
||
|
{
|
||
|
MATH_EXC_ON;
|
||
|
euler.makeNear (target);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static void
|
||
|
eulerSetOrder(Euler<T> &euler, typename IMATH_NAMESPACE::Eulerf::Order order)
|
||
|
{
|
||
|
typename Euler<T>::Order o = interpretOrder<T>(order);
|
||
|
euler.setOrder (o);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static void
|
||
|
eulerSet(Euler<T> &euler, IMATH_NAMESPACE::Eulerf::Axis axis, int relative, int parityEven, int firstRepeats)
|
||
|
{
|
||
|
MATH_EXC_ON;
|
||
|
typename Euler<T>::Axis a = interpretAxis<T>(axis);
|
||
|
euler.set (a, relative, parityEven, firstRepeats);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static void
|
||
|
extract1(Euler<T> &euler, const Matrix33<T> &m)
|
||
|
{
|
||
|
MATH_EXC_ON;
|
||
|
euler.extract(m);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static void
|
||
|
extract2(Euler<T> &euler, const Matrix44<T> &m)
|
||
|
{
|
||
|
MATH_EXC_ON;
|
||
|
euler.extract(m);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static void
|
||
|
extract3(Euler<T> &euler, const Quat<T> &q)
|
||
|
{
|
||
|
MATH_EXC_ON;
|
||
|
euler.extract(q);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Matrix33<T>
|
||
|
toMatrix33(Euler<T> &euler)
|
||
|
{
|
||
|
MATH_EXC_ON;
|
||
|
return euler.toMatrix33();
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Matrix44<T>
|
||
|
toMatrix44(Euler<T> &euler)
|
||
|
{
|
||
|
MATH_EXC_ON;
|
||
|
return euler.toMatrix44();
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Quat<T>
|
||
|
toQuat(Euler<T> &euler)
|
||
|
{
|
||
|
MATH_EXC_ON;
|
||
|
return euler.toQuat();
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
static Vec3<T>
|
||
|
toXYZVector(Euler<T> &euler)
|
||
|
{
|
||
|
MATH_EXC_ON;
|
||
|
return euler.toXYZVector();
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
class_<Euler<T>,bases<IMATH_NAMESPACE::Vec3<T> > >
|
||
|
register_Euler()
|
||
|
{
|
||
|
class_<Euler<T>,bases<Vec3<T> > > euler_class(EulerName<T>::value,EulerName<T>::value,init<Euler<T> >("copy construction"));
|
||
|
euler_class
|
||
|
.def(init<>("imath Euler default construction"))
|
||
|
.def("__init__", make_constructor(eulerConstructor1<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor1a<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor1b<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor2<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor2a<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor2b<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor3<T>),
|
||
|
"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<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor3b<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor4<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor4a<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor4b<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor5<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor5a<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor5b<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor6<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor7<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor7a<T>))
|
||
|
.def("__init__", make_constructor(eulerConstructor7b<T>))
|
||
|
.def("__init__", make_constructor(eulerConversionConstructor<T, float>))
|
||
|
.def("__init__", make_constructor(eulerConversionConstructor<T, double>))
|
||
|
|
||
|
.def("angleOrder", &getAngleOrder<T>, "angleOrder() set the angle order")
|
||
|
|
||
|
.def("frameStatic", &Euler<T>::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<T>::initialAxis,
|
||
|
"e.initialAxis() -- returns the initial rotation\n"
|
||
|
"axis of e (EULER_X_AXIS, EULER_Y_AXIS, EULER_Z_AXIS)")
|
||
|
|
||
|
.def("initialRepeated", &Euler<T>::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<T>,
|
||
|
"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<T>::order,
|
||
|
"e.order() -- returns the rotation order in e\n"
|
||
|
"(EULER_XYZ, EULER_XZY, ...)")
|
||
|
|
||
|
.def("parityEven", &Euler<T>::parityEven,
|
||
|
"e.parityEven() -- returns the parity of the\n"
|
||
|
"axis permutation of e\n")
|
||
|
|
||
|
.def("set", &eulerSet<T>,
|
||
|
"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<T>,
|
||
|
"e.setOrder(o) -- sets the rotation order in e\n"
|
||
|
"to o (EULER_XYZ, EULER_XZY, ...)")
|
||
|
|
||
|
.def("setXYZVector", &Euler<T>::setXYZVector,
|
||
|
"e.setXYZVector(v) -- sets the three rotation\n"
|
||
|
"angles in e to v[0], v[1], v[2]")
|
||
|
.def("setXYZVector", &setXYZTuple<T>)
|
||
|
|
||
|
.def("extract", &extract1<T>,
|
||
|
"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<T>,
|
||
|
"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<T>,
|
||
|
"e.extract(q) -- extracts the rotation component\n"
|
||
|
"from quaternion q and stores the result in e")
|
||
|
|
||
|
.def("toMatrix33", &toMatrix33<T>, "e.toMatrix33() -- converts e into a 3x3 matrix\n")
|
||
|
|
||
|
.def("toMatrix44", &toMatrix44<T>, "e.toMatrix44() -- converts e into a 4x4 matrix\n")
|
||
|
|
||
|
.def("toQuat", &toQuat<T>, "e.toQuat() -- converts e into a quaternion\n")
|
||
|
|
||
|
.def("toXYZVector", &toXYZVector<T>,
|
||
|
"e.toXYZVector() -- converts e into an XYZ\n"
|
||
|
"rotation vector")
|
||
|
.def("__str__", &Euler_str<T>)
|
||
|
.def("__repr__", &Euler_repr<T>)
|
||
|
|
||
|
.def("__eq__", &equal<T>)
|
||
|
.def("__ne__", ¬equal<T>)
|
||
|
;
|
||
|
|
||
|
// fill in the Euler scope
|
||
|
{
|
||
|
scope euler_scope(euler_class);
|
||
|
enum_<typename Euler<T>::Order> euler_order("Order");
|
||
|
euler_order
|
||
|
.value("XYZ",Euler<T>::XYZ)
|
||
|
.value("XZY",Euler<T>::XZY)
|
||
|
.value("YZX",Euler<T>::YZX)
|
||
|
.value("YXZ",Euler<T>::YXZ)
|
||
|
.value("ZXY",Euler<T>::ZXY)
|
||
|
.value("ZYX",Euler<T>::ZYX)
|
||
|
.value("XZX",Euler<T>::XZX)
|
||
|
.value("XYX",Euler<T>::XYX)
|
||
|
.value("YXY",Euler<T>::YXY)
|
||
|
.value("YZY",Euler<T>::YZY)
|
||
|
.value("ZYZ",Euler<T>::ZYZ)
|
||
|
.value("ZXZ",Euler<T>::ZXZ)
|
||
|
.value("XYZr",Euler<T>::XYZr)
|
||
|
.value("XZYr",Euler<T>::XZYr)
|
||
|
.value("YZXr",Euler<T>::YZXr)
|
||
|
.value("YXZr",Euler<T>::YXZr)
|
||
|
.value("ZXYr",Euler<T>::ZXYr)
|
||
|
.value("ZYXr",Euler<T>::ZYXr)
|
||
|
.value("XZXr",Euler<T>::XZXr)
|
||
|
.value("XYXr",Euler<T>::XYXr)
|
||
|
.value("YXYr",Euler<T>::YXYr)
|
||
|
.value("YZYr",Euler<T>::YZYr)
|
||
|
.value("ZYZr",Euler<T>::ZYZr)
|
||
|
.value("ZXZr",Euler<T>::ZXZr)
|
||
|
|
||
|
// don't export these, they're not really part of the public interface
|
||
|
//.value("Legal",Euler<T>::Legal)
|
||
|
//.value("Min",Euler<T>::Min)
|
||
|
//.value("Max",Euler<T>::Max)
|
||
|
|
||
|
// handle Default seperately since boost sets up a 1-1 mapping for enum values
|
||
|
//.value("Default",Euler<T>::Default)
|
||
|
.export_values()
|
||
|
;
|
||
|
// just set it to the XYZ value manually
|
||
|
euler_scope.attr("Default") = euler_scope.attr("XYZ");
|
||
|
|
||
|
enum_<typename Euler<T>::Axis>("Axis")
|
||
|
.value("X",Euler<T>::X)
|
||
|
.value("Y",Euler<T>::Y)
|
||
|
.value("Z",Euler<T>::Z)
|
||
|
.export_values()
|
||
|
;
|
||
|
|
||
|
enum_<typename Euler<T>::InputLayout>("InputLayout")
|
||
|
.value("XYZLayout",Euler<T>::XYZLayout)
|
||
|
.value("IJKLayout",Euler<T>::IJKLayout)
|
||
|
.export_values()
|
||
|
;
|
||
|
}
|
||
|
|
||
|
decoratecopy(euler_class);
|
||
|
|
||
|
return euler_class;
|
||
|
}
|
||
|
|
||
|
// XXX fixme - template this
|
||
|
// really this should get generated automatically...
|
||
|
|
||
|
/*
|
||
|
template <class T,int index>
|
||
|
static FixedArray<T>
|
||
|
EulerArray_get(FixedArray<IMATH_NAMESPACE::Euler<T> > &qa)
|
||
|
{
|
||
|
return FixedArray<T>( &(qa[0].r)+index, qa.len(), 4*qa.stride());
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
template <class T>
|
||
|
static FixedArray<IMATH_NAMESPACE::Euler<T> > *
|
||
|
EulerArray_eulerConstructor7a(const FixedArray<IMATH_NAMESPACE::Quat<T> > &q)
|
||
|
{
|
||
|
MATH_EXC_ON;
|
||
|
size_t len = q.len();
|
||
|
FixedArray<IMATH_NAMESPACE::Euler<T> >* result = new FixedArray<IMATH_NAMESPACE::Euler<T> >(len);
|
||
|
for (size_t i = 0; i < len; ++i) {
|
||
|
(*result)[i].extract(q[i]);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
class_<FixedArray<IMATH_NAMESPACE::Euler<T> > >
|
||
|
register_EulerArray()
|
||
|
{
|
||
|
class_<FixedArray<IMATH_NAMESPACE::Euler<T> > > eulerArray_class = FixedArray<IMATH_NAMESPACE::Euler<T> >::register_("Fixed length array of IMATH_NAMESPACE::Euler");
|
||
|
eulerArray_class
|
||
|
//.add_property("x",&EulerArray_get<T,1>)
|
||
|
//.add_property("y",&EulerArray_get<T,2>)
|
||
|
//.add_property("z",&EulerArray_get<T,3>)
|
||
|
.def("__init__", make_constructor(EulerArray_eulerConstructor7a<T>))
|
||
|
;
|
||
|
|
||
|
add_comparison_functions(eulerArray_class);
|
||
|
PyImath::add_explicit_construction_from_type<IMATH_NAMESPACE::Matrix33<T> >(eulerArray_class);
|
||
|
PyImath::add_explicit_construction_from_type<IMATH_NAMESPACE::Matrix44<T> >(eulerArray_class);
|
||
|
return eulerArray_class;
|
||
|
}
|
||
|
|
||
|
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Euler<float>,bases<IMATH_NAMESPACE::Vec3<float> > > register_Euler<float>();
|
||
|
template PYIMATH_EXPORT class_<IMATH_NAMESPACE::Euler<double>,bases<IMATH_NAMESPACE::Vec3<double> > > register_Euler<double>();
|
||
|
|
||
|
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Euler<float> > > register_EulerArray<float>();
|
||
|
template PYIMATH_EXPORT class_<FixedArray<IMATH_NAMESPACE::Euler<double> > > register_EulerArray<double>();
|
||
|
}
|
||
|
namespace PyImath {
|
||
|
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Euler<float> FixedArrayDefaultValue<IMATH_NAMESPACE::Euler<float> >::value() { return IMATH_NAMESPACE::Euler<float>(); }
|
||
|
template<> PYIMATH_EXPORT IMATH_NAMESPACE::Euler<double> FixedArrayDefaultValue<IMATH_NAMESPACE::Euler<double> >::value() { return IMATH_NAMESPACE::Euler<double>(); }
|
||
|
}
|