Ejemplo n.º 1
0
def ikFkMatch(model, ikfk_attr, uiHost_name, fks, ik, upv, ikRot=None):
    # type: (pm.nodetypes.Transform, str, str, List[str], str, str, str) -> None

    nameSpace = syn_uti.getNamespace(model)

    fkCtrls = [_getNode(nameSpace, x) for x in fks]
    fkTargets = [_getMth(nameSpace, x) for x in fks]

    ikCtrl = _getNode(nameSpace, ik)
    ikTarget = _getMth(nameSpace, ik)

    upvCtrl = _getNode(nameSpace, upv)
    upvTarget = _getMth(nameSpace, upv)

    if ikRot:
        ikRotNode = _getNode(nameSpace, ikRot)
        ikRotTarget = ikTarget

    uiNode = _getNode(nameSpace, uiHost_name)
    oAttr = uiNode.attr(ikfk_attr)
    val = oAttr.get()

    # if is IK change to FK
    if val == 1.0:

        for target, ctl in zip(fkTargets, fkCtrls):
            tra.matchWorldTransform(target, ctl)

        if ikRot:
            tra.matchWorldTransform(ikRotNode, fkCtrls[-1])
            rot = cmds.xform(ikTarget.name(), query=True, ro=True)

            if re.search(r"_L\d", ikCtrl.name()):
                cmds.rotate(rot[0] * -1.,
                            rot[2],
                            rot[1] * -1,
                            fkCtrls[-1].name(),
                            relative=True,
                            objectSpace=True)

            else:
                cmds.rotate(rot[0] * -1.,
                            rot[2] * -1,
                            rot[1],
                            fkCtrls[-1].name(),
                            relative=True,
                            objectSpace=True)

        oAttr.set(0.0)

    # if is FK change to IK
    elif val == 0.0:

        tra.matchWorldTransform(ikTarget, ikCtrl)
        if ikRot:
            tra.matchWorldTransform(ikRotTarget, ikRotNode)

        tra.matchWorldTransform(upvTarget, upvCtrl)
        oAttr.set(1.0)
Ejemplo n.º 2
0
def matchWorldXform(*args):
    """Align 2 selected objects in world space"""

    if len(pm.selected()) < 2:
        mgear.log(
            "2 objects or more must be selected. Source and Targets "
            "transform", mgear.sev_warning)
    else:
        source = pm.selected()[0]
        for target in pm.selected()[1:]:
            transform.matchWorldTransform(source, target)
Ejemplo n.º 3
0
    def addObjects(self):
        """Add all the objects needed to create the component."""
        # Align root back to guide orientation
        transform.matchWorldTransform(self.guide.root, self.root)
        t = self.guide.tra["root"]
        if self.settings["mirrorBehaviour"] and self.negate:
            scl = [1, 1, -1]
        else:
            scl = [1, 1, 1]
        t = transform.setMatrixScale(t, scl)

        self.ik_cns = primitive.addTransform(self.root, self.getName("ik_cns"),
                                             t)

        self.ctl = self.addCtl(self.ik_cns,
                               "ctl",
                               t,
                               self.color_ik,
                               self.settings["icon"],
                               w=self.settings["ctlSize"] * self.size,
                               h=self.settings["ctlSize"] * self.size,
                               d=self.settings["ctlSize"] * self.size,
                               tp=self.parentCtlTag)

        # we need to set the rotation order before lock any rotation axis
        if self.settings["k_ro"]:
            rotOderList = ["XYZ", "YZX", "ZXY", "XZY", "YXZ", "ZYX"]
            attribute.setRotOrder(
                self.ctl, rotOderList[self.settings["default_rotorder"]])

        params = [
            s for s in
            ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx", "sy", "sz"]
            if self.settings["k_" + s]
        ]
        attribute.setKeyableAttributes(self.ctl, params)

        if self.settings["joint"]:
            self.jnt_pos.append([self.ctl, 0, None, self.settings["uniScale"]])
Ejemplo n.º 4
0
    def addOperators(self):
        """Create operators and set the relations for the component rig

        Apply operators, constraints, expressions to the hierarchy.
        In order to keep the code clean and easier to debug,
        we shouldn't create any new object in this method.

        """
        # 1 bone chain Upv ref ==============================================
        self.ikHandleUpvRef = primitive.addIkHandle(
            self.root, self.getName("ikHandleArmChainUpvRef"),
            self.armChainUpvRef, "ikSCsolver")
        pm.pointConstraint(self.ik_ctl, self.ikHandleUpvRef)
        pm.parentConstraint(self.armChainUpvRef[0], self.upv_cns, mo=True)

        # Visibilities -------------------------------------
        # fk
        fkvis_node = node.createReverseNode(self.blend_att)

        for shp in self.fk0_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))
        for shp in self.fk1_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))
        for shp in self.fk2_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))

        # ik
        for shp in self.upv_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.ikcns_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.ik_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.line_ref.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        if self.settings["ikTR"]:
            for shp in self.ikRot_ctl.getShapes():
                pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.roll_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))

        # Controls ROT order -----------------------------------
        attribute.setRotOrder(self.fk0_ctl, "XZY")
        attribute.setRotOrder(self.fk1_ctl, "XYZ")
        attribute.setRotOrder(self.fk2_ctl, "YZX")
        attribute.setRotOrder(self.ik_ctl, "XYZ")

        # IK Solver -----------------------------------------
        out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc]
        o_node = applyop.gear_ikfk2bone_op(out, self.root, self.ik_ref,
                                           self.upv_ctl, self.fk_ctl[0],
                                           self.fk_ctl[1], self.fk_ref,
                                           self.length0, self.length1,
                                           self.negate)

        # NOTE: Ideally we should not change hierarchy or move object after
        # object generation method. But is much easier this way since every
        # part is in the final and correct position
        # after the  ctrn_loc is in the correct position with the ikfk2bone op

        # point constrain tip reference
        pm.pointConstraint(self.ik_ctl, self.tip_ref, mo=False)

        # interpolate transform  mid point locator
        int_matrix = applyop.gear_intmatrix_op(
            self.armChainUpvRef[0].attr("worldMatrix"),
            self.tip_ref.attr("worldMatrix"), .5)
        applyop.gear_mulmatrix_op(
            int_matrix.attr("output"),
            self.interpolate_lvl.attr("parentInverseMatrix[0]"),
            self.interpolate_lvl)

        # match roll ctl npo to ctrn_loc current transform (so correct orient)
        transform.matchWorldTransform(self.ctrn_loc, self.roll_ctl_npo)

        # match roll ctl npo to interpolate transform current position
        pos = self.interpolate_lvl.getTranslation(space="world")
        self.roll_ctl_npo.setTranslation(pos, space="world")

        # parent constraint roll control npo to interpolate trans
        pm.parentConstraint(self.interpolate_lvl, self.roll_ctl_npo, mo=True)

        if self.settings["ikTR"]:
            # connect the control inputs
            outEff_dm = o_node.listConnections(c=True)[-1][1]

            inAttr = self.ikRot_npo.attr("translate")
            outEff_dm.attr("outputTranslate") >> inAttr

            outEff_dm.attr("outputScale") >> self.ikRot_npo.attr("scale")
            dm_node = node.createDecomposeMatrixNode(o_node.attr("outB"))
            dm_node.attr("outputRotate") >> self.ikRot_npo.attr("rotate")

            # rotation
            mulM_node = applyop.gear_mulmatrix_op(
                self.ikRot_ctl.attr("worldMatrix"),
                self.eff_loc.attr("parentInverseMatrix"))
            intM_node = applyop.gear_intmatrix_op(o_node.attr("outEff"),
                                                  mulM_node.attr("output"),
                                                  o_node.attr("blend"))
            dm_node = node.createDecomposeMatrixNode(intM_node.attr("output"))
            dm_node.attr("outputRotate") >> self.eff_loc.attr("rotate")
            transform.matchWorldTransform(self.fk2_ctl, self.ikRot_cns)

        # scale: this fix the scalin popping issue
        intM_node = applyop.gear_intmatrix_op(
            self.fk2_ctl.attr("worldMatrix"),
            self.ik_ctl_ref.attr("worldMatrix"), o_node.attr("blend"))
        mulM_node = applyop.gear_mulmatrix_op(
            intM_node.attr("output"), self.eff_loc.attr("parentInverseMatrix"))
        dm_node = node.createDecomposeMatrixNode(mulM_node.attr("output"))
        dm_node.attr("outputScale") >> self.eff_loc.attr("scale")

        pm.connectAttr(self.blend_att, o_node + ".blend")
        if self.negate:
            mulVal = -1
            rollMulVal = 1
        else:
            mulVal = 1
            rollMulVal = -1
        roll_m_node = node.createMulNode(self.roll_att, mulVal)
        roll_m_node2 = node.createMulNode(self.roll_ctl.attr("rx"), rollMulVal)
        node.createPlusMinusAverage1D(
            [roll_m_node.outputX, roll_m_node2.outputX],
            operation=1,
            output=o_node + ".roll")
        pm.connectAttr(self.scale_att, o_node + ".scaleA")
        pm.connectAttr(self.scale_att, o_node + ".scaleB")
        pm.connectAttr(self.maxstretch_att, o_node + ".maxstretch")
        pm.connectAttr(self.slide_att, o_node + ".slide")
        pm.connectAttr(self.softness_att, o_node + ".softness")
        pm.connectAttr(self.reverse_att, o_node + ".reverse")

        # Twist references ---------------------------------

        pm.pointConstraint(self.mid_ctl_twst_ref,
                           self.tws1_npo,
                           maintainOffset=False)
        pm.connectAttr(self.mid_ctl.scaleX, self.tws1_loc.scaleX)
        pm.connectAttr(self.mid_ctl.scaleX, self.tws1B_loc.scaleX)
        pm.orientConstraint(self.mid_ctl_twst_ref,
                            self.tws1_npo,
                            maintainOffset=False)
        applyop.oriCns(self.mid_ctl, self.tws1_rot, maintainOffset=False)
        applyop.oriCns(self.mid_ctl, self.tws1B_rot, maintainOffset=False)

        if self.negate:
            axis = "xz"
            axisb = "-xz"
        else:
            axis = "-xz"
            axisb = "xz"
        applyop.aimCns(self.tws1_loc,
                       self.root,
                       axis=axis,
                       wupType=4,
                       wupVector=[0, 0, 1],
                       wupObject=self.mid_ctl,
                       maintainOffset=False)

        applyop.aimCns(self.tws1B_loc,
                       self.eff_loc,
                       axis=axisb,
                       wupType=4,
                       wupVector=[0, 0, 1],
                       wupObject=self.mid_ctl,
                       maintainOffset=False)

        pm.pointConstraint(self.thick_ctl,
                           self.tws1B_loc,
                           maintainOffset=False)

        o_node = applyop.gear_mulmatrix_op(
            self.eff_loc.attr("worldMatrix"),
            self.root.attr("worldInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        pm.connectAttr(dm_node + ".outputTranslate",
                       self.tws2_npo.attr("translate"))

        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        pm.connectAttr(dm_node + ".outputRotate", self.tws2_npo.attr("rotate"))

        o_node = applyop.gear_mulmatrix_op(
            self.eff_loc.attr("worldMatrix"),
            self.tws2_rot.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        attribute.setRotOrder(self.tws2_rot, "XYZ")
        pm.connectAttr(dm_node + ".outputRotate", self.tws2_rot + ".rotate")

        self.tws0_rot.setAttr("sx", .001)
        self.tws2_rot.setAttr("sx", .001)

        add_node = node.createAddNode(self.roundness_att, .001)
        pm.connectAttr(add_node + ".output", self.tws1_rot.attr("sx"))
        pm.connectAttr(add_node + ".output", self.tws1B_rot.attr("sx"))

        pm.connectAttr(self.armpit_roll_att, self.tws0_rot + ".rotateX")

        # Roll Shoulder
        applyop.splineIK(self.getName("rollRef"),
                         self.rollRef,
                         parent=self.root,
                         cParent=self.bone0)

        # Volume -------------------------------------------
        distA_node = node.createDistNode(self.tws0_loc, self.tws1_loc)
        distB_node = node.createDistNode(self.tws1_loc, self.tws2_loc)
        add_node = node.createAddNode(distA_node + ".distance",
                                      distB_node + ".distance")
        div_node = node.createDivNode(add_node + ".output",
                                      self.root.attr("sx"))

        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(self.root.attr("worldMatrix"), dm_node + ".inputMatrix")

        div_node2 = node.createDivNode(div_node + ".outputX",
                                       dm_node + ".outputScaleX")
        self.volDriver_att = div_node2 + ".outputX"

        if self.settings["extraTweak"]:
            for tweak_ctl in self.tweak_ctl:
                for shp in tweak_ctl.getShapes():
                    pm.connectAttr(self.tweakVis_att, shp.attr("visibility"))

        # Divisions ----------------------------------------
        # at 0 or 1 the division will follow exactly the rotation of the
        # controler.. and we wont have this nice tangent + roll
        b_twist = False
        for i, div_cns in enumerate(self.div_cns):

            if self.settings["supportJoints"]:
                if i < (self.settings["div0"] + 1):
                    perc = i * .5 / (self.settings["div0"] + 1.0)
                elif i < (self.settings["div0"] + 2):
                    perc = .49
                elif i < (self.settings["div0"] + 3):
                    perc = .50
                elif i < (self.settings["div0"] + 4):
                    b_twist = True
                    perc = .51

                else:
                    perc = .5 + \
                        (i - self.settings["div0"] - 3.0) * .5 / \
                        (self.settings["div1"] + 1.0)
            else:
                if i < (self.settings["div0"] + 1):
                    perc = i * .5 / (self.settings["div0"] + 1.0)
                elif i < (self.settings["div0"] + 2):
                    b_twist = True
                    perc = .501
                else:
                    perc = .5 + \
                        (i - self.settings["div0"] - 1.0) * .5 / \
                        (self.settings["div1"] + 1.0)

            perc = max(.001, min(.990, perc))

            # mid twist distribution
            if b_twist:
                mid_twist = self.tws1B_rot
            else:
                mid_twist = self.tws1_rot

            # Roll
            if self.negate:
                o_node = applyop.gear_rollsplinekine_op(
                    div_cns, [self.tws2_rot, mid_twist, self.tws0_rot],
                    1.0 - perc, 40)
            else:
                o_node = applyop.gear_rollsplinekine_op(
                    div_cns, [self.tws0_rot, mid_twist, self.tws2_rot], perc,
                    40)

            pm.connectAttr(self.resample_att, o_node + ".resample")
            pm.connectAttr(self.absolute_att, o_node + ".absolute")

            # Squash n Stretch
            o_node = applyop.gear_squashstretch2_op(
                div_cns, None, pm.getAttr(self.volDriver_att), "x")
            pm.connectAttr(self.volume_att, o_node + ".blend")
            pm.connectAttr(self.volDriver_att, o_node + ".driver")
            pm.connectAttr(self.st_att[i], o_node + ".stretch")
            pm.connectAttr(self.sq_att[i], o_node + ".squash")

        # match IK/FK ref
        pm.parentConstraint(self.bone0, self.match_fk0_off, mo=True)
        pm.parentConstraint(self.bone1, self.match_fk1_off, mo=True)
        if self.settings["ikTR"]:
            transform.matchWorldTransform(self.ikRot_ctl, self.match_ikRot)
            transform.matchWorldTransform(self.fk_ctl[2], self.match_fk2)

        # connect_reader
        pm.parentConstraint(self.bone0, self.readerA, mo=True)
        pm.parentConstraint(self.bone1, self.readerB, mo=True)

        # connect auto thickness
        if self.negate and not self.settings["mirrorMid"]:
            d_val = 180 / self.length1
        else:
            d_val = -180 / self.length1
        div_thick_node = node.createDivNode(self.elbow_thickness_att, d_val)
        node.createMulNode(div_thick_node.outputX, self.readerB.ry,
                           self.thick_lvl.tx)

        return
Ejemplo n.º 5
0
    def addOperators(self):
        """Create operators and set the relations for the component rig

        Apply operators, constraints, expressions to the hierarchy.
        In order to keep the code clean and easier to debug,
        we shouldn't create any new object in this method.

        """

        # 1 bone chain Upv ref ==============================
        self.ikHandleUpvRef = primitive.addIkHandle(
            self.root, self.getName("ikHandleLegChainUpvRef"),
            self.legChainUpvRef, "ikSCsolver")
        pm.pointConstraint(self.ik_ctl, self.ikHandleUpvRef)
        pm.parentConstraint(self.legChainUpvRef[0],
                            self.ik_ctl,
                            self.upv_cns,
                            mo=True)

        # Visibilities -------------------------------------
        # shape.dispGeometry
        # fk
        fkvis_node = node.createReverseNode(self.blend_att)

        for shp in self.fk0_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))
        for shp in self.fk1_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))
        for shp in self.fk2_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))

        # ik
        for shp in self.upv_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.ikcns_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.ik_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.line_ref.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))

        # IK Solver -----------------------------------------
        out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc]
        o_node = applyop.gear_ikfk2bone_op(out, self.root_ctl, self.ik_ref,
                                           self.upv_ctl, self.fk_ctl[0],
                                           self.fk_ctl[1], self.fk_ref,
                                           self.length0, self.length1,
                                           self.negate)

        pm.connectAttr(self.blend_att, o_node + ".blend")
        if self.negate:
            mulVal = -1
        else:
            mulVal = 1
        node.createMulNode(self.roll_att, mulVal, o_node + ".roll")
        # pm.connectAttr(self.roll_att, o_node+".roll")
        pm.connectAttr(self.scale_att, o_node + ".scaleA")
        pm.connectAttr(self.scale_att, o_node + ".scaleB")
        pm.connectAttr(self.maxstretch_att, o_node + ".maxstretch")
        pm.connectAttr(self.slide_att, o_node + ".slide")
        pm.connectAttr(self.softness_att, o_node + ".softness")
        pm.connectAttr(self.reverse_att, o_node + ".reverse")

        # Twist references ---------------------------------
        o_node = applyop.gear_mulmatrix_op(
            self.eff_loc.attr("worldMatrix"),
            self.root.attr("worldInverseMatrix"))

        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        pm.connectAttr(dm_node + ".outputTranslate",
                       self.tws2_npo.attr("translate"))

        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        pm.connectAttr(dm_node + ".outputRotate", self.tws2_npo.attr("rotate"))

        # spline IK for  twist jnts
        self.ikhUpLegTwist, self.uplegTwistCrv = applyop.splineIK(
            self.getName("uplegTwist"),
            self.uplegTwistChain,
            parent=self.root,
            cParent=self.bone0)

        self.ikhLowLegTwist, self.lowlegTwistCrv = applyop.splineIK(
            self.getName("lowlegTwist"),
            self.lowlegTwistChain,
            parent=self.root,
            cParent=self.bone1)

        # references
        self.ikhUpLegRef, self.tmpCrv = applyop.splineIK(
            self.getName("uplegRollRef"),
            self.uplegRollRef,
            parent=self.root,
            cParent=self.bone0)

        self.ikhLowLegRef, self.tmpCrv = applyop.splineIK(
            self.getName("lowlegRollRef"),
            self.lowlegRollRef,
            parent=self.root,
            cParent=self.eff_loc)

        self.ikhAuxTwist, self.tmpCrv = applyop.splineIK(
            self.getName("auxTwist"),
            self.auxTwistChain,
            parent=self.root,
            cParent=self.eff_loc)

        # setting connexions for ikhUpLegTwist
        self.ikhUpLegTwist.attr("dTwistControlEnable").set(True)
        self.ikhUpLegTwist.attr("dWorldUpType").set(4)
        self.ikhUpLegTwist.attr("dWorldUpAxis").set(3)
        self.ikhUpLegTwist.attr("dWorldUpVectorZ").set(1.0)
        self.ikhUpLegTwist.attr("dWorldUpVectorY").set(0.0)
        self.ikhUpLegTwist.attr("dWorldUpVectorEndZ").set(1.0)
        self.ikhUpLegTwist.attr("dWorldUpVectorEndY").set(0.0)
        pm.connectAttr(self.uplegRollRef[0].attr("worldMatrix[0]"),
                       self.ikhUpLegTwist.attr("dWorldUpMatrix"))
        pm.connectAttr(self.bone0.attr("worldMatrix[0]"),
                       self.ikhUpLegTwist.attr("dWorldUpMatrixEnd"))

        # setting connexions for ikhAuxTwist
        self.ikhAuxTwist.attr("dTwistControlEnable").set(True)
        self.ikhAuxTwist.attr("dWorldUpType").set(4)
        self.ikhAuxTwist.attr("dWorldUpAxis").set(3)
        self.ikhAuxTwist.attr("dWorldUpVectorZ").set(1.0)
        self.ikhAuxTwist.attr("dWorldUpVectorY").set(0.0)
        self.ikhAuxTwist.attr("dWorldUpVectorEndZ").set(1.0)
        self.ikhAuxTwist.attr("dWorldUpVectorEndY").set(0.0)
        pm.connectAttr(self.lowlegRollRef[0].attr("worldMatrix[0]"),
                       self.ikhAuxTwist.attr("dWorldUpMatrix"))
        pm.connectAttr(self.tws_ref.attr("worldMatrix[0]"),
                       self.ikhAuxTwist.attr("dWorldUpMatrixEnd"))
        pm.connectAttr(self.auxTwistChain[1].attr("rx"),
                       self.ikhLowLegTwist.attr("twist"))

        pm.parentConstraint(self.bone1, self.aux_npo, maintainOffset=True)

        # scale arm length for twist chain (not the squash and stretch)
        arclen_node = pm.arclen(self.uplegTwistCrv, ch=True)
        alAttrUpLeg = arclen_node.attr("arcLength")
        muldiv_nodeArm = pm.createNode("multiplyDivide")
        pm.connectAttr(arclen_node.attr("arcLength"),
                       muldiv_nodeArm.attr("input1X"))
        muldiv_nodeArm.attr("input2X").set(alAttrUpLeg.get())
        muldiv_nodeArm.attr("operation").set(2)
        for jnt in self.uplegTwistChain:
            pm.connectAttr(muldiv_nodeArm.attr("outputX"), jnt.attr("sx"))

        # scale forearm length for twist chain (not the squash and stretch)
        arclen_node = pm.arclen(self.lowlegTwistCrv, ch=True)
        alAttrLowLeg = arclen_node.attr("arcLength")
        muldiv_nodeLowLeg = pm.createNode("multiplyDivide")
        pm.connectAttr(arclen_node.attr("arcLength"),
                       muldiv_nodeLowLeg.attr("input1X"))
        muldiv_nodeLowLeg.attr("input2X").set(alAttrLowLeg.get())
        muldiv_nodeLowLeg.attr("operation").set(2)
        for jnt in self.lowlegTwistChain:
            pm.connectAttr(muldiv_nodeLowLeg.attr("outputX"), jnt.attr("sx"))

        # scale compensation for the first  twist join
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(self.root.attr("worldMatrix[0]"),
                       dm_node.attr("inputMatrix"))
        pm.connectAttr(dm_node.attr("outputScale"),
                       self.uplegTwistChain[0].attr("inverseScale"))
        pm.connectAttr(dm_node.attr("outputScale"),
                       self.lowlegTwistChain[0].attr("inverseScale"))

        # tangent controls
        muldiv_node = pm.createNode("multiplyDivide")
        muldiv_node.attr("input2X").set(-1)
        pm.connectAttr(self.tws1A_npo.attr("rz"), muldiv_node.attr("input1X"))
        muldiv_nodeBias = pm.createNode("multiplyDivide")
        pm.connectAttr(muldiv_node.attr("outputX"),
                       muldiv_nodeBias.attr("input1X"))
        pm.connectAttr(self.roundness_att, muldiv_nodeBias.attr("input2X"))
        pm.connectAttr(muldiv_nodeBias.attr("outputX"),
                       self.tws1A_loc.attr("rz"))
        if self.negate:
            axis = "xz"
        else:
            axis = "-xz"
        applyop.aimCns(self.tws1A_npo,
                       self.tws0_loc,
                       axis=axis,
                       wupType=2,
                       wupVector=[0, 0, 1],
                       wupObject=self.mid_ctl,
                       maintainOffset=False)

        applyop.aimCns(self.lowlegTangentB_loc,
                       self.lowlegTangentA_npo,
                       axis=axis,
                       wupType=2,
                       wupVector=[0, 0, 1],
                       wupObject=self.mid_ctl,
                       maintainOffset=False)

        pm.pointConstraint(self.eff_loc, self.lowlegTangentB_loc)

        muldiv_node = pm.createNode("multiplyDivide")
        muldiv_node.attr("input2X").set(-1)
        pm.connectAttr(self.tws1B_npo.attr("rz"), muldiv_node.attr("input1X"))
        muldiv_nodeBias = pm.createNode("multiplyDivide")
        pm.connectAttr(muldiv_node.attr("outputX"),
                       muldiv_nodeBias.attr("input1X"))
        pm.connectAttr(self.roundness_att, muldiv_nodeBias.attr("input2X"))
        pm.connectAttr(muldiv_nodeBias.attr("outputX"),
                       self.tws1B_loc.attr("rz"))
        if self.negate:
            axis = "-xz"
        else:
            axis = "xz"
        applyop.aimCns(self.tws1B_npo,
                       self.tws2_loc,
                       axis=axis,
                       wupType=2,
                       wupVector=[0, 0, 1],
                       wupObject=self.mid_ctl,
                       maintainOffset=False)

        applyop.aimCns(self.uplegTangentA_loc,
                       self.uplegTangentB_npo,
                       axis=axis,
                       wupType=2,
                       wupVector=[0, 0, 1],
                       wupObject=self.mid_ctl,
                       maintainOffset=False)

        # Volume -------------------------------------------
        distA_node = node.createDistNode(self.tws0_loc, self.tws1_loc)
        distB_node = node.createDistNode(self.tws1_loc, self.tws2_loc)
        add_node = node.createAddNode(distA_node + ".distance",
                                      distB_node + ".distance")
        div_node = node.createDivNode(add_node + ".output",
                                      self.root_ctl.attr("sx"))

        # comp scaling issue
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(self.root.attr("worldMatrix"), dm_node + ".inputMatrix")

        div_node2 = node.createDivNode(div_node + ".outputX",
                                       dm_node + ".outputScaleX")

        self.volDriver_att = div_node2 + ".outputX"

        # connecting tangent scaele compensation after volume to
        # avoid duplicate some nodes
        distA_node = node.createDistNode(self.tws0_loc, self.mid_ctl)
        distB_node = node.createDistNode(self.mid_ctl, self.tws2_loc)

        div_nodeUpLeg = node.createDivNode(distA_node + ".distance",
                                           dm_node.attr("outputScaleX"))

        div_node2 = node.createDivNode(div_nodeUpLeg + ".outputX",
                                       distA_node.attr("distance").get())

        pm.connectAttr(div_node2.attr("outputX"), self.tws1A_loc.attr("sx"))

        pm.connectAttr(div_node2.attr("outputX"),
                       self.uplegTangentA_loc.attr("sx"))

        div_nodeLowLeg = node.createDivNode(distB_node + ".distance",
                                            dm_node.attr("outputScaleX"))
        div_node2 = node.createDivNode(div_nodeLowLeg + ".outputX",
                                       distB_node.attr("distance").get())

        pm.connectAttr(div_node2.attr("outputX"), self.tws1B_loc.attr("sx"))
        pm.connectAttr(div_node2.attr("outputX"),
                       self.lowlegTangentB_loc.attr("sx"))

        # conection curve
        cnts = [
            self.uplegTangentA_loc, self.uplegTangentA_ctl,
            self.uplegTangentB_ctl, self.kneeTangent_ctl
        ]
        applyop.gear_curvecns_op(self.uplegTwistCrv, cnts)

        cnts = [
            self.kneeTangent_ctl, self.lowlegTangentA_ctl,
            self.lowlegTangentB_ctl, self.lowlegTangentB_loc
        ]
        applyop.gear_curvecns_op(self.lowlegTwistCrv, cnts)

        # Tangent controls vis
        for shp in self.uplegTangentA_ctl.getShapes():
            pm.connectAttr(self.tangentVis_att, shp.attr("visibility"))
        for shp in self.uplegTangentB_ctl.getShapes():
            pm.connectAttr(self.tangentVis_att, shp.attr("visibility"))
        for shp in self.lowlegTangentA_ctl.getShapes():
            pm.connectAttr(self.tangentVis_att, shp.attr("visibility"))
        for shp in self.lowlegTangentB_ctl.getShapes():
            pm.connectAttr(self.tangentVis_att, shp.attr("visibility"))
        for shp in self.kneeTangent_ctl.getShapes():
            pm.connectAttr(self.tangentVis_att, shp.attr("visibility"))

        # Divisions ----------------------------------------
        # at 0 or 1 the division will follow exactly the rotation of the
        # controler.. and we wont have this nice tangent + roll
        for i, div_cns in enumerate(self.div_cns):
            if i < (self.settings["div0"] + 2):
                mulmat_node = applyop.gear_mulmatrix_op(
                    self.uplegTwistChain[i] + ".worldMatrix",
                    div_cns + ".parentInverseMatrix")
                lastUpLegDiv = div_cns
            else:
                o_node = self.lowlegTwistChain[i - (self.settings["div0"] + 2)]
                mulmat_node = applyop.gear_mulmatrix_op(
                    o_node + ".worldMatrix", div_cns + ".parentInverseMatrix")
                lastLowLegDiv = div_cns
            dm_node = node.createDecomposeMatrixNode(mulmat_node + ".output")
            pm.connectAttr(dm_node + ".outputTranslate", div_cns + ".t")
            pm.connectAttr(dm_node + ".outputRotate", div_cns + ".r")

            # Squash n Stretch
            o_node = applyop.gear_squashstretch2_op(
                div_cns, None, pm.getAttr(self.volDriver_att), "x")
            pm.connectAttr(self.volume_att, o_node + ".blend")
            pm.connectAttr(self.volDriver_att, o_node + ".driver")
            pm.connectAttr(self.st_att[i], o_node + ".stretch")
            pm.connectAttr(self.sq_att[i], o_node + ".squash")

        # force translation for last loc arm and foreamr
        applyop.gear_mulmatrix_op(self.kneeTangent_ctl.worldMatrix,
                                  lastUpLegDiv.parentInverseMatrix,
                                  lastUpLegDiv, "t")
        applyop.gear_mulmatrix_op(self.tws2_loc.worldMatrix,
                                  lastLowLegDiv.parentInverseMatrix,
                                  lastLowLegDiv, "t")

        # NOTE: next line fix the issue on meters.
        # This is special case becasuse the IK solver from mGear use the
        # scale as lenght and we have shear
        # TODO: check for a more clean and elegant solution instead of
        # re-match the world matrix again
        transform.matchWorldTransform(self.fk_ctl[0], self.match_fk0_off)
        transform.matchWorldTransform(self.fk_ctl[1], self.match_fk1_off)
        transform.matchWorldTransform(self.fk_ctl[0], self.match_fk0)
        transform.matchWorldTransform(self.fk_ctl[1], self.match_fk1)

        # match IK/FK ref
        pm.parentConstraint(self.bone0, self.match_fk0_off, mo=True)
        pm.parentConstraint(self.bone1, self.match_fk1_off, mo=True)

        return
Ejemplo n.º 6
0
    def addOperators(self):
        """Create operators and set the relations for the component rig

        Apply operators, constraints, expressions to the hierarchy.
        In order to keep the code clean and easier to debug,
        we shouldn't create any new object in this method.

        """
        # 1 bone chain Upv ref ==============================================
        self.ikHandleUpvRef = primitive.addIkHandle(
            self.root, self.getName("ikHandleArmChainUpvRef"),
            self.armChainUpvRef, "ikSCsolver")
        pm.pointConstraint(self.ik_ctl, self.ikHandleUpvRef)
        pm.parentConstraint(self.armChainUpvRef[0], self.upv_cns, mo=True)

        # Visibilities -------------------------------------
        # fk
        fkvis_node = node.createReverseNode(self.blend_att)

        for shp in self.fk0_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))
        for shp in self.fk1_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))
        for shp in self.fk2_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))

        # ik
        for shp in self.upv_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.ikcns_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.ik_ctl.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        for shp in self.line_ref.getShapes():
            pm.connectAttr(self.blend_att, shp.attr("visibility"))
        if self.settings["ikTR"]:
            for shp in self.ikRot_ctl.getShapes():
                pm.connectAttr(self.blend_att, shp.attr("visibility"))

        # Controls ROT order -----------------------------------
        attribute.setRotOrder(self.fk0_ctl, "XZY")
        attribute.setRotOrder(self.fk1_ctl, "XYZ")
        attribute.setRotOrder(self.fk2_ctl, "YZX")
        attribute.setRotOrder(self.ik_ctl, "XYZ")

        # IK Solver -----------------------------------------
        out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc]
        o_node = applyop.gear_ikfk2bone_op(out, self.root, self.ik_ref,
                                           self.upv_ctl, self.fk_ctl[0],
                                           self.fk_ctl[1], self.fk_ref,
                                           self.length0, self.length1,
                                           self.negate)

        if self.settings["ikTR"]:
            # connect the control inputs
            outEff_dm = o_node.listConnections(c=True)[-1][1]

            inAttr = self.ikRot_npo.attr("translate")
            outEff_dm.attr("outputTranslate") >> inAttr

            outEff_dm.attr("outputScale") >> self.ikRot_npo.attr("scale")
            dm_node = node.createDecomposeMatrixNode(o_node.attr("outB"))
            dm_node.attr("outputRotate") >> self.ikRot_npo.attr("rotate")

            # rotation
            mulM_node = applyop.gear_mulmatrix_op(
                self.ikRot_ctl.attr("worldMatrix"),
                self.eff_loc.attr("parentInverseMatrix"))
            intM_node = applyop.gear_intmatrix_op(o_node.attr("outEff"),
                                                  mulM_node.attr("output"),
                                                  o_node.attr("blend"))
            dm_node = node.createDecomposeMatrixNode(intM_node.attr("output"))
            dm_node.attr("outputRotate") >> self.eff_loc.attr("rotate")
            transform.matchWorldTransform(self.fk2_ctl, self.ikRot_cns)

        # scale: this fix the scalin popping issue
        intM_node = applyop.gear_intmatrix_op(
            self.fk2_ctl.attr("worldMatrix"),
            self.ik_ctl_ref.attr("worldMatrix"), o_node.attr("blend"))
        mulM_node = applyop.gear_mulmatrix_op(
            intM_node.attr("output"), self.eff_loc.attr("parentInverseMatrix"))
        dm_node = node.createDecomposeMatrixNode(mulM_node.attr("output"))
        dm_node.attr("outputScale") >> self.eff_loc.attr("scale")

        pm.connectAttr(self.blend_att, o_node + ".blend")
        if self.negate:
            mulVal = -1
        else:
            mulVal = 1
        node.createMulNode(self.roll_att, mulVal, o_node + ".roll")
        pm.connectAttr(self.scale_att, o_node + ".scaleA")
        pm.connectAttr(self.scale_att, o_node + ".scaleB")
        pm.connectAttr(self.maxstretch_att, o_node + ".maxstretch")
        pm.connectAttr(self.slide_att, o_node + ".slide")
        pm.connectAttr(self.softness_att, o_node + ".softness")
        pm.connectAttr(self.reverse_att, o_node + ".reverse")

        # Twist references ---------------------------------

        pm.pointConstraint(self.mid_ctl_twst_ref,
                           self.tws1_npo,
                           maintainOffset=False)
        pm.connectAttr(self.mid_ctl.scaleX, self.tws1_loc.scaleX)
        pm.orientConstraint(self.mid_ctl_twst_ref,
                            self.tws1_npo,
                            maintainOffset=False)

        o_node = applyop.gear_mulmatrix_op(
            self.eff_loc.attr("worldMatrix"),
            self.root.attr("worldInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        pm.connectAttr(dm_node + ".outputTranslate",
                       self.tws2_npo.attr("translate"))

        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        pm.connectAttr(dm_node + ".outputRotate", self.tws2_npo.attr("rotate"))

        o_node = applyop.gear_mulmatrix_op(
            self.eff_loc.attr("worldMatrix"),
            self.tws2_rot.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        attribute.setRotOrder(self.tws2_rot, "XYZ")
        pm.connectAttr(dm_node + ".outputRotate", self.tws2_rot + ".rotate")

        self.tws0_rot.setAttr("sx", .001)
        self.tws2_rot.setAttr("sx", .001)

        add_node = node.createAddNode(self.roundness_att, .001)
        pm.connectAttr(add_node + ".output", self.tws1_rot.attr("sx"))

        pm.connectAttr(self.armpit_roll_att, self.tws0_rot + ".rotateX")

        # Roll Shoulder
        applyop.splineIK(self.getName("rollRef"),
                         self.rollRef,
                         parent=self.root,
                         cParent=self.bone0)

        # Volume -------------------------------------------
        distA_node = node.createDistNode(self.tws0_loc, self.tws1_loc)
        distB_node = node.createDistNode(self.tws1_loc, self.tws2_loc)
        add_node = node.createAddNode(distA_node + ".distance",
                                      distB_node + ".distance")
        div_node = node.createDivNode(add_node + ".output",
                                      self.root.attr("sx"))

        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(self.root.attr("worldMatrix"), dm_node + ".inputMatrix")

        div_node2 = node.createDivNode(div_node + ".outputX",
                                       dm_node + ".outputScaleX")
        self.volDriver_att = div_node2 + ".outputX"

        if self.settings["extraTweak"]:
            for tweak_ctl in self.tweak_ctl:
                for shp in tweak_ctl.getShapes():
                    pm.connectAttr(self.tweakVis_att, shp.attr("visibility"))

        # Divisions ----------------------------------------
        # at 0 or 1 the division will follow exactly the rotation of the
        # controler.. and we wont have this nice tangent + roll
        for i, div_cns in enumerate(self.div_cns):

            if self.settings["supportJoints"]:
                if i < (self.settings["div0"] + 1):
                    perc = i * .5 / (self.settings["div0"] + 1.0)
                elif i < (self.settings["div0"] + 2):
                    perc = .49
                elif i < (self.settings["div0"] + 3):
                    perc = .50
                elif i < (self.settings["div0"] + 4):
                    perc = .51

                else:
                    perc = .5 + \
                        (i - self.settings["div0"] - 3.0) * .5 / \
                        (self.settings["div1"] + 1.0)
            else:
                if i < (self.settings["div0"] + 1):
                    perc = i * .5 / (self.settings["div0"] + 1.0)
                elif i < (self.settings["div0"] + 2):
                    perc = .501
                else:
                    perc = .5 + \
                        (i - self.settings["div0"] - 1.0) * .5 / \
                        (self.settings["div1"] + 1.0)

            perc = max(.001, min(.990, perc))

            # Roll
            if self.negate:
                o_node = applyop.gear_rollsplinekine_op(
                    div_cns, [self.tws2_rot, self.tws1_rot, self.tws0_rot],
                    1.0 - perc, 40)
            else:
                o_node = applyop.gear_rollsplinekine_op(
                    div_cns, [self.tws0_rot, self.tws1_rot, self.tws2_rot],
                    perc, 40)

            pm.connectAttr(self.resample_att, o_node + ".resample")
            pm.connectAttr(self.absolute_att, o_node + ".absolute")

            # Squash n Stretch
            o_node = applyop.gear_squashstretch2_op(
                div_cns, None, pm.getAttr(self.volDriver_att), "x")
            pm.connectAttr(self.volume_att, o_node + ".blend")
            pm.connectAttr(self.volDriver_att, o_node + ".driver")
            pm.connectAttr(self.st_att[i], o_node + ".stretch")
            pm.connectAttr(self.sq_att[i], o_node + ".squash")

        # match IK/FK ref
        pm.parentConstraint(self.bone0, self.match_fk0_off, mo=True)
        pm.parentConstraint(self.bone1, self.match_fk1_off, mo=True)
        if self.settings["ikTR"]:
            transform.matchWorldTransform(self.ikRot_ctl, self.match_ikRot)
            transform.matchWorldTransform(self.fk_ctl[2], self.match_fk2)

        return
Ejemplo n.º 7
0
def characterizeBiped(*args):
    try:
        gCtl = pm.PyNode("global_C0_ctl")
        mocapAttach = att.addAttribute(
            gCtl,
            "mocapAttach",
            "float",
            1.0,
            minValue=0.0,
            maxValue=1.0
        )
    except Exception:
        pm.displayWarning("global_C0_ctl: Is not in the scene")
        return

    # Align skeleton
    for a, b in zip(skelFK, gearFK):
        try:
            oA = pm.PyNode(a)
        except Exception:
            pm.displayWarning(a + ": Is not in the scene")
        try:
            oB = pm.PyNode(b)
        except Exception:
            pm.displayWarning(b + ": Is not in the scene")
        tra.matchWorldTransform(oB, oA)

    # Constrain FK controls
    for a, b in zip(skelFK, gearFK):
        oA = pm.PyNode(a)
        oB = pm.PyNode(b)
        cns = pm.parentConstraint(oA, oB, mo=True)

        pb_node = pm.createNode("pairBlend")

        pm.connectAttr(cns + ".constraintRotateX", pb_node + ".inRotateX2")
        pm.connectAttr(cns + ".constraintRotateY", pb_node + ".inRotateY2")
        pm.connectAttr(cns + ".constraintRotateZ", pb_node + ".inRotateZ2")
        pm.connectAttr(pb_node + ".outRotateX", oB + ".rotateX", f=True)
        pm.connectAttr(pb_node + ".outRotateY", oB + ".rotateY", f=True)
        pm.connectAttr(pb_node + ".outRotateZ", oB + ".rotateZ", f=True)
        pm.setKeyframe(oB, at="rotateX")
        pm.setKeyframe(oB, at="rotateY")
        pm.setKeyframe(oB, at="rotateZ")

        pm.connectAttr(cns + ".constraintTranslateX",
                       pb_node + ".inTranslateX2")
        pm.connectAttr(cns + ".constraintTranslateY",
                       pb_node + ".inTranslateY2")
        pm.connectAttr(cns + ".constraintTranslateZ",
                       pb_node + ".inTranslateZ2")
        pm.connectAttr(pb_node + ".outTranslateX", oB + ".translateX", f=True)
        pm.connectAttr(pb_node + ".outTranslateY", oB + ".translateY", f=True)
        pm.connectAttr(pb_node + ".outTranslateZ", oB + ".translateZ", f=True)
        pm.setKeyframe(oB, at="translateX")
        pm.setKeyframe(oB, at="translateY")
        pm.setKeyframe(oB, at="translateZ")

        pm.connectAttr(mocapAttach, pb_node.attr("weight"))

    # Align IK controls with FK controls
    for a, b in zip(alignIK, alignFK):
        oA = pm.PyNode(a)
        oB = pm.PyNode(b)
        tra.matchWorldTransform(oB, oA)
        if a in [u"arm_L0_upv_ctl", u"arm_R0_upv_ctl"]:
            oA.attr("tz").set(-3)
        if a == u"arm_L0_ikcns_ctl":
            oA.attr("rx").set((oA.attr("rx").get() + 90))
        if a == u"arm_R0_ikcns_ctl":
            oA.attr("rx").set((oA.attr("rx").get() - 90))

    # constrain IK controls
    for a, b in zip(skelIK, gearIK):
        oA = pm.PyNode(a)
        oB = pm.PyNode(b)
        print b
        pb_node = pm.createNode("pairBlend")
        try:
            if b in (u"leg_L0_upv_ctl", u"leg_R0_upv_ctl"):
                att.lockAttribute(pm.PyNode(b), lock=False, keyable=True)
            if b in (u"leg_L0_mid_ctl",
                     u"leg_R0_mid_ctl",
                     u"arm_L0_mid_ctl",
                     u"arm_R0_mid_ctl"):
                cns = pm.pointConstraint(oA, oB, mo=True)
            else:
                cns = pm.parentConstraint(oA, oB, mo=True)
            pm.connectAttr(cns + ".constraintRotateX", pb_node + ".inRotateX2")
            pm.connectAttr(cns + ".constraintRotateY", pb_node + ".inRotateY2")
            pm.connectAttr(cns + ".constraintRotateZ", pb_node + ".inRotateZ2")
            pm.connectAttr(pb_node + ".outRotateX", oB + ".rotateX", f=True)
            pm.connectAttr(pb_node + ".outRotateY", oB + ".rotateY", f=True)
            pm.connectAttr(pb_node + ".outRotateZ", oB + ".rotateZ", f=True)
            pm.setKeyframe(oB, at="rotateX")
            pm.setKeyframe(oB, at="rotateY")
            pm.setKeyframe(oB, at="rotateZ")
        except Exception:
            cns = pm.pointConstraint(oA, oB, mo=True)

        pm.connectAttr(cns + ".constraintTranslateX",
                       pb_node + ".inTranslateX2")
        pm.connectAttr(cns + ".constraintTranslateY",
                       pb_node + ".inTranslateY2")
        pm.connectAttr(cns + ".constraintTranslateZ",
                       pb_node + ".inTranslateZ2")
        pm.connectAttr(pb_node + ".outTranslateX", oB + ".translateX", f=True)
        pm.connectAttr(pb_node + ".outTranslateY", oB + ".translateY", f=True)
        pm.connectAttr(pb_node + ".outTranslateZ", oB + ".translateZ", f=True)
        pm.setKeyframe(oB, at="translateX")
        pm.setKeyframe(oB, at="translateY")
        pm.setKeyframe(oB, at="translateZ")

        pm.connectAttr(mocapAttach, pb_node.attr("weight"))
Ejemplo n.º 8
0
def slice(parent=False, oSel=False, *args):
    """Create a proxy geometry from a skinned object"""

    startTime = datetime.datetime.now()
    print oSel
    if not oSel:
        oSel = pm.selected()[0]
        print "----"
        print oSel

    oColl = pm.skinCluster(oSel, query=True, influence=True)
    oFaces = oSel.faces
    nFaces = oSel.numFaces()

    faceGroups = []
    for x in oColl:
        faceGroups.append([])
    sCluster = pm.listConnections(oSel.getShape(), type="skinCluster")
    print sCluster
    sCName = sCluster[0].name()
    for iFace in range(nFaces):
        faceVtx = oFaces[iFace].getVertices()
        oSum = False
        for iVtx in faceVtx:
            values = pm.skinPercent(sCName, oSel.vtx[iVtx], q=True, v=True)
            if oSum:
                oSum = [L + l for L, l in zip(oSum, values)]
            else:
                oSum = values

        print "adding face: " \
              + str(iFace) \
              + " to group in: " \
              + str(oColl[oSum.index(max(oSum))])

        faceGroups[oSum.index(max(oSum))].append(iFace)

    original = oSel
    if not parent:
        try:
            parentGroup = pm.PyNode("ProxyGeo")
        except TypeError:
            parentGroup = pm.createNode("transform", n="ProxyGeo")
    try:
        proxySet = pm.PyNode("rig_proxyGeo_grp")
    except TypeError:
        proxySet = pm.sets(name="rig_proxyGeo_grp", em=True)

    for boneList in faceGroups:

        if len(boneList):
            newObj = pm.duplicate(
                original,
                rr=True,
                name=oColl[faceGroups.index(boneList)] + "_Proxy")

            for trans in ["tx",
                          "ty",
                          "tz",
                          "rx",
                          "ry",
                          "rz",
                          "sx",
                          "sy",
                          "sz"]:

                pm.setAttr(newObj[0].name() + "." + trans, lock=0)

            c = list(newObj[0].faces)

            for index in reversed(boneList):

                c.pop(index)

            pm.delete(c)
            if parent:
                pm.parent(newObj,
                          pm.PyNode(oColl[faceGroups.index(boneList)]),
                          a=True)
            else:
                pm.parent(newObj, parentGroup, a=True)
                dummyCopy = pm.duplicate(newObj[0])[0]
                pm.delete(newObj[0].listRelatives(c=True))

                transform.matchWorldTransform(
                    pm.PyNode(oColl[faceGroups.index(boneList)]), newObj[0])

                pm.parent(dummyCopy.listRelatives(c=True)[0],
                          newObj[0],
                          shape=True)

                pm.delete(dummyCopy)

                pm.rename(newObj[0].listRelatives(c=True)[0],
                          newObj[0].name() + "_offset")

                o_multiplayer = pm.PyNode(oColl[faceGroups.index(boneList)])
                mulmat_node = applyop.gear_mulmatrix_op(
                    o_multiplayer.name() + ".worldMatrix",
                    newObj[0].name() + ".parentInverseMatrix")

                outPlug = mulmat_node + ".output"
                dm_node = node.createDecomposeMatrixNode(outPlug)

                pm.connectAttr(dm_node + ".outputTranslate",
                               newObj[0].name() + ".t")
                pm.connectAttr(dm_node + ".outputRotate",
                               newObj[0].name() + ".r")
                pm.connectAttr(dm_node + ".outputScale",
                               newObj[0].name() + ".s")

            print "Creating proxy for: {}".format(
                str(oColl[faceGroups.index(boneList)]))

            pm.sets(proxySet, add=newObj)

    endTime = datetime.datetime.now()
    finalTime = endTime - startTime
    mgear.log("=============== Slicing for: %s finish ======= [ %s  ] ==="
              "===" % (oSel.name(), str(finalTime)))
Ejemplo n.º 9
0
    def addOperators(self):
        """Create operators and set the relations for the component rig

        Apply operators, constraints, expressions to the hierarchy.
        In order to keep the code clean and easier to debug,
        we shouldn't create any new object in this method.

        """

        # Auto bend ----------------------------
        if self.settings["autoBend"]:
            mul_node = node.createMulNode(
                [self.autoBendChain[0].ry, self.autoBendChain[0].rz],
                [self.sideBend_att, self.frontBend_att])

            mul_node.outputX >> self.ik1autoRot_lvl.rz
            mul_node.outputY >> self.ik1autoRot_lvl.rx

            self.ikHandleAutoBend = primitive.addIkHandle(
                self.autoBend_ctl, self.getName("ikHandleAutoBend"),
                self.autoBendChain, "ikSCsolver")

        # Tangent position ---------------------------------
        # common part
        d = vector.getDistance(self.guide.apos[1], self.guide.apos[-2])
        dist_node = node.createDistNode(self.ik0_ctl, self.ik1_ctl)
        rootWorld_node = node.createDecomposeMatrixNode(
            self.root.attr("worldMatrix"))

        div_node = node.createDivNode(dist_node + ".distance",
                                      rootWorld_node + ".outputScaleX")

        div_node = node.createDivNode(div_node + ".outputX", d)

        # tan0
        mul_node = node.createMulNode(self.tan0_att,
                                      self.tan0_npo.getAttr("ty"))

        res_node = node.createMulNode(mul_node + ".outputX",
                                      div_node + ".outputX")

        pm.connectAttr(res_node + ".outputX", self.tan0_npo.attr("ty"))

        # tan1
        mul_node = node.createMulNode(self.tan1_att,
                                      self.tan1_npo.getAttr("ty"))

        res_node = node.createMulNode(mul_node + ".outputX",
                                      div_node + ".outputX")

        pm.connectAttr(res_node + ".outputX", self.tan1_npo.attr("ty"))

        # Tangent Mid --------------------------------------
        if self.settings["centralTangent"]:
            tanIntMat = applyop.gear_intmatrix_op(
                self.tan0_npo.attr("worldMatrix"),
                self.tan1_npo.attr("worldMatrix"), .5)

            applyop.gear_mulmatrix_op(
                tanIntMat.attr("output"),
                self.tan_npo.attr("parentInverseMatrix[0]"), self.tan_npo)

            pm.connectAttr(self.tan_ctl.attr("translate"),
                           self.tan0_off.attr("translate"))

            pm.connectAttr(self.tan_ctl.attr("translate"),
                           self.tan1_off.attr("translate"))

        # Curves -------------------------------------------
        op = applyop.gear_curveslide2_op(self.slv_crv, self.mst_crv, 0, 1.5,
                                         .5, .5)

        pm.connectAttr(self.position_att, op + ".position")
        pm.connectAttr(self.maxstretch_att, op + ".maxstretch")
        pm.connectAttr(self.maxsquash_att, op + ".maxsquash")
        pm.connectAttr(self.softness_att, op + ".softness")

        # Volume driver ------------------------------------
        crv_node = node.createCurveInfoNode(self.slv_crv)

        # Division -----------------------------------------
        tangents = [None, "tan0", "tan1"]
        for i in range(self.settings["division"]):

            # References
            u = i / (self.settings["division"] - 1.0)

            # check the indx to calculate mid point based on number of division
            # we want to use the same spine for mannequin and metahuman spine
            if self.settings["division"] == 4 and i in [1, 2]:
                u_param = curve.getCurveParamAtPosition(
                    self.slv_crv, self.guide.pos[tangents[i]])[0]
                cnsType = True
            elif self.settings["division"] == 3 and i in [1]:
                u_param = curve.getCurveParamAtPosition(
                    self.slv_crv, self.guide.pos[tangents[i]])[0]
                cnsType = True
            else:
                u_param = u
                cnsType = False

            cns = applyop.pathCns(self.div_cns[i], self.slv_crv, cnsType,
                                  u_param, True)

            cns.setAttr("frontAxis", 1)  # front axis is 'Y'
            cns.setAttr("upAxis", 0)  # front axis is 'X'

            # Roll
            intMatrix = applyop.gear_intmatrix_op(
                self.ik0_ctl + ".worldMatrix", self.ik1_ctl + ".worldMatrix",
                u)

            dm_node = node.createDecomposeMatrixNode(intMatrix + ".output")
            pm.connectAttr(dm_node + ".outputRotate",
                           self.twister[i].attr("rotate"))

            pm.parentConstraint(self.twister[i],
                                self.ref_twist[i],
                                maintainOffset=True)

            pm.connectAttr(self.ref_twist[i] + ".translate",
                           cns + ".worldUpVector")

            # compensate scale reference
            div_node = node.createDivNode([1, 1, 1], [
                rootWorld_node + ".outputScaleX", rootWorld_node +
                ".outputScaleY", rootWorld_node + ".outputScaleZ"
            ])

            # Squash n Stretch
            op = applyop.gear_squashstretch2_op(self.scl_transforms[i],
                                                self.root,
                                                pm.arclen(self.slv_crv), "y",
                                                div_node + ".output")

            pm.connectAttr(self.volume_att, op + ".blend")
            pm.connectAttr(crv_node + ".arcLength", op + ".driver")
            pm.connectAttr(self.st_att[i], op + ".stretch")
            pm.connectAttr(self.sq_att[i], op + ".squash")

            # Controlers
            if i == 0:
                mulmat_node = applyop.gear_mulmatrix_op(
                    self.div_cns[i].attr("worldMatrix"),
                    self.root.attr("worldInverseMatrix"))

                dm_node = node.createDecomposeMatrixNode(mulmat_node +
                                                         ".output")

                pm.connectAttr(dm_node + ".outputTranslate",
                               self.fk_npo[i].attr("t"))

            else:
                mulmat_node = applyop.gear_mulmatrix_op(
                    self.div_cns[i].attr("worldMatrix"),
                    self.div_cns[i - 1].attr("worldInverseMatrix"))

                dm_node = node.createDecomposeMatrixNode(mulmat_node +
                                                         ".output")

                mul_node = node.createMulNode(div_node + ".output",
                                              dm_node + ".outputTranslate")

                pm.connectAttr(mul_node + ".output", self.fk_npo[i].attr("t"))

            pm.connectAttr(dm_node + ".outputRotate", self.fk_npo[i].attr("r"))

            # Orientation Lock
            if i == 0:
                dm_node = node.createDecomposeMatrixNode(self.ik0_ctl +
                                                         ".worldMatrix")

                blend_node = node.createBlendNode(
                    [dm_node + ".outputRotate%s" % s for s in "XYZ"],
                    [cns + ".rotate%s" % s for s in "XYZ"], self.lock_ori0_att)

                self.div_cns[i].attr("rotate").disconnect()

                pm.connectAttr(blend_node + ".output",
                               self.div_cns[i] + ".rotate")

            elif i == self.settings["division"] - 1:
                dm_node = node.createDecomposeMatrixNode(self.ik1_ctl +
                                                         ".worldMatrix")

                blend_node = node.createBlendNode(
                    [dm_node + ".outputRotate%s" % s for s in "XYZ"],
                    [cns + ".rotate%s" % s for s in "XYZ"], self.lock_ori1_att)

                self.div_cns[i].attr("rotate").disconnect()
                pm.connectAttr(blend_node + ".output",
                               self.div_cns[i] + ".rotate")

        # change parent after operators applied
        pm.parent(self.scl_transforms[-1], self.fk_ctl[-1])

        # Connections (Hooks) ------------------------------
        pm.parentConstraint(self.pelvis_lvl, self.cnx0)
        pm.scaleConstraint(self.pelvis_lvl, self.cnx0)

        transform.matchWorldTransform(self.scl_transforms[-1], self.cnx1)
        t = transform.setMatrixPosition(transform.getTransform(self.cnx1),
                                        self.guide.apos[-1])
        self.cnx1.setMatrix(t, worldSpace=True)
        pm.parentConstraint(self.scl_transforms[-1], self.cnx1, mo=True)
        pm.scaleConstraint(self.scl_transforms[-1], self.cnx1)