Add an Options template paramter to Transform to enable/disable alignment
diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 1fdc55b..3c5f915 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h
@@ -246,7 +246,7 @@ #endif #if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS -template<typename Scalar,int Dim,int Mode> class Transform; +template<typename Scalar,int Dim,int Mode,int _Options=AutoAlign> class Transform; template <typename _Scalar, int _AmbientDim> class ParametrizedLine; template <typename _Scalar, int _AmbientDim> class Hyperplane; template<typename Scalar> class UniformScaling;
diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h index 24ec662..5c4f260 100644 --- a/Eigen/src/Geometry/Homogeneous.h +++ b/Eigen/src/Geometry/Homogeneous.h
@@ -112,12 +112,12 @@ return internal::homogeneous_left_product_impl<Homogeneous,Lhs>(lhs.derived(),rhs.m_matrix); } - template<typename Scalar, int Dim, int Mode> friend - inline const internal::homogeneous_left_product_impl<Homogeneous,Transform<Scalar,Dim,Mode> > - operator* (const Transform<Scalar,Dim,Mode>& lhs, const Homogeneous& rhs) + template<typename Scalar, int Dim, int Mode, int Options> friend + inline const internal::homogeneous_left_product_impl<Homogeneous,Transform<Scalar,Dim,Mode,Options> > + operator* (const Transform<Scalar,Dim,Mode,Options>& lhs, const Homogeneous& rhs) { eigen_assert(int(Direction)==Vertical); - return internal::homogeneous_left_product_impl<Homogeneous,Transform<Scalar,Dim,Mode> >(lhs,rhs.m_matrix); + return internal::homogeneous_left_product_impl<Homogeneous,Transform<Scalar,Dim,Mode,Options> >(lhs,rhs.m_matrix); } protected: @@ -212,18 +212,18 @@ static const type& run(const type &x) { return x; } }; -template<typename Scalar, int Dim, int Mode> -struct take_matrix_for_product<Transform<Scalar, Dim, Mode> > +template<typename Scalar, int Dim, int Mode,int Options> +struct take_matrix_for_product<Transform<Scalar, Dim, Mode, Options> > { - typedef Transform<Scalar, Dim, Mode> TransformType; + typedef Transform<Scalar, Dim, Mode, Options> TransformType; typedef typename TransformType::ConstAffinePart type; static const type run (const TransformType& x) { return x.affine(); } }; -template<typename Scalar, int Dim> -struct take_matrix_for_product<Transform<Scalar, Dim, Projective> > +template<typename Scalar, int Dim, int Options> +struct take_matrix_for_product<Transform<Scalar, Dim, Projective, Options> > { - typedef Transform<Scalar, Dim, Projective> TransformType; + typedef Transform<Scalar, Dim, Projective, Options> TransformType; typedef typename TransformType::MatrixType type; static const type& run (const TransformType& x) { return x.matrix(); } };
diff --git a/Eigen/src/Geometry/Hyperplane.h b/Eigen/src/Geometry/Hyperplane.h index b532cad..f22b23a 100644 --- a/Eigen/src/Geometry/Hyperplane.h +++ b/Eigen/src/Geometry/Hyperplane.h
@@ -229,7 +229,8 @@ * or a more generic Affine transformation. The default is Affine. * Other kind of transformations are not supported. */ - inline Hyperplane& transform(const Transform<Scalar,AmbientDimAtCompileTime,Affine>& t, + template<int TrOptions> + inline Hyperplane& transform(const Transform<Scalar,AmbientDimAtCompileTime,Affine,TrOptions>& t, TransformTraits traits = Affine) { transform(t.linear(), traits);
diff --git a/Eigen/src/Geometry/RotationBase.h b/Eigen/src/Geometry/RotationBase.h index 65b9cd8..1abf06b 100644 --- a/Eigen/src/Geometry/RotationBase.h +++ b/Eigen/src/Geometry/RotationBase.h
@@ -98,8 +98,8 @@ } /** \returns the concatenation of the rotation \c *this with a transformation \a t */ - template<int Mode> - inline Transform<Scalar,Dim,Mode> operator*(const Transform<Scalar,Dim,Mode>& t) const + template<int Mode, int Options> + inline Transform<Scalar,Dim,Mode> operator*(const Transform<Scalar,Dim,Mode,Options>& t) const { return toRotationMatrix() * t; } template<typename OtherVectorType>
diff --git a/Eigen/src/Geometry/Scaling.h b/Eigen/src/Geometry/Scaling.h index 9ad6778..c911d13 100644 --- a/Eigen/src/Geometry/Scaling.h +++ b/Eigen/src/Geometry/Scaling.h
@@ -72,8 +72,8 @@ inline Transform<Scalar,Dim,Affine> operator* (const Translation<Scalar,Dim>& t) const; /** Concatenates a uniform scaling and an affine transformation */ - template<int Dim, int Mode> - inline Transform<Scalar,Dim,Mode> operator* (const Transform<Scalar,Dim, Mode>& t) const; + template<int Dim, int Mode, int Options> + inline Transform<Scalar,Dim,Mode> operator* (const Transform<Scalar,Dim, Mode, Options>& t) const; /** Concatenates a uniform scaling and a linear transformation matrix */ // TODO returns an expression @@ -170,9 +170,9 @@ } template<typename Scalar> -template<int Dim,int Mode> +template<int Dim,int Mode,int Options> inline Transform<Scalar,Dim,Mode> -UniformScaling<Scalar>::operator* (const Transform<Scalar,Dim, Mode>& t) const +UniformScaling<Scalar>::operator* (const Transform<Scalar,Dim, Mode, Options>& t) const { Transform<Scalar,Dim,Mode> res = t; res.prescale(factor());
diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h index 2b679dc..2066e68 100644 --- a/Eigen/src/Geometry/Transform.h +++ b/Eigen/src/Geometry/Transform.h
@@ -48,6 +48,7 @@ template< typename Other, int Mode, + int Options, int Dim, int HDim, int OtherRows=Other::RowsAtCompileTime, @@ -63,6 +64,7 @@ template< typename Other, int Mode, + int Options, int Dim, int HDim, int OtherRows=Other::RowsAtCompileTime, @@ -88,6 +90,7 @@ * - AffineCompact: the transformation is stored as a (Dim)x(Dim+1) matrix. * - Projective: the transformation is stored as a (Dim+1)^2 matrix * without any assumption. + * \param _Options can be \b AutoAlign or \b DontAlign. Default is \b AutoAlign * * The homography is internally represented and stored by a matrix which * is available through the matrix() method. To understand the behavior of @@ -177,13 +180,14 @@ * * \sa class Matrix, class Quaternion */ -template<typename _Scalar, int _Dim, int _Mode> +template<typename _Scalar, int _Dim, int _Mode, int _Options> class Transform { public: EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1)) enum { Mode = _Mode, + Options = _Options, Dim = _Dim, ///< space dimension in which the transformation holds HDim = _Dim+1, ///< size of a respective homogeneous vector Rows = int(Mode)==(AffineCompact) ? Dim : HDim @@ -192,7 +196,7 @@ typedef _Scalar Scalar; typedef DenseIndex Index; /** type of the matrix used to represent the transformation */ - typedef Matrix<Scalar,Rows,HDim> MatrixType; + typedef Matrix<Scalar,Rows,HDim,Options&DontAlign> MatrixType; /** constified MatrixType */ typedef const MatrixType ConstMatrixType; /** type of the matrix used to represent the linear part of the transformation */ @@ -233,19 +237,33 @@ * If Mode==Affine, then the last row is set to [0 ... 0 1] */ inline Transform() { + check_template_params(); if (int(Mode)==Affine) makeAffine(); } inline Transform(const Transform& other) { + check_template_params(); m_matrix = other.m_matrix; } - inline explicit Transform(const TranslationType& t) { *this = t; } - inline explicit Transform(const UniformScaling<Scalar>& s) { *this = s; } + inline explicit Transform(const TranslationType& t) + { + check_template_params(); + *this = t; + } + inline explicit Transform(const UniformScaling<Scalar>& s) + { + check_template_params(); + *this = s; + } template<typename Derived> - inline explicit Transform(const RotationBase<Derived, Dim>& r) { *this = r; } + inline explicit Transform(const RotationBase<Derived, Dim>& r) + { + check_template_params(); + *this = r; + } inline Transform& operator=(const Transform& other) { m_matrix = other.m_matrix; return *this; } @@ -256,20 +274,30 @@ template<typename OtherDerived> inline explicit Transform(const EigenBase<OtherDerived>& other) { - internal::transform_construct_from_matrix<OtherDerived,Mode,Dim,HDim>::run(this, other.derived()); + check_template_params(); + internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived()); } /** Set \c *this from a Dim^2 or (Dim+1)^2 matrix. */ template<typename OtherDerived> inline Transform& operator=(const EigenBase<OtherDerived>& other) { - internal::transform_construct_from_matrix<OtherDerived,Mode,Dim,HDim>::run(this, other.derived()); + internal::transform_construct_from_matrix<OtherDerived,Mode,Options,Dim,HDim>::run(this, other.derived()); return *this; } - - template<int OtherMode> - inline Transform(const Transform<Scalar,Dim,OtherMode>& other) + + template<int OtherOptions> + inline Transform(const Transform<Scalar,Dim,Mode,OtherOptions>& other) { + check_template_params(); + // only the options change, we can directly copy the matrices + m_matrix = other.matrix(); + } + + template<int OtherMode,int OtherOptions> + inline Transform(const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) + { + check_template_params(); // prevent conversions as: // Affine | AffineCompact | Isometry = Projective EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Projective), Mode==int(Projective)), @@ -294,8 +322,8 @@ } else if(OtherModeIsAffineCompact) { - typedef typename Transform<Scalar,Dim,OtherMode>::MatrixType OtherMatrixType; - internal::transform_construct_from_matrix<OtherMatrixType,Mode,Dim,HDim>::run(this, other.matrix()); + typedef typename Transform<Scalar,Dim,OtherMode,OtherOptions>::MatrixType OtherMatrixType; + internal::transform_construct_from_matrix<OtherMatrixType,Mode,Options,Dim,HDim>::run(this, other.matrix()); } else { @@ -310,6 +338,7 @@ template<typename OtherDerived> Transform(const ReturnByValue<OtherDerived>& other) { + check_template_params(); other.evalTo(*this); } @@ -381,9 +410,9 @@ * \li a general transformation matrix of size Dim+1 x Dim+1. */ template<typename OtherDerived> friend - inline const typename internal::transform_left_product_impl<OtherDerived,Mode,_Dim,_Dim+1>::ResultType + inline const typename internal::transform_left_product_impl<OtherDerived,Mode,Options,_Dim,_Dim+1>::ResultType operator * (const EigenBase<OtherDerived> &a, const Transform &b) - { return internal::transform_left_product_impl<OtherDerived,Mode,Dim,HDim>::run(a.derived(),b); } + { return internal::transform_left_product_impl<OtherDerived,Mode,Options,Dim,HDim>::run(a.derived(),b); } /** \returns The product expression of a transform \a a times a diagonal matrix \a b * @@ -428,12 +457,12 @@ } /** Concatenates two different transformations */ - template<int OtherMode> + template<int OtherMode,int OtherOptions> inline const typename internal::transform_transform_product_impl< - Transform,Transform<Scalar,Dim,OtherMode> >::ResultType - operator * (const Transform<Scalar,Dim,OtherMode>& other) const + Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::ResultType + operator * (const Transform<Scalar,Dim,OtherMode,OtherOptions>& other) const { - return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode> >::run(*this,other); + return internal::transform_transform_product_impl<Transform,Transform<Scalar,Dim,OtherMode,OtherOptions> >::run(*this,other); } /** \sa MatrixBase::setIdentity() */ @@ -512,13 +541,16 @@ * then this function smartly returns a const reference to \c *this. */ template<typename NewScalarType> - inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode> >::type cast() const - { return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode> >::type(*this); } + inline typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type cast() const + { return typename internal::cast_return_type<Transform,Transform<NewScalarType,Dim,Mode,Options> >::type(*this); } /** Copy constructor with scalar type conversion */ template<typename OtherScalarType> - inline explicit Transform(const Transform<OtherScalarType,Dim,Mode>& other) - { m_matrix = other.matrix().template cast<Scalar>(); } + inline explicit Transform(const Transform<OtherScalarType,Dim,Mode,Options>& other) + { + check_template_params(); + m_matrix = other.matrix().template cast<Scalar>(); + } /** \returns \c true if \c *this is approximately equal to \a other, within the precision * determined by \a prec. @@ -568,6 +600,14 @@ #ifdef EIGEN_TRANSFORM_PLUGIN #include EIGEN_TRANSFORM_PLUGIN #endif + +protected: + #ifndef EIGEN_PARSED_BY_DOXYGEN + EIGEN_STRONG_INLINE static void check_template_params() + { + EIGEN_STATIC_ASSERT((Options & (DontAlign)) == Options, INVALID_MATRIX_TEMPLATE_PARAMETERS) + } + #endif }; @@ -616,9 +656,10 @@ * * This function is available only if the token EIGEN_QT_SUPPORT is defined. */ -template<typename Scalar, int Dim, int Mode> -Transform<Scalar,Dim,Mode>::Transform(const QMatrix& other) +template<typename Scalar, int Dim, int Mode,int Options> +Transform<Scalar,Dim,Mode,Options>::Transform(const QMatrix& other) { + check_template_params(); *this = other; } @@ -626,8 +667,8 @@ * * This function is available only if the token EIGEN_QT_SUPPORT is defined. */ -template<typename Scalar, int Dim, int Mode> -Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const QMatrix& other) +template<typename Scalar, int Dim, int Mode,int Otpions> +Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QMatrix& other) { EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) m_matrix << other.m11(), other.m21(), other.dx(), @@ -642,9 +683,10 @@ * * This function is available only if the token EIGEN_QT_SUPPORT is defined. */ -template<typename Scalar, int Dim, int Mode> -QMatrix Transform<Scalar,Dim,Mode>::toQMatrix(void) const +template<typename Scalar, int Dim, int Mode, int Options> +QMatrix Transform<Scalar,Dim,Mode,Options>::toQMatrix(void) const { + check_template_params(); EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) return QMatrix(m_matrix.coeff(0,0), m_matrix.coeff(1,0), m_matrix.coeff(0,1), m_matrix.coeff(1,1), @@ -655,9 +697,10 @@ * * This function is available only if the token EIGEN_QT_SUPPORT is defined. */ -template<typename Scalar, int Dim, int Mode> -Transform<Scalar,Dim,Mode>::Transform(const QTransform& other) +template<typename Scalar, int Dim, int Mode,int Options> +Transform<Scalar,Dim,Mode,Options>::Transform(const QTransform& other) { + check_template_params(); *this = other; } @@ -665,9 +708,10 @@ * * This function is available only if the token EIGEN_QT_SUPPORT is defined. */ -template<typename Scalar, int Dim, int Mode> -Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const QTransform& other) +template<typename Scalar, int Dim, int Mode, int Options> +Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const QTransform& other) { + check_template_params(); EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) m_matrix << other.m11(), other.m21(), other.dx(), other.m12(), other.m22(), other.dy(), @@ -679,8 +723,8 @@ * * This function is available only if the token EIGEN_QT_SUPPORT is defined. */ -template<typename Scalar, int Dim, int Mode> -QTransform Transform<Scalar,Dim,Mode>::toQTransform(void) const +template<typename Scalar, int Dim, int Mode, int Options> +QTransform Transform<Scalar,Dim,Mode,Options>::toQTransform(void) const { EIGEN_STATIC_ASSERT(Dim==2, YOU_MADE_A_PROGRAMMING_MISTAKE) return QTransform(matrix.coeff(0,0), matrix.coeff(1,0), matrix.coeff(2,0) @@ -697,10 +741,10 @@ * by the vector \a other to \c *this and returns a reference to \c *this. * \sa prescale() */ -template<typename Scalar, int Dim, int Mode> +template<typename Scalar, int Dim, int Mode, int Options> template<typename OtherDerived> -Transform<Scalar,Dim,Mode>& -Transform<Scalar,Dim,Mode>::scale(const MatrixBase<OtherDerived> &other) +Transform<Scalar,Dim,Mode,Options>& +Transform<Scalar,Dim,Mode,Options>::scale(const MatrixBase<OtherDerived> &other) { EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) @@ -712,8 +756,8 @@ * and returns a reference to \c *this. * \sa prescale(Scalar) */ -template<typename Scalar, int Dim, int Mode> -inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::scale(Scalar s) +template<typename Scalar, int Dim, int Mode, int Options> +inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::scale(Scalar s) { EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) linearExt() *= s; @@ -724,10 +768,10 @@ * by the vector \a other to \c *this and returns a reference to \c *this. * \sa scale() */ -template<typename Scalar, int Dim, int Mode> +template<typename Scalar, int Dim, int Mode, int Options> template<typename OtherDerived> -Transform<Scalar,Dim,Mode>& -Transform<Scalar,Dim,Mode>::prescale(const MatrixBase<OtherDerived> &other) +Transform<Scalar,Dim,Mode,Options>& +Transform<Scalar,Dim,Mode,Options>::prescale(const MatrixBase<OtherDerived> &other) { EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) @@ -739,8 +783,8 @@ * and returns a reference to \c *this. * \sa scale(Scalar) */ -template<typename Scalar, int Dim, int Mode> -inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::prescale(Scalar s) +template<typename Scalar, int Dim, int Mode, int Options> +inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::prescale(Scalar s) { EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) m_matrix.template topRows<Dim>() *= s; @@ -751,10 +795,10 @@ * to \c *this and returns a reference to \c *this. * \sa pretranslate() */ -template<typename Scalar, int Dim, int Mode> +template<typename Scalar, int Dim, int Mode, int Options> template<typename OtherDerived> -Transform<Scalar,Dim,Mode>& -Transform<Scalar,Dim,Mode>::translate(const MatrixBase<OtherDerived> &other) +Transform<Scalar,Dim,Mode,Options>& +Transform<Scalar,Dim,Mode,Options>::translate(const MatrixBase<OtherDerived> &other) { EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) translationExt() += linearExt() * other; @@ -765,10 +809,10 @@ * to \c *this and returns a reference to \c *this. * \sa translate() */ -template<typename Scalar, int Dim, int Mode> +template<typename Scalar, int Dim, int Mode, int Options> template<typename OtherDerived> -Transform<Scalar,Dim,Mode>& -Transform<Scalar,Dim,Mode>::pretranslate(const MatrixBase<OtherDerived> &other) +Transform<Scalar,Dim,Mode,Options>& +Transform<Scalar,Dim,Mode,Options>::pretranslate(const MatrixBase<OtherDerived> &other) { EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) if(int(Mode)==int(Projective)) @@ -795,10 +839,10 @@ * * \sa rotate(Scalar), class Quaternion, class AngleAxis, prerotate(RotationType) */ -template<typename Scalar, int Dim, int Mode> +template<typename Scalar, int Dim, int Mode, int Options> template<typename RotationType> -Transform<Scalar,Dim,Mode>& -Transform<Scalar,Dim,Mode>::rotate(const RotationType& rotation) +Transform<Scalar,Dim,Mode,Options>& +Transform<Scalar,Dim,Mode,Options>::rotate(const RotationType& rotation) { linearExt() *= internal::toRotationMatrix<Scalar,Dim>(rotation); return *this; @@ -811,10 +855,10 @@ * * \sa rotate() */ -template<typename Scalar, int Dim, int Mode> +template<typename Scalar, int Dim, int Mode, int Options> template<typename RotationType> -Transform<Scalar,Dim,Mode>& -Transform<Scalar,Dim,Mode>::prerotate(const RotationType& rotation) +Transform<Scalar,Dim,Mode,Options>& +Transform<Scalar,Dim,Mode,Options>::prerotate(const RotationType& rotation) { m_matrix.template block<Dim,HDim>(0,0) = internal::toRotationMatrix<Scalar,Dim>(rotation) * m_matrix.template block<Dim,HDim>(0,0); @@ -826,9 +870,9 @@ * \warning 2D only. * \sa preshear() */ -template<typename Scalar, int Dim, int Mode> -Transform<Scalar,Dim,Mode>& -Transform<Scalar,Dim,Mode>::shear(Scalar sx, Scalar sy) +template<typename Scalar, int Dim, int Mode, int Options> +Transform<Scalar,Dim,Mode,Options>& +Transform<Scalar,Dim,Mode,Options>::shear(Scalar sx, Scalar sy) { EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) @@ -842,9 +886,9 @@ * \warning 2D only. * \sa shear() */ -template<typename Scalar, int Dim, int Mode> -Transform<Scalar,Dim,Mode>& -Transform<Scalar,Dim,Mode>::preshear(Scalar sx, Scalar sy) +template<typename Scalar, int Dim, int Mode, int Options> +Transform<Scalar,Dim,Mode,Options>& +Transform<Scalar,Dim,Mode,Options>::preshear(Scalar sx, Scalar sy) { EIGEN_STATIC_ASSERT(int(Dim)==2, YOU_MADE_A_PROGRAMMING_MISTAKE) EIGEN_STATIC_ASSERT(Mode!=int(Isometry), THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS) @@ -856,8 +900,8 @@ *** Scaling, Translation and Rotation compatibility *** ******************************************************/ -template<typename Scalar, int Dim, int Mode> -inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const TranslationType& t) +template<typename Scalar, int Dim, int Mode, int Options> +inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const TranslationType& t) { linear().setIdentity(); translation() = t.vector(); @@ -865,16 +909,16 @@ return *this; } -template<typename Scalar, int Dim, int Mode> -inline Transform<Scalar,Dim,Mode> Transform<Scalar,Dim,Mode>::operator*(const TranslationType& t) const +template<typename Scalar, int Dim, int Mode, int Options> +inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const TranslationType& t) const { Transform res = *this; res.translate(t.vector()); return res; } -template<typename Scalar, int Dim, int Mode> -inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const UniformScaling<Scalar>& s) +template<typename Scalar, int Dim, int Mode, int Options> +inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const UniformScaling<Scalar>& s) { m_matrix.setZero(); linear().diagonal().fill(s.factor()); @@ -882,17 +926,17 @@ return *this; } -template<typename Scalar, int Dim, int Mode> -inline Transform<Scalar,Dim,Mode> Transform<Scalar,Dim,Mode>::operator*(const UniformScaling<Scalar>& s) const +template<typename Scalar, int Dim, int Mode, int Options> +inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const UniformScaling<Scalar>& s) const { Transform res = *this; res.scale(s.factor()); return res; } -template<typename Scalar, int Dim, int Mode> +template<typename Scalar, int Dim, int Mode, int Options> template<typename Derived> -inline Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::operator=(const RotationBase<Derived,Dim>& r) +inline Transform<Scalar,Dim,Mode,Options>& Transform<Scalar,Dim,Mode,Options>::operator=(const RotationBase<Derived,Dim>& r) { linear() = internal::toRotationMatrix<Scalar,Dim>(r); translation().setZero(); @@ -900,9 +944,9 @@ return *this; } -template<typename Scalar, int Dim, int Mode> +template<typename Scalar, int Dim, int Mode, int Options> template<typename Derived> -inline Transform<Scalar,Dim,Mode> Transform<Scalar,Dim,Mode>::operator*(const RotationBase<Derived,Dim>& r) const +inline Transform<Scalar,Dim,Mode,Options> Transform<Scalar,Dim,Mode,Options>::operator*(const RotationBase<Derived,Dim>& r) const { Transform res = *this; res.rotate(r.derived()); @@ -920,9 +964,9 @@ * * \sa computeRotationScaling(), computeScalingRotation(), class SVD */ -template<typename Scalar, int Dim, int Mode> -typename Transform<Scalar,Dim,Mode>::LinearMatrixType -Transform<Scalar,Dim,Mode>::rotation() const +template<typename Scalar, int Dim, int Mode, int Options> +typename Transform<Scalar,Dim,Mode,Options>::LinearMatrixType +Transform<Scalar,Dim,Mode,Options>::rotation() const { LinearMatrixType result; computeRotationScaling(&result, (LinearMatrixType*)0); @@ -941,9 +985,9 @@ * * \sa computeScalingRotation(), rotation(), class SVD */ -template<typename Scalar, int Dim, int Mode> +template<typename Scalar, int Dim, int Mode, int Options> template<typename RotationMatrixType, typename ScalingMatrixType> -void Transform<Scalar,Dim,Mode>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const +void Transform<Scalar,Dim,Mode,Options>::computeRotationScaling(RotationMatrixType *rotation, ScalingMatrixType *scaling) const { JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV); @@ -970,9 +1014,9 @@ * * \sa computeRotationScaling(), rotation(), class SVD */ -template<typename Scalar, int Dim, int Mode> +template<typename Scalar, int Dim, int Mode, int Options> template<typename ScalingMatrixType, typename RotationMatrixType> -void Transform<Scalar,Dim,Mode>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const +void Transform<Scalar,Dim,Mode,Options>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const { JacobiSVD<LinearMatrixType> svd(linear(), ComputeFullU | ComputeFullV); @@ -991,10 +1035,10 @@ /** Convenient method to set \c *this from a position, orientation and scale * of a 3D object. */ -template<typename Scalar, int Dim, int Mode> +template<typename Scalar, int Dim, int Mode, int Options> template<typename PositionDerived, typename OrientationType, typename ScaleDerived> -Transform<Scalar,Dim,Mode>& -Transform<Scalar,Dim,Mode>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position, +Transform<Scalar,Dim,Mode,Options>& +Transform<Scalar,Dim,Mode,Options>::fromPositionOrientationScale(const MatrixBase<PositionDerived> &position, const OrientationType& orientation, const MatrixBase<ScaleDerived> &scale) { linear() = internal::toRotationMatrix<Scalar,Dim>(orientation); @@ -1045,9 +1089,9 @@ * * \sa MatrixBase::inverse() */ -template<typename Scalar, int Dim, int Mode> -Transform<Scalar,Dim,Mode> -Transform<Scalar,Dim,Mode>::inverse(TransformTraits hint) const +template<typename Scalar, int Dim, int Mode, int Options> +Transform<Scalar,Dim,Mode,Options> +Transform<Scalar,Dim,Mode,Options>::inverse(TransformTraits hint) const { Transform res; if (hint == Projective) @@ -1103,10 +1147,10 @@ *** Specializations of construct from matrix *** *****************************************************/ -template<typename Other, int Mode, int Dim, int HDim> -struct transform_construct_from_matrix<Other, Mode,Dim,HDim, Dim,Dim> +template<typename Other, int Mode, int Options, int Dim, int HDim> +struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,Dim> { - static inline void run(Transform<typename Other::Scalar,Dim,Mode> *transform, const Other& other) + static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other) { transform->linear() = other; transform->translation().setZero(); @@ -1114,25 +1158,25 @@ } }; -template<typename Other, int Mode, int Dim, int HDim> -struct transform_construct_from_matrix<Other, Mode,Dim,HDim, Dim,HDim> +template<typename Other, int Mode, int Options, int Dim, int HDim> +struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, Dim,HDim> { - static inline void run(Transform<typename Other::Scalar,Dim,Mode> *transform, const Other& other) + static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other) { transform->affine() = other; transform->makeAffine(); } }; -template<typename Other, int Mode, int Dim, int HDim> -struct transform_construct_from_matrix<Other, Mode,Dim,HDim, HDim,HDim> +template<typename Other, int Mode, int Options, int Dim, int HDim> +struct transform_construct_from_matrix<Other, Mode,Options,Dim,HDim, HDim,HDim> { - static inline void run(Transform<typename Other::Scalar,Dim,Mode> *transform, const Other& other) + static inline void run(Transform<typename Other::Scalar,Dim,Mode,Options> *transform, const Other& other) { transform->matrix() = other; } }; -template<typename Other, int Dim, int HDim> -struct transform_construct_from_matrix<Other, AffineCompact,Dim,HDim, HDim,HDim> +template<typename Other, int Options, int Dim, int HDim> +struct transform_construct_from_matrix<Other, AffineCompact,Options,Dim,HDim, HDim,HDim> { static inline void run(Transform<typename Other::Scalar,Dim,AffineCompact> *transform, const Other& other) { transform->matrix() = other.template block<Dim,HDim>(0,0); } @@ -1204,23 +1248,23 @@ **********************************************************/ // generic HDim x HDim matrix * T => Projective -template<typename Other,int Mode, int Dim, int HDim> -struct transform_left_product_impl<Other,Mode,Dim,HDim, HDim,HDim> +template<typename Other,int Mode, int Options, int Dim, int HDim> +struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, HDim,HDim> { - typedef Transform<typename Other::Scalar,Dim,Mode> TransformType; + typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType; typedef typename TransformType::MatrixType MatrixType; - typedef Transform<typename Other::Scalar,Dim,Projective> ResultType; + typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType; static ResultType run(const Other& other,const TransformType& tr) { return ResultType(other * tr.matrix()); } }; // generic HDim x HDim matrix * AffineCompact => Projective -template<typename Other, int Dim, int HDim> -struct transform_left_product_impl<Other,AffineCompact,Dim,HDim, HDim,HDim> +template<typename Other, int Options, int Dim, int HDim> +struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, HDim,HDim> { - typedef Transform<typename Other::Scalar,Dim,AffineCompact> TransformType; + typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType; typedef typename TransformType::MatrixType MatrixType; - typedef Transform<typename Other::Scalar,Dim,Projective> ResultType; + typedef Transform<typename Other::Scalar,Dim,Projective,Options> ResultType; static ResultType run(const Other& other,const TransformType& tr) { ResultType res; @@ -1231,10 +1275,10 @@ }; // affine matrix * T -template<typename Other,int Mode, int Dim, int HDim> -struct transform_left_product_impl<Other,Mode,Dim,HDim, Dim,HDim> +template<typename Other,int Mode, int Options, int Dim, int HDim> +struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,HDim> { - typedef Transform<typename Other::Scalar,Dim,Mode> TransformType; + typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType; typedef typename TransformType::MatrixType MatrixType; typedef TransformType ResultType; static ResultType run(const Other& other,const TransformType& tr) @@ -1247,10 +1291,10 @@ }; // affine matrix * AffineCompact -template<typename Other, int Dim, int HDim> -struct transform_left_product_impl<Other,AffineCompact,Dim,HDim, Dim,HDim> +template<typename Other, int Options, int Dim, int HDim> +struct transform_left_product_impl<Other,AffineCompact,Options,Dim,HDim, Dim,HDim> { - typedef Transform<typename Other::Scalar,Dim,AffineCompact> TransformType; + typedef Transform<typename Other::Scalar,Dim,AffineCompact,Options> TransformType; typedef typename TransformType::MatrixType MatrixType; typedef TransformType ResultType; static ResultType run(const Other& other,const TransformType& tr) @@ -1263,10 +1307,10 @@ }; // linear matrix * T -template<typename Other,int Mode, int Dim, int HDim> -struct transform_left_product_impl<Other,Mode,Dim,HDim, Dim,Dim> +template<typename Other,int Mode, int Options, int Dim, int HDim> +struct transform_left_product_impl<Other,Mode,Options,Dim,HDim, Dim,Dim> { - typedef Transform<typename Other::Scalar,Dim,Mode> TransformType; + typedef Transform<typename Other::Scalar,Dim,Mode,Options> TransformType; typedef typename TransformType::MatrixType MatrixType; typedef TransformType ResultType; static ResultType run(const Other& other, const TransformType& tr) @@ -1284,13 +1328,13 @@ *** Specializations of operator* with another Transform *** **********************************************************/ -template<typename Scalar, int Dim, int LhsMode, int RhsMode> -struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode>,Transform<Scalar,Dim,RhsMode>,false > +template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions> +struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,false > { enum { ResultMode = transform_product_result<LhsMode,RhsMode>::Mode }; - typedef Transform<Scalar,Dim,LhsMode> Lhs; - typedef Transform<Scalar,Dim,RhsMode> Rhs; - typedef Transform<Scalar,Dim,ResultMode> ResultType; + typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs; + typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs; + typedef Transform<Scalar,Dim,ResultMode,LhsOptions> ResultType; static ResultType run(const Lhs& lhs, const Rhs& rhs) { ResultType res; @@ -1301,11 +1345,11 @@ } }; -template<typename Scalar, int Dim, int LhsMode, int RhsMode> -struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode>,Transform<Scalar,Dim,RhsMode>,true > +template<typename Scalar, int Dim, int LhsMode, int LhsOptions, int RhsMode, int RhsOptions> +struct transform_transform_product_impl<Transform<Scalar,Dim,LhsMode,LhsOptions>,Transform<Scalar,Dim,RhsMode,RhsOptions>,true > { - typedef Transform<Scalar,Dim,LhsMode> Lhs; - typedef Transform<Scalar,Dim,RhsMode> Rhs; + typedef Transform<Scalar,Dim,LhsMode,LhsOptions> Lhs; + typedef Transform<Scalar,Dim,RhsMode,RhsOptions> Rhs; typedef Transform<Scalar,Dim,Projective> ResultType; static ResultType run(const Lhs& lhs, const Rhs& rhs) {
diff --git a/Eigen/src/Geometry/Translation.h b/Eigen/src/Geometry/Translation.h index f442d82..d8fe50f 100644 --- a/Eigen/src/Geometry/Translation.h +++ b/Eigen/src/Geometry/Translation.h
@@ -132,8 +132,8 @@ } /** Concatenates a translation and a transformation */ - template<int Mode> - inline Transform<Scalar,Dim,Mode> operator* (const Transform<Scalar,Dim,Mode>& t) const + template<int Mode, int Options> + inline Transform<Scalar,Dim,Mode> operator* (const Transform<Scalar,Dim,Mode,Options>& t) const { Transform<Scalar,Dim,Mode> res = t; res.pretranslate(m_coeffs);
diff --git a/test/geo_transformations.cpp b/test/geo_transformations.cpp index 43a4aee..317ed9a 100644 --- a/test/geo_transformations.cpp +++ b/test/geo_transformations.cpp
@@ -27,7 +27,7 @@ #include <Eigen/LU> #include <Eigen/SVD> -template<typename Scalar, int Mode> void non_projective_only(void) +template<typename Scalar, int Mode, int Options> void non_projective_only() { /* this test covers the following files: Cross.h Quaternion.h, Transform.cpp @@ -40,10 +40,10 @@ typedef Matrix<Scalar,4,1> Vector4; typedef Quaternion<Scalar> Quaternionx; typedef AngleAxis<Scalar> AngleAxisx; - typedef Transform<Scalar,2,Mode> Transform2; - typedef Transform<Scalar,3,Mode> Transform3; - typedef Transform<Scalar,2,Isometry> Isometry2; - typedef Transform<Scalar,3,Isometry> Isometry3; + typedef Transform<Scalar,2,Mode,Options> Transform2; + typedef Transform<Scalar,3,Mode,Options> Transform3; + typedef Transform<Scalar,2,Isometry,Options> Isometry2; + typedef Transform<Scalar,3,Isometry,Options> Isometry3; typedef typename Transform3::MatrixType MatrixType; typedef DiagonalMatrix<Scalar,2> AlignedScaling2; typedef DiagonalMatrix<Scalar,3> AlignedScaling3; @@ -102,7 +102,7 @@ VERIFY_IS_APPROX((t0 * v1).template head<3>(), AlignedScaling3(v0) * v1); } -template<typename Scalar, int Mode> void transformations(void) +template<typename Scalar, int Mode, int Options> void transformations() { /* this test covers the following files: Cross.h Quaternion.h, Transform.cpp @@ -115,10 +115,10 @@ typedef Matrix<Scalar,4,1> Vector4; typedef Quaternion<Scalar> Quaternionx; typedef AngleAxis<Scalar> AngleAxisx; - typedef Transform<Scalar,2,Mode> Transform2; - typedef Transform<Scalar,3,Mode> Transform3; - typedef Transform<Scalar,2,Isometry> Isometry2; - typedef Transform<Scalar,3,Isometry> Isometry3; + typedef Transform<Scalar,2,Mode,Options> Transform2; + typedef Transform<Scalar,3,Mode,Options> Transform3; + typedef Transform<Scalar,2,Isometry,Options> Isometry2; + typedef Transform<Scalar,3,Isometry,Options> Isometry3; typedef typename Transform3::MatrixType MatrixType; typedef DiagonalMatrix<Scalar,2> AlignedScaling2; typedef DiagonalMatrix<Scalar,3> AlignedScaling3; @@ -427,15 +427,45 @@ } +template<typename Scalar> void transform_alignment() +{ + typedef Transform<Scalar,3,Projective,AutoAlign> Projective4a; + typedef Transform<Scalar,3,Projective,DontAlign> Projective4u; + + EIGEN_ALIGN16 Scalar array1[16]; + EIGEN_ALIGN16 Scalar array2[16]; + EIGEN_ALIGN16 Scalar array3[16+1]; + Scalar* array3u = array3+1; + + Projective4a *p1 = ::new(reinterpret_cast<void*>(array1)) Projective4a; + Projective4u *p2 = ::new(reinterpret_cast<void*>(array2)) Projective4u; + Projective4u *p3 = ::new(reinterpret_cast<void*>(array3u)) Projective4u; + + p1->matrix().setRandom(); + *p2 = *p1; + *p3 = *p1; + + VERIFY_IS_APPROX(p1->matrix(), p2->matrix()); + VERIFY_IS_APPROX(p1->matrix(), p3->matrix()); + + VERIFY_IS_APPROX( (*p1) * (*p1), (*p2)*(*p3)); + + #ifdef EIGEN_VECTORIZE + VERIFY_RAISES_ASSERT((::new(reinterpret_cast<void*>(array3u)) Projective4a)); + #endif +} + void test_geo_transformations() { for(int i = 0; i < g_repeat; i++) { - CALL_SUBTEST_1(( transformations<double,Affine>() )); - CALL_SUBTEST_1(( non_projective_only<double,Affine>() )); + CALL_SUBTEST_1(( transformations<double,Affine,AutoAlign>() )); + CALL_SUBTEST_1(( non_projective_only<double,Affine,AutoAlign>() )); - CALL_SUBTEST_2(( transformations<float,AffineCompact>() )); - CALL_SUBTEST_2(( non_projective_only<float,AffineCompact>() )); + CALL_SUBTEST_2(( transformations<float,AffineCompact,AutoAlign>() )); + CALL_SUBTEST_2(( non_projective_only<float,AffineCompact,AutoAlign>() )); - CALL_SUBTEST_3(( transformations<double,Projective>() )); + CALL_SUBTEST_3(( transformations<double,Projective,AutoAlign>() )); + CALL_SUBTEST_3(( transformations<double,Projective,DontAlign>() )); + CALL_SUBTEST_3(( transform_alignment<double>() )); } }