def getSymmetricalTransform(t, axis="yz", fNegScale=False): """ Get the symmetrical tranformation matrix from a define 2 axis mirror plane. exp:"yz". Args: t (matrix): The transformation matrix to mirror. axis (str): The mirror plane. fNegScale(bool): This function is not yet implemented. Returns: matrix: The symmetrical tranformation matrix. """ if axis == "yz": mirror = dt.TransformationMatrix(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) if axis == "xy": mirror = dt.TransformationMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1) if axis == "zx": mirror = dt.TransformationMatrix(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) t *= mirror #TODO: getSymmetricalTransform: add freeze negative scaling procedure. return t
def determineHanded(self, thumb, wrist): #thumb, wrist handed = "" objectJoint = pc.ls(thumb, type="joint")[0] objWorldMat = objectJoint.attr("worldMatrix").get() objTransformationMat = dt.TransformationMatrix(objWorldMat) objectTrans = objTransformationMat.getTranslation('world') tarJoint = pc.ls(wrist, type="joint")[0] tarWorldMat = tarJoint.attr("worldMatrix").get() targetTransformationMat = dt.TransformationMatrix(tarWorldMat) targetTrans = targetTransformationMat.getTranslation('world') worldVector = dt.Vector(0, 0, 0) targetVector = (objectTrans - targetTrans) targetVector.normalize() targetUp = tarWorldMat[1][:3] targetUp.normalize() # find dot product between target and object dotProduct = dt.dot(targetUp, targetVector) if dotProduct > 0: handed = "R" if dotProduct <= 0: handed = "L" return handed
def _add_rotate(cls, node, rotation): rotation = dt.EulerRotation([axis for axis in rotation]) matrix = dt.TransformationMatrix() q = rotation.asQuaternion() matrix.addRotationQuaternion(q.x, q.y, q.z, q.w, space='object') cls._add_transformation(node, matrix)
def convert2TransformMatrix(tm): """ Convert a transformation Matrix or a matrix to a transformation matrix in world space. Args: tm (matrix): The input matrix. Returns: matrix: The transformation matrix in worldSpace """ if isinstance(tm, nt.Transform): tm = dt.TransformationMatrix(tm.getMatrix(worldSpace=True)) if isinstance(tm, dt.Matrix): tm = dt.TransformationMatrix(tm) return tm
def matrix_normalize_scale(matrix): """ Will normalize the scale in given four by four matrix to 1 or -1. Args: matrix(dt.Matrix): Four by four matrix. Return: dt.Matrix: The scale normalized matrix. """ scale = matrix.scale tm = dt.TransformationMatrix(matrix) if scale[0] > 0: scale[0] = 1 else: scale[0] = -1 if scale[1] > 0: scale[1] = 1 else: scale[1] = -1 if scale[2] > 0: scale[2] = 1 else: scale[2] = -1 tm.setScale(scale, space="world") return dt.Matrix(tm)
def MTransform(item, target, attrs): Ipwm = item.getAttr('worldMatrix') if target.getParent(): Tpim = target.getParent().getAttr('worldMatrix').inverse() else: Tpim = target.getAttr('parentInverseMatrix') prod = Ipwm * Tpim tMat = dt.TransformationMatrix(prod) translate = tMat.getTranslation('transform') quat_rotate = tMat.getRotationQuaternion() quat = dt.Quaternion(quat_rotate) euler = quat.asEulerRotation() rotate = map(math.degrees, euler) scale = tMat.getScale('transform') data = {} if 't' in attrs: data["translate"] = translate if 'r' in attrs: data["rotate"] = rotate if 'jo' in attrs: data["jointOrient"] = rotate if 's' in attrs: data["scale"] = scale for DItem in data.items(): setKwargs(target, DItem[0], DItem[1])
def _add_translate(cls, node, translation): if not isinstance(translation, list): translation = dt.Vector(translation) translation *= 100 matrix = dt.TransformationMatrix() matrix.addTranslation(translation, space='world') cls._add_transformation(node, matrix)
def test_world_position(self): """ Test the world space position in translate and rotate. """ ws_matrix_test_op_1 = datatypes.TransformationMatrix( self.test_op_1.get_main_op_ws_matrix() ) test_ws_vec = datatypes.Vector( [27.820655082060398, -0.7524801847300928, -4.0237613976076] ) test_ws_rotation = datatypes.EulerRotation( [1.934698909968065, -0.16331263127797427, 1.1967119606022243], unit="radians", ) ws_matrix_test_op_1_subs = [ datatypes.TransformationMatrix(matrix) for matrix in self.test_op_1.get_sub_op_nodes_ws_matrix() ] ws_vec_test_op_1_subs = [ ts_matrix.getTranslation("world") for ts_matrix in ws_matrix_test_op_1_subs ] test_ws_vec_subs = [ datatypes.Vector( [31.42623634611877, 8.432088910758539, -2.397884932907285] ), datatypes.Vector( [35.03181761017714, 17.61665800624717, -0.7720084682069708] ), datatypes.Vector( [38.637398874235515, 26.801227101735805, 0.8538679964933436] ), ] self.assertEqual(ws_vec_test_op_1_subs, test_ws_vec_subs) self.assertEqual( ws_matrix_test_op_1.getTranslation("world"), test_ws_vec ) self.assertEqual(ws_matrix_test_op_1.getRotation(), test_ws_rotation)
def test_control_curve_worldspace_orientation(self): """ Test if the control curve in orientated in worldspace zero. """ self.single_control.set_worldspace_orientation(True) self.single_control.build_from_operator() control_curve = self.single_control.controls[0] ws_matrix = control_curve.getMatrix(worldSpace=True) tm_matrix = dt.TransformationMatrix(ws_matrix) self.assertEqual( tm_matrix.getRotation(), dt.EulerRotation([0.0, -0.0, 0.0], unit="radians"), )
def addLengthCtrl(self, crv): t = getTransform(self.guide.root) t = self._getTransformWithRollByBlade(t) cvs = crv.length() tm = datatypes.TransformationMatrix(t) tm.addTranslation([0.0, cvs * 0.01, cvs * 1.4], om.MSpace.kObject) local_t = datatypes.Matrix(tm) self.length_npo = addTransform(self.aim_npo, self.getName("length_npo"), local_t) self.length_in = addTransform(self.length_npo, self.getName("sacle_in"), local_t) size = self.size w = size h = size d = size self.length_ctl = self.addCtl( self.length_in, "length_ctl", local_t, self.color_ik, "arrow", w=w, h=h, d=d, ro=datatypes.Vector([-math.pi / 2., math.pi / 2., 0.]) ) self.fk_upvectors = [] chain = getChainTransform2(self.guide.apos, self.normal, self.negate) for i, t in enumerate(chain): upv_npo = addTransform(self.length_in, self.getName("%s_fkupv_npo" % i), t) self.fk_upvectors.append(upv_npo) # global input self.scale_npo = addTransform(self.root, self.getName("scale_npo"), local_t) self.scale_in = addTransform(self.scale_npo, self.getName("sacle_in"), local_t) self.scale_ctl = self.addCtl( self.scale_in, "scale_ctl", local_t, self.color_ik, "cube", w=w*.2, h=h*.2, d=d*.2, ro=datatypes.Vector([-math.pi / 2., 0., 0.]) ) ymt_util.setKeyableAttributesDontLockVisibility(self.scale_ctl, self.s_params) ymt_util.setKeyableAttributesDontLockVisibility(self.length_ctl, ["tx", "ty", "tz"])
def matrix_reset_rotation(matrix): """ Will reset the rotation values in four by four matrix to zero in worldspace. Args: matrix(dt.Matrix): Four by four matrix. Return: dt.Matrix: The matrix reset in rotation. """ tm = dt.TransformationMatrix(matrix) tm.setRotation((0, 0, 0)) return dt.Matrix(tm)
def getInterpolateTransformMatrix(t1, t2, blend=.5): """Interpolate 2 matrix. Arguments: t1 (matrix): Input matrix 1. t2 (matrix): Input matrix 2. blend (float): The blending value. Default 0.5 Returns: matrix: The newly interpolated transformation matrix. >>> t = tra.getInterpolateTransformMatrix(self.fk_ctl[0], self.tws1A_npo, .3333) """ # check if the input transforms are transformMatrix t1 = convert2TransformMatrix(t1) t2 = convert2TransformMatrix(t2) if (blend == 1.0): return t2 elif (blend == 0.0): return t1 # translate pos = vector.linearlyInterpolate(t1.getTranslation(space="world"), t2.getTranslation(space="world"), blend) # scale scaleA = datatypes.Vector(*t1.getScale(space="world")) scaleB = datatypes.Vector(*t2.getScale(space="world")) vs = vector.linearlyInterpolate(scaleA, scaleB, blend) # rotate q = quaternionSlerp(datatypes.Quaternion(t1.getRotationQuaternion()), datatypes.Quaternion(t2.getRotationQuaternion()), blend) # out result = datatypes.TransformationMatrix() result.setTranslation(pos, space="world") result.setRotationQuaternion(q.x, q.y, q.z, q.w) result.setScale([vs.x, vs.y, vs.z], space="world") return result
def _getTransformWithRollByBlade(self, t): # t = getTransform(self.guide.root) a = self.guide.blades["blade"].y x = vector.Blade(t).x z = vector.Blade(t).z x = vecProjection(a, x)[0] z = vecProjection(a, z)[2] theta = math.atan2(x, z) roll = theta + math.pi tm = datatypes.TransformationMatrix(t) tm.addRotation([0., roll, 0], 'XYZ', om.MSpace.kObject) return datatypes.Matrix(tm)
def translateBuffer(self, index, translation): if not isinstance(translation, list): translation = dt.Vector(translation) translation *= 100 buffer = self.get_buffer_at(index) buffer_child = self.get_buffer_at(index - 1) if not buffer_child: buffer_child = self.control_curve matrix = dt.TransformationMatrix() matrix.addTranslation(translation, space='world') buffer.setMatrix(buffer.getMatrix(worldSpace=True) * matrix, worldSpace=True) buffer_child.setMatrix(buffer_child.getMatrix() * matrix.asMatrixInverse())
def setMatrixScale(m, scl=[1, 1, 1]): """Set the scale for a given matrix Arguments: in_m (matrix): The input Matrix. scl (list of float): The scale values for xyz Returns: matrix: The matrix with the new scale """ tm = datatypes.TransformationMatrix(m) tm.setScale(scl, space="world") m = datatypes.Matrix(tm) return m
def orientHandJointTo(self, target, object, handed): objectJoint = pc.ls(object, type="joint")[0] objWorldMat = objectJoint.attr("worldMatrix").get() objWorldPos = objWorldMat[3][:3] tarJoint = pc.ls(target, type="joint")[0] tarWorldMat = tarJoint.attr("worldMatrix").get() tarWorldPos = tarWorldMat[3][:3] wristJoint = pc.ls(self.wristJoint, type="joint")[0] wristWorldMat = wristJoint.attr("worldMatrix").get() wristWorldPos = wristWorldMat[3][:3] # get aim vector from object to target if handed == "L": aimVector = tarWorldPos - objWorldPos if handed == "R": aimVector = objWorldPos - tarWorldPos aimVector = dt.Vector(aimVector) aimVector.normalize() aimX = aimVector # get z axis used to rotate object around its z objUpVector = dt.Vector(objWorldMat[2][:3]) # find dot product of objUpVector and aimX to help get up vector of aimX dotProduct = dt.dot(objUpVector, aimX) # construct rotation matrix aimRotationMat = dt.Matrix(3) aimRotationMat[0] = aimX aimRotationMat[1] = dt.Vector(wristWorldMat[1][:3]) aimRotationMat[2] = dt.Vector(wristWorldMat[2][:3]) # convert rotation matrix to Euler angles aimRotationTransMat = dt.TransformationMatrix(aimRotationMat) aimRotationQuaternion = aimRotationTransMat.getRotationQuaternion() # set object rotation to final aim rotation vector objectJoint.setOrientation(aimRotationQuaternion)
def addObjects(self): """Add all the objects needed to create the component.""" # Auto bend with position controls ------------------- if self.settings["autoBend"]: self.autoBendChain = primitive.add2DChain( self.root, self.getName("autoBend%s_jnt"), [self.guide.apos[0], self.guide.apos[-1]], self.guide.blades["blade"].z * -1, False, True) for j in self.autoBendChain: j.drawStyle.set(2) # Ik Controlers ------------------------------------ if self.settings["IKWorldOri"]: t = datatypes.TransformationMatrix() t = transform.setMatrixPosition(t, self.guide.apos[0]) else: t = transform.getTransformLookingAt( self.guide.apos[0], self.guide.apos[-1], self.guide.blades["blade"].z * -1, "yx", self.negate) self.ik0_npo = primitive.addTransform(self.root, self.getName("ik0_npo"), t) self.ik0_ctl = self.addCtl(self.ik0_npo, "ik0_ctl", t, self.color_ik, "compas", w=self.size, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.ik0_ctl, self.tr_params) attribute.setRotOrder(self.ik0_ctl, "ZXY") attribute.setInvertMirror(self.ik0_ctl, ["tx", "ry", "rz"]) # hip base joint # TODO: add option in setting for on/off if True: self.hip_lvl = primitive.addTransform(self.ik0_ctl, self.getName("hip_lvl"), t) self.jnt_pos.append([self.hip_lvl, "hip"]) t = transform.setMatrixPosition(t, self.guide.apos[-1]) if self.settings["autoBend"]: self.autoBend_npo = primitive.addTransform( self.root, self.getName("spinePosition_npo"), t) self.autoBend_ctl = self.addCtl(self.autoBend_npo, "spinePosition_ctl", t, self.color_ik, "square", w=self.size, d=.3 * self.size, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.autoBend_ctl, ["tx", "ty", "tz", "ry"]) attribute.setInvertMirror(self.autoBend_ctl, ["tx", "ry"]) self.ik1_npo = primitive.addTransform(self.autoBendChain[0], self.getName("ik1_npo"), t) self.ik1autoRot_lvl = primitive.addTransform( self.ik1_npo, self.getName("ik1autoRot_lvl"), t) self.ik1_ctl = self.addCtl(self.ik1autoRot_lvl, "ik1_ctl", t, self.color_ik, "compas", w=self.size, tp=self.autoBend_ctl) else: t = transform.setMatrixPosition(t, self.guide.apos[-1]) self.ik1_npo = primitive.addTransform(self.root, self.getName("ik1_npo"), t) self.ik1_ctl = self.addCtl(self.ik1_npo, "ik1_ctl", t, self.color_ik, "compas", w=self.size, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.ik1_ctl, self.tr_params) attribute.setRotOrder(self.ik1_ctl, "ZXY") attribute.setInvertMirror(self.ik1_ctl, ["tx", "ry", "rz"]) # Tangent controllers ------------------------------- if self.settings["centralTangent"]: # vec_pos = vector.linearlyInterpolate(self.guide.apos[0], # self.guide.apos[-1], # .33) vec_pos = self.guide.pos["tan0"] t = transform.setMatrixPosition(t, vec_pos) self.tan0_npo = primitive.addTransform(self.ik0_ctl, self.getName("tan0_npo"), t) self.tan0_off = primitive.addTransform(self.tan0_npo, self.getName("tan0_off"), t) self.tan0_ctl = self.addCtl(self.tan0_off, "tan0_ctl", t, self.color_ik, "sphere", w=self.size * .1, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan0_ctl, self.t_params) # vec_pos = vector.linearlyInterpolate(self.guide.apos[0], # self.guide.apos[-1], # .66) vec_pos = self.guide.pos["tan1"] t = transform.setMatrixPosition(t, vec_pos) self.tan1_npo = primitive.addTransform(self.ik1_ctl, self.getName("tan1_npo"), t) self.tan1_off = primitive.addTransform(self.tan1_npo, self.getName("tan1_off"), t) self.tan1_ctl = self.addCtl(self.tan1_off, "tan1_ctl", t, self.color_ik, "sphere", w=self.size * .1, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan1_ctl, self.t_params) # Tangent mid control vec_pos = vector.linearlyInterpolate(self.guide.apos[0], self.guide.apos[-1], .5) t = transform.setMatrixPosition(t, vec_pos) self.tan_npo = primitive.addTransform(self.tan0_npo, self.getName("tan_npo"), t) self.tan_ctl = self.addCtl(self.tan_npo, "tan_ctl", t, self.color_fk, "sphere", w=self.size * .2, tp=self.ik1_ctl) attribute.setKeyableAttributes(self.tan_ctl, self.t_params) attribute.setInvertMirror(self.tan_ctl, ["tx"]) else: # vec_pos = vector.linearlyInterpolate(self.guide.apos[0], # self.guide.apos[-1], # .33) vec_pos = self.guide.pos["tan0"] t = transform.setMatrixPosition(t, vec_pos) self.tan0_npo = primitive.addTransform(self.ik0_ctl, self.getName("tan0_npo"), t) self.tan0_ctl = self.addCtl(self.tan0_npo, "tan0_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan0_ctl, self.t_params) # vec_pos = vector.linearlyInterpolate(self.guide.apos[0], # self.guide.apos[-1], # .66) vec_pos = self.guide.pos["tan1"] t = transform.setMatrixPosition(t, vec_pos) self.tan1_npo = primitive.addTransform(self.ik1_ctl, self.getName("tan1_npo"), t) self.tan1_ctl = self.addCtl(self.tan1_npo, "tan1_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.ik1_ctl) attribute.setKeyableAttributes(self.tan1_ctl, self.t_params) attribute.setInvertMirror(self.tan0_ctl, ["tx"]) attribute.setInvertMirror(self.tan1_ctl, ["tx"]) # Curves ------------------------------------------- self.mst_crv = curve.addCnsCurve( self.root, self.getName("mst_crv"), [self.ik0_ctl, self.tan0_ctl, self.tan1_ctl, self.ik1_ctl], 3) self.slv_crv = curve.addCurve(self.root, self.getName("slv_crv"), [datatypes.Vector()] * 10, False, 3) self.mst_crv.setAttr("visibility", False) self.slv_crv.setAttr("visibility", False) # Division ----------------------------------------- # The user only define how many intermediate division he wants. # First and last divisions are an obligation. parentdiv = self.root parentctl = self.root self.div_cns = [] self.fk_ctl = [] self.fk_npo = [] self.scl_transforms = [] self.twister = [] self.ref_twist = [] t = transform.getTransformLookingAt(self.guide.apos[0], self.guide.apos[-1], self.guide.blades["blade"].z * -1, "yx", self.negate) parent_twistRef = primitive.addTransform( self.root, self.getName("reference"), transform.getTransform(self.root)) self.jointList = [] self.preiviousCtlTag = self.parentCtlTag for i in range(self.settings["division"]): # References div_cns = primitive.addTransform(parentdiv, self.getName("%s_cns" % i)) pm.setAttr(div_cns + ".inheritsTransform", False) self.div_cns.append(div_cns) parentdiv = div_cns # Controlers (First and last one are fake) # if i in [0]: # TODO: add option setting to add or not the first and # last controller for the fk if i in [0, self.settings["division"] - 1] and False: # if i in [0, self.settings["division"] - 1]: fk_ctl = primitive.addTransform( parentctl, self.getName("%s_loc" % i), transform.getTransform(parentctl)) fk_npo = fk_ctl if i in [self.settings["division"] - 1]: self.fk_ctl.append(fk_ctl) else: m = transform.getTransform(self.root) t = transform.getTransform(parentctl) m.inverse() fk_npo = primitive.addTransform(parentctl, self.getName("fk%s_npo" % (i)), t) fk_ctl = self.addCtl(fk_npo, "fk%s_ctl" % (i), transform.getTransform(parentctl), self.color_fk, "cube", w=self.size, h=self.size * .05, d=self.size, tp=self.preiviousCtlTag) attribute.setKeyableAttributes(self.fk_ctl) attribute.setRotOrder(fk_ctl, "ZXY") self.fk_ctl.append(fk_ctl) self.preiviousCtlTag = fk_ctl self.fk_npo.append(fk_npo) parentctl = fk_ctl scl_ref = primitive.addTransform(parentctl, self.getName("%s_scl_ref" % i), transform.getTransform(parentctl)) self.scl_transforms.append(scl_ref) # Deformers (Shadow) self.jnt_pos.append([scl_ref, i]) # Twist references (This objects will replace the spinlookup # slerp solver behavior) t = transform.getTransformLookingAt( self.guide.apos[0], self.guide.apos[-1], self.guide.blades["blade"].z * -1, "yx", self.negate) twister = primitive.addTransform(parent_twistRef, self.getName("%s_rot_ref" % i), t) ref_twist = primitive.addTransform(parent_twistRef, self.getName("%s_pos_ref" % i), t) ref_twist.setTranslation(datatypes.Vector(1.0, 0, 0), space="preTransform") self.twister.append(twister) self.ref_twist.append(ref_twist) # TODO: update this part with the optiona FK controls update for x in self.fk_ctl[:-1]: attribute.setInvertMirror(x, ["tx", "rz", "ry"]) # Connections (Hooks) ------------------------------ self.cnx0 = primitive.addTransform(self.root, self.getName("0_cnx")) self.cnx1 = primitive.addTransform(self.root, self.getName("1_cnx"))
def addObjects(self): """Add all the objects needed to create the component.""" # joint Description Names jd_names = ast.literal_eval( self.settings["jointNamesDescription_custom"]) jdn_neck = jd_names[0] jdn_head = jd_names[1] self.normal = self.guide.blades["blade"].z * -1 self.up_axis = pm.upAxis(q=True, axis=True) # Ik Controlers ------------------------------------ if self.settings["IKWorldOri"]: t = datatypes.TransformationMatrix() else: t = transform.getTransformLookingAt( self.guide.pos["tan1"], self.guide.pos["neck"], self.normal, "yx", self.negate, ) t = transform.setMatrixPosition(t, self.guide.pos["neck"]) self.ik_off = primitive.addTransform(self.root, self.getName("ik_off"), t) # handle Z up orientation offset if self.up_axis == "z" and self.settings["IKWorldOri"]: self.ik_off.rx.set(90) t = transform.getTransform(self.ik_off) self.ik_cns = primitive.addTransform(self.ik_off, self.getName("ik_cns"), t) self.ik_ctl = self.addCtl( self.ik_cns, "ik_ctl", t, self.color_ik, "compas", w=self.size * 0.5, tp=self.parentCtlTag, ) attribute.setKeyableAttributes(self.ik_ctl, self.tr_params) attribute.setRotOrder(self.ik_ctl, "ZXY") attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"]) # Tangents ----------------------------------------- if self.settings["tangentControls"]: t = transform.setMatrixPosition(t, self.guide.pos["tan1"]) self.tan1_loc = primitive.addTransform(self.ik_ctl, self.getName("tan1_loc"), t) self.tan1_ctl = self.addCtl( self.tan1_loc, "tan1_ctl", t, self.color_ik, "sphere", w=self.size * 0.2, tp=self.ik_ctl, ) attribute.setKeyableAttributes(self.tan1_ctl, self.t_params) attribute.setInvertMirror(self.tan1_ctl, ["tx"]) t = transform.getTransformLookingAt( self.guide.pos["root"], self.guide.pos["tan0"], self.normal, "yx", self.negate, ) t = transform.setMatrixPosition(t, self.guide.pos["tan0"]) self.tan0_loc = primitive.addTransform(self.root, self.getName("tan0_loc"), t) self.tan0_ctl = self.addCtl( self.tan0_loc, "tan0_ctl", t, self.color_ik, "sphere", w=self.size * 0.2, tp=self.ik_ctl, ) attribute.setKeyableAttributes(self.tan0_ctl, self.t_params) attribute.setInvertMirror(self.tan0_ctl, ["tx"]) # Curves ------------------------------------------- self.mst_crv = curve.addCnsCurve( self.root, self.getName("mst_crv"), [self.root, self.tan0_ctl, self.tan1_ctl, self.ik_ctl], 3, ) self.slv_crv = curve.addCurve( self.root, self.getName("slv_crv"), [datatypes.Vector()] * 10, False, 3, ) self.mst_crv.setAttr("visibility", False) else: t = transform.setMatrixPosition(t, self.guide.pos["tan1"]) self.tan1_loc = primitive.addTransform(self.ik_ctl, self.getName("tan1_loc"), t) t = transform.getTransformLookingAt( self.guide.pos["root"], self.guide.pos["tan0"], self.normal, "yx", self.negate, ) t = transform.setMatrixPosition(t, self.guide.pos["tan0"]) self.tan0_loc = primitive.addTransform(self.root, self.getName("tan0_loc"), t) # Curves ------------------------------------------- self.mst_crv = curve.addCnsCurve( self.root, self.getName("mst_crv"), [self.root, self.tan0_loc, self.tan1_loc, self.ik_ctl], 3, ) self.slv_crv = curve.addCurve( self.root, self.getName("slv_crv"), [datatypes.Vector()] * 10, False, 3, ) self.mst_crv.setAttr("visibility", False) self.slv_crv.setAttr("visibility", False) # Division ----------------------------------------- # The user only define how many intermediate division he wants. # First and last divisions are an obligation. parentdiv = self.root parentctl = self.root self.div_cns = [] self.fk_ctl = [] self.fk_npo = [] self.scl_npo = [] self.twister = [] self.ref_twist = [] # adding 1 for the head self.divisions = self.settings["division"] + 1 parent_twistRef = primitive.addTransform( self.root, self.getName("reference"), transform.getTransform(self.root), ) t = transform.getTransformLookingAt( self.guide.pos["root"], self.guide.pos["neck"], self.normal, "yx", self.negate, ) self.intMRef = primitive.addTransform(self.root, self.getName("intMRef"), t) self.previousCtlTag = self.parentCtlTag for i in range(self.divisions): # References div_cns = primitive.addTransform(parentdiv, self.getName("%s_cns" % i), t) pm.setAttr(div_cns + ".inheritsTransform", False) self.div_cns.append(div_cns) parentdiv = div_cns scl_npo = primitive.addTransform( parentctl, self.getName("%s_scl_npo" % i), transform.getTransform(parentctl), ) # Controlers (First and last one are fake) if i in [self.divisions - 1]: # 0, fk_ctl = primitive.addTransform( scl_npo, self.getName("%s_loc" % i), transform.getTransform(parentctl), ) fk_npo = fk_ctl else: fk_npo = primitive.addTransform( scl_npo, self.getName("fk%s_npo" % i), transform.getTransform(parentctl), ) fk_ctl = self.addCtl( fk_npo, "fk%s_ctl" % i, transform.getTransform(parentctl), self.color_fk, "cube", w=self.size * 0.2, h=self.size * 0.05, d=self.size * 0.2, tp=self.previousCtlTag, ) attribute.setKeyableAttributes(self.fk_ctl) attribute.setRotOrder(fk_ctl, "ZXY") self.previousCtlTag = fk_ctl self.fk_ctl.append(fk_ctl) self.scl_npo.append(scl_npo) self.fk_npo.append(fk_npo) parentctl = fk_ctl if i != self.divisions - 1: self.jnt_pos.append( [fk_ctl, string.replaceSharpWithPadding(jdn_neck, i + 1)]) t = transform.getTransformLookingAt( self.guide.pos["root"], self.guide.pos["neck"], self.guide.blades["blade"].z * -1, "yx", self.negate, ) twister = primitive.addTransform(parent_twistRef, self.getName("%s_rot_ref" % i), t) ref_twist = primitive.addTransform(parent_twistRef, self.getName("%s_pos_ref" % i), t) ref_twist.setTranslation(datatypes.Vector(0.0, 0, 1.0), space="preTransform") self.twister.append(twister) self.ref_twist.append(ref_twist) for x in self.fk_ctl[:-1]: attribute.setInvertMirror(x, ["tx", "rz", "ry"]) # Head --------------------------------------------- t = transform.getTransformLookingAt( self.guide.pos["head"], self.guide.pos["eff"], self.normal, "yx", self.negate, ) self.head_cns = primitive.addTransform(self.root, self.getName("head_cns"), t) dist = vector.getDistance(self.guide.pos["head"], self.guide.pos["eff"]) self.head_ctl = self.addCtl( self.head_cns, "head_ctl", t, self.color_fk, "cube", w=self.size * 0.5, h=dist, d=self.size * 0.5, po=datatypes.Vector(0, dist * 0.5, 0), tp=self.previousCtlTag, ) attribute.setRotOrder(self.head_ctl, "ZXY") attribute.setInvertMirror(self.head_ctl, ["tx", "rz", "ry"]) self.jnt_pos.append([self.head_ctl, jdn_head])
def addJnt(obj=False, parent=False, noReplace=False, grp=None, jntName=None, *args): """Create one joint for each selected object. Args: obj (bool or dagNode, optional): The object to drive the new joint. If False will use the current selection. parent (bool or dagNode, optional): The parent for the joint. If False will try to parent to jnt_org. If jnt_org doesn't exist will parent the joint under the obj noReplace (bool, optional): If True will add the extension "_jnt" to the new joint name grp (pyNode or None, optional): The set to add the new joint. If none will use "rig_deformers_grp" *args: Maya's dummy Returns: pyNode: The New created joint. """ if not obj: oSel = pm.selected() else: oSel = [obj] for obj in oSel: if not parent: try: oParent = pm.PyNode("jnt_org") except TypeError: oParent = obj else: oParent = parent if not jntName: if noReplace: jntName = "_".join(obj.name().split("_")) + "_jnt" else: jntName = "_".join(obj.name().split("_")[:-1]) + "_jnt" jnt = primitive.addJoint(oParent, jntName, transform.getTransform(obj)) if grp: grp.add(jnt) else: try: defSet = pm.PyNode("rig_deformers_grp") pm.sets(defSet, add=jnt) except TypeError: pm.sets(n="rig_deformers_grp") defSet = pm.PyNode("rig_deformers_grp") pm.sets(defSet, add=jnt) jnt.setAttr("segmentScaleCompensate", False) jnt.setAttr("jointOrient", 0, 0, 0) try: cns_m = applyop.gear_matrix_cns(obj, jnt) # setting the joint orient compensation in order to have clean # rotation channels m = cns_m.drivenRestMatrix.get() tm = datatypes.TransformationMatrix(m) r = datatypes.degrees(tm.getRotation()) jnt.attr("jointOrientX").set(r[0]) jnt.attr("jointOrientY").set(r[1]) jnt.attr("jointOrientZ").set(r[2]) except RuntimeError: for axis in ["tx", "ty", "tz", "rx", "ry", "rz"]: jnt.attr(axis).set(0.0) return jnt
def _addObjectsFkControl(self, i, parentdiv, parentctl, t, parent_twistRef): # References tm = datatypes.TransformationMatrix(t) tm.addRotation([0., 0., math.pi / -2.], 'XYZ', om.MSpace.kObject) # TODO: align with convention tm.addRotation([0., math.pi / -2., 0], 'XYZ', om.MSpace.kObject) global_t = datatypes.Matrix(tm) # global input div_cns = addTransform(parentdiv, self.getName("%s_cns" % i)) div_cns_npo = addTransform(div_cns, self.getName("%s_cns_npo" % i)) pm.setAttr(div_cns + ".inheritsTransform", False) div_cns.setMatrix(global_t, worldSpace=True) self.div_cns.append(div_cns) self.div_cns_npo.append(div_cns_npo) parentdiv = div_cns # t = getTransform(parentctl) if i == 0: p = parentctl else: # p = self.scl_transforms[i - 1] p = self.fk_local_in[i - 1] fk_npo = addTransform(p, self.getName("fk%s_npo" % (i)), global_t) # local input fk_local_npo = addTransform(fk_npo, self.getName("fk%s_local_npo" % i), global_t) fk_local_in = addTransform(fk_local_npo, self.getName("fk%s_local_in" % i), global_t) self.fk_local_in.append(fk_local_in) if i < len(self.guide.apos) - 1: h = (self.guide.apos[i] - self.guide.apos[i + 1]).length() * .8 else: h = (self.guide.apos[-1] - self.guide.apos[0]).length() / (len(self.guide.apos) - 1) # FIXME: rotate by blade po = datatypes.Vector([0, h / 2., 0]) fk_ctl = self.addCtl( fk_local_in, "fk%s_ctl" % (i), global_t, self.color_fk, "cube", w=h * .66, h=h, d=h * 0.3, # ro=datatypes.Vector([0, -math.pi / 2., 0]), po=po, tp=self.preiviousCtlTag, mirrorConf=self.mirror_conf) ymt_util.setKeyableAttributesDontLockVisibility(self.fk_ctl) attribute.setRotOrder(fk_ctl, "ZXY") self.fk_ctl.append(fk_ctl) self.preiviousCtlTag = fk_ctl self.fk_npo.append(fk_npo) self.fk_local_npo.append(fk_local_npo) parentctl = fk_ctl scl_ref = addTransform(parentctl, self.getName("%s_scl_ref" % i), getTransform(parentctl)) self.scl_transforms.append(scl_ref) if i == 0 and self.settings["isSplitHip"]: t = self._getTransformWithRollByBlade(getTransform(self.guide.root)) h = (self.guide.apos[-1] - self.guide.apos[0]).length() / (len(self.guide.apos) - 1) po = datatypes.Vector([0, self.size / len(self.guide.apos) * -.8, 0]) hip_fk_local_in = addTransform(p, self.getName("hip_fk_local_in"), t) self.hip_fk_local_in = hip_fk_local_in self.fk_hip_ctl = self.addCtl( hip_fk_local_in, "fk_hip_ctl", t, self.color_fk, "cube", w=h * .66, h=h, d=h * 0.3, # ro=datatypes.Vector([0, -math.pi / 2., 0]), po=po, tp=self.preiviousCtlTag, mirrorConf=self.mirror_conf) hip_scl_ref = addTransform(self.fk_hip_ctl, self.getName("hip_scl_ref"), t) # Deformers (Shadow) if self.settings["addJoints"]: if self.settings["isSplitHip"]: if i == 0: self.jnt_pos.append([hip_scl_ref, 0]) self.jnt_pos.append([scl_ref, i + 1]) else: self.jnt_pos.append([scl_ref, i]) # Twist references (This objects will replace the spinlookup # slerp solver behavior) t = transform.getTransformLookingAt( self.guide.apos[0], self.guide.apos[-1], self.guide.blades["blade"].z * -1, "yx", self.negate) twister = addTransform( parent_twistRef, self.getName("%s_rot_ref" % i), t) ref_twist = addTransform( parent_twistRef, self.getName("%s_pos_ref" % i), t) ref_twist.setTranslation( datatypes.Vector(1.0, 0, 0), space="preTransform") self.twister.append(twister) self.ref_twist.append(ref_twist) for x in self.fk_ctl: attribute.setInvertMirror(x, ["tx", "rz", "ry"]) attribute.setInvertMirror(self.fk_hip_ctl, ["tx", "rz", "ry"]) return parentdiv, parentctl
def addObjects(self): """Add all the objects needed to create the component.""" self.normal = self.guide.blades["blade"].z * -1 # Ik Controlers ------------------------------------ if self.settings["IKWorldOri"]: t = datatypes.TransformationMatrix() else: t = transform.getTransformLookingAt(self.guide.pos["tan1"], self.guide.pos["neck"], self.normal, "yx", self.negate) t = transform.setMatrixPosition(t, self.guide.pos["neck"]) self.ik_cns = primitive.addTransform( self.root, self.getName("ik_cns"), t) self.ik_ctl = self.addCtl(self.ik_cns, "ik_ctl", t, self.color_ik, "compas", w=self.size * .5, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.ik_ctl, self.tr_params) attribute.setRotOrder(self.ik_ctl, "ZXY") attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"]) # Tangents ----------------------------------------- if self.settings["tangentControls"]: t = transform.setMatrixPosition(t, self.guide.pos["tan1"]) self.tan1_loc = primitive.addTransform( self.ik_ctl, self.getName("tan1_loc"), t) self.tan1_ctl = self.addCtl(self.tan1_loc, "tan1_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.ik_ctl) attribute.setKeyableAttributes(self.tan1_ctl, self.t_params) attribute.setInvertMirror(self.tan1_ctl, ["tx"]) t = transform.getTransformLookingAt(self.guide.pos["root"], self.guide.pos["tan0"], self.normal, "yx", self.negate) t = transform.setMatrixPosition(t, self.guide.pos["tan0"]) self.tan0_loc = primitive.addTransform( self.root, self.getName("tan0_loc"), t) self.tan0_ctl = self.addCtl(self.tan0_loc, "tan0_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.ik_ctl) attribute.setKeyableAttributes(self.tan0_ctl, self.t_params) attribute.setInvertMirror(self.tan0_ctl, ["tx"]) # Curves ------------------------------------------- self.mst_crv = curve.addCnsCurve( self.root, self.getName("mst_crv"), [self.root, self.tan0_ctl, self.tan1_ctl, self.ik_ctl], 3) self.slv_crv = curve.addCurve(self.root, self.getName("slv_crv"), [datatypes.Vector()] * 10, False, 3) self.mst_crv.setAttr("visibility", False) else: t = transform.setMatrixPosition(t, self.guide.pos["tan1"]) self.tan1_loc = primitive.addTransform( self.ik_ctl, self.getName("tan1_loc"), t) t = transform.getTransformLookingAt(self.guide.pos["root"], self.guide.pos["tan0"], self.normal, "yx", self.negate) t = transform.setMatrixPosition(t, self.guide.pos["tan0"]) self.tan0_loc = primitive.addTransform( self.root, self.getName("tan0_loc"), t) # Curves ------------------------------------------- self.mst_crv = curve.addCnsCurve( self.root, self.getName("mst_crv"), [self.root, self.tan0_loc, self.tan1_loc, self.ik_ctl], 3) self.slv_crv = curve.addCurve(self.root, self.getName("slv_crv"), [datatypes.Vector()] * 10, False, 3) self.mst_crv.setAttr("visibility", False) self.slv_crv.setAttr("visibility", False) # Division ----------------------------------------- # The user only define how many intermediate division he wants. # First and last divisions are an obligation. parentdiv = self.root parentctl = self.root self.div_cns = [] self.fk_ctl = [] self.fk_npo = [] self.scl_npo = [] self.twister = [] self.ref_twist = [] parent_twistRef = primitive.addTransform( self.root, self.getName("reference"), transform.getTransform(self.root)) t = transform.getTransformLookingAt(self.guide.pos["root"], self.guide.pos["neck"], self.normal, "yx", self.negate) self.intMRef = primitive.addTransform( self.root, self.getName("intMRef"), t) self.previousCtlTag = self.parentCtlTag for i in range(self.settings["division"]): # References div_cns = primitive.addTransform( parentdiv, self.getName("%s_cns" % i), t) pm.setAttr(div_cns + ".inheritsTransform", False) self.div_cns.append(div_cns) parentdiv = div_cns scl_npo = primitive.addTransform(parentctl, self.getName("%s_scl_npo" % i), transform.getTransform(parentctl)) # Controlers (First and last one are fake) if i in [self.settings["division"] - 1]: # 0, fk_ctl = primitive.addTransform( scl_npo, self.getName("%s_loc" % i), transform.getTransform(parentctl)) fk_npo = fk_ctl else: fk_npo = primitive.addTransform( scl_npo, self.getName("fk%s_npo" % i), transform.getTransform(parentctl)) fk_ctl = self.addCtl(fk_npo, "fk%s_ctl" % i, transform.getTransform(parentctl), self.color_fk, "cube", w=self.size * .2, h=self.size * .05, d=self.size * .2, tp=self.previousCtlTag) attribute.setKeyableAttributes(self.fk_ctl) attribute.setRotOrder(fk_ctl, "ZXY") self.previousCtlTag = fk_ctl self.fk_ctl.append(fk_ctl) self.scl_npo.append(scl_npo) self.fk_npo.append(fk_npo) parentctl = fk_ctl self.jnt_pos.append([fk_ctl, i]) t = transform.getTransformLookingAt( self.guide.pos["root"], self.guide.pos["neck"], self.guide.blades["blade"].z * -1, "yx", self.negate) twister = primitive.addTransform( parent_twistRef, self.getName("%s_rot_ref" % i), t) ref_twist = primitive.addTransform( parent_twistRef, self.getName("%s_pos_ref" % i), t) ref_twist.setTranslation( datatypes.Vector(0.0, 0, 1.0), space="preTransform") self.twister.append(twister) self.ref_twist.append(ref_twist) for x in self.fk_ctl[:-1]: attribute.setInvertMirror(x, ["tx", "rz", "ry"]) # Head --------------------------------------------- t = transform.getTransformLookingAt(self.guide.pos["head"], self.guide.pos["eff"], self.normal, "yx", self.negate) self.head_cns = primitive.addTransform( self.root, self.getName("head_cns"), t) dist = vector.getDistance(self.guide.pos["head"], self.guide.pos["eff"]) self.head_ctl = self.addCtl(self.head_cns, "head_ctl", t, self.color_fk, "cube", w=self.size * .5, h=dist, d=self.size * .5, po=datatypes.Vector(0, dist * .5, 0), tp=self.previousCtlTag) attribute.setRotOrder(self.head_ctl, "ZXY") attribute.setInvertMirror(self.head_ctl, ["tx", "rz", "ry"]) self.jnt_pos.append([self.head_ctl, "head"])
def _add_scale(cls, node, scale): matrix = dt.TransformationMatrix() matrix.addScale(scale, space='world') cls._add_transformation(node, matrix)
def addObjects(self): """Add all the objects needed to create the component.""" self.up_axis = pm.upAxis(q=True, axis=True) # Auto bend with position controls ------------------- if self.settings["autoBend"]: self.autoBendChain = primitive.add2DChain( self.root, self.getName("autoBend%s_jnt"), [self.guide.apos[1], self.guide.apos[-2]], self.guide.blades["blade"].z * -1, False, True) for j in self.autoBendChain: j.drawStyle.set(2) # Ik Controlers ------------------------------------ if self.settings["IKWorldOri"]: t = datatypes.TransformationMatrix() t = transform.setMatrixPosition(t, self.guide.apos[1]) else: t = transform.getTransformLookingAt( self.guide.apos[1], self.guide.apos[-2], self.guide.blades["blade"].z * -1, "yx", self.negate) self.ik_off = primitive.addTransform(self.root, self.getName("ik_off"), t) # handle Z up orientation offset if self.up_axis == "z" and self.settings["IKWorldOri"]: self.ik_off.rx.set(90) t = transform.getTransform(self.ik_off) self.ik0_npo = primitive.addTransform(self.ik_off, self.getName("ik0_npo"), t) self.ik0_ctl = self.addCtl(self.ik0_npo, "ik0_ctl", t, self.color_ik, "compas", w=self.size, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.ik0_ctl, self.tr_params) attribute.setRotOrder(self.ik0_ctl, "ZXY") attribute.setInvertMirror(self.ik0_ctl, ["tx", "ry", "rz"]) # pelvis self.length0 = vector.getDistance(self.guide.apos[0], self.guide.apos[1]) vec_po = datatypes.Vector(0, .5 * self.length0 * -1, 0) self.pelvis_npo = primitive.addTransform(self.ik0_ctl, self.getName("pelvis_npo"), t) self.pelvis_ctl = self.addCtl(self.pelvis_npo, "pelvis_ctl", t, self.color_ik, "cube", h=self.length0, w=self.size * .1, d=self.size * .1, po=vec_po, tp=self.parentCtlTag) self.pelvis_lvl = primitive.addTransform( self.pelvis_ctl, self.getName("pelvis_lvl"), transform.setMatrixPosition(t, self.guide.apos[0])) self.jnt_pos.append([self.pelvis_lvl, "pelvis"]) t = transform.setMatrixPosition(t, self.guide.apos[-2]) if self.settings["autoBend"]: self.autoBend_npo = primitive.addTransform( self.root, self.getName("spinePosition_npo"), t) self.autoBend_ctl = self.addCtl(self.autoBend_npo, "spinePosition_ctl", t, self.color_ik, "square", w=self.size, d=.3 * self.size, tp=self.parentCtlTag) attribute.setKeyableAttributes(self.autoBend_ctl, ["tx", "ty", "tz", "ry"]) attribute.setInvertMirror(self.autoBend_ctl, ["tx", "ry"]) self.ik1_npo = primitive.addTransform(self.autoBendChain[0], self.getName("ik1_npo"), t) self.ik1autoRot_lvl = primitive.addTransform( self.ik1_npo, self.getName("ik1autoRot_lvl"), t) self.ik1_ctl = self.addCtl(self.ik1autoRot_lvl, "ik1_ctl", t, self.color_ik, "compas", w=self.size, tp=self.autoBend_ctl) else: t = transform.setMatrixPosition(t, self.guide.apos[-2]) self.ik1_npo = primitive.addTransform(self.root, self.getName("ik1_npo"), t) self.ik1_ctl = self.addCtl(self.ik1_npo, "ik1_ctl", t, self.color_ik, "compas", w=self.size, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.ik1_ctl, self.tr_params) attribute.setRotOrder(self.ik1_ctl, "ZXY") attribute.setInvertMirror(self.ik1_ctl, ["tx", "ry", "rz"]) # Tangent controllers ------------------------------- if self.settings["centralTangent"]: vec_pos = self.guide.pos["tan0"] t = transform.setMatrixPosition(t, vec_pos) self.tan0_npo = primitive.addTransform(self.ik0_ctl, self.getName("tan0_npo"), t) self.tan0_off = primitive.addTransform(self.tan0_npo, self.getName("tan0_off"), t) self.tan0_ctl = self.addCtl(self.tan0_off, "tan0_ctl", t, self.color_ik, "sphere", w=self.size * .1, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan0_ctl, self.t_params) vec_pos = self.guide.pos["tan1"] t = transform.setMatrixPosition(t, vec_pos) self.tan1_npo = primitive.addTransform(self.ik1_ctl, self.getName("tan1_npo"), t) self.tan1_off = primitive.addTransform(self.tan1_npo, self.getName("tan1_off"), t) self.tan1_ctl = self.addCtl(self.tan1_off, "tan1_ctl", t, self.color_ik, "sphere", w=self.size * .1, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan1_ctl, self.t_params) # Tangent mid control vec_pos = vector.linearlyInterpolate(self.guide.apos[1], self.guide.apos[-2], .5) t = transform.setMatrixPosition(t, vec_pos) self.tan_npo = primitive.addTransform(self.tan0_npo, self.getName("tan_npo"), t) self.tan_ctl = self.addCtl(self.tan_npo, "tan_ctl", t, self.color_fk, "sphere", w=self.size * .2, tp=self.ik1_ctl) attribute.setKeyableAttributes(self.tan_ctl, self.t_params) attribute.setInvertMirror(self.tan_ctl, ["tx"]) else: vec_pos = self.guide.pos["tan0"] t = transform.setMatrixPosition(t, vec_pos) self.tan0_npo = primitive.addTransform(self.ik0_ctl, self.getName("tan0_npo"), t) self.tan0_ctl = self.addCtl(self.tan0_npo, "tan0_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.ik0_ctl) attribute.setKeyableAttributes(self.tan0_ctl, self.t_params) vec_pos = self.guide.pos["tan1"] t = transform.setMatrixPosition(t, vec_pos) self.tan1_npo = primitive.addTransform(self.ik1_ctl, self.getName("tan1_npo"), t) self.tan1_ctl = self.addCtl(self.tan1_npo, "tan1_ctl", t, self.color_ik, "sphere", w=self.size * .2, tp=self.ik1_ctl) attribute.setKeyableAttributes(self.tan1_ctl, self.t_params) attribute.setInvertMirror(self.tan0_ctl, ["tx"]) attribute.setInvertMirror(self.tan1_ctl, ["tx"]) # Curves ------------------------------------------- self.mst_crv = curve.addCnsCurve( self.root, self.getName("mst_crv"), [self.ik0_ctl, self.tan0_ctl, self.tan1_ctl, self.ik1_ctl], 3) self.slv_crv = curve.addCurve(self.root, self.getName("slv_crv"), [datatypes.Vector()] * 10, False, 3) self.mst_crv.setAttr("visibility", False) self.slv_crv.setAttr("visibility", False) # Division ----------------------------------------- # The user only define how many intermediate division he wants. # First and last divisions are an obligation. parentdiv = self.root parentctl = self.root self.div_cns = [] self.fk_ctl = [] self.fk_npo = [] self.scl_transforms = [] self.twister = [] self.ref_twist = [] t = transform.getTransformLookingAt(self.guide.apos[1], self.guide.apos[-2], self.guide.blades["blade"].z * -1, "yx", self.negate) parent_twistRef = primitive.addTransform( self.root, self.getName("reference"), transform.getTransform(self.root)) self.jointList = [] self.preiviousCtlTag = self.parentCtlTag for i in range(self.settings["division"]): # References div_cns = primitive.addTransform(parentdiv, self.getName("%s_cns" % i)) pm.setAttr(div_cns + ".inheritsTransform", False) self.div_cns.append(div_cns) parentdiv = div_cns t = transform.getTransform(parentctl) fk_npo = primitive.addTransform(parentctl, self.getName("fk%s_npo" % (i)), t) fk_ctl = self.addCtl(fk_npo, "fk%s_ctl" % (i), transform.getTransform(parentctl), self.color_fk, "cube", w=self.size, h=self.size * .05, d=self.size, tp=self.preiviousCtlTag) attribute.setKeyableAttributes(self.fk_ctl) attribute.setRotOrder(fk_ctl, "ZXY") self.fk_ctl.append(fk_ctl) self.preiviousCtlTag = fk_ctl self.fk_npo.append(fk_npo) parentctl = fk_ctl if i == self.settings["division"] - 1: t = transform.getTransformLookingAt( self.guide.pos["spineTop"], self.guide.pos["chest"], self.guide.blades["blade"].z * -1, "yx", False) scl_ref_parent = self.root else: t = transform.getTransform(parentctl) scl_ref_parent = parentctl scl_ref = primitive.addTransform(scl_ref_parent, self.getName("%s_scl_ref" % i), t) self.scl_transforms.append(scl_ref) # Deformers (Shadow) self.jnt_pos.append([scl_ref, "spine_" + str(i + 1).zfill(2)]) # Twist references (This objects will replace the spinlookup # slerp solver behavior) t = transform.getTransformLookingAt( self.guide.apos[0], self.guide.apos[1], self.guide.blades["blade"].z * -1, "yx", self.negate) twister = primitive.addTransform(parent_twistRef, self.getName("%s_rot_ref" % i), t) ref_twist = primitive.addTransform(parent_twistRef, self.getName("%s_pos_ref" % i), t) ref_twist.setTranslation(datatypes.Vector(1.0, 0, 0), space="preTransform") self.twister.append(twister) self.ref_twist.append(ref_twist) for x in self.fk_ctl[:-1]: attribute.setInvertMirror(x, ["tx", "rz", "ry"]) # Connections (Hooks) ------------------------------ self.cnx0 = primitive.addTransform(self.root, self.getName("0_cnx")) self.cnx1 = primitive.addTransform(self.root, self.getName("1_cnx")) self.jnt_pos.append([self.cnx1, "spine_" + str(i + 2).zfill(2)])