11 #ifndef __UT_TRANSFORMUTIL_H_INCLUDED__
12 #define __UT_TRANSFORMUTIL_H_INCLUDED__
62 template<
typename PREC>
72 bool* pLS_init_ptr=
nullptr
92 bool* pLS_init_ptr =
nullptr);
96 template<
typename PREC>
105 template<
typename PREC>
119 bool HAS_EFFECTIVE_LOCAL =
false
147 bool NORMALIZE_WEIGHTS =
true,
163 const PREC input_weight);
168 bool NORMALIZE_WEIGHTS =
true
174 template<
typename PREC>
225 bool tmp_pLS_init =
true;
229 bool &pLS_init = HAS_PLS ? *pLS_init_ptr : tmp_pLS_init;
231 if (effective_local && effective_local != &L)
232 *effective_local = L;
318 template<
typename PREC>
330 #define UT_TRANSFORM_COMBINE(M, A) \
331 return UTtransformCombineLocalT<PREC, M, A>( \
332 L, pW, pL, effective_local, pLS_ptr, pLS_inv_ptr, pLS_init_ptr); \
334 #define IF_UT_TRANSFORM_COMBINE(M, A) \
336 UT_TRANSFORM_COMBINE(M, A) \
339 if (pLS_init_ptr && pLS_ptr && pLS_inv_ptr)
351 pLS_inv_ptr =
nullptr;
352 pLS_init_ptr =
nullptr;
364 template<
typename PREC>
393 *effective_local = L;
417 *effective_local = L;
440 *effective_local = L;
464 *effective_local = L;
480 *effective_local = L;
487 *effective_local = L;
494 template<
typename PREC, UT_ScaleInheritanceMode MODE,
bool HAS_EFFECTIVE_LOCAL>
521 if (HAS_EFFECTIVE_LOCAL && effective_local)
522 *effective_local = L;
545 if (HAS_EFFECTIVE_LOCAL && effective_local)
546 *effective_local = L;
568 if (HAS_EFFECTIVE_LOCAL && effective_local)
569 *effective_local = L;
592 if (HAS_EFFECTIVE_LOCAL && effective_local)
593 *effective_local = L;
608 if (HAS_EFFECTIVE_LOCAL && effective_local)
609 *effective_local = L;
615 if (HAS_EFFECTIVE_LOCAL && effective_local)
616 *effective_local = L;
623 template<
typename PREC>
642 bool NORMALIZE_WEIGHTS,
650 const int n = xforms.size();
658 const PREC *weights = input_weights.
data();
660 const int kSmallArrayElements = 16;
662 if (NORMALIZE_WEIGHTS)
664 PREC total_weights = 0;
665 for (PREC
w : input_weights)
668 if (total_weights > 0)
671 for (
int i = 0; i <
n; ++i)
672 new_weights[i] = input_weights[i] / total_weights;
673 weights = new_weights.
data();
685 xforms[0].getTranslates(translate);
686 translate *= weights[0];
690 stretch *= weights[0];
697 for (
int i = 1; i <
n; ++i)
699 const PREC
w = weights[i];
702 xforms[i].getTranslates(t);
708 stretch += w * stretch_tmp;
730 rots.setSizeNoInit(n);
731 for (
int i = 0; i <
n; ++i)
733 const PREC
w = weights[i];
736 xforms[i].getTranslates(t);
742 stretch += w * stretch_tmp;
744 rots[i].updateFromRotationMatrix(rotate_tmp);
748 quat.
interpolate(rots.data(), weights, rots.size());
756 result.setTranslates(translate);
767 const PREC input_weight)
769 const PREC weight0 = ((PREC)1.0) - input_weight;
770 const PREC weight1 = input_weight;
781 translate *= weight0;
793 const PREC
w = weight1;
801 rotate_tmp.makeRotationMatrix(&stretch_tmp);
802 stretch += w * stretch_tmp;
825 const PREC
w = weight0;
833 rotate_tmp.makeRotationMatrix(&stretch_tmp);
834 stretch += w * stretch_tmp;
840 const PREC
w = weight1;
848 rotate_tmp.makeRotationMatrix(&stretch_tmp);
849 stretch += w * stretch_tmp;
863 result.setTranslates(translate);
876 const PREC weight0 = ((PREC)1.0) - input_weight;
877 const PREC weight1 = input_weight;
884 auto cachedMakeRot = [&makerotcache](
890 if (makerotcache->
rot==in_xfo)
892 io_quat = makerotcache->
quat;
893 io_stretch = makerotcache->
stretch;
900 in_rot.makeRotationMatrix(&io_stretch);
901 io_quat.updateFromRotationMatrix(in_rot);
904 makerotcache->
rot = in_xfo;
905 makerotcache->
quat = io_quat;
906 makerotcache->
stretch = io_stretch;
917 translate *= weight0;
920 cachedMakeRot(xform0,stretch,quat);
927 const PREC
w = weight1;
935 cachedMakeRot(xform1,stretch_tmp,q);
936 stretch += w * stretch_tmp;
956 const PREC
w = weight0;
963 cachedMakeRot(xform0,stretch_tmp,rot0);
964 stretch += w * stretch_tmp;
969 const PREC
w = weight1;
976 cachedMakeRot(xform1,stretch_tmp,rot1);
977 stretch += w * stretch_tmp;
989 result.setTranslates(translate);
995 template <
typename T,
bool NORMALIZE_WEIGHTS>
998 template <
typename T>
1011 template <
typename T>
1018 const T *
w = weights.
data();
1022 const int n = weights.
size();
1023 for (
int i = 0; i <
n; ++i)
1028 for (
int i = 0; i <
n; ++i)
1029 tmp_weights[i] = w[i] / total;
1030 w = tmp_weights.
data();
1040 template <
typename PREC,
bool NORMALIZE_WEIGHTS>
1049 template<
typename PREC>
1068 pivotspace.myTranslate = parm_p;
1069 pivotspace.myRotate = parm_pr;
1072 adjust.
xform(adjust_ord,
1073 parm_t[0], parm_t[1], parm_t[2],
1074 parm_r[0], parm_r[1], parm_r[2],
1075 parm_s[0], parm_s[1], parm_s[2],
1089 local.
explode(order, local_r, local_s, local_t,
nullptr);
1095 order, r, s, t,
nullptr );
1099 if( scales_local_t )
1114 t *= 1.0 / (parent_local_s);
1131 q = parm_q * local_q;
1133 q = local_q * parm_q;
1149 t.x(), t.y(), t.z(),
1150 r.
x(), r.
y(), r.
z(),
1151 s.x(), s.y(), s.z() );
1154 template <
typename PREC>
1173 local.
explode(parmorder, parm_r, parm_s, parm_t,
nullptr);
1183 local.
explode(order, local_r, local_s, local_t,
nullptr);
1188 inputlocal.
explode(order, input_r, input_s, input_t,
nullptr);
1190 adjust.explode(order, parm_r, parm_s, parm_t,
nullptr);
1193 parm_t = local_t - input_t;
1194 parm_s = local_s / input_s;
1201 parm_t *= (parent_local_s);
1228 q = local_q * input_q;
1233 q = input_q * local_q;
1239 mq.
crack(parm_r,order);
1244 result.
xform(order, parm_t[0], parm_t[1], parm_t[2],
1245 parm_r[0], parm_r[1], parm_r[2],
1246 parm_s[0], parm_s[1], parm_s[2]);
1247 result.
explode(parmorder, parm_r, parm_s, parm_t,
nullptr);
1251 #endif // __UT_TRANSFORMUTIL_H_INCLUDED__
UT_Matrix3T< PREC > stretch
void setSizeNoInit(exint newsize)
void radToDeg()
conversion between degrees and radians
constexpr SYS_FORCE_INLINE T & z() noexcept
void prescale(T sx, T sy, T sz)
**But if you need a result
void getRotationMatrix(UT_Matrix3 &mat) const
GLdouble GLdouble GLdouble q
UT_QuaternionT< PREC > quat
static const UT_Matrix4T< T > & getIdentityMatrix()
fpreal64 dot(const CE_VectorT< T > &a, const CE_VectorT< T > &b)
int explode(const UT_XformOrder &order, UT_Vector3F &r, UT_Vector3F &s, UT_Vector3F &t, UT_Vector3F *shears=0) const
GLdouble GLdouble GLint GLint order
void identity()
Set the matrix to identity.
ImageBuf OIIO_API rotate(const ImageBuf &src, float angle, string_view filtername=string_view(), float filterwidth=0.0f, bool recompute_roi=false, ROI roi={}, int nthreads=0)
void xform(const UT_XformOrder &order, T tx=0, T ty=0, T tz=0, T rx=0, T ry=0, T rz=0, T sx=1, T sy=1, T sz=1, T px=0, T py=0, T pz=0, int reverse=0)
void setTranslates(const UT_Vector3T< S > &translates)
UT_QuaternionT< T > operator()(const UT_Array< UT_QuaternionT< T >> &quats, const UT_Array< T > &weights)
UT_QuaternionT< T > interpolate(const UT_QuaternionT< T > &target, T t, T b=0.0f) const
Interpolates between this quat (t==0) and the target (t==1)
bool polarDecompose(UT_Matrix3T< T > *stretch=nullptr, bool reverse=true, const int max_iter=64, const T rel_tol=FLT_EPSILON)
GLubyte GLubyte GLubyte GLubyte w
void leftMult(const UT_Matrix4T< T > &m)
PUGI__FN char_t * translate(char_t *buffer, const char_t *from, const char_t *to, size_t to_length)
constexpr SYS_FORCE_INLINE T & y() noexcept
UT_QuaternionT< T > operator()(const UT_Array< UT_QuaternionT< T >> &quats, const UT_Array< T > &weights)
bool polarDecompose(UT_Matrix3T< T > *stretch=nullptr, bool reverse=true, const int max_iter=64, const T rel_tol=FLT_EPSILON)
int crack(UT_Vector3T< S > &rvec, const UT_XformOrder &order) const
bool makeRotationMatrix(UT_Matrix3T< T > *stretch=nullptr, bool reverse=true, const int max_iter=64, const T rel_tol=FLT_EPSILON)
void getTranslates(UT_Vector3T< S > &translates) const
void updateFromRotationMatrix(const UT_Matrix3 &)
void preMultiply(const UT_Matrix4T< T > &m)
constexpr SYS_FORCE_INLINE T & x() noexcept