Example #1
0
    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
Example #2
0
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")
Example #3
0
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
Example #4
0
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
Example #5
0
    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
Example #6
0
    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