def addJoint(self, obj, name, newActiveJnt=None, UniScale=True): """ Add joint as child of the active joint or under driver object. Args: obj (dagNode): The input driver object for the joint. name (str): The joint name. newActiveJnt (bool or dagNode): If a joint is pass, this joint will be the active joint and parent of the newly created joint. Returns: dagNode: The newly created joint. """ if self.options["joint_rig"]: if newActiveJnt: self.active_jnt = newActiveJnt jnt = pri.addJoint(self.active_jnt, self.getName(str(name) + "_jnt"), tra.getTransform(obj)) #All new jnts are the active by default self.active_jnt = jnt mulmat_node = nod.createMultMatrixNode(obj + ".worldMatrix", jnt + ".parentInverseMatrix") dm_node = nod.createDecomposeMatrixNode(mulmat_node+".matrixSum") pm.connectAttr(dm_node+".outputTranslate", jnt+".t") pm.connectAttr(dm_node+".outputRotate", jnt+".r") # TODO: fix squash stretch solver to scale the joint uniform # the next line cheat the uniform scaling only fo X or Y axis oriented joints if UniScale: pm.connectAttr(dm_node+".outputScaleZ", jnt+".sx") pm.connectAttr(dm_node+".outputScaleZ", jnt+".sy") pm.connectAttr(dm_node+".outputScaleZ", jnt+".sz") else: pm.connectAttr(dm_node+".outputScale", jnt+".s") # Segment scale compensate Off to avoid issues with the global scale jnt.setAttr("segmentScaleCompensate", 0) jnt.setAttr("jointOrient", 0, 0, 0) # setting the joint orient compensation in order to have clean rotation channels jnt.attr("jointOrientX").set(jnt.attr("rx").get()) jnt.attr("jointOrientY").set(jnt.attr("ry").get()) jnt.attr("jointOrientZ").set(jnt.attr("rz").get()) m = mulmat_node.attr('matrixSum').get() im = m.inverse() mulmat_node2 = nod.createMultMatrixNode(mulmat_node.attr('matrixSum'), im, jnt,'r') else: jnt = pri.addJoint(obj, self.getName(str(name)+"_jnt"), tra.getTransform(obj)) pm.connectAttr(self.rig.jntVis_att, jnt.attr("visibility")) self.addToGroup(jnt, "deformers") return jnt
def connectWorldTransform(source, target): """Connect the source world transform of one object to another object. Args: source (dagNode): Source dagNode. target (dagNode): target dagNode. """ mulmat_node = nod.createMultMatrixNode(source + ".worldMatrix", target + ".parentInverseMatrix") dm_node = nod.createDecomposeMatrixNode(mulmat_node+".matrixSum") pm.connectAttr(dm_node+".outputTranslate", target+".t") pm.connectAttr(dm_node+".outputRotate", target+".r") pm.connectAttr(dm_node+".outputScale", target+".s")
def addJnt(obj=False, parent=False, noReplace=False, *args): """ Create one joint for each selected object. """ if not obj: oSel = pm.selected() else: oSel = [obj] for obj in oSel: if not parent: try: oParent = pm.PyNode("jnt_org") except: oParent = obj else: oParent = parent if noReplace: jntName = "_".join(obj.name().split("_")) + "_jnt" else: jntName = "_".join(obj.name().split("_")[:-1]) + "_jnt" jnt = pm.createNode("joint", n=jntName) try: defSet = pm.PyNode("rig_deformers_grp") pm.sets(defSet, add=jnt) except: pm.sets(n="rig_deformers_grp") defSet = pm.PyNode("rig_deformers_grp") pm.sets(defSet, add=jnt) oParent.addChild(jnt) jnt.setAttr("jointOrient", 0, 0, 0) try: mulmat_node = nod.createMultMatrixNode( obj + ".worldMatrix", jnt + ".parentInverseMatrix") dm_node = nod.createDecomposeMatrixNode(mulmat_node + ".matrixSum") pm.connectAttr(dm_node + ".outputTranslate", jnt + ".t") pm.connectAttr(dm_node + ".outputRotate", jnt + ".r") pm.connectAttr(dm_node + ".outputScale", jnt + ".s") except: for axis in ["tx", "ty", "tz", "rx", "ry", "rz"]: jnt.attr(axis).set(0.0) return jnt
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 = pm.createNode("joint", n=jntName) 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) oParent.addChild(jnt) jnt.setAttr("jointOrient", 0, 0, 0) try: mulmat_node = node.createMultMatrixNode( obj + ".worldMatrix", jnt + ".parentInverseMatrix") dm_node = node.createDecomposeMatrixNode( mulmat_node + ".matrixSum") pm.connectAttr(dm_node + ".outputTranslate", jnt + ".t") pm.connectAttr(dm_node + ".outputRotate", jnt + ".r") pm.connectAttr(dm_node + ".outputScale", jnt + ".s") except RuntimeError: for axis in ["tx", "ty", "tz", "rx", "ry", "rz"]: jnt.attr(axis).set(0.0) return jnt
def addJoint(self, obj, name, newActiveJnt=None, UniScale=False, segComp=0, gearMulMatrix=True): """Add joint as child of the active joint or under driver object. Args: obj (dagNode): The input driver object for the joint. name (str): The joint name. newActiveJnt (bool or dagNode): If a joint is pass, this joint will be the active joint and parent of the newly created joint. UniScale (bool): Connects the joint scale with the Z axis for a unifor scalin, if set Falsewill connect with each axis separated. segComp (bool): Set True or False the segment compensation in the joint.. gearMulMatrix (bool): Use the custom gear_multiply matrix node, if False will use Maya's default mulMatrix node. Returns: dagNode: The newly created joint. """ if self.options["joint_rig"]: if newActiveJnt: self.active_jnt = newActiveJnt jnt = primitive.addJoint(self.active_jnt, self.getName(str(name) + "_jnt"), transform.getTransform(obj)) # TODO: Set the joint to have always positive scaling # jnt.scale.set([1, 1, 1]) # Disconnect inversScale for better preformance if isinstance(self.active_jnt, pm.nodetypes.Joint): try: pm.disconnectAttr(self.active_jnt.scale, jnt.inverseScale) except RuntimeError: # This handle the situation where we have in between joints # transformation due a negative scaling pm.ungroup(jnt.getParent()) # All new jnts are the active by default self.active_jnt = jnt if gearMulMatrix: mulmat_node = applyop.gear_mulmatrix_op( obj + ".worldMatrix", jnt + ".parentInverseMatrix") dm_node = node.createDecomposeMatrixNode(mulmat_node + ".output") m = mulmat_node.attr('output').get() else: mulmat_node = node.createMultMatrixNode( obj + ".worldMatrix", jnt + ".parentInverseMatrix") dm_node = node.createDecomposeMatrixNode(mulmat_node + ".matrixSum") m = mulmat_node.attr('matrixSum').get() pm.connectAttr(dm_node + ".outputTranslate", jnt + ".t") pm.connectAttr(dm_node + ".outputRotate", jnt + ".r") # TODO: fix squash stretch solver to scale the joint uniform # the next line cheat the uniform scaling only fo X or Y axis # oriented joints if UniScale: pm.connectAttr(dm_node + ".outputScaleZ", jnt + ".sx") pm.connectAttr(dm_node + ".outputScaleZ", jnt + ".sy") pm.connectAttr(dm_node + ".outputScaleZ", jnt + ".sz") else: pm.connectAttr(dm_node + ".outputScale", jnt + ".s") pm.connectAttr(dm_node + ".outputShear", jnt + ".shear") # Segment scale compensate Off to avoid issues with the global # scale jnt.setAttr("segmentScaleCompensate", segComp) jnt.setAttr("jointOrient", 0, 0, 0) # setting the joint orient compensation in order to have clean # rotation channels jnt.attr("jointOrientX").set(jnt.attr("rx").get()) jnt.attr("jointOrientY").set(jnt.attr("ry").get()) jnt.attr("jointOrientZ").set(jnt.attr("rz").get()) im = m.inverse() if gearMulMatrix: mul_nod = applyop.gear_mulmatrix_op(mulmat_node.attr('output'), im, jnt, 'r') dm_node2 = mul_nod.output.listConnections()[0] else: mul_nod = node.createMultMatrixNode( mulmat_node.attr('matrixSum'), im, jnt, 'r') dm_node2 = mul_nod.matrixSum.listConnections()[0] if jnt.attr("sz").get() < 0: # if negative scaling we have to negate some axis for rotation neg_rot_node = pm.createNode("multiplyDivide") pm.setAttr(neg_rot_node + ".operation", 1) pm.connectAttr(dm_node2.outputRotate, neg_rot_node + ".input1", f=True) for v, axis in zip([-1, -1, 1], "XYZ"): pm.setAttr(neg_rot_node + ".input2" + axis, v) pm.connectAttr(neg_rot_node + ".output", jnt + ".r", f=True) # set not keyable attribute.setNotKeyableAttributes(jnt) else: jnt = primitive.addJoint(obj, self.getName(str(name) + "_jnt"), transform.getTransform(obj)) pm.connectAttr(self.rig.jntVis_att, jnt.attr("visibility")) attribute.lockAttribute(jnt) self.addToGroup(jnt, "deformers") # This is a workaround due the evaluation problem with compound attr # TODO: This workaround, should be removed onces the evaluation issue # is fixed # github issue: Shifter: Joint connection: Maya evaluation Bug #210 dm = jnt.r.listConnections(p=True, type="decomposeMatrix") if dm: at = dm[0] dm_node = at.node() pm.disconnectAttr(at, jnt.r) pm.connectAttr(dm_node.outputRotateX, jnt.rx) pm.connectAttr(dm_node.outputRotateY, jnt.ry) pm.connectAttr(dm_node.outputRotateZ, jnt.rz) dm = jnt.t.listConnections(p=True, type="decomposeMatrix") if dm: at = dm[0] dm_node = at.node() pm.disconnectAttr(at, jnt.t) pm.connectAttr(dm_node.outputTranslateX, jnt.tx) pm.connectAttr(dm_node.outputTranslateY, jnt.ty) pm.connectAttr(dm_node.outputTranslateZ, jnt.tz) dm = jnt.s.listConnections(p=True, type="decomposeMatrix") if dm: at = dm[0] dm_node = at.node() pm.disconnectAttr(at, jnt.s) pm.connectAttr(dm_node.outputScaleX, jnt.sx) pm.connectAttr(dm_node.outputScaleY, jnt.sy) pm.connectAttr(dm_node.outputScaleZ, jnt.sz) return jnt
def addJoint(self, obj, name, newActiveJnt=None, UniScale=True, segComp=0, gearMulMatrix=True): """Add joint as child of the active joint or under driver object. Args: obj (dagNode): The input driver object for the joint. name (str): The joint name. newActiveJnt (bool or dagNode): If a joint is pass, this joint will be the active joint and parent of the newly created joint. UniScale (bool): Connects the joint scale with the Z axis for a unifor scalin, if set Falsewill connect with each axis separated. segComp (bool): Set True or False the segment compensation in the joint.. gearMulMatrix (bool): Use the custom gear_multiply matrix node, if False will use Maya's default mulMatrix node. Returns: dagNode: The newly created joint. """ if self.options["joint_rig"]: if newActiveJnt: self.active_jnt = newActiveJnt jnt = primitive.addJoint(self.active_jnt, self.getName(str(name) + "_jnt"), transform.getTransform(obj)) # All new jnts are the active by default self.active_jnt = jnt if gearMulMatrix: mulmat_node = applyop.gear_mulmatrix_op( obj + ".worldMatrix", jnt + ".parentInverseMatrix") dm_node = node.createDecomposeMatrixNode(mulmat_node + ".output") m = mulmat_node.attr('output').get() else: mulmat_node = node.createMultMatrixNode( obj + ".worldMatrix", jnt + ".parentInverseMatrix") dm_node = node.createDecomposeMatrixNode(mulmat_node + ".matrixSum") m = mulmat_node.attr('matrixSum').get() pm.connectAttr(dm_node + ".outputTranslate", jnt + ".t") pm.connectAttr(dm_node + ".outputRotate", jnt + ".r") # TODO: fix squash stretch solver to scale the joint uniform # the next line cheat the uniform scaling only fo X or Y axis # oriented joints if UniScale: pm.connectAttr(dm_node + ".outputScaleZ", jnt + ".sx") pm.connectAttr(dm_node + ".outputScaleZ", jnt + ".sy") pm.connectAttr(dm_node + ".outputScaleZ", jnt + ".sz") else: pm.connectAttr(dm_node + ".outputScale", jnt + ".s") pm.connectAttr(dm_node + ".outputShear", jnt + ".shear") # Segment scale compensate Off to avoid issues with the global # scale jnt.setAttr("segmentScaleCompensate", segComp) jnt.setAttr("jointOrient", 0, 0, 0) # setting the joint orient compensation in order to have clean # rotation channels jnt.attr("jointOrientX").set(jnt.attr("rx").get()) jnt.attr("jointOrientY").set(jnt.attr("ry").get()) jnt.attr("jointOrientZ").set(jnt.attr("rz").get()) im = m.inverse() if gearMulMatrix: applyop.gear_mulmatrix_op(mulmat_node.attr('output'), im, jnt, 'r') else: node.createMultMatrixNode(mulmat_node.attr('matrixSum'), im, jnt, 'r') else: jnt = primitive.addJoint(obj, self.getName(str(name) + "_jnt"), transform.getTransform(obj)) pm.connectAttr(self.rig.jntVis_att, jnt.attr("visibility")) self.addToGroup(jnt, "deformers") return jnt