Пример #1
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"))

        # 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.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 ---------------------------------
        self.ikhArmRef, self.tmpCrv = applyop.splineIK(
            self.getName("legRollRef"),
            self.rollRef,
            parent=self.root,
            cParent=self.bone0)

        pm.pointConstraint(self.mid_ctl, self.tws1_loc, maintainOffset=False)
        pm.connectAttr(self.mid_ctl.scaleX, self.tws1_loc.scaleX)
        applyop.oriCns(self.mid_ctl, self.tws1_rot, maintainOffset=False)

        pm.pointConstraint(self.eff_loc, self.tws2_loc, maintainOffset=False)
        pm.scaleConstraint(self.eff_loc, self.tws2_loc, maintainOffset=False)
        applyop.oriCns(self.bone1, self.tws2_loc, maintainOffset=False)

        applyop.oriCns(self.tws_ref, self.tws2_rot)

        self.tws0_loc.setAttr("sx", .001)

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

        # 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"

        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):
            subdiv = False
            if i == len(self.div_cns) - 1 or i == 0:
                subdiv = 45
            else:
                subdiv = 10

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

            else:
                perc = (.5 + (i - self.settings["div0"] - 3.0) * .5 /
                        (self.settings["div1"] + 1.0))

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

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

            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")

        # 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
Пример #2
0
    def addOperators(self):

        # Tangent position ---------------------------------
        # common part
        d = vec.getDistance(self.guide.pos["root"], self.guide.pos["neck"])
        dist_node = nod.createDistNode(self.root, self.ik_ctl)
        rootWorld_node = nod.createDecomposeMatrixNode(
            self.root.attr("worldMatrix"))
        div_node = nod.createDivNode(dist_node + ".distance",
                                     rootWorld_node + ".outputScaleX")
        div_node = nod.createDivNode(div_node + ".outputX", d)

        # tan0
        mul_node = nod.createMulNode(self.tan0_att,
                                     self.tan0_loc.getAttr("ty"))
        res_node = nod.createMulNode(mul_node + ".outputX",
                                     div_node + ".outputX")
        connectAttr(res_node + ".outputX", self.tan0_loc + ".ty")

        # tan1
        mul_node = nod.createMulNode(self.tan1_att,
                                     self.tan1_loc.getAttr("ty"))
        res_node = nod.createMulNode(mul_node + ".outputX",
                                     div_node + ".outputX")
        connectAttr(res_node + ".outputX", self.tan1_loc.attr("ty"))

        # Curves -------------------------------------------
        op = aop.gear_curveslide2_op(self.slv_crv, self.mst_crv, 0, 1.5, .5,
                                     .5)
        connectAttr(self.maxstretch_att, op + ".maxstretch")
        connectAttr(self.maxsquash_att, op + ".maxsquash")
        connectAttr(self.softness_att, op + ".softness")

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

        # Division -----------------------------------------
        for i in range(self.settings["division"]):

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

            cns = aop.pathCns(self.div_cns[i], self.slv_crv, False, u, True)
            cns.setAttr("frontAxis", 1)  # front axis is 'Y'
            cns.setAttr("upAxis", 2)  # front axis is 'Z'

            # Roll
            aop.gear_spinePointAtOp(cns, self.root, self.ik_ctl, u, "Z")

            # Squash n Stretch
            op = aop.gear_squashstretch2_op(self.fk_npo[i], self.root,
                                            arclen(self.slv_crv), "y")
            connectAttr(self.volume_att, op + ".blend")
            connectAttr(crv_node + ".arcLength", op + ".driver")
            connectAttr(self.st_att[i], op + ".stretch")
            connectAttr(self.sq_att[i], op + ".squash")

            # scl compas
            if i != 0:
                div_node = nod.createDivNode([1, 1, 1], [
                    self.fk_npo[i - 1] + ".sx", self.fk_npo[i - 1] + ".sy",
                    self.fk_npo[i - 1] + ".sz"
                ])
                connectAttr(div_node + ".output", self.scl_npo[i] + ".scale")

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

            dm_node = nod.createDecomposeMatrixNode(mulmat_node + ".output")
            connectAttr(dm_node + ".outputTranslate", self.fk_npo[i].attr("t"))
            connectAttr(dm_node + ".outputRotate", self.fk_npo[i].attr("r"))
            #connectAttr(dm_node+".outputScale", self.fk_npo[i].attr("s"))

            # Orientation Lock
            if i == self.settings["division"] - 1:
                dm_node = nod.createDecomposeMatrixNode(self.ik_ctl +
                                                        ".worldMatrix")
                blend_node = nod.createBlendNode(
                    [dm_node + ".outputRotate%s" % s for s in "XYZ"],
                    [cns + ".rotate%s" % s for s in "XYZ"], self.lock_ori_att)
                self.div_cns[i].attr("rotate").disconnect()
                connectAttr(blend_node + ".output",
                            self.div_cns[i] + ".rotate")

        # Head ---------------------------------------------
        self.fk_ctl[-1].addChild(self.head_cns)
Пример #3
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"))

        # 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
Пример #4
0
    def addOperators(self):

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

        # Visibilities -------------------------------------
        # fk
        fkvis_node = nod.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"))
        if self.settings["ikTR"]:
            for shp in self.ikRot_ctl.getShapes():
                pm.connectAttr(self.blend_att, shp.attr("visibility"))


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


        # IK Solver -----------------------------------------
        out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc]
        node = aop.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 = node.listConnections(c=True)[-1][1]

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

            #rotation

            mulM_node = aop.gear_mulmatrix_op(self.ikRot_ctl.attr("worldMatrix"), self.eff_loc.attr("parentInverseMatrix"))
            intM_node = aop.gear_intmatrix_op(node.attr("outEff"), mulM_node.attr("output"), node.attr("blend"))
            dm_node = nod.createDecomposeMatrixNode(intM_node.attr("output"))
            dm_node.attr("outputRotate") >> self.eff_loc.attr("rotate")
            tra.matchWorldTransform(self.fk2_ctl, self.ikRot_cns)

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


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

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

        pm.pointConstraint(self.mid_ctl_twst_ref, self.tws1_npo, maintainOffset=False)
        pm.scaleConstraint(self.mid_ctl_twst_ref, self.tws1_npo, maintainOffset=False)
        pm.orientConstraint(self.mid_ctl_twst_ref, self.tws1_npo, maintainOffset=False)

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

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

        node = aop.gear_mulmatrix_op(self.eff_loc.attr("worldMatrix"), self.tws2_rot.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(node+".output", dm_node+".inputMatrix")
        att.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 = nod.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
        aop.splineIK(self.getName("rollRef"), self.rollRef, parent=self.root, cParent=self.bone0 )



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

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

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

        # 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"]+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)

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

            # Roll
            if self.negate:
                node = aop.gear_rollsplinekine_op(div_cns, [self.tws2_rot, self.tws1_rot, self.tws0_rot], 1-perc, 40)
            else:
                node = aop.gear_rollsplinekine_op(div_cns, [self.tws0_rot, self.tws1_rot, self.tws2_rot], perc, 40)

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

            # Squash n Stretch
            node = aop.gear_squashstretch2_op(div_cns, None, pm.getAttr(self.volDriver_att), "x")
            pm.connectAttr(self.volume_att, node+".blend")
            pm.connectAttr(self.volDriver_att, node+".driver")
            pm.connectAttr(self.st_att[i], node+".stretch")
            pm.connectAttr(self.sq_att[i], 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"]:
            tra.matchWorldTransform(self.ikRot_ctl,self.match_ikRot )
            tra.matchWorldTransform(self.fk_ctl[2], self.match_fk2 )

        return
Пример #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.

        """

        # 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[0], self.guide.apos[1])
        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 -----------------------------------------
        for i in range(self.settings["division"]):

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

            cns = applyop.pathCns(self.div_cns[i], self.slv_crv, False, u,
                                  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")

        # Connections (Hooks) ------------------------------

        pm.parentConstraint(self.scl_transforms[0], self.cnx0)
        pm.scaleConstraint(self.scl_transforms[0], self.cnx0)
        pm.parentConstraint(self.scl_transforms[-1], self.cnx1)
        pm.scaleConstraint(self.scl_transforms[-1], self.cnx1)
Пример #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.

        """
        # Tangent position ---------------------------------
        # common part
        d = vector.getDistance(self.guide.pos["root"], self.guide.pos["neck"])
        dist_node = node.createDistNode(self.root, self.ik_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_loc.getAttr("ty"))
        res_node = node.createMulNode(mul_node + ".outputX",
                                      div_node + ".outputX")
        pm.connectAttr(res_node + ".outputX", self.tan0_loc + ".ty")

        # tan1
        mul_node = node.createMulNode(self.tan1_att,
                                      self.tan1_loc.getAttr("ty"))
        res_node = node.createMulNode(mul_node + ".outputX",
                                      div_node + ".outputX")
        pm.connectAttr(res_node + ".outputX", self.tan1_loc.attr("ty"))

        # Curves -------------------------------------------
        op = applyop.gear_curveslide2_op(self.slv_crv, self.mst_crv, 0, 1.5,
                                         .5, .5)
        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 -----------------------------------------
        for i in range(self.settings["division"]):

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

            cns = applyop.pathCns(self.div_cns[i], self.slv_crv, False, u,
                                  True)
            cns.setAttr("frontAxis", 1)  # front axis is 'Y'
            cns.setAttr("upAxis", 2)  # front axis is 'Z'

            # Roll
            intMatrix = applyop.gear_intmatrix_op(
                self.intMRef + ".worldMatrix", self.ik_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")

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

            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")
            op.setAttr("driver_min", .1)

            # scl compas
            if i != 0:
                div_node = node.createDivNode([1, 1, 1], [
                    self.fk_npo[i - 1] + ".sx", self.fk_npo[i - 1] + ".sy",
                    self.fk_npo[i - 1] + ".sz"
                ])

                pm.connectAttr(div_node + ".output",
                               self.scl_npo[i] + ".scale")

            # Controlers
            if i == 0:
                mulmat_node = applyop.gear_mulmatrix_op(
                    self.div_cns[i].attr("worldMatrix"),
                    self.root.attr("worldInverseMatrix"))
            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")
            pm.connectAttr(dm_node + ".outputTranslate",
                           self.fk_npo[i].attr("t"))
            pm.connectAttr(dm_node + ".outputRotate", self.fk_npo[i].attr("r"))

            # Orientation Lock
            if i == self.settings["division"] - 1:
                dm_node = node.createDecomposeMatrixNode(self.ik_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_ori_att)
                self.div_cns[i].attr("rotate").disconnect()

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

        # Head ---------------------------------------------
        self.fk_ctl[-1].addChild(self.head_cns)

        # scale compensation
        dm_node = node.createDecomposeMatrixNode(self.scl_npo[0] +
                                                 ".parentInverseMatrix")

        pm.connectAttr(dm_node + ".outputScale", self.scl_npo[0] + ".scale")
Пример #7
0
    def addOperators(self):

        # Visibilities -------------------------------------
        # fk
        fkvis_node = nod.createReverseNode(self.blend_att)
        
        for shp in self.fk0_ctl.getShapes():
            connectAttr(fkvis_node+".outputX", shp.attr("visibility"))
        for shp in self.fk1_ctl.getShapes():
            connectAttr(fkvis_node+".outputX", shp.attr("visibility"))
        for shp in self.fk2_ctl.getShapes():
            connectAttr(fkvis_node+".outputX", shp.attr("visibility"))

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

        # IK Solver -----------------------------------------
        out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc]
        node = aop.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)

        connectAttr(self.blend_att, node+".blend")
        connectAttr(self.roll_att, node+".roll")
        connectAttr(self.scale_att, node+".scaleA")
        connectAttr(self.scale_att, node+".scaleB")
        connectAttr(self.maxstretch_att, node+".maxstretch")
        connectAttr(self.slide_att, node+".slide")
        connectAttr(self.softness_att, node+".softness")
        connectAttr(self.reverse_att, node+".reverse")

        # Twist references ---------------------------------
        pointConstraint(self.root, self.tws0_loc, maintainOffset=True)
        aop.aimCns(self.tws0_loc, self.mid_ctl, self.n_sign+"xz", 2, [0,1,0], self.root, False)

        pointConstraint(self.mid_ctl, self.tws1_loc, maintainOffset=False)
        scaleConstraint(self.mid_ctl, self.tws1_loc, maintainOffset=False)
        orientConstraint(self.mid_ctl, self.tws1_rot, maintainOffset=False)

        pointConstraint(self.eff_loc, self.tws2_loc, maintainOffset=False)
        scaleConstraint(self.eff_loc, self.tws2_loc, maintainOffset=False)
        orientConstraint(self.bone1, self.tws2_loc, maintainOffset=False) 
        # orientConstraint(self.eff_loc, self.tws2_rot, maintainOffset=False)
        node = aop.gear_mulmatrix_op(self.eff_loc.attr("worldMatrix"), self.tws2_rot.attr("parentInverseMatrix"))
        dm_node = createNode("decomposeMatrix")
        connectAttr(node+".output", dm_node+".inputMatrix")
        connectAttr(dm_node+".outputRotate", self.tws2_rot+".rotate")
        # att.setRotOrder(self.tws2_rot, "YZX")

        self.tws0_loc.setAttr("sx", .001)
        self.tws2_loc.setAttr("sx", .001)

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

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

        # 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"]+1):
                perc = i*.5 / (self.settings["div0"]+1.0)
            else:
                perc = .5 + (i-self.settings["div0"]-1.0)*.5 / (self.settings["div1"]+1.0)

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

            # Roll
            if self.negate:
                node = aop.gear_rollsplinekine_op(div_cns, [self.tws2_rot, self.tws1_rot, self.tws0_rot], 1-perc)
            else:
                node = aop.gear_rollsplinekine_op(div_cns, [self.tws0_rot, self.tws1_rot, self.tws2_rot], perc)

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

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

        return
Пример #8
0
    def addOperators(self):

        # Tangent position ---------------------------------
        # common part
        d = vec.getDistance(self.guide.apos[0], self.guide.apos[1])
        dist_node = nod.createDistNode(self.ik0_ctl, self.ik1_ctl)
        rootWorld_node = nod.createDecomposeMatrixNode(self.root.attr("worldMatrix"))
        div_node = nod.createDivNode(dist_node+".distance", rootWorld_node+".outputScaleX")
        div_node = nod.createDivNode(div_node+".outputX", d)

        # tan0
        mul_node = nod.createMulNode(self.tan0_att, self.tan0_npo.getAttr("ty"))
        res_node = nod.createMulNode(mul_node+".outputX", div_node+".outputX")
        pm.connectAttr( res_node+".outputX", self.tan0_npo.attr("ty"))

        # tan1
        mul_node = nod.createMulNode(self.tan1_att, self.tan1_npo.getAttr("ty"))
        res_node = nod.createMulNode(mul_node+".outputX", div_node+".outputX")
        pm.connectAttr( res_node+".outputX", self.tan1_npo.attr("ty"))

        # Curves -------------------------------------------
        op = aop.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 = nod.createCurveInfoNode(self.slv_crv)

        # Division -----------------------------------------
        for i in range(self.settings["division"]):

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

            cns = aop.pathCns(self.div_cns[i], self.slv_crv, False, u, True)
            cns.setAttr("frontAxis", 1)# front axis is 'Y'
            cns.setAttr("upAxis", 0)# front axis is 'X'

            # Roll
            intMatrix = aop.gear_intmatrix_op(self.ik0_ctl+".worldMatrix", self.ik1_ctl+".worldMatrix", u)
            dm_node = nod.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")

            # Squash n Stretch
            op = aop.gear_squashstretch2_op(self.fk_npo[i], self.root, pm.arclen(self.slv_crv), "y")
            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")

            # scl compensation

            if i == 0:
                dm_node = nod.createDecomposeMatrixNode(self.root+".worldMatrix")
                div_node = nod.createDivNode([1,1,1], [dm_node+".outputScaleX", dm_node+".outputScaleY", dm_node+".outputScaleZ"])
                pm.connectAttr(div_node+".output", self.scl_npo[i]+".scale")

            elif i == 1:
                div_node = nod.createDivNode([1,1,1], [self.fk_npo[i-1]+".sx", self.fk_npo[i-1]+".sy", self.fk_npo[i-1]+".sz"])
                pm.connectAttr(div_node+".output", self.scl_npo[i]+".scale")


            else:
                div_node = nod.createDivNode([1,1,1], [self.fk_npo[i-1]+".sx", self.fk_npo[i-1]+".sy", self.fk_npo[i-1]+".sz"])
                pm.connectAttr(div_node+".output", self.scl_npo[i]+".scale")


            # Controlers
            if i == 0:
                mulmat_node = aop.gear_mulmatrix_op(self.div_cns[i].attr("worldMatrix"),
                                                    self.scl_npo[0].attr("worldInverseMatrix"))
            else:
                mulmat_node = aop.gear_mulmatrix_op(self.div_cns[i].attr("worldMatrix"),
                                                    self.div_cns[i - 1].attr("worldInverseMatrix"))
            dm_node = nod.createDecomposeMatrixNode(mulmat_node+".output")
            pm.connectAttr(dm_node+".outputTranslate", self.fk_npo[i].attr("t"))
            pm.connectAttr(dm_node+".outputRotate", self.fk_npo[i].attr("r"))

            # Orientation Lock
            if i == 0 :
                dm_node = nod.createDecomposeMatrixNode(self.ik0_ctl+".worldMatrix")
                blend_node = nod.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 = nod.createDecomposeMatrixNode(self.ik1_ctl+".worldMatrix")
                blend_node = nod.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")

        # Connections (Hooks) ------------------------------
        pm.pointConstraint(self.div_cns[0], self.cnx0)
        pm.orientConstraint(self.div_cns[0], self.cnx0)
        pm.pointConstraint(self.fk_ctl[-1], self.cnx1)
        pm.orientConstraint(self.fk_ctl[-1], self.cnx1)
Пример #9
0
    def addOperators(self):

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

        for shp in self.fk0_ctl.getShapes():
            pm.connectAttr(fkvis_node+".outputX", shp.attr("visibility"))
        for shp in self.fk0_roll_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.fk1_roll_ctl.getShapes():
            pm.connectAttr(fkvis_node+".outputX", shp.attr("visibility"))

        fkvis2_node = nod.createReverseNode(self.blend2_att)
        for shp in self.fk2_ctl.getShapes():
            pm.connectAttr(fkvis2_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"))

        # jnt ctl
        for ctl in (self.div_ctls):
            for shp in ctl.getShapes():
                pm.connectAttr(self.jntctl_vis_att, shp.attr("visibility"))
        # Controls ROT order -----------------------------------

        att.setRotOrder(self.ik_ctl, "XZY")


        # IK Solver -----------------------------------------
        out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_npo]

        #self.fk_ctl = [self.fk0_roll_ctl, self.fk1_ctl, self.fk2_mtx]
        node = aop.gear_ikfk2bone_op(out, self.root, self.ik_ref, self.upv_ctl, self.fk0_mtx, self.fk1_mtx, self.fk2_mtx, self.length0, self.length1, self.negate)

        pm.connectAttr(self.blend_att, node+".blend")
        if self.negate:
            mulVal = -1
        else:
            mulVal = 1
        nod.createMulNode(self.roll_att, mulVal, node+".roll")
        # pm.connectAttr(self.roll_att, node+".roll")
        pm.connectAttr(self.scale_att, node+".scaleA")
        pm.connectAttr(self.scale_att, node+".scaleB")
        pm.connectAttr(self.maxstretch_att, node+".maxstretch")
        pm.connectAttr(self.slide_att, node+".slide")
        pm.connectAttr(self.softness_att, node+".softness")
        pm.connectAttr(self.reverse_att, node+".reverse")
        # update issue on effector scale interpolation, disconnect for stability
        pm.disconnectAttr(self.eff_npo.scale)
        # auto upvector -------------------------------------


        # leg aim
        node = aop.aimCns(self.upv_auv, self.ik_ctl, axis="-yz", wupType=1, wupVector=[0,1,0], wupObject=self.upv2_auv, maintainOffset=False)


        # foot aim
        node = aop.aimCns(self.upv1_auv, self.root, axis="yz", wupType=4, wupVector=[0,1,0], wupObject=self.root, maintainOffset=False)


        # auto upvector connection
        node = aop.gear_mulmatrix_op(self.upv_auv.attr("worldMatrix"), self.upv_mtx.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(node+".output", dm_node+".inputMatrix")
        pb_node = pm.createNode("pairBlend")
        pb_node.attr("rotInterpolation").set (1)
        pm.connectAttr(dm_node+".outputTranslate", pb_node+".inTranslate2")
        pm.connectAttr(dm_node+".outputRotate", pb_node+".inRotate2")
        pm.connectAttr(pb_node+".outRotate", self.upv_mtx.attr("rotate"))
        pm.connectAttr(pb_node+".outTranslate", self.upv_mtx.attr("translate"))
        pm.connectAttr(self.auv_att, pb_node+".weight")

        # fk0 mtx parent constraint
        node = aop.gear_mulmatrix_op(self.fk0_roll_ctl.attr("worldMatrix"), self.fk0_mtx.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(node+".output", dm_node+".inputMatrix")
        pm.connectAttr(dm_node+".outputTranslate", self.fk0_mtx.attr("translate"))
        pm.connectAttr(dm_node+".outputRotate", self.fk0_mtx.attr("rotate"))
        # fk1 loc to fk1 ref parent constraint
        node = aop.gear_mulmatrix_op(self.fk1_ref.attr("worldMatrix"), self.fk1_loc.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(node+".output", dm_node+".inputMatrix")
        pm.connectAttr(dm_node+".outputTranslate", self.fk1_loc.attr("translate"))
        pm.connectAttr(dm_node+".outputRotate", self.fk1_loc.attr("rotate"))
        # fk1 mtx orient cns to fk1 roll
        pm.connectAttr(self.fk1_roll_ctl.attr("rotate"), self.fk1_mtx.attr("rotate"))
        # fk2_loc position constraint to effector------------------------
        node = aop.gear_mulmatrix_op(self.eff_npo.attr("worldMatrix"), self.fk2_loc.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(node+".output", dm_node+".inputMatrix")
        pm.connectAttr(dm_node+".outputTranslate", self.fk2_loc.attr("translate"))
        # fk2_loc rotation constraint to bone1 ------------------------

        node = aop.gear_mulmatrix_op(self.bone1.attr("worldMatrix"), self.fk2_loc.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(node+".output", dm_node+".inputMatrix")
        pm.connectAttr(dm_node+".outputRotate", self.fk2_loc.attr("rotate"))


        # foot ikfk blending from fk ref to ik ref (serious bugfix)--------------------------------
        node = aop.gear_mulmatrix_op(self.fk_ref.attr("worldMatrix"), self.eff_loc.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pb_node = pm.createNode("pairBlend")
        pb_node.attr("rotInterpolation").set (1)
        pm.connectAttr(node+".output", dm_node+".inputMatrix")
        pm.connectAttr(dm_node+".outputRotate", pb_node+".inRotate1")
        pm.connectAttr(self.blend2_att, pb_node+".weight")
        pm.connectAttr(pb_node+".outRotate", self.eff_loc.attr("rotate"))
        node = aop.gear_mulmatrix_op(self.ik_ref.attr("worldMatrix"), self.eff_loc.attr("parentInverseMatrix"))
        dm_node1 = pm.createNode("decomposeMatrix")
        pm.connectAttr(node+".output", dm_node1+".inputMatrix")
        pm.connectAttr(dm_node1+".outputRotate", pb_node+".inRotate2")
        # use blendcolors to blend scale
        bc_node = pm.createNode("blendColors")
        pm.connectAttr(self.blend_att, bc_node+".blender")
        pm.connectAttr(dm_node+".outputScale", bc_node+".color2")
        pm.connectAttr(dm_node1+".outputScale", bc_node+".color1")
        pm.connectAttr(bc_node+".output", self.eff_loc.attr("scale"))

        # Twist references ---------------------------------
        pm.connectAttr(self.mid_ctl.attr("translate"), self.tws1_npo.attr("translate"))
        pm.connectAttr(self.mid_ctl.attr("rotate"), self.tws1_npo.attr("rotate"))
        pm.connectAttr(self.mid_ctl.attr("scale"), self.tws1_npo.attr("scale"))


        node = aop.gear_mulmatrix_op(self.eff_loc.attr("worldMatrix"), self.tws3_npo.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(node+".output", dm_node+".inputMatrix")
        pm.connectAttr(dm_node+".outputTranslate", self.tws3_npo.attr("translate"))
        node = aop.gear_mulmatrix_op(self.bone1.attr("worldMatrix"), self.tws3_npo.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(node+".output", dm_node+".inputMatrix")
        pm.connectAttr(dm_node+".outputRotate", self.tws3_npo.attr("rotate"))

        node = aop.gear_mulmatrix_op(self.tws_ref.attr("worldMatrix"), self.tws3_rot.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(node+".output", dm_node+".inputMatrix")
        pm.connectAttr(dm_node+".outputRotate", self.tws3_rot.attr("rotate"))


        # knee thickness connection
        if self.negate:
            node = nod.createMulNode([self.knee_thickness_att,self.knee_thickness_att], [0.5,-0.5,0], [self.tws1_loc+".translateX",self.tws2_loc+".translateX"])
        else:
            node = nod.createMulNode([self.knee_thickness_att,self.knee_thickness_att], [-0.5,0.5,0], [self.tws1_loc+".translateX",self.tws2_loc+".translateX"])

        # connect both tws1 and tws2  (mid tws)
        self.tws0_rot.setAttr("sx", .001)
        self.tws3_rot.setAttr("sx", .001)

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

        add_node = nod.createAddNode(self.roundness1_att, .001)
        pm.connectAttr(add_node+".output", self.tws2_rot.attr("sx"))

        #Roll Shoulder--use aimconstraint withour uovwctor to solve the stable twist

        if self.negate:
            node = aop.aimCns(self.tws0_loc, self.mid_ctl, axis="-xy", wupType=4, wupVector=[0,1,0], wupObject=self.tws0_npo, maintainOffset=False)
        else:
            node = aop.aimCns(self.tws0_loc, self.mid_ctl, axis="xy", wupType=4, wupVector=[0,1,0], wupObject=self.tws0_npo, maintainOffset=False)


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

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

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

        # Divisions ----------------------------------------
        # div mid constraint to mid ctl
        node = aop.gear_mulmatrix_op(self.mid_ctl.attr("worldMatrix"), self.div_mid.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(node+".output", dm_node+".inputMatrix")
        pm.connectAttr(dm_node+".outputTranslate", self.div_mid.attr("translate"))
        pm.connectAttr(dm_node+".outputRotate", self.div_mid.attr("rotate"))

        # at 0 or 1 the division will follow exactly the rotation of the controler.. and we wont have this nice tangent + roll
        scl_1_perc = []
        scl_2_perc = []

        for i, div_cnsUp in enumerate(self.div_cnsUp):

            if i < (self.settings["div0"]+1):
                perc = i/ (self.settings["div0"]+1.0)
            elif i < (self.settings["div0"] + 2):
                perc = .95

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

            # Roll
            if self.negate:
                node = aop.gear_rollsplinekine_op(div_cnsUp, [self.tws1_rot, self.tws0_rot], 1-perc, 20)

            else:
                node = aop.gear_rollsplinekine_op(div_cnsUp, [self.tws0_rot, self.tws1_rot], perc, 20)
            pm.connectAttr(self.resample_att, node+".resample")
            pm.connectAttr(self.absolute_att, node+".absolute")

            scl_1_perc.append(perc/2)
            scl_2_perc.append(perc)
        scl_1_perc.append(0.5)
        scl_2_perc.append(1)
        for i, div_cnsDn in enumerate(self.div_cnsDn):

            if i == (0):
                perc = .05
            elif i < (self.settings["div1"]+1):
                perc = i/ (self.settings["div1"]+1.0)
            elif i < (self.settings["div1"] + 2):
                perc = .95

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

            # Roll
            if self.negate:
                node = aop.gear_rollsplinekine_op(div_cnsDn, [self.tws3_rot, self.tws2_rot], 1-perc, 20)

            else:
                node = aop.gear_rollsplinekine_op(div_cnsDn, [self.tws2_rot, self.tws3_rot], perc, 20)
            pm.connectAttr(self.resample_att, node+".resample")
            pm.connectAttr(self.absolute_att, node+".absolute")

            scl_1_perc.append(perc/2+0.5)
            scl_2_perc.append(1-perc)
        # Squash n Stretch
        for i, div_cns in enumerate(self.div_cns):
            node = aop.gear_squashstretch2_op(div_cns, None, pm.getAttr(self.volDriver_att), "x")
            pm.connectAttr(self.volume_att, node+".blend")
            pm.connectAttr(self.volDriver_att, node+".driver")
            pm.connectAttr(self.st_att[i], node+".stretch")
            pm.connectAttr(self.sq_att[i], node+".squash")
            # get the first mult_node after sq op
            mult_node = pm.listHistory(node, future=True )[1]
            # linear blend effector scale
            bc_node = pm.createNode("blendColors")
            bc_node.setAttr("color2R", 1)
            bc_node.setAttr("color2G", 1)
            bc_node.setAttr("blender", scl_1_perc[i])
            pm.connectAttr(self.eff_loc.attr("scale"), bc_node+".color1")
            # linear blend mid scale
            bc_node2 = pm.createNode("blendColors")
            bc_node2.setAttr("color2R", 1)
            bc_node2.setAttr("color2G", 1)
            bc_node2.setAttr("blender", scl_2_perc[i])
            pm.connectAttr(self.mid_ctl.attr("scale"), bc_node2+".color1")
            # mid_ctl scale * effector scale
            mult_node2 = pm.createNode("multiplyDivide")
            pm.connectAttr(bc_node2+".output", mult_node2+".input1")
            pm.connectAttr(bc_node+".output", mult_node2+".input2")
            # plug to sq scale
            pm.connectAttr(mult_node2+".output", mult_node+".input2")

        # match IK/FK ref
        pm.connectAttr(self.bone0.attr("rotate"), self.match_fk0.attr("rotate"))
        pm.connectAttr(self.bone0.attr("translate"), self.match_fk0.attr("translate"))
        pm.connectAttr(self.bone1.attr("rotate"), self.match_fk1.attr("rotate"))
        pm.connectAttr(self.bone1.attr("translate"), self.match_fk1.attr("translate"))

        return
Пример #10
0
    def addOperators(self):

        # Visibilities -------------------------------------
        #shape.dispGeometry
        # fk
        fkvis_node = nod.createReverseNode(self.blend_att)
        
        for shp in self.fk0_ctl.getShapes():
            connectAttr(fkvis_node+".outputX", shp.attr("visibility"))
        for shp in self.fk1_ctl.getShapes():
            connectAttr(fkvis_node+".outputX", shp.attr("visibility"))
        for shp in self.fk2_ctl.getShapes():
            connectAttr(fkvis_node+".outputX", shp.attr("visibility"))

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

        # IK Solver -----------------------------------------
        out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc]
        node = aop.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)

        connectAttr(self.blend_att, node+".blend")
        connectAttr(self.roll_att, node+".roll")
        connectAttr(self.scale_att, node+".scaleA")
        connectAttr(self.scale_att, node+".scaleB")
        connectAttr(self.maxstretch_att, node+".maxstretch")
        connectAttr(self.slide_att, node+".slide")
        connectAttr(self.softness_att, node+".softness")
        connectAttr(self.reverse_att, node+".reverse")

        # Twist references ---------------------------------
        pointConstraint(self.root, self.tws0_loc, maintainOffset=True)
        cns = aop.aimCns(self.tws0_loc, self.mid_ctl, self.n_sign+"xz", 2, [-1,0,0], self.root, False)

        pointConstraint(self.mid_ctl, self.tws1_loc, maintainOffset=False)
        scaleConstraint(self.mid_ctl, self.tws1_loc, maintainOffset=False)
        orientConstraint(self.mid_ctl, self.tws1_rot, maintainOffset=False)

        pointConstraint(self.eff_loc, self.tws2_loc, maintainOffset=False)
        scaleConstraint(self.eff_loc, self.tws2_loc, maintainOffset=False)
        orientConstraint(self.bone1, self.tws2_loc, maintainOffset=False) 
        orientConstraint(self.tws_ref, self.tws2_rot, maintainOffset=False)
        # att.setRotOrder(self.tws2_rot, "YZX")

        self.tws0_loc.setAttr("sx", .001)
        self.tws2_loc.setAttr("sx", .001)

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

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

        # 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"]+1):
                perc = i*.5 / (self.settings["div0"]+1.0)
            else:
                perc = .5 + (i-self.settings["div0"]-1.0)*.5 / (self.settings["div1"]+1.0)

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

            # Roll
            if self.negate:
                node = aop.gear_rollsplinekine_op(div_cns, [self.tws2_rot, self.tws1_rot, self.tws0_rot], 1-perc)
            else:
                node = aop.gear_rollsplinekine_op(div_cns, [self.tws0_rot, self.tws1_rot, self.tws2_rot], perc)

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

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

        return
Пример #11
0
    def addOperators(self):

        if self.settings["ikSolver"]:
            self.ikSolver = "ikRPsolver"
        else:
            pm.mel.eval("ikSpringSolver;")
            self.ikSolver = "ikSpringSolver"

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

        # mid joints =====================================================================================
        for xjnt, midJ in zip(self.legBones[1:3],
                              [self.mid1_jnt, self.mid2_jnt]):
            nod.createPairBlend(None, xjnt, .5, 1, midJ)
            pm.connectAttr(xjnt + ".translate", midJ + ".translate", f=True)

        pm.parentConstraint(self.mid1_jnt, self.knee_lvl)
        pm.parentConstraint(self.mid2_jnt, self.ankle_lvl)

        #joint length multiply
        multJnt1_node = nod.createMulNode(self.boneALenght_attr,
                                          self.boneALenghtMult_attr)
        multJnt2_node = nod.createMulNode(self.boneBLenght_attr,
                                          self.boneBLenghtMult_attr)
        multJnt3_node = nod.createMulNode(self.boneCLenght_attr,
                                          self.boneCLenghtMult_attr)

        # # IK 3 bones ======================================================================================================

        self.ikHandle = pri.addIkHandle(self.softblendLoc,
                                        self.getName("ik3BonesHandle"),
                                        self.chain3bones, self.ikSolver,
                                        self.upv_ctl)

        # TwistTest
        if [
                round(elem, 4)
                for elem in tra.getTranslation(self.chain3bones[1])
        ] != [round(elem, 4) for elem in self.guide.apos[1]]:
            add_nodeTwist = nod.createAddNode(180.0, self.roll_att)
            # pm.connectAttr(add_nodeTwist+".output", self.ikHandle.attr("twist"))
        else:
            add_nodeTwist = nod.createAddNode(0, self.roll_att)
            # pm.connectAttr(self.roll_att, self.ikHandle.attr("twist"))
        if self.negate:
            mulVal = 1
        else:
            mulVal = -1
        nod.createMulNode(add_nodeTwist + ".output", mulVal,
                          self.ikHandle.attr("twist"))
        # pm.connectAttr(add_nodeTwist+".output", self.ikHandle.attr("twist"))

        # stable spring solver doble rotation
        pm.pointConstraint(self.root_ctl, self.chain3bones[0])

        # softIK 3 bones operators
        aop.aimCns(self.aim_tra,
                   self.ik_ref,
                   axis="zx",
                   wupType=4,
                   wupVector=[1, 0, 0],
                   wupObject=self.root_ctl,
                   maintainOffset=False)

        plusTotalLength_node = nod.createPlusMinusAverage1D([
            multJnt1_node.attr("outputX"),
            multJnt2_node.attr("outputX"),
            multJnt3_node.attr("outputX")
        ])
        subtract1_node = nod.createPlusMinusAverage1D(
            [plusTotalLength_node.attr("output1D"), self.soft_attr], 2)

        distance1_node = nod.createDistNode(self.ik_ref, self.aim_tra)
        div1_node = nod.createDivNode(1.0, self.rig.global_ctl + ".sx")
        mult1_node = nod.createMulNode(distance1_node + ".distance",
                                       div1_node + ".outputX")
        subtract2_node = nod.createPlusMinusAverage1D(
            [mult1_node.attr("outputX"),
             subtract1_node.attr("output1D")], 2)
        div2_node = nod.createDivNode(subtract2_node + ".output1D",
                                      self.soft_attr)
        mult2_node = nod.createMulNode(-1, div2_node + ".outputX")
        power_node = nod.createPowNode(self.softSpeed_attr,
                                       mult2_node + ".outputX")
        mult3_node = nod.createMulNode(self.soft_attr, power_node + ".outputX")
        subtract3_node = nod.createPlusMinusAverage1D([
            plusTotalLength_node.attr("output1D"),
            mult3_node.attr("outputX")
        ], 2)

        cond1_node = nod.createConditionNode(
            self.soft_attr, 0, 2, subtract3_node + ".output1D",
            plusTotalLength_node + ".output1D")
        cond2_node = nod.createConditionNode(mult1_node + ".outputX",
                                             subtract1_node + ".output1D", 2,
                                             cond1_node + ".outColorR",
                                             mult1_node + ".outputX")

        pm.connectAttr(cond2_node + ".outColorR", self.wristSoftIK + ".tz")

        #soft blend
        pc_node = pm.pointConstraint(self.wristSoftIK, self.ik_ref,
                                     self.softblendLoc)
        nod.createReverseNode(self.stretch_attr,
                              pc_node + ".target[0].targetWeight")
        pm.connectAttr(self.stretch_attr,
                       pc_node + ".target[1].targetWeight",
                       f=True)

        #Stretch
        distance2_node = nod.createDistNode(self.softblendLoc,
                                            self.wristSoftIK)
        mult4_node = nod.createMulNode(distance2_node + ".distance",
                                       div1_node + ".outputX")

        #bones
        for i, mulNode in enumerate(
            [multJnt1_node, multJnt2_node, multJnt3_node]):
            div3_node = nod.createDivNode(mulNode + ".outputX",
                                          plusTotalLength_node + ".output1D")
            mult5_node = nod.createMulNode(mult4_node + ".outputX",
                                           div3_node + ".outputX")
            mult6_node = nod.createMulNode(self.stretch_attr,
                                           mult5_node + ".outputX")
            nod.createPlusMinusAverage1D(
                [mulNode.attr("outputX"),
                 mult6_node.attr("outputX")], 1,
                self.chain3bones[i + 1] + ".tx")

        # IK 2 bones ======================================================================================================

        self.ikHandle2 = pri.addIkHandle(self.softblendLoc2,
                                         self.getName("ik2BonesHandle"),
                                         self.chain2bones, self.ikSolver,
                                         self.upv_ctl)

        nod.createMulNode(self.roll_att, mulVal, self.ikHandle2.attr("twist"))
        # pm.connectAttr(self.roll_att, self.ikHandle2.attr("twist"))

        # stable spring solver doble rotation
        pm.pointConstraint(self.root_ctl, self.chain2bones[0])

        parentc_node = pm.parentConstraint(self.ik2b_ikCtl_ref,
                                           self.ik2b_bone_ref, self.ik2b_blend)
        nod.createReverseNode(self.fullIK_attr,
                              parentc_node + ".target[0].targetWeight")
        pm.connectAttr(self.fullIK_attr,
                       parentc_node + ".target[1].targetWeight",
                       f=True)

        # softIK 2 bones operators
        aop.aimCns(self.aim_tra2,
                   self.ik2b_ik_ref,
                   axis="zx",
                   wupType=4,
                   wupVector=[1, 0, 0],
                   wupObject=self.root_ctl,
                   maintainOffset=False)

        plusTotalLength_node = nod.createPlusMinusAverage1D(
            [multJnt1_node.attr("outputX"),
             multJnt2_node.attr("outputX")])
        subtract1_node = nod.createPlusMinusAverage1D(
            [plusTotalLength_node.attr("output1D"), self.soft_attr], 2)
        distance1_node = nod.createDistNode(self.ik2b_ik_ref, self.aim_tra2)
        div1_node = nod.createDivNode(1, self.rig.global_ctl + ".sx")

        mult1_node = nod.createMulNode(distance1_node + ".distance",
                                       div1_node + ".outputX")
        subtract2_node = nod.createPlusMinusAverage1D(
            [mult1_node.attr("outputX"),
             subtract1_node.attr("output1D")], 2)
        div2_node = nod.createDivNode(subtract2_node + ".output1D",
                                      self.soft_attr)
        mult2_node = nod.createMulNode(-1, div2_node + ".outputX")
        power_node = nod.createPowNode(self.softSpeed_attr,
                                       mult2_node + ".outputX")
        mult3_node = nod.createMulNode(self.soft_attr, power_node + ".outputX")
        subtract3_node = nod.createPlusMinusAverage1D([
            plusTotalLength_node.attr("output1D"),
            mult3_node.attr("outputX")
        ], 2)

        cond1_node = nod.createConditionNode(
            self.soft_attr, 0, 2, subtract3_node + ".output1D",
            plusTotalLength_node + ".output1D")
        cond2_node = nod.createConditionNode(mult1_node + ".outputX",
                                             subtract1_node + ".output1D", 2,
                                             cond1_node + ".outColorR",
                                             mult1_node + ".outputX")

        pm.connectAttr(cond2_node + ".outColorR", self.ankleSoftIK + ".tz")

        #soft blend
        pc_node = pm.pointConstraint(self.ankleSoftIK, self.ik2b_ik_ref,
                                     self.softblendLoc2)
        nod.createReverseNode(self.stretch_attr,
                              pc_node + ".target[0].targetWeight")
        pm.connectAttr(self.stretch_attr,
                       pc_node + ".target[1].targetWeight",
                       f=True)

        #Stretch
        distance2_node = nod.createDistNode(self.softblendLoc2,
                                            self.ankleSoftIK)
        mult4_node = nod.createMulNode(distance2_node + ".distance",
                                       div1_node + ".outputX")

        for i, mulNode in enumerate([multJnt1_node, multJnt2_node]):
            div3_node = nod.createDivNode(mulNode + ".outputX",
                                          plusTotalLength_node + ".output1D")
            mult5_node = nod.createMulNode(mult4_node + ".outputX",
                                           div3_node + ".outputX")
            mult6_node = nod.createMulNode(self.stretch_attr,
                                           mult5_node + ".outputX")
            nod.createPlusMinusAverage1D(
                [mulNode.attr("outputX"),
                 mult6_node.attr("outputX")], 1,
                self.chain2bones[i + 1] + ".tx")

        ###  IK/FK connections

        for i, x in enumerate(self.fk_ctl):
            pm.parentConstraint(x, self.legBonesFK[i], mo=True)

        for i, x in enumerate([self.chain2bones[0], self.chain2bones[1]]):
            pm.parentConstraint(x, self.legBonesIK[i], mo=True)

        pm.pointConstraint(self.ik2b_ik_ref, self.legBonesIK[2])
        aop.aimCns(self.legBonesIK[2],
                   self.roll_ctl,
                   axis="xy",
                   wupType=4,
                   wupVector=[0, 1, 0],
                   wupObject=self.legBonesIK[1],
                   maintainOffset=False)
        pm.connectAttr(self.chain3bones[-1].attr("tx"),
                       self.legBonesIK[-1].attr("tx"))
        # foot twist roll
        pm.orientConstraint(self.ik_ref, self.legBonesIK[-1], mo=True)

        nod.createMulNode(-1, self.chain3bones[-1].attr("tx"),
                          self.ik2b_ik_ref.attr("tx"))

        for i, x in enumerate(self.legBones):
            nod.createPairBlend(self.legBonesFK[i], self.legBonesIK[i],
                                self.blend_att, 1, x)

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

        self.ikhArmRef, self.tmpCrv = aop.splineIK(self.getName("legRollRef"),
                                                   self.rollRef,
                                                   parent=self.root,
                                                   cParent=self.legBones[0])

        initRound = .001
        multVal = 1

        multTangent_node = nod.createMulNode(self.roundnessKnee_att, multVal)
        add_node = nod.createAddNode(multTangent_node + ".outputX", initRound)
        pm.connectAttr(add_node + ".output", self.tws1_rot.attr("sx"))
        for x in ["translate"]:
            pm.connectAttr(self.knee_ctl.attr(x), self.tws1_loc.attr(x))
        for x in "xy":
            pm.connectAttr(self.knee_ctl.attr("r" + x),
                           self.tws1_loc.attr("r" + x))

        multTangent_node = nod.createMulNode(self.roundnessAnkle_att, multVal)
        add_node = nod.createAddNode(multTangent_node + ".outputX", initRound)
        pm.connectAttr(add_node + ".output", self.tws2_rot.attr("sx"))
        for x in ["translate"]:
            pm.connectAttr(self.ankle_ctl.attr(x), self.tws2_loc.attr(x))
        for x in "xy":
            pm.connectAttr(self.ankle_ctl.attr("r" + x),
                           self.tws2_loc.attr("r" + x))

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

        #comp scaling
        dm_node = nod.createDecomposeMatrixNode(self.root.attr("worldMatrix"))

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

        self.volDriver_att = div_node2 + ".outputX"

        # Flip Offset ----------------------------------------
        pm.connectAttr(self.ankleFlipOffset_att, self.tws2_loc.attr("rz"))
        pm.connectAttr(self.kneeFlipOffset_att, self.tws1_loc.attr("rz"))
        # 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):
            subdiv = False
            if i == len(self.div_cns) - 1 or i == 0:
                subdiv = 45
            else:
                subdiv = 45

            if i < (self.settings["div0"] + 1):
                perc = i * .333 / (self.settings["div0"] + 1.0)

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

            if i < (self.settings["div0"] + 2):
                perc = i * .333 / (self.settings["div0"] + 1.0)

            elif i < (self.settings["div0"] + self.settings["div1"] + 3):
                perc = .333 + (i - self.settings["div0"] -
                               1) * .333 / (self.settings["div1"] + 1.0)
            else:
                perc = .666 + (i - self.settings["div1"] -
                               self.settings["div0"] -
                               2.0) * .333 / (self.settings["div2"] + 1.0)

            # we neet to offset the ankle and knee point to force the bone orientation to the nex bone span
            if perc == .333:
                perc = .3338
            elif perc == .666:
                perc = .6669

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

            # Roll
            node = aop.gear_rollsplinekine_op(
                div_cns,
                [self.tws0_rot, self.tws1_rot, self.tws2_rot, self.tws3_rot],
                perc, subdiv)

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

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

        # Visibilities -------------------------------------
        # fk
        fkvis_node = nod.createReverseNode(self.blend_att)
        for ctrl in self.fk_ctl:
            for shp in ctrl.getShapes():
                pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))
        # ik
        for ctrl in [self.ik_ctl, self.roll_ctl]:
            for shp in ctrl.getShapes():
                pm.connectAttr(self.blend_att, shp.attr("visibility"))

        # setup leg node scale compensate
        pm.connectAttr(self.rig.global_ctl + ".scale", self.setup + ".scale")

        return
Пример #12
0
    def addOperators(self):

        # Tangent position ---------------------------------
        # common part
        d = vec.getDistance(self.guide.pos["root"], self.guide.pos["neck"])
        dist_node = nod.createDistNode(self.root, self.ik_ctl)
        rootWorld_node = nod.createDecomposeMatrixNode(self.root.attr("worldMatrix"))
        div_node = nod.createDivNode(dist_node+".distance", rootWorld_node+".outputScaleX")
        div_node = nod.createDivNode(div_node+".outputX", d)

        # tan0
        mul_node = nod.createMulNode(self.tan0_att, self.tan0_loc.getAttr("ty"))
        res_node = nod.createMulNode(mul_node+".outputX", div_node+".outputX")
        connectAttr( res_node+".outputX", self.tan0_loc+".ty")

        # tan1
        mul_node = nod.createMulNode(self.tan1_att, self.tan1_loc.getAttr("ty"))
        res_node = nod.createMulNode(mul_node+".outputX", div_node+".outputX")
        connectAttr( res_node+".outputX", self.tan1_loc.attr("ty"))

        # Curves -------------------------------------------
        op = aop.gear_curveslide2_op(self.slv_crv, self.mst_crv, 0, 1.5, .5, .5)
        connectAttr(self.maxstretch_att, op+".maxstretch")
        connectAttr(self.maxsquash_att, op+".maxsquash")
        connectAttr(self.softness_att, op+".softness")

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

        # Division -----------------------------------------
        for i in range(self.settings["division"]):

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

            cns = aop.pathCns(self.div_cns[i], self.slv_crv, False, u, True)
            cns.setAttr("frontAxis", 1)# front axis is 'Y'
            cns.setAttr("upAxis", 2)# front axis is 'Z'

            # Roll
            aop.gear_spinePointAtOp(cns, self.root, self.ik_ctl, u, "Z")

            # Squash n Stretch
            op = aop.gear_squashstretch2_op(self.fk_npo[i], self.root, arclen(self.slv_crv), "y")
            connectAttr(self.volume_att, op+".blend")
            connectAttr(crv_node+".arcLength", op+".driver")
            connectAttr(self.st_att[i], op+".stretch")
            connectAttr(self.sq_att[i], op+".squash")

            # scl compas
            if i != 0:
                div_node = nod.createDivNode([1,1,1], [self.fk_npo[i-1]+".sx", self.fk_npo[i-1]+".sy", self.fk_npo[i-1]+".sz"])
                connectAttr(div_node+".output", self.scl_npo[i]+".scale")

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

            dm_node = nod.createDecomposeMatrixNode(mulmat_node+".output")
            connectAttr(dm_node+".outputTranslate", self.fk_npo[i].attr("t"))
            connectAttr(dm_node+".outputRotate", self.fk_npo[i].attr("r"))
            #connectAttr(dm_node+".outputScale", self.fk_npo[i].attr("s"))

            # Orientation Lock
            if i == self.settings["division"] - 1 :
                dm_node = nod.createDecomposeMatrixNode(self.ik_ctl+".worldMatrix")
                blend_node = nod.createBlendNode([dm_node+".outputRotate%s"%s for s in "XYZ"], [cns+".rotate%s"%s for s in "XYZ"], self.lock_ori_att)
                self.div_cns[i].attr("rotate").disconnect()
                connectAttr(blend_node+".output", self.div_cns[i]+".rotate")


        # Head ---------------------------------------------
        self.fk_ctl[-1].addChild(self.head_cns)