def test(self): _sphere1 = hom.CMDS.polySphere() _sphere2 = hom.CMDS.polySphere() _sphere3 = hom.CMDS.polySphere() # Test apply euler rotation to sphere _rot = hom.HEulerRotation(0, 0, math.pi) _rot.apply_to(_sphere1) assert cmds.getAttr(_sphere1.rotate) == [(0, 0, 180)] # Test apply euler rot as mtx to sphere hom.HMatrix().apply_to(_sphere1) _rot = hom.HEulerRotation(0, math.pi, 0) _mtx = _rot.as_mtx() cmds.xform(_sphere1, matrix=_mtx) assert cmds.getAttr(_sphere1.rotate) == [(0, 180, 0)] hom.HMatrix().apply_to(_sphere1) _mtx.apply_to(_sphere2) assert cmds.getAttr(_sphere2.rotate) == [(0, 180, 0)] # Test apply vector + rot as mtxs to sphere hom.HMatrix().apply_to(_sphere1) _mtx1 = hom.HVector(5, 10, 20).as_mtx() _mtx2 = hom.HEulerRotation(0, math.pi, 0).as_mtx() (_mtx2 * _mtx1).apply_to(_sphere1) print cmds.getAttr(_sphere1.rotate) assert cmds.getAttr(_sphere1.rotate) == [(0, 180, 0)] assert cmds.getAttr(_sphere1.translate) == [(5, 10, 20)] (_mtx1 * _mtx2).apply_to(_sphere1) assert cmds.getAttr(_sphere1.rotate) == [(0, 180, 0)] assert cmds.getAttr(_sphere1.translate) == [(-4.999999999999997, 10.0, -20.0)] (_mtx1 * _mtx1).apply_to(_sphere1) assert cmds.getAttr(_sphere1.rotate) == [(0, 0, 0)] assert cmds.getAttr(_sphere1.translate) == [(10, 20, 40)] # Offset matrix cookbook _mtx_b = _rand_m() _mtx_a = _rand_m() _offs_a_to_b = _mtx_a.inverse() * _mtx_b assert _mtx_a * _offs_a_to_b == _mtx_b _mtx_b.apply_to(_sphere1) _mtx_a.apply_to(_sphere2) (_mtx_a * _offs_a_to_b).apply_to(_sphere3) assert hom.get_m(_sphere3) == _mtx_b # Test load/save preset _sphere2.tx.set_val(10) _tmp_preset = '{}/tmp.preset'.format(tempfile.gettempdir()) assert (_sphere1.get_p() - _sphere2.get_p()).length() _sphere1.save_preset(_tmp_preset) print _tmp_preset _sphere2.load_preset(_tmp_preset) print(_sphere1.get_p() - _sphere2.get_p()).length() assert not round((_sphere1.get_p() - _sphere2.get_p()).length(), 5)
def as_euler(self): """Get this matrix as euler rotations. Returns: (HEulerRotation): euler rotations """ from maya_psyhive import open_maya as hom return hom.HEulerRotation(om.MTransformationMatrix(self).rotation())
def rot(self): """Get rotation. Returns: (HEulerRotation): rotation component """ from maya_psyhive import open_maya as hom _tm = om.MTransformationMatrix(self) return hom.HEulerRotation(_tm.rotation())
def apply_fk_to_ik(self, pole_vect_depth=10.0, apply_=True, build_tmp_geo=False, verbose=1): """Apply fk to ik. First the pole vector is calculated by extending a line from the elbow joint in the direction of the cross product of the limb vector (fk_ctrls[0] to fk3) and the limb bend. The ik joint is then moved to the position of the fk3 control. The arm/knee offset is reset on apply. Args: pole_vect_depth (float): distance of pole vector from fk_ctrls[1] apply_ (bool): apply the update to gimbal ctrl build_tmp_geo (bool): build tmp geo verbose (int): print process data """ lprint('APPLYING FK -> IK', verbose=verbose) # Reset offset for _offs in self.ik_offs: cmds.setAttr(_offs, 0) # Calculate pole pos _limb_v = hom.get_p(self.fk_ctrls[2]) - hom.get_p(self.fk_ctrls[0]) if self.limb is Limb.ARM: _limb_bend = -hom.get_m(self.fk_ctrls[1]).ly_().normalized() elif self.limb == Limb.LEG: _limb_bend = hom.get_m(self.fk_ctrls[1]).lx_().normalized() else: raise ValueError(self.limb) _pole_dir = (_limb_v ^ _limb_bend).normalized() _pole_p = hom.get_p(self.fk_ctrls[1]) + _pole_dir*pole_vect_depth _pole_p.apply_to(self.ik_pole, use_constraint=True) # Read fk3 mtx _ik_mtx = hom.get_m(self.fk_ctrls[2]) _side_offs = hom.HMatrix() if self.side == Side.RIGHT: _side_offs = hom.HEulerRotation(math.pi, 0, 0).as_mtx() _ik_mtx = _side_offs * _ik_mtx _ik_mtx.apply_to(self.ik_) # Apply vals to ik ctrls if apply_: self.set_to_ik() lprint('SET', self.ik_, 'TO IK', verbose=verbose) if build_tmp_geo: _limb_v.build_crv(hom.get_p(self.fk_ctrls[0]), name='limb_v') _limb_bend.build_crv(hom.get_p(self.fk_ctrls[1]), name='limb_bend') _pole_dir.build_crv(hom.get_p(self.fk_ctrls[1]), name='pole_dir') _pole_p.build_loc(name='pole') _ik_mtx.build_geo(name='fk3') hom.get_m(self.ik_).build_geo(name='ik')
def apply_fk_to_ik(self, pole_vect_depth=30.0, apply_=True, build_tmp_geo=False, verbose=0): """Apply fk to ik. First the pole vector is calculated by extending a line from the elbow joint in the direction of the cross product of the limb vector (fk_ctrls[0] to fk3) and the limb bend. The ik joint is then moved to the position of the fk3 control. The arm/knee offset is reset on apply. Args: pole_vect_depth (float): distance of pole vector from fk_ctrls[1] apply_ (bool): apply the update to gimbal ctrl build_tmp_geo (bool): build tmp geo verbose (int): print process data """ lprint('APPLYING FK -> IK', verbose=verbose) # Reset offset for _offs in self.ik_offs: cmds.setAttr(_offs, 0) # Calculate pole pos _limb_v = hom.get_p(self.fk_ctrls[2]) - hom.get_p(self.fk_ctrls[0]) if self.limb is Limb.ARM: _limb_bend = -hom.get_m(self.fk_ctrls[1]).lz_().normalized() elif self.limb is Limb.LEG: _limb_bend = hom.get_m(self.fk_ctrls[1]).lz_().normalized() else: raise ValueError(self.limb) _pole_dir = -(_limb_v ^ _limb_bend).normalized() _pole_p = hom.get_p(self.fk_ctrls[1]) + _pole_dir * pole_vect_depth lprint(' - APPLYING POLE', self.ik_pole, verbose=verbose) # Read fk3 mtx _ik_mtx = hom.get_m(self.fk_ctrls[2]) _diff = None if self.side is Side.LEFT and self.limb is Limb.ARM: _offs = hom.HEulerRotation(math.pi / 2, math.pi, 0) elif self.side is Side.LEFT and self.limb is Limb.LEG: _offs = hom.HEulerRotation(0, math.pi / 2, -math.pi / 2) elif self.side is Side.RIGHT and self.limb is Limb.ARM: _offs = hom.HEulerRotation(-math.pi / 2, math.pi, 0) elif self.side is Side.RIGHT and self.limb is Limb.LEG: _offs = hom.HEulerRotation(0, math.pi / 2, math.pi / 2) else: raise ValueError(self.side, self.limb) _ik_mtx = _offs.as_mtx() * _ik_mtx # Apply vals to ik ctrls if apply_: _ik_mtx.apply_to(self.ik_) if _diff: print 'APPLY DIFF', _diff _diff.apply_to(self.ik_, relative=True) _pole_p.apply_to(self.ik_pole, use_constraint=True) self.set_to_ik() lprint('SET', self.ik_, 'TO IK', verbose=verbose) if build_tmp_geo: set_namespace(":tmp", clean=True) _limb_v.build_crv(hom.get_p(self.fk_ctrls[0]), name='limb_v') _limb_bend.build_crv(hom.get_p(self.fk_ctrls[1]), name='limb_bend') _pole_dir.build_crv(hom.get_p(self.fk_ctrls[1]), name='pole_dir') _pole_p.build_loc(name='pole') _ik_mtx.build_geo(name='trg_ik') hom.get_m(self.ik_).build_geo(name='cur_ik') set_namespace(":")