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>() ));
   }
 }