def addObjects(self):
        """Add all the objects needed to create the component."""

        if self.settings["neutralRotation"]:
            t = transform.getTransformFromPos(self.guide.pos["root"])
        else:
            t = self.guide.tra["root"]
            if self.settings["mirrorBehaviour"] and self.negate:
                scl = [1, 1, -1]
            else:
                scl = [1, 1, 1]
            t = transform.setMatrixScale(t, scl)

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

        self.SDKctl = self.addCtl(
            self.ik_cns,
            "SDK_ctl",
            t,
            self.color_ik,
            "cube",
            w=self.settings["ctlSize"] * self.size * 1.35,
            h=self.settings["ctlSize"] * self.size * 0.75,
            d=self.settings["ctlSize"] * self.size * 0.75,
            tp=self.parentCtlTag)

        self.ctl = self.addCtl(self.SDKctl,
                               "ctl",
                               t,
                               self.color_fk,
                               "sphere",
                               w=self.settings["ctlSize"] * self.size,
                               h=self.settings["ctlSize"] * self.size,
                               d=self.settings["ctlSize"] * self.size,
                               tp=self.parentCtlTag)

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

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

        if self.settings["joint"]:
            self.jnt_pos.append([self.ctl, 0, None, self.settings["uniScale"]])
Exemple #2
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

        if self.settings["neutralRotation"]:
            t = transform.getTransformFromPos(self.guide.pos["root"])
        else:
            t = self.guide.tra["root"]
            if self._needToMirror():
                scl = [1, 1, 1]
                scl[0] = -1 if self.settings["mirrorAxisX"] else 1
                scl[1] = -1 if self.settings["mirrorAxisY"] else 1
                scl[2] = -1 if self.settings["mirrorAxisZ"] else 1
                t = transform.setMatrixScale(t, scl)

                rx = self.settings["mirrorAxisX"] * math.pi
                ry = self.settings["mirrorAxisY"] * math.pi
                rz = self.settings["mirrorAxisZ"] * math.pi
                # t = pm.datatypes.TransformationMatrix(t)
                # t.addRotation((rx, ry, rz), 'XYZ', 'object')

            else:
                scl = [1, 1, 1]
                t = transform.setMatrixScale(t, scl)

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

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

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

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

        if self.settings["joint"]:
            self.jnt_pos.append([self.ctl, 0, None, self.settings["uniScale"]])
Exemple #3
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

        if self.settings["neutralRotation"]:
            t = transform.getTransformFromPos(self.guide.pos["root"])
        else:
            t = self.guide.tra["root"]
            if self.settings["mirrorBehaviour"] and self.negate:
                scl = [1, 1, -1]
            else:
                scl = [1, 1, 1]
            t = transform.setMatrixScale(t, scl)
        if self.settings["joint"] and self.settings["leafJoint"]:
            pm.displayInfo("Skipping ctl creation, just leaf joint")
            self.have_ctl = False
        else:
            self.have_ctl = True
            self.ik_cns = primitive.addTransform(self.root,
                                                 self.getName("ik_cns"), t)

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

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

            params = [
                s for s in
                ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx", "sy", "sz"]
                if self.settings["k_" + s]
            ]
            attribute.setKeyableAttributes(self.ctl, params)
        if self.settings["joint"]:
            # TODO WIP: add new attr for seeting leaf joint + not build objcts
            if self.settings["leafJoint"]:
                self.jnt_pos.append([t, 0, None, self.settings["uniScale"]])
            else:
                self.jnt_pos.append(
                    [self.ctl, 0, None, self.settings["uniScale"]])
Exemple #4
0
    def initialHierarchy(self):
        """Build the initial hierarchy of the rig.

        Create the rig model, the main properties,
        and a couple of base organisation nulls.
        Get the global size of the rig.

        """
        mgear.log("Initial Hierarchy")

        # --------------------------------------------------
        # Model
        self.model = primitive.addTransformFromPos(None,
                                                   self.options["rig_name"])
        attribute.lockAttribute(self.model)

        # --------------------------------------------------
        # INFOS
        self.isRig_att = attribute.addAttribute(self.model, "is_rig", "bool",
                                                True)
        self.rigName_att = attribute.addAttribute(self.model, "rig_name",
                                                  "string",
                                                  self.options["rig_name"])
        self.user_att = attribute.addAttribute(self.model, "user", "string",
                                               getpass.getuser())
        self.isWip_att = attribute.addAttribute(self.model, "wip", "bool",
                                                self.options["mode"] != 0)
        self.date_att = attribute.addAttribute(self.model, "date", "string",
                                               str(datetime.datetime.now()))
        self.mayaVersion_att = attribute.addAttribute(
            self.model, "maya_version", "string",
            str(pm.mel.eval("getApplicationVersionAsFloat")))
        self.gearVersion_att = attribute.addAttribute(self.model,
                                                      "gear_version", "string",
                                                      mgear.getVersion())
        self.synoptic_att = attribute.addAttribute(
            self.model, "synoptic", "string", str(self.options["synoptic"]))
        self.comments_att = attribute.addAttribute(
            self.model, "comments", "string", str(self.options["comments"]))
        self.ctlVis_att = attribute.addAttribute(self.model, "ctl_vis", "bool",
                                                 True)
        if versions.current() >= 201650:
            self.ctlVisPlayback_att = attribute.addAttribute(
                self.model, "ctl_vis_on_playback", "bool", True)
        self.jntVis_att = attribute.addAttribute(self.model, "jnt_vis", "bool",
                                                 True)

        self.qsA_att = attribute.addAttribute(self.model, "quickselA",
                                              "string", "")
        self.qsB_att = attribute.addAttribute(self.model, "quickselB",
                                              "string", "")
        self.qsC_att = attribute.addAttribute(self.model, "quickselC",
                                              "string", "")
        self.qsD_att = attribute.addAttribute(self.model, "quickselD",
                                              "string", "")
        self.qsE_att = attribute.addAttribute(self.model, "quickselE",
                                              "string", "")
        self.qsF_att = attribute.addAttribute(self.model, "quickselF",
                                              "string", "")

        self.rigGroups = self.model.addAttr("rigGroups", at='message', m=1)
        self.rigPoses = self.model.addAttr("rigPoses", at='message', m=1)
        self.rigCtlTags = self.model.addAttr("rigCtlTags", at='message', m=1)
        self.rigScriptNodes = self.model.addAttr("rigScriptNodes",
                                                 at='message',
                                                 m=1)

        # ------------------------- -------------------------
        # Global Ctl
        if self.options["worldCtl"]:
            if self.options["world_ctl_name"]:
                name = self.options["world_ctl_name"]
            else:
                name = "world_ctl"

            icon_shape = "circle"

        else:
            name = "global_C0_ctl"
            icon_shape = "crossarrow"

        self.global_ctl = self.addCtl(self.model,
                                      name,
                                      datatypes.Matrix(),
                                      self.options["C_color_fk"],
                                      icon_shape,
                                      w=10)
        attribute.setRotOrder(self.global_ctl, "ZXY")

        # Connect global visibility
        pm.connectAttr(self.ctlVis_att, self.global_ctl.attr("visibility"))
        if versions.current() >= 201650:
            pm.connectAttr(self.ctlVisPlayback_att,
                           self.global_ctl.attr("hideOnPlayback"))
        attribute.lockAttribute(self.global_ctl, ['v'])

        # --------------------------------------------------
        # Setup in world Space
        self.setupWS = primitive.addTransformFromPos(self.model, "setup")
        attribute.lockAttribute(self.setupWS)
        # --------------------------------------------------
        # Basic set of null
        if self.options["joint_rig"]:
            self.jnt_org = primitive.addTransformFromPos(self.model, "jnt_org")
            pm.connectAttr(self.jntVis_att, self.jnt_org.attr("visibility"))
Exemple #5
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

        self.WIP = self.options["mode"]
        self.up_axis = pm.upAxis(q=True, axis=True)

        self.normal = self.getNormalFromPos(self.guide.apos)

        self.length0 = vector.getDistance(
            self.guide.apos[0], self.guide.apos[1])
        self.length1 = vector.getDistance(
            self.guide.apos[1], self.guide.apos[2])
        self.length2 = vector.getDistance(
            self.guide.apos[2], self.guide.apos[3])

        # 1 bone chain for upv ref
        self.legChainUpvRef = primitive.add2DChain(
            self.root,
            self.getName("legUpvRef%s_jnt"),
            [self.guide.apos[0], self.guide.apos[2]],
            self.normal,
            False,
            self.WIP)

        self.legChainUpvRef[1].setAttr(
            "jointOrientZ",
            self.legChainUpvRef[1].getAttr("jointOrientZ") * -1)

        # extra neutral pose
        t = transform.getTransformFromPos(self.guide.apos[0])

        self.root_npo = primitive.addTransform(self.root,
                                               self.getName("root_npo"),
                                               t)
        self.root_ctl = self.addCtl(self.root_npo,
                                    "root_ctl",
                                    t,
                                    self.color_fk,
                                    "circle",
                                    w=self.length0 / 6,
                                    tp=self.parentCtlTag)

        # FK Controlers -----------------------------------
        t = transform.getTransformLookingAt(self.guide.apos[0],
                                            self.guide.apos[1],
                                            self.normal,
                                            "xz",
                                            self.negate)
        if self.settings["FK_rest_T_Pose"]:
            if self.negate:
                x_dir = 1
            else:
                x_dir = -1

            if self.up_axis == "y":
                x = datatypes.Vector(0, x_dir, 0)
            else:
                x = datatypes.Vector(0, 0, x_dir)
            z = datatypes.Vector(-1, 0, 0)

            t_npo = transform.getRotationFromAxis(x, z, "xz", False)
            t_npo = transform.setMatrixPosition(t_npo, self.guide.apos[0])
        else:
            t_npo = t

        self.fk0_npo = primitive.addTransform(self.root_ctl,
                                              self.getName("fk0_npo"),
                                              t_npo)
        po_vec = datatypes.Vector(.5 * self.length0 * self.n_factor, 0, 0)
        self.fk0_ctl = self.addCtl(self.fk0_npo,
                                   "fk0_ctl",
                                   t,
                                   self.color_fk,
                                   "cube",
                                   w=self.length0,
                                   h=self.size * .1,
                                   d=self.size * .1,
                                   po=po_vec,
                                   tp=self.root_ctl)
        attribute.setKeyableAttributes(
            self.fk0_ctl, ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"])

        t = transform.getTransformLookingAt(self.guide.apos[1],
                                            self.guide.apos[2],
                                            self.normal,
                                            "xz",
                                            self.negate)

        if self.settings["FK_rest_T_Pose"]:
            t_npo = transform.setMatrixPosition(
                transform.getTransform(self.fk0_ctl), self.guide.apos[1])
        else:
            t_npo = t

        self.fk1_npo = primitive.addTransform(
            self.fk0_ctl, self.getName("fk1_npo"), t_npo)

        po_vec = datatypes.Vector(.5 * self.length1 * self.n_factor, 0, 0)
        self.fk1_ctl = self.addCtl(self.fk1_npo,
                                   "fk1_ctl",
                                   t,
                                   self.color_fk,
                                   "cube",
                                   w=self.length1,
                                   h=self.size * .1,
                                   d=self.size * .1,
                                   po=po_vec,
                                   tp=self.fk0_ctl)

        attribute.setKeyableAttributes(
            self.fk1_ctl, ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"])

        t = transform.getTransformLookingAt(self.guide.apos[2],
                                            self.guide.apos[3],
                                            self.normal,
                                            "xz",
                                            self.negate)
        if self.settings["FK_rest_T_Pose"]:
            t_npo = transform.setMatrixPosition(
                transform.getTransform(self.fk0_ctl), self.guide.apos[2])
        else:
            t_npo = t

        self.fk2_npo = primitive.addTransform(
            self.fk1_ctl, self.getName("fk2_npo"), t_npo)

        if self.settings["FK_rest_T_Pose"]:
            self.fk2_npo.rz.set(90)

        po_vec = datatypes.Vector(.5 * self.length2 * self.n_factor, 0, 0)
        self.fk2_ctl = self.addCtl(self.fk2_npo,
                                   "fk2_ctl",
                                   t,
                                   self.color_fk,
                                   "cube",
                                   w=self.length2,
                                   h=self.size * .1,
                                   d=self.size * .1,
                                   po=po_vec,
                                   tp=self.fk1_ctl)
        attribute.setKeyableAttributes(self.fk2_ctl)

        self.fk_ctl = [self.fk0_ctl, self.fk1_ctl, self.fk2_ctl]

        for x in self.fk_ctl:
            attribute.setInvertMirror(x, ["tx", "ty", "tz"])

        # IK Controlers -----------------------------------

        self.ik_cns = primitive.addTransformFromPos(self.root_ctl,
                                                    self.getName("ik_cns"),
                                                    self.guide.pos["ankle"])

        self.ikcns_ctl = self.addCtl(
            self.ik_cns,
            "ikcns_ctl",
            transform.getTransformFromPos(self.guide.pos["ankle"]),
            self.color_ik,
            "null",
            w=self.size * .12,
            tp=self.root_ctl)
        attribute.setInvertMirror(self.ikcns_ctl, ["tx"])

        # m = transform.getTransformLookingAt(self.guide.pos["ankle"],
        #                                     self.guide.pos["eff"],
        #                                     self.x_axis,
        #                                     "zx",
        #                                     False)
        # if self.settings["FK_rest_T_Pose"]:
        #     t_ik = transform.getTransformLookingAt(self.guide.pos["ankle"],
        #                                            self.guide.pos["eff"],
        #                                            self.normal * -1,
        #                                            "zx",
        #                                            False)
        # else:
        t_ik = transform.getTransformFromPos(self.guide.pos["ankle"])

        self.ik_ctl = self.addCtl(
            self.ikcns_ctl,
            "ik_ctl",
            t_ik,
            self.color_ik,
            "cube",
            w=self.size * .12,
            h=self.size * .12,
            d=self.size * .12)
        attribute.setKeyableAttributes(self.ik_ctl)
        attribute.setRotOrder(self.ik_ctl, "XZY")
        attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"])

        # upv
        v = self.guide.apos[2] - self.guide.apos[0]
        v = self.normal ^ v
        v.normalize()
        v *= self.size * .5
        v += self.guide.apos[1]

        self.upv_cns = primitive.addTransformFromPos(self.ik_ctl,
                                                     self.getName("upv_cns"),
                                                     v)

        self.upv_ctl = self.addCtl(
            self.upv_cns,
            "upv_ctl",
            transform.getTransform(self.upv_cns),
            self.color_ik,
            "diamond",
            w=self.size * .12,
            tp=self.root_ctl)

        self.add_controller_tag(self.ik_ctl, self.upv_ctl)
        if self.settings["mirrorMid"]:
            if self.negate:
                self.upv_cns.rz.set(180)
                self.upv_cns.sy.set(-1)
        else:
            attribute.setInvertMirror(self.upv_ctl, ["tx"])
        attribute.setKeyableAttributes(self.upv_ctl, self.t_params)

        # References --------------------------------------
        self.ik_ref = primitive.addTransform(
            self.ik_ctl,
            self.getName("ik_ref"),
            transform.getTransform(self.ik_ctl))
        self.fk_ref = primitive.addTransform(
            self.fk_ctl[2],
            self.getName("fk_ref"),
            transform.getTransform(self.ik_ctl))

        # Chain --------------------------------------------
        # The outputs of the ikfk2bone solver
        self.bone0 = primitive.addLocator(
            self.root_ctl,
            self.getName("0_bone"),
            transform.getTransform(self.fk_ctl[0]))

        self.bone0_shp = self.bone0.getShape()
        self.bone0_shp.setAttr("localPositionX", self.n_factor * .5)
        self.bone0_shp.setAttr("localScale", .5, 0, 0)
        self.bone0.setAttr("sx", self.length0)
        self.bone0.setAttr("visibility", False)

        self.bone1 = primitive.addLocator(
            self.root_ctl,
            self.getName("1_bone"),
            transform.getTransform(self.fk_ctl[1]))
        self.bone1_shp = self.bone1.getShape()
        self.bone1_shp.setAttr("localPositionX", self.n_factor * .5)
        self.bone1_shp.setAttr("localScale", .5, 0, 0)
        self.bone1.setAttr("sx", self.length1)
        self.bone1.setAttr("visibility", False)

        self.ctrn_loc = primitive.addTransformFromPos(self.root_ctl,
                                                      self.getName("ctrn_loc"),
                                                      self.guide.apos[1])
        self.eff_loc = primitive.addTransformFromPos(self.root_ctl,
                                                     self.getName("eff_loc"),
                                                     self.guide.apos[2])

        # tws_ref
        t = transform.getRotationFromAxis(
            datatypes.Vector(0, -1, 0), self.normal, "xz", self.negate)
        t = transform.setMatrixPosition(t, self.guide.pos["ankle"])

        # addind an npo parent transform to fix flip in Maya 2018.2
        self.tws_npo = primitive.addTransform(
            self.eff_loc, self.getName("tws_npo"), t)

        self.tws_ref = primitive.addTransform(
            self.tws_npo, self.getName("tws_ref"), t)

        # Mid Controler ------------------------------------
        t = transform.getTransform(self.ctrn_loc)
        self.mid_cns = primitive.addTransform(
            self.ctrn_loc, self.getName("mid_cns"), t)
        self.mid_ctl = self.addCtl(self.mid_cns,
                                   "mid_ctl",
                                   t,
                                   self.color_ik,
                                   "sphere",
                                   w=self.size * .2,
                                   tp=self.root_ctl)

        attribute.setKeyableAttributes(self.mid_ctl,
                                       params=["tx", "ty", "tz",
                                               "ro", "rx", "ry", "rz",
                                               "sx"])

        if self.settings["mirrorMid"]:
            if self.negate:
                self.mid_cns.rz.set(180)
                self.mid_cns.sz.set(-1)
        else:
            attribute.setInvertMirror(self.mid_ctl, ["tx", "ty", "tz"])

        # Twist references ---------------------------------
        x = datatypes.Vector(0, -1, 0)
        x = x * transform.getTransform(self.eff_loc)
        z = datatypes.Vector(self.normal.x, self.normal.y, self.normal.z)
        z = z * transform.getTransform(self.eff_loc)

        m = transform.getRotationFromAxis(x, z, "xz", self.negate)
        m = transform.setMatrixPosition(
            m, transform.getTranslation(self.ik_ctl))

        self.rollRef = primitive.add2DChain(self.root,
                                            self.getName("rollChain"),
                                            self.guide.apos[:2],
                                            self.normal,
                                            self.negate,
                                            self.WIP)

        t = transform.getTransformLookingAt(self.guide.pos["base"],
                                            self.guide.apos[1],
                                            self.normal,
                                            "xz",
                                            self.negate)
        self.tws0_loc = primitive.addTransform(
            self.root_ctl,
            self.getName("tws0_loc"),
            t)

        self.tws0_rot = primitive.addTransform(
            self.tws0_loc,
            self.getName("tws0_rot"),
            t)

        self.tws1_loc = primitive.addTransform(
            self.ctrn_loc,
            self.getName("tws1_loc"),
            transform.getTransform(self.ctrn_loc))

        self.tws1_rot = primitive.addTransform(
            self.tws1_loc,
            self.getName("tws1_rot"),
            transform.getTransform(self.ctrn_loc))

        self.tws2_loc = primitive.addTransform(
            self.root_ctl,
            self.getName("tws2_loc"),
            transform.getTransform(self.tws_ref))

        self.tws2_rot = primitive.addTransform(
            self.tws2_loc,
            self.getName("tws2_rot"),
            transform.getTransform(self.tws_ref))

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

        # Divisions ----------------------------------------

        self.divisions = self.settings["div0"] + self.settings["div1"] + 2

        self.div_cns = []

        if self.settings["extraTweak"]:
            tagP = self.parentCtlTag
            self.tweak_ctl = []

        for i in range(self.divisions):

            div_cns = primitive.addTransform(self.root_ctl,
                                             self.getName("div%s_loc" % i))

            self.div_cns.append(div_cns)

            if self.settings["extraTweak"]:
                t = transform.getTransform(div_cns)
                tweak_ctl = self.addCtl(div_cns,
                                        "tweak%s_ctl" % i,
                                        t,
                                        self.color_fk,
                                        "square",
                                        w=self.size * .15,
                                        d=self.size * .15,
                                        ro=datatypes.Vector([0, 0, 1.5708]),
                                        tp=tagP)
                attribute.setKeyableAttributes(tweak_ctl)

                tagP = tweak_ctl
                self.tweak_ctl.append(tweak_ctl)
                driver = tweak_ctl
            else:
                driver = div_cns

            # setting the joints
            if i == 0:
                self.jnt_pos.append([driver, "thigh"])
                current_parent = "root"
                twist_name = "thigh_twist_"
                twist_idx = 1
                increment = 1
            elif i == self.settings["div0"] + 1:
                self.jnt_pos.append([driver, "calf", current_parent])
                twist_name = "calf_twist_"
                current_parent = "knee"
                twist_idx = self.settings["div1"]
                increment = -1
            else:
                self.jnt_pos.append(
                    [driver,
                     twist_name + str(twist_idx).zfill(2),
                     current_parent])
                twist_idx += increment

        # End reference ------------------------------------
        # To help the deformation on the ankle
        self.end_ref = primitive.addTransform(self.tws2_rot,
                                              self.getName("end_ref"), m)
        # set the offset rotation for the hand
        self.end_jnt_off = primitive.addTransform(self.end_ref,
                                                  self.getName("end_off"), m)
        if self.up_axis == "z":
            self.end_jnt_off.rz.set(-90)
        self.jnt_pos.append([self.end_jnt_off, 'foot', current_parent])

        # match IK FK references
        self.match_fk0_off = self.add_match_ref(self.fk_ctl[1],
                                                self.root,
                                                "matchFk0_npo",
                                                False)

        self.match_fk0 = self.add_match_ref(self.fk_ctl[0],
                                            self.match_fk0_off,
                                            "fk0_mth")

        self.match_fk1_off = self.add_match_ref(self.fk_ctl[2],
                                                self.root,
                                                "matchFk1_npo",
                                                False)

        self.match_fk1 = self.add_match_ref(self.fk_ctl[1],
                                            self.match_fk1_off,
                                            "fk1_mth")

        self.match_fk2 = self.add_match_ref(self.fk_ctl[2],
                                            self.ik_ctl,
                                            "fk2_mth")

        self.match_ik = self.add_match_ref(self.ik_ctl,
                                           self.fk2_ctl,
                                           "ik_mth")

        self.match_ikUpv = self.add_match_ref(self.upv_ctl,
                                              self.fk0_ctl,
                                              "upv_mth")

        # add visual reference
        self.line_ref = icon.connection_display_curve(
            self.getName("visalRef"), [self.upv_ctl, self.mid_ctl])
Exemple #6
0
    def addOperators(self):
        """Create operators and set the relations for the component rig

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return
Exemple #7
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

        self.div_count = len(self.guide.apos) - 5

        plane = [self.guide.apos[0], self.guide.apos[-4], self.guide.apos[-3]]
        self.normal = self.getNormalFromPos(plane)
        self.binormal = self.getBiNormalFromPos(plane)

        # Heel ---------------------------------------------
        # bank pivot
        # Aim the heel towards the first locator, but flat to the world.
        # So get the y component from itself.
        #TODO: Try to see if the self.normal and self.binormal can be used to do this more intelligently.
        heelLook = [
            self.guide.apos[-4][0], self.guide.pos["heel"][1],
            self.guide.apos[-4][2]
        ]
        t = transform.getTransformLookingAt(self.guide.pos["heel"], heelLook,
                                            self.normal, "xz", self.negate)

        t = transform.setMatrixPosition(t, self.guide.pos["inpivot"])

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

        self.in_piv = primitive.addTransform(self.in_npo,
                                             self.getName("in_piv"), t)

        t = transform.setMatrixPosition(t, self.guide.pos["outpivot"])

        self.out_piv = primitive.addTransform(self.in_piv,
                                              self.getName("out_piv"), t)

        # heel
        t = transform.getTransformLookingAt(self.guide.pos["heel"], heelLook,
                                            self.normal, "xz", self.negate)

        self.heel_loc = primitive.addTransform(self.out_piv,
                                               self.getName("heel_loc"), t)

        attribute.setRotOrder(self.heel_loc, "YZX")
        self.heel_ctl = self.addCtl(self.heel_loc,
                                    "heel_ctl",
                                    t,
                                    self.color_ik,
                                    "sphere",
                                    w=self.size * .1,
                                    tp=self.parentCtlTag)

        attribute.setKeyableAttributes(self.heel_ctl, self.r_params)

        # Tip ----------------------------------------------
        v = datatypes.Vector(self.guide.apos[-5].x, self.guide.apos[-1].y,
                             self.guide.apos[-5].z)
        t = transform.setMatrixPosition(t, v)
        self.tip_ctl = self.addCtl(self.heel_ctl,
                                   "tip_ctl",
                                   t,
                                   self.color_ik,
                                   "circle",
                                   w=self.size,
                                   tp=self.heel_ctl)
        attribute.setKeyableAttributes(self.tip_ctl, self.r_params)

        # Roll ---------------------------------------------
        if self.settings["useRollCtl"]:
            t = transform.getTransformLookingAt(self.guide.pos["heel"],
                                                heelLook, self.normal, "xz",
                                                self.negate)
            t = transform.setMatrixPosition(t, self.guide.pos["root"])

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

            self.roll_ctl = self.addCtl(self.roll_np,
                                        "roll_ctl",
                                        t,
                                        self.color_ik,
                                        "cylinder",
                                        w=self.size * .5,
                                        h=self.size * .5,
                                        ro=datatypes.Vector(3.1415 * .5, 0, 0),
                                        tp=self.tip_ctl)

            attribute.setKeyableAttributes(self.roll_ctl, ["rx", "rz"])

        # Backward Controlers ------------------------------
        bk_pos = self.guide.apos[1:-3]
        bk_pos.reverse()
        parent = self.tip_ctl
        self.bk_ctl = []
        self.bk_loc = []
        self.previousTag = self.tip_ctl
        for i, pos in enumerate(bk_pos):

            if i == 0:
                t = transform.getTransform(self.heel_ctl)
                t = transform.setMatrixPosition(t, pos)
            else:
                dir = bk_pos[i - 1]
                t = transform.getTransformLookingAt(pos, dir, self.normal,
                                                    "xz", self.negate)

            bk_loc = primitive.addTransform(parent,
                                            self.getName("bk%s_loc" % i), t)
            bk_ctl = self.addCtl(bk_loc,
                                 "bk%s_ctl" % i,
                                 t,
                                 self.color_ik,
                                 "sphere",
                                 w=self.size * .15,
                                 tp=self.previousTag)
            attribute.setKeyableAttributes(bk_ctl, self.r_params)
            self.previousTag = bk_ctl

            self.bk_loc.append(bk_loc)
            self.bk_ctl.append(bk_ctl)
            parent = bk_ctl

        # FK Reference ------------------------------------
        self.fk_ref = primitive.addTransformFromPos(self.bk_ctl[-1],
                                                    self.getName("fk_ref"),
                                                    self.guide.apos[0])
        self.fk_npo = primitive.addTransform(
            self.fk_ref, self.getName("fk0_npo"),
            transform.getTransform(self.bk_ctl[-1]))

        # Forward Controlers ------------------------------
        self.fk_ctl = []
        self.fk_loc = []
        parent = self.fk_npo
        self.previousTag = self.tip_ctl
        for i, bk_ctl in enumerate(reversed(self.bk_ctl[1:])):
            t = transform.getTransform(bk_ctl)
            dist = vector.getDistance(self.guide.apos[i + 1],
                                      self.guide.apos[i + 2])

            fk_loc = primitive.addTransform(parent,
                                            self.getName("fk%s_loc" % i), t)

            po_vec = datatypes.Vector(dist * .5 * self.n_factor, 0, 0)
            fk_ctl = self.addCtl(fk_loc,
                                 "fk%s_ctl" % i,
                                 t,
                                 self.color_fk,
                                 "cube",
                                 w=dist,
                                 h=self.size * .5,
                                 d=self.size * .5,
                                 po=po_vec,
                                 tp=self.previousTag)

            self.previousTag = fk_ctl
            attribute.setKeyableAttributes(fk_ctl)
            self.jnt_pos.append([fk_ctl, i])

            parent = fk_ctl
            self.fk_ctl.append(fk_ctl)
            self.fk_loc.append(fk_loc)
Exemple #8
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

        self.up_axis = pm.upAxis(q=True, axis=True)

        # Auto bend with position controls  -------------------
        if self.settings["autoBend"]:
            self.autoBendChain = primitive.add2DChain(
                self.root, self.getName("autoBend%s_jnt"),
                [self.guide.apos[1], self.guide.apos[-2]],
                self.guide.blades["blade"].z * -1, False, True)

            for j in self.autoBendChain:
                j.drawStyle.set(2)

        # Ik Controlers ------------------------------------
        if self.settings["IKWorldOri"]:
            t = datatypes.TransformationMatrix()
            t = transform.setMatrixPosition(t, self.guide.apos[1])
        else:
            t = transform.getTransformLookingAt(
                self.guide.apos[1], self.guide.apos[-2],
                self.guide.blades["blade"].z * -1, "yx", self.negate)
        self.ik_off = primitive.addTransform(self.root, self.getName("ik_off"),
                                             t)
        # handle Z up orientation offset
        if self.up_axis == "z" and self.settings["IKWorldOri"]:
            self.ik_off.rx.set(90)
            t = transform.getTransform(self.ik_off)

        self.ik0_npo = primitive.addTransform(self.ik_off,
                                              self.getName("ik0_npo"), t)

        self.ik0_ctl = self.addCtl(self.ik0_npo,
                                   "ik0_ctl",
                                   t,
                                   self.color_ik,
                                   "compas",
                                   w=self.size,
                                   tp=self.parentCtlTag)

        attribute.setKeyableAttributes(self.ik0_ctl, self.tr_params)
        attribute.setRotOrder(self.ik0_ctl, "ZXY")
        attribute.setInvertMirror(self.ik0_ctl, ["tx", "ry", "rz"])

        # pelvis
        self.length0 = vector.getDistance(self.guide.apos[0],
                                          self.guide.apos[1])
        vec_po = datatypes.Vector(0, .5 * self.length0 * -1, 0)
        self.pelvis_npo = primitive.addTransform(self.ik0_ctl,
                                                 self.getName("pelvis_npo"), t)

        self.pelvis_ctl = self.addCtl(self.pelvis_npo,
                                      "pelvis_ctl",
                                      t,
                                      self.color_ik,
                                      "cube",
                                      h=self.length0,
                                      w=self.size * .1,
                                      d=self.size * .1,
                                      po=vec_po,
                                      tp=self.parentCtlTag)
        self.pelvis_lvl = primitive.addTransform(
            self.pelvis_ctl, self.getName("pelvis_lvl"),
            transform.setMatrixPosition(t, self.guide.apos[0]))
        self.jnt_pos.append([self.pelvis_lvl, "pelvis"])

        t = transform.setMatrixPosition(t, self.guide.apos[-2])
        if self.settings["autoBend"]:
            self.autoBend_npo = primitive.addTransform(
                self.root, self.getName("spinePosition_npo"), t)

            self.autoBend_ctl = self.addCtl(self.autoBend_npo,
                                            "spinePosition_ctl",
                                            t,
                                            self.color_ik,
                                            "square",
                                            w=self.size,
                                            d=.3 * self.size,
                                            tp=self.parentCtlTag)

            attribute.setKeyableAttributes(self.autoBend_ctl,
                                           ["tx", "ty", "tz", "ry"])

            attribute.setInvertMirror(self.autoBend_ctl, ["tx", "ry"])

            self.ik1_npo = primitive.addTransform(self.autoBendChain[0],
                                                  self.getName("ik1_npo"), t)

            self.ik1autoRot_lvl = primitive.addTransform(
                self.ik1_npo, self.getName("ik1autoRot_lvl"), t)

            self.ik1_ctl = self.addCtl(self.ik1autoRot_lvl,
                                       "ik1_ctl",
                                       t,
                                       self.color_ik,
                                       "compas",
                                       w=self.size,
                                       tp=self.autoBend_ctl)
        else:
            t = transform.setMatrixPosition(t, self.guide.apos[-2])
            self.ik1_npo = primitive.addTransform(self.root,
                                                  self.getName("ik1_npo"), t)

            self.ik1_ctl = self.addCtl(self.ik1_npo,
                                       "ik1_ctl",
                                       t,
                                       self.color_ik,
                                       "compas",
                                       w=self.size,
                                       tp=self.ik0_ctl)

        attribute.setKeyableAttributes(self.ik1_ctl, self.tr_params)
        attribute.setRotOrder(self.ik1_ctl, "ZXY")
        attribute.setInvertMirror(self.ik1_ctl, ["tx", "ry", "rz"])

        # Tangent controllers -------------------------------
        if self.settings["centralTangent"]:
            vec_pos = self.guide.pos["tan0"]
            t = transform.setMatrixPosition(t, vec_pos)

            self.tan0_npo = primitive.addTransform(self.ik0_ctl,
                                                   self.getName("tan0_npo"), t)

            self.tan0_off = primitive.addTransform(self.tan0_npo,
                                                   self.getName("tan0_off"), t)

            self.tan0_ctl = self.addCtl(self.tan0_off,
                                        "tan0_ctl",
                                        t,
                                        self.color_ik,
                                        "sphere",
                                        w=self.size * .1,
                                        tp=self.ik0_ctl)

            attribute.setKeyableAttributes(self.tan0_ctl, self.t_params)
            vec_pos = self.guide.pos["tan1"]
            t = transform.setMatrixPosition(t, vec_pos)

            self.tan1_npo = primitive.addTransform(self.ik1_ctl,
                                                   self.getName("tan1_npo"), t)

            self.tan1_off = primitive.addTransform(self.tan1_npo,
                                                   self.getName("tan1_off"), t)

            self.tan1_ctl = self.addCtl(self.tan1_off,
                                        "tan1_ctl",
                                        t,
                                        self.color_ik,
                                        "sphere",
                                        w=self.size * .1,
                                        tp=self.ik0_ctl)

            attribute.setKeyableAttributes(self.tan1_ctl, self.t_params)

            # Tangent mid control
            vec_pos = vector.linearlyInterpolate(self.guide.apos[1],
                                                 self.guide.apos[-2], .5)
            t = transform.setMatrixPosition(t, vec_pos)

            self.tan_npo = primitive.addTransform(self.tan0_npo,
                                                  self.getName("tan_npo"), t)

            self.tan_ctl = self.addCtl(self.tan_npo,
                                       "tan_ctl",
                                       t,
                                       self.color_fk,
                                       "sphere",
                                       w=self.size * .2,
                                       tp=self.ik1_ctl)

            attribute.setKeyableAttributes(self.tan_ctl, self.t_params)
            attribute.setInvertMirror(self.tan_ctl, ["tx"])

        else:
            vec_pos = self.guide.pos["tan0"]
            t = transform.setMatrixPosition(t, vec_pos)

            self.tan0_npo = primitive.addTransform(self.ik0_ctl,
                                                   self.getName("tan0_npo"), t)

            self.tan0_ctl = self.addCtl(self.tan0_npo,
                                        "tan0_ctl",
                                        t,
                                        self.color_ik,
                                        "sphere",
                                        w=self.size * .2,
                                        tp=self.ik0_ctl)

            attribute.setKeyableAttributes(self.tan0_ctl, self.t_params)

            vec_pos = self.guide.pos["tan1"]
            t = transform.setMatrixPosition(t, vec_pos)

            self.tan1_npo = primitive.addTransform(self.ik1_ctl,
                                                   self.getName("tan1_npo"), t)

            self.tan1_ctl = self.addCtl(self.tan1_npo,
                                        "tan1_ctl",
                                        t,
                                        self.color_ik,
                                        "sphere",
                                        w=self.size * .2,
                                        tp=self.ik1_ctl)

            attribute.setKeyableAttributes(self.tan1_ctl, self.t_params)

        attribute.setInvertMirror(self.tan0_ctl, ["tx"])
        attribute.setInvertMirror(self.tan1_ctl, ["tx"])

        # Curves -------------------------------------------
        self.mst_crv = curve.addCnsCurve(
            self.root, self.getName("mst_crv"),
            [self.ik0_ctl, self.tan0_ctl, self.tan1_ctl, self.ik1_ctl], 3)
        self.slv_crv = curve.addCurve(self.root, self.getName("slv_crv"),
                                      [datatypes.Vector()] * 10, False, 3)
        self.mst_crv.setAttr("visibility", False)
        self.slv_crv.setAttr("visibility", False)

        # Division -----------------------------------------
        # The user only define how many intermediate division he wants.
        # First and last divisions are an obligation.
        parentdiv = self.root
        parentctl = self.root
        self.div_cns = []
        self.fk_ctl = []
        self.fk_npo = []
        self.scl_transforms = []
        self.twister = []
        self.ref_twist = []

        t = transform.getTransformLookingAt(self.guide.apos[1],
                                            self.guide.apos[-2],
                                            self.guide.blades["blade"].z * -1,
                                            "yx", self.negate)

        parent_twistRef = primitive.addTransform(
            self.root, self.getName("reference"),
            transform.getTransform(self.root))

        self.jointList = []
        self.preiviousCtlTag = self.parentCtlTag

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

            # References
            div_cns = primitive.addTransform(parentdiv,
                                             self.getName("%s_cns" % i))
            pm.setAttr(div_cns + ".inheritsTransform", False)
            self.div_cns.append(div_cns)
            parentdiv = div_cns

            t = transform.getTransform(parentctl)

            fk_npo = primitive.addTransform(parentctl,
                                            self.getName("fk%s_npo" % (i)), t)

            fk_ctl = self.addCtl(fk_npo,
                                 "fk%s_ctl" % (i),
                                 transform.getTransform(parentctl),
                                 self.color_fk,
                                 "cube",
                                 w=self.size,
                                 h=self.size * .05,
                                 d=self.size,
                                 tp=self.preiviousCtlTag)

            attribute.setKeyableAttributes(self.fk_ctl)
            attribute.setRotOrder(fk_ctl, "ZXY")
            self.fk_ctl.append(fk_ctl)
            self.preiviousCtlTag = fk_ctl

            self.fk_npo.append(fk_npo)
            parentctl = fk_ctl
            if i == self.settings["division"] - 1:
                t = transform.getTransformLookingAt(
                    self.guide.pos["spineTop"], self.guide.pos["chest"],
                    self.guide.blades["blade"].z * -1, "yx", False)
                scl_ref_parent = self.root
            else:
                t = transform.getTransform(parentctl)
                scl_ref_parent = parentctl

            scl_ref = primitive.addTransform(scl_ref_parent,
                                             self.getName("%s_scl_ref" % i), t)

            self.scl_transforms.append(scl_ref)

            # Deformers (Shadow)
            self.jnt_pos.append([scl_ref, "spine_" + str(i + 1).zfill(2)])

            # Twist references (This objects will replace the spinlookup
            # slerp solver behavior)
            t = transform.getTransformLookingAt(
                self.guide.apos[0], self.guide.apos[1],
                self.guide.blades["blade"].z * -1, "yx", self.negate)

            twister = primitive.addTransform(parent_twistRef,
                                             self.getName("%s_rot_ref" % i), t)

            ref_twist = primitive.addTransform(parent_twistRef,
                                               self.getName("%s_pos_ref" % i),
                                               t)
            ref_twist.setTranslation(datatypes.Vector(1.0, 0, 0),
                                     space="preTransform")

            self.twister.append(twister)
            self.ref_twist.append(ref_twist)

            for x in self.fk_ctl[:-1]:
                attribute.setInvertMirror(x, ["tx", "rz", "ry"])

        # Connections (Hooks) ------------------------------
        self.cnx0 = primitive.addTransform(self.root, self.getName("0_cnx"))
        self.cnx1 = primitive.addTransform(self.root, self.getName("1_cnx"))
        self.jnt_pos.append([self.cnx1, "spine_" + str(i + 2).zfill(2)])
Exemple #9
0
    def addOperators(self):
        """Create operators and set the relations for the component rig

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

        """

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

        for shp in self.fk0_ctl.getShapes():
            pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility"))
        for shp in self.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 = node.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"))
        for shp in self.line_ref.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 -----------------------------------
        attribute.setRotOrder(self.fk0_ctl, "YZX")
        attribute.setRotOrder(self.fk1_ctl, "XYZ")
        attribute.setRotOrder(self.fk2_ctl, "YZX")
        attribute.setRotOrder(self.ik_ctl, "XYZ")

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

        o_node = applyop.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, o_node + ".blend")
        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")
        # update issue on effector scale interpol, disconnect for stability
        pm.disconnectAttr(self.eff_npo.scale)
        # auto upvector -------------------------------------

        if self.negate:
            o_node = applyop.aimCns(self.upv_auv,
                                    self.ik_ctl,
                                    axis="-xy",
                                    wupType=4,
                                    wupVector=[0, 1, 0],
                                    wupObject=self.upv_auv,
                                    maintainOffset=False)
        else:
            o_node = applyop.aimCns(self.upv_auv,
                                    self.ik_ctl,
                                    axis="xy",
                                    wupType=4,
                                    wupVector=[0, 1, 0],
                                    wupObject=self.upv_auv,
                                    maintainOffset=False)

        o_node = applyop.gear_mulmatrix_op(
            self.upv_auv.attr("worldMatrix"),
            self.upv_mtx.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_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 connection
        o_node = applyop.gear_mulmatrix_op(
            self.fk0_roll_ctl.attr("worldMatrix"),
            self.fk0_mtx.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_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 connect to fk1 ref @ pos and rot, not scl to avoid shearing
        o_node = applyop.gear_mulmatrix_op(
            self.fk1_ref.attr("worldMatrix"),
            self.fk1_loc.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_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------------------------
        o_node = applyop.gear_mulmatrix_op(
            self.eff_npo.attr("worldMatrix"),
            self.fk2_loc.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        pm.connectAttr(dm_node + ".outputTranslate",
                       self.fk2_loc.attr("translate"))
        # fk2_loc rotation constraint to bone1 (bugfixed) --------------
        o_node = applyop.gear_mulmatrix_op(
            self.bone1.attr("worldMatrix"),
            self.fk2_loc.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")
        pm.connectAttr(dm_node + ".outputRotate", self.fk2_loc.attr("rotate"))

        # hand ikfk blending from fk ref to ik ref (serious bugfix)--------
        o_node = applyop.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(o_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"))
        o_node = applyop.gear_mulmatrix_op(
            self.ik_ref.attr("worldMatrix"),
            self.eff_loc.attr("parentInverseMatrix"))
        dm_node1 = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_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"))

        o_node = applyop.gear_mulmatrix_op(
            self.eff_loc.attr("worldMatrix"),
            self.tws3_npo.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix")

        pm.connectAttr(dm_node + ".outputTranslate",
                       self.tws3_npo.attr("translate"))

        pm.connectAttr(dm_node + ".outputRotate",
                       self.tws3_npo.attr("rotate"))

        attribute.setRotOrder(self.tws3_rot, "XYZ")

        # elbow thickness connection
        if self.negate:
            o_node = node.createMulNode(
                [self.elbow_thickness_att, self.elbow_thickness_att],
                [0.5, -0.5, 0],
                [self.tws1_loc + ".translateX", self.tws2_loc + ".translateX"])
        else:
            o_node = node.createMulNode(
                [self.elbow_thickness_att, self.elbow_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 = node.createAddNode(self.roundness0_att, .001)
        pm.connectAttr(add_node + ".output", self.tws1_rot.attr("sx"))

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

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

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

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

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

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

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

        # Divisions ----------------------------------------
        # div mid constraint to mid ctl
        o_node = applyop.gear_mulmatrix_op(
            self.mid_ctl.attr("worldMatrix"),
            self.div_mid.attr("parentInverseMatrix"))
        dm_node = pm.createNode("decomposeMatrix")
        pm.connectAttr(o_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
        # linear scaling percentage (1) to effector (2) to elbow
        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:
                o_node = applyop.gear_rollsplinekine_op(
                    div_cnsUp, [self.tws1_rot, self.tws0_rot], 1 - perc, 20)

            else:
                o_node = applyop.gear_rollsplinekine_op(
                    div_cnsUp, [self.tws0_rot, self.tws1_rot], perc, 20)

            pm.connectAttr(self.resample_att, o_node + ".resample")
            pm.connectAttr(self.absolute_att, o_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:
                o_node = applyop.gear_rollsplinekine_op(
                    div_cnsDn, [self.tws3_rot, self.tws2_rot], 1 - perc, 20)

            else:
                o_node = applyop.gear_rollsplinekine_op(
                    div_cnsDn, [self.tws2_rot, self.tws3_rot], perc, 20)
            pm.connectAttr(self.resample_att, o_node + ".resample")
            pm.connectAttr(self.absolute_att, o_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):
            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")
            # get the first mult_node after sq op
            mult_node = pm.listHistory(o_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
Exemple #10
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

        self.WIP = self.options["mode"]

        self.normal = self.getNormalFromPos(self.guide.apos)
        self.binormal = self.getBiNormalFromPos(self.guide.apos)

        self.length0 = vector.getDistance(self.guide.apos[0],
                                          self.guide.apos[1])
        self.length1 = vector.getDistance(self.guide.apos[1],
                                          self.guide.apos[2])
        self.length2 = vector.getDistance(self.guide.apos[2],
                                          self.guide.apos[3])

        # 1 bone chain for upv ref
        self.legChainUpvRef = primitive.add2DChain(
            self.root, self.getName("legUpvRef%s_jnt"),
            [self.guide.apos[0], self.guide.apos[2]], self.normal, False,
            self.WIP)

        self.legChainUpvRef[1].setAttr(
            "jointOrientZ",
            self.legChainUpvRef[1].getAttr("jointOrientZ") * -1)

        # extra neutral pose
        t = transform.getTransformFromPos(self.guide.apos[0])

        self.root_npo = primitive.addTransform(self.root,
                                               self.getName("root_npo"), t)
        self.root_ctl = self.addCtl(self.root_npo,
                                    "root_ctl",
                                    t,
                                    self.color_fk,
                                    "circle",
                                    w=self.length0 / 6,
                                    tp=self.parentCtlTag)

        # FK Controlers -----------------------------------
        t = transform.getTransformLookingAt(self.guide.apos[0],
                                            self.guide.apos[1], self.normal,
                                            "xz", self.negate)
        self.fk0_npo = primitive.addTransform(self.root_ctl,
                                              self.getName("fk0_npo"), t)
        po_vec = datatypes.Vector(.5 * self.length0 * self.n_factor, 0, 0)
        self.fk0_ctl = self.addCtl(self.fk0_npo,
                                   "fk0_ctl",
                                   t,
                                   self.color_fk,
                                   "cube",
                                   w=self.length0,
                                   h=self.size * .1,
                                   d=self.size * .1,
                                   po=po_vec,
                                   tp=self.root_ctl)
        attribute.setKeyableAttributes(
            self.fk0_ctl, ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"])

        t = transform.getTransformLookingAt(self.guide.apos[1],
                                            self.guide.apos[2], self.normal,
                                            "xz", self.negate)

        self.fk1_npo = primitive.addTransform(self.fk0_ctl,
                                              self.getName("fk1_npo"), t)

        po_vec = datatypes.Vector(.5 * self.length1 * self.n_factor, 0, 0)
        self.fk1_ctl = self.addCtl(self.fk1_npo,
                                   "fk1_ctl",
                                   t,
                                   self.color_fk,
                                   "cube",
                                   w=self.length1,
                                   h=self.size * .1,
                                   d=self.size * .1,
                                   po=po_vec,
                                   tp=self.fk0_ctl)

        attribute.setKeyableAttributes(
            self.fk1_ctl, ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"])

        t = transform.getTransformLookingAt(self.guide.apos[2],
                                            self.guide.apos[3], self.normal,
                                            "xz", self.negate)

        self.fk2_npo = primitive.addTransform(self.fk1_ctl,
                                              self.getName("fk2_npo"), t)

        po_vec = datatypes.Vector(.5 * self.length2 * self.n_factor, 0, 0)
        self.fk2_ctl = self.addCtl(self.fk2_npo,
                                   "fk2_ctl",
                                   t,
                                   self.color_fk,
                                   "cube",
                                   w=self.length2,
                                   h=self.size * .1,
                                   d=self.size * .1,
                                   po=po_vec,
                                   tp=self.fk1_ctl)
        attribute.setKeyableAttributes(self.fk2_ctl)

        self.fk_ctl = [self.fk0_ctl, self.fk1_ctl, self.fk2_ctl]

        for x in self.fk_ctl:
            attribute.setInvertMirror(x, ["tx", "ty", "tz"])

        # IK Controlers -----------------------------------

        self.ik_cns = primitive.addTransformFromPos(self.root_ctl,
                                                    self.getName("ik_cns"),
                                                    self.guide.pos["ankle"])

        self.ikcns_ctl = self.addCtl(self.ik_cns,
                                     "ikcns_ctl",
                                     transform.getTransformFromPos(
                                         self.guide.pos["ankle"]),
                                     self.color_ik,
                                     "null",
                                     w=self.size * .12,
                                     tp=self.root_ctl)
        attribute.setInvertMirror(self.ikcns_ctl, ["tx"])

        m = transform.getTransformLookingAt(self.guide.pos["ankle"],
                                            self.guide.pos["eff"], self.x_axis,
                                            "zx", False)

        self.ik_ctl = self.addCtl(self.ikcns_ctl,
                                  "ik_ctl",
                                  transform.getTransformFromPos(
                                      self.guide.pos["ankle"]),
                                  self.color_ik,
                                  "cube",
                                  w=self.size * .12,
                                  h=self.size * .12,
                                  d=self.size * .12)
        attribute.setKeyableAttributes(self.ik_ctl)
        attribute.setRotOrder(self.ik_ctl, "XZY")
        attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"])

        # upv
        v = self.guide.apos[2] - self.guide.apos[0]
        v = self.normal ^ v
        v.normalize()
        v *= self.size * .5
        v += self.guide.apos[1]

        self.upv_cns = primitive.addTransformFromPos(self.ik_ctl,
                                                     self.getName("upv_cns"),
                                                     v)

        self.upv_ctl = self.addCtl(self.upv_cns,
                                   "upv_ctl",
                                   transform.getTransform(self.upv_cns),
                                   self.color_ik,
                                   "diamond",
                                   w=self.size * .12,
                                   tp=self.root_ctl)

        self.add_controller_tag(self.ik_ctl, self.upv_ctl)
        if self.settings["mirrorMid"]:
            if self.negate:
                self.upv_cns.rz.set(180)
                self.upv_cns.sy.set(-1)
        else:
            attribute.setInvertMirror(self.upv_ctl, ["tx"])
        attribute.setKeyableAttributes(self.upv_ctl, self.t_params)

        # References --------------------------------------
        self.ik_ref = primitive.addTransform(
            self.ik_ctl, self.getName("ik_ref"),
            transform.getTransform(self.ik_ctl))
        self.fk_ref = primitive.addTransform(
            self.fk_ctl[2], self.getName("fk_ref"),
            transform.getTransform(self.ik_ctl))

        # Chain --------------------------------------------
        # The outputs of the ikfk2bone solver
        self.bone0 = primitive.addLocator(
            self.root_ctl, self.getName("0_bone"),
            transform.getTransform(self.fk_ctl[0]))

        self.bone0_shp = self.bone0.getShape()
        self.bone0_shp.setAttr("localPositionX", self.n_factor * .5)
        self.bone0_shp.setAttr("localScale", .5, 0, 0)
        self.bone0.setAttr("sx", self.length0)
        self.bone0.setAttr("visibility", False)

        self.bone1 = primitive.addLocator(
            self.root_ctl, self.getName("1_bone"),
            transform.getTransform(self.fk_ctl[1]))
        self.bone1_shp = self.bone1.getShape()
        self.bone1_shp.setAttr("localPositionX", self.n_factor * .5)
        self.bone1_shp.setAttr("localScale", .5, 0, 0)
        self.bone1.setAttr("sx", self.length1)
        self.bone1.setAttr("visibility", False)

        self.ctrn_loc = primitive.addTransformFromPos(self.root_ctl,
                                                      self.getName("ctrn_loc"),
                                                      self.guide.apos[1])
        self.eff_loc = primitive.addTransformFromPos(self.root_ctl,
                                                     self.getName("eff_loc"),
                                                     self.guide.apos[2])

        # tws_ref
        t = transform.getRotationFromAxis(datatypes.Vector(0, -1, 0),
                                          self.normal, "xz", self.negate)
        t = transform.setMatrixPosition(t, self.guide.pos["ankle"])

        # addind an npo parent transform to fix flip in Maya 2018.2
        self.tws_npo = primitive.addTransform(self.eff_loc,
                                              self.getName("tws_npo"), t)

        self.tws_ref = primitive.addTransform(self.tws_npo,
                                              self.getName("tws_ref"), t)

        # Mid Controler ------------------------------------
        t = transform.getTransform(self.ctrn_loc)
        self.mid_cns = primitive.addTransform(self.ctrn_loc,
                                              self.getName("mid_cns"), t)
        self.mid_ctl = self.addCtl(self.mid_cns,
                                   "mid_ctl",
                                   t,
                                   self.color_ik,
                                   "sphere",
                                   w=self.size * .2,
                                   tp=self.root_ctl)

        attribute.setKeyableAttributes(
            self.mid_ctl,
            params=["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"])

        if self.settings["mirrorMid"]:
            if self.negate:
                self.mid_cns.rz.set(180)
                self.mid_cns.sz.set(-1)
        else:
            attribute.setInvertMirror(self.mid_ctl, ["tx", "ty", "tz"])

        # Twist references ---------------------------------
        x = datatypes.Vector(0, -1, 0)
        x = x * transform.getTransform(self.eff_loc)
        z = datatypes.Vector(self.normal.x, self.normal.y, self.normal.z)
        z = z * transform.getTransform(self.eff_loc)

        m = transform.getRotationFromAxis(x, z, "xz", self.negate)
        m = transform.setMatrixPosition(m,
                                        transform.getTranslation(self.ik_ctl))

        self.rollRef = primitive.add2DChain(self.root,
                                            self.getName("rollChain"),
                                            self.guide.apos[:2], self.normal,
                                            self.negate, self.WIP)

        self.tws0_loc = primitive.addTransform(
            self.rollRef[0], self.getName("tws0_loc"),
            transform.getTransform(self.fk_ctl[0]))

        self.tws0_rot = primitive.addTransform(
            self.tws0_loc, self.getName("tws0_rot"),
            transform.getTransform(self.fk_ctl[0]))

        self.tws1_loc = primitive.addTransform(
            self.ctrn_loc, self.getName("tws1_loc"),
            transform.getTransform(self.ctrn_loc))

        self.tws1_rot = primitive.addTransform(
            self.tws1_loc, self.getName("tws1_rot"),
            transform.getTransform(self.ctrn_loc))

        # thickness control
        self.thick_lvl = primitive.addTransform(
            self.mid_ctl, self.getName("thickness_lvl"),
            transform.getTransform(self.ctrn_loc))
        self.thick_ctl = self.addCtl(self.thick_lvl,
                                     "thickness_ctl",
                                     transform.getTransform(self.mid_ctl),
                                     self.color_ik,
                                     "arrow",
                                     w=self.size * .1,
                                     ro=datatypes.Vector([0, 1.5708, 0]),
                                     tp=self.mid_ctl)
        if self.negate and not self.settings["mirrorMid"]:
            self.thick_ctl.rz.set(180)
            self.thick_ctl.sz.set(-1)
        attribute.setKeyableAttributes(self.thick_ctl, ["tx", "ty"])

        self.tws1B_loc = primitive.addTransform(
            self.ctrn_loc, self.getName("tws1B_loc"),
            transform.getTransform(self.ctrn_loc))

        self.tws1B_rot = primitive.addTransform(
            self.tws1B_loc, self.getName("tws1B_rot"),
            transform.getTransform(self.ctrn_loc))

        self.tws2_loc = primitive.addTransform(
            self.root_ctl, self.getName("tws2_loc"),
            transform.getTransform(self.tws_ref))

        self.tws2_rot = primitive.addTransform(
            self.tws2_loc, self.getName("tws2_rot"),
            transform.getTransform(self.tws_ref))

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

        # angle reader ----------------------------------------
        t = transform.getTransformLookingAt(self.guide.apos[1],
                                            self.guide.apos[0], self.binormal,
                                            "yz")
        self.readerA = primitive.addTransform(self.root,
                                              self.getName("readerA_loc"), t)
        self.readerB = primitive.addTransform(self.readerA,
                                              self.getName("readerB_loc"), t)
        self.readerB.rotateOrder.set(2)

        # Divisions ----------------------------------------
        # We have at least one division at the start, the end and one for
        # the elbow. + 2 for knee angle control
        if self.settings["supportJoints"]:
            ej = 2
        else:
            ej = 0

        self.divisions = self.settings["div0"] + self.settings["div1"] + 3 + ej

        self.div_cns = []

        if self.settings["extraTweak"]:
            tagP = self.parentCtlTag
            self.tweak_ctl = []

        for i in range(self.divisions):

            div_cns = primitive.addTransform(self.root_ctl,
                                             self.getName("div%s_loc" % i))

            self.div_cns.append(div_cns)

            if self.settings["extraTweak"]:
                t = transform.getTransform(div_cns)
                tweak_ctl = self.addCtl(div_cns,
                                        "tweak%s_ctl" % i,
                                        t,
                                        self.color_fk,
                                        "square",
                                        w=self.size * .15,
                                        d=self.size * .15,
                                        ro=datatypes.Vector([0, 0, 1.5708]),
                                        tp=tagP)
                attribute.setKeyableAttributes(tweak_ctl)

                tagP = tweak_ctl
                self.tweak_ctl.append(tweak_ctl)
                self.jnt_pos.append([tweak_ctl, i, None, False])
            else:
                self.jnt_pos.append([div_cns, i])

        # End reference ------------------------------------
        # To help the deformation on the ankle
        self.end_ref = primitive.addTransform(self.tws2_rot,
                                              self.getName("end_ref"), m)
        self.jnt_pos.append([self.end_ref, 'end'])

        # match IK FK references
        self.match_fk0_off = self.add_match_ref(self.fk_ctl[1], self.root,
                                                "matchFk0_npo", False)

        self.match_fk0 = self.add_match_ref(self.fk_ctl[0], self.match_fk0_off,
                                            "fk0_mth")

        self.match_fk1_off = self.add_match_ref(self.fk_ctl[2], self.root,
                                                "matchFk1_npo", False)

        self.match_fk1 = self.add_match_ref(self.fk_ctl[1], self.match_fk1_off,
                                            "fk1_mth")

        self.match_fk2 = self.add_match_ref(self.fk_ctl[2], self.ik_ctl,
                                            "fk2_mth")

        self.match_ik = self.add_match_ref(self.ik_ctl, self.fk2_ctl, "ik_mth")

        self.match_ikUpv = self.add_match_ref(self.upv_ctl, self.fk0_ctl,
                                              "upv_mth")

        # add visual reference
        self.line_ref = icon.connection_display_curve(
            self.getName("visalRef"), [self.upv_ctl, self.mid_ctl])
    def addOperators(self):
        """Create operators and set the relations for the component rig

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return
Exemple #12
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

        self.setup = primitive.addTransformFromPos(
            self.setupWS, self.getName("WS"))
        attribute.lockAttribute(self.setup)

        self.WIP = self.options["mode"]

        self.normal = self.getNormalFromPos(self.guide.apos)

        self.length0 = vector.getDistance(self.guide.apos[0],
                                          self.guide.apos[1])
        self.length1 = vector.getDistance(self.guide.apos[1],
                                          self.guide.apos[2])
        self.length2 = vector.getDistance(self.guide.apos[2],
                                          self.guide.apos[3])
        self.length3 = vector.getDistance(self.guide.apos[3],
                                          self.guide.apos[4])

        # 3bones chain
        self.chain3bones = primitive.add2DChain(
            self.setup,
            self.getName("chain3bones%s_jnt"),
            self.guide.apos[0:4],
            self.normal,
            False,
            self.WIP)

        # 2bones chain
        self.chain2bones = primitive.add2DChain(
            self.setup,
            self.getName("chain2bones%s_jnt"),
            self.guide.apos[0:3],
            self.normal,
            False,
            self.WIP)

        # Leg chain
        self.legBones = primitive.add2DChain(
            self.root,
            self.getName("legBones%s_jnt"),
            self.guide.apos[0:4],
            self.normal,
            False,
            self.WIP)

        # Leg chain FK ref
        self.legBonesFK = primitive.add2DChain(
            self.root,
            self.getName("legFK%s_jnt"),
            self.guide.apos[0:4],
            self.normal,
            False,
            self.WIP)

        # Leg chain IK ref
        self.legBonesIK = primitive.add2DChain(
            self.root,
            self.getName("legIK%s_jnt"),
            self.guide.apos[0:4],
            self.normal,
            False,
            self.WIP)

        # 1 bone chain for upv ref
        self.legChainUpvRef = primitive.add2DChain(
            self.root,
            self.getName("legUpvRef%s_jnt"),
            [self.guide.apos[0], self.guide.apos[3]],
            self.normal,
            False,
            self.WIP)

        # mid joints
        self.mid1_jnt = primitive.addJoint(
            self.legBones[0],
            self.getName("mid1_jnt"),
            self.legBones[1].getMatrix(worldSpace=True),
            self.WIP)

        self.mid1_jnt.attr("radius").set(3)
        self.mid1_jnt.setAttr("jointOrient", 0, 0, 0)

        self.mid2_jnt = primitive.addJoint(
            self.legBones[1],
            self.getName("mid2_jnt"),
            self.legBones[2].getMatrix(worldSpace=True),
            self.WIP)

        self.mid2_jnt.attr("radius").set(3)
        self.mid2_jnt.setAttr("jointOrient", 0, 0, 0)

        # base Controlers -----------------------------------
        t = transform.getTransformFromPos(self.guide.apos[0])
        self.root_npo = primitive.addTransform(
            self.root, self.getName("root_npo"), t)

        self.root_ctl = self.addCtl(self.root_npo,
                                    "root_ctl",
                                    t,
                                    self.color_fk,
                                    "circle",
                                    w=self.length0 / 6,
                                    tp=self.parentCtlTag)
        attribute.lockAttribute(self.root_ctl, ["sx", "sy", "sz", "v"])

        # FK Controlers -----------------------------------
        t = transform.getTransformLookingAt(self.guide.apos[0],
                                            self.guide.apos[1],
                                            self.normal,
                                            "xz",
                                            self.negate)

        self.fk0_npo = primitive.addTransform(
            self.root_ctl, self.getName("fk0_npo"), t)

        self.fk0_ctl = self.addCtl(
            self.fk0_npo,
            "fk0_ctl",
            t,
            self.color_fk,
            "cube",
            w=self.length0,
            h=self.size * .1,
            d=self.size * .1,
            po=datatypes.Vector(.5 * self.length0 * self.n_factor, 0, 0),
            tp=self.root_ctl)
        attribute.setKeyableAttributes(self.fk0_ctl)

        t = transform.getTransformLookingAt(self.guide.apos[1],
                                            self.guide.apos[2],
                                            self.normal,
                                            "xz",
                                            self.negate)
        self.fk1_npo = primitive.addTransform(
            self.fk0_ctl, self.getName("fk1_npo"), t)
        self.fk1_ctl = self.addCtl(
            self.fk1_npo,
            "fk1_ctl",
            t,
            self.color_fk,
            "cube",
            w=self.length1,
            h=self.size * .1,
            d=self.size * .1,
            po=datatypes.Vector(.5 * self.length1 * self.n_factor, 0, 0),
            tp=self.fk0_ctl)
        attribute.setKeyableAttributes(self.fk1_ctl)

        t = transform.getTransformLookingAt(self.guide.apos[2],
                                            self.guide.apos[3],
                                            self.normal,
                                            "xz",
                                            self.negate)

        self.fk2_npo = primitive.addTransform(
            self.fk1_ctl, self.getName("fk2_npo"), t)

        self.fk2_ctl = self.addCtl(
            self.fk2_npo,
            "fk2_ctl",
            t,
            self.color_fk,
            "cube",
            w=self.length2,
            h=self.size * .1,
            d=self.size * .1,
            po=datatypes.Vector(.5 * self.length2 * self.n_factor, 0, 0),
            tp=self.fk1_ctl)

        attribute.setKeyableAttributes(self.fk2_ctl)

        t = transform.getTransformLookingAt(self.guide.apos[3],
                                            self.guide.apos[4],
                                            self.normal,
                                            "xz",
                                            self.negate)

        self.fk3_npo = primitive.addTransform(
            self.fk2_ctl, self.getName("fk3_npo"), t)

        self.fk3_ctl = self.addCtl(
            self.fk3_npo,
            "fk3_ctl",
            t,
            self.color_fk,
            "cube",
            w=self.length3,
            h=self.size * .1,
            d=self.size * .1,
            po=datatypes.Vector(.5 * self.length3 * self.n_factor, 0, 0),
            tp=self.fk2_ctl)

        attribute.setKeyableAttributes(self.fk3_ctl)

        self.fk_ctl = [self.fk0_ctl, self.fk1_ctl, self.fk2_ctl, self.fk3_ctl]

        for x in self.fk_ctl:
            attribute.setInvertMirror(x, ["tx", "ty", "tz"])

        # Mid Controlers ------------------------------------
        self.knee_lvl = primitive.addTransform(
            self.root,
            self.getName("knee_lvl"),
            transform.getTransform(self.mid1_jnt))

        self.knee_ctl = self.addCtl(
            self.knee_lvl,
            "knee_ctl",
            transform.getTransform(self.mid1_jnt),
            self.color_ik,
            "sphere",
            w=self.size * .2,
            tp=self.root_ctl)

        attribute.setInvertMirror(self.knee_ctl, ["tx", "ty", "tz"])
        attribute.lockAttribute(self.knee_ctl, ["sx", "sy", "sz", "v"])

        self.ankle_lvl = primitive.addTransform(
            self.root,
            self.getName("ankle_lvl"),
            transform.getTransform(self.mid2_jnt))

        self.ankle_ctl = self.addCtl(
            self.ankle_lvl,
            "ankle_ctl",
            transform.getTransform(self.mid2_jnt),
            self.color_ik,
            "sphere",
            w=self.size * .2,
            tp=self.knee_ctl)

        attribute.setInvertMirror(self.ankle_ctl, ["tx", "ty", "tz"])
        attribute.lockAttribute(self.ankle_ctl, ["sx", "sy", "sz", "v"])

        # IK controls --------------------------------------------------------

        # foot IK

        # "z-x",
        t_align = transform.getTransformLookingAt(self.guide.apos[3],
                                                  self.guide.apos[4],
                                                  self.normal,
                                                  "zx",
                                                  False)

        if self.settings["ikOri"]:
            t = transform.getTransformFromPos(self.guide.pos["foot"])
            # t = transform.getTransformLookingAt(self.guide.pos["foot"],
            #                                     self.guide.pos["eff"],
            #                                     self.x_axis,
            #                                     "zx",
            #                                     False)
        else:
            t = t_align

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

        self.ikcns_ctl = self.addCtl(self.ik_cns,
                                     "ikcns_ctl",
                                     t,
                                     self.color_ik,
                                     "null",
                                     w=self.size * .12,
                                     tp=self.ankle_ctl)

        attribute.setInvertMirror(self.ikcns_ctl, ["tx"])
        attribute.lockAttribute(self.ikcns_ctl, ["sx", "sy", "sz", "v"])

        self.ik_ctl = self.addCtl(self.ikcns_ctl,
                                  "ik_ctl",
                                  t,
                                  self.color_ik,
                                  "cube",
                                  w=self.size * .12,
                                  h=self.size * .12,
                                  d=self.size * .12,
                                  tp=self.ikcns_ctl)
        attribute.setKeyableAttributes(self.ik_ctl)
        attribute.setRotOrder(self.ik_ctl, "XZY")
        attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"])
        attribute.lockAttribute(self.ik_ctl, ["sx", "sy", "sz", "v"])

        # 2 bones ik layer
        self.ik2b_ikCtl_ref = primitive.addTransform(
            self.ik_ctl, self.getName("ik2B_A_ref"), t_align)
        self.ik2b_bone_ref = primitive.addTransform(
            self.chain3bones[3], self.getName("ik2B_B_ref"), t_align)
        self.ik2b_blend = primitive.addTransform(
            self.ik_ctl, self.getName("ik2B_blend"), t_align)

        self.roll_ctl = self.addCtl(self.ik2b_blend,
                                    "roll_ctl",
                                    t_align,
                                    self.color_ik,
                                    "crossarrow",
                                    w=self.length2 * .5 * self.n_factor,
                                    tp=self.ik_ctl)

        self.ik2b_ik_npo = primitive.addTransform(
            self.roll_ctl,
            self.getName("ik2B_ik_npo"),
            transform.getTransform(self.chain3bones[-1]))

        self.ik2b_ik_ref = primitive.addTransformFromPos(
            self.ik2b_ik_npo,
            self.getName("ik2B_ik_ref"),
            self.guide.pos["ankle"])

        attribute.lockAttribute(
            self.roll_ctl, ["tx", "ty", "tz", "sx", "sy", "sz", "v"])

        # upv
        v = self.guide.apos[2] - self.guide.apos[0]
        v = self.normal ^ v
        v.normalize()
        v *= self.size * .5
        v += self.guide.apos[1]

        self.upv_lvl = primitive.addTransformFromPos(
            self.root, self.getName("upv_lvl"), v)
        self.upv_cns = primitive.addTransformFromPos(
            self.upv_lvl, self.getName("upv_cns"), v)

        self.upv_ctl = self.addCtl(self.upv_cns,
                                   "upv_ctl",
                                   transform.getTransform(self.upv_cns),
                                   self.color_ik,
                                   "diamond",
                                   w=self.size * .12,
                                   tp=self.ik_ctl)

        attribute.setInvertMirror(self.upv_ctl, ["tx"])
        attribute.setKeyableAttributes(self.upv_ctl, ["tx", "ty", "tz"])

        # Soft IK objects 3 bones chain --------------------------------
        t = transform.getTransformLookingAt(self.guide.pos["root"],
                                            self.guide.pos["foot"],
                                            self.x_axis,
                                            "zx",
                                            False)

        self.aim_tra = primitive.addTransform(
            self.root_ctl, self.getName("aimSoftIK"), t)

        t = transform.getTransformFromPos(self.guide.pos["foot"])
        self.wristSoftIK = primitive.addTransform(
            self.aim_tra, self.getName("wristSoftIK"), t)

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

        # Soft IK objects 2 Bones chain ----------------------------
        t = transform.getTransformLookingAt(self.guide.pos["root"],
                                            self.guide.pos["ankle"],
                                            self.x_axis,
                                            "zx",
                                            False)

        self.aim_tra2 = primitive.addTransform(
            self.root_ctl, self.getName("aimSoftIK2"), t)

        t = transform.getTransformFromPos(self.guide.pos["ankle"])

        self.ankleSoftIK = primitive.addTransform(
            self.aim_tra2, self.getName("ankleSoftIK"), t)

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

        # References --------------------------------------
        self.ik_ref = primitive.addTransform(
            self.ik_ctl,
            self.getName("ik_ref"),
            transform.getTransform(self.ik_ctl))

        self.fk_ref = primitive.addTransform(
            self.fk_ctl[3],
            self.getName("fk_ref"),
            transform.getTransform(self.ik_ctl))

        # twist references --------------------------------------
        self.rollRef = primitive.add2DChain(self.root,
                                            self.getName("rollChain"),
                                            self.guide.apos[:2],
                                            self.normal,
                                            False,
                                            self.WIP)

        self.tws0_loc = primitive.addTransform(
            self.rollRef[0],
            self.getName("tws0_loc"),
            transform.getTransform(self.legBones[0]))

        self.tws0_rot = primitive.addTransform(
            self.tws0_loc,
            self.getName("tws0_rot"),
            transform.getTransform(self.legBones[0]))

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

        self.tws1_loc = primitive.addTransform(
            self.mid1_jnt,
            self.getName("tws1_loc"),
            transform.getTransform(self.mid1_jnt))

        self.tws1_rot = primitive.addTransform(
            self.tws1_loc,
            self.getName("tws1_rot"),
            transform.getTransform(self.mid1_jnt))

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

        self.tws2_loc = primitive.addTransform(
            self.mid2_jnt,
            self.getName("tws2_loc"),
            transform.getTransform(self.mid2_jnt))

        self.tws2_rot = primitive.addTransform(
            self.tws2_loc,
            self.getName("tws2_rot"),
            transform.getTransform(self.mid2_jnt))

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

        self.tws3_loc = primitive.addTransform(
            self.legBones[3],
            self.getName("tws3_loc"),
            transform.getTransform(self.legBones[3]))

        self.tws3_rot = primitive.addTransform(
            self.tws3_loc,
            self.getName("tws3_rot"),
            transform.getTransform(self.legBones[3]))

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

        # Divisions ----------------------------------------
        # We have at least one division at the start, the end and one for
        # the knee and one ankle
        o_set = self.settings
        self.divisions = o_set["div0"] + o_set["div1"] + o_set["div2"] + 4

        self.div_cns = []
        for i in range(self.divisions):
            div_cns = primitive.addTransform(self.root_ctl,
                                             self.getName("div%s_loc" % i))
            self.div_cns.append(div_cns)
            self.jnt_pos.append([div_cns, i])

        # End reference ------------------------------------
        # To help the deformation on the foot
        self.end_ref = primitive.addTransform(
            self.tws3_rot,
            self.getName("end_ref"),
            transform.getTransform(self.legBones[3]))
        self.jnt_pos.append([self.end_ref, 'end'])

        # match IK FK references
        self.match_fk0_off = primitive.addTransform(
            self.root,
            self.getName("matchFk0_npo"),
            transform.getTransform(self.fk_ctl[1]))

        self.match_fk0 = primitive.addTransform(
            self.match_fk0_off,
            self.getName("fk0_mth"),
            transform.getTransform(self.fk_ctl[0]))

        self.match_fk1_off = primitive.addTransform(
            self.root,
            self.getName("matchFk1_npo"),
            transform.getTransform(self.fk_ctl[2]))

        self.match_fk1 = primitive.addTransform(
            self.match_fk1_off,
            self.getName("fk1_mth"),
            transform.getTransform(self.fk_ctl[1]))

        self.match_fk2_off = primitive.addTransform(
            self.root,
            self.getName("matchFk2_npo"),
            transform.getTransform(self.fk_ctl[3]))

        self.match_fk2 = primitive.addTransform(
            self.match_fk2_off,
            self.getName("fk2_mth"),
            transform.getTransform(self.fk_ctl[2]))

        self.match_fk3 = primitive.addTransform(
            self.ik_ctl,
            self.getName("fk3_mth"),
            transform.getTransform(self.fk_ctl[3]))

        self.match_ik = primitive.addTransform(
            self.fk3_ctl,
            self.getName("ik_mth"),
            transform.getTransform(self.ik_ctl))

        self.match_ikUpv = primitive.addTransform(
            self.fk0_ctl,
            self.getName("upv_mth"),
            transform.getTransform(self.upv_ctl))

        # add visual reference
        self.line_ref = icon.connection_display_curve(
            self.getName("visalRef"), [self.upv_ctl, self.knee_ctl])
Exemple #13
0
    def addObjects(self):
        """Add all the objects needed to create the component."""
        self.normal = self.guide.blades["blade"].z * -1
        self.binormal = self.guide.blades["blade"].x

        self.WIP = self.options["mode"]

        if self.negate and self.settings["overrideNegate"]:
            self.negate = False
            self.n_factor = 1

        if self.settings["overrideNegate"]:
            self.mirror_conf = [0, 0, 1, 1, 1, 0, 0, 0, 0]
        else:
            self.mirror_conf = [0, 0, 0, 0, 0, 0, 0, 0, 0]

        # IK controls ---------------------------------------------
        self.ik_ctl = []
        # tOld = False
        self.previusTag = self.parentCtlTag
        for i, t in enumerate(
                transform.getChainTransform2(self.guide.apos, self.normal,
                                             self.negate)):

            ik_npo = primitive.addTransform(self.root,
                                            self.getName("ik%s_npo" % i), t)

            ik_ctl = self.addCtl(ik_npo,
                                 "ik%s_ctl" % i,
                                 t,
                                 self.color_ik,
                                 "square",
                                 w=self.size * .15,
                                 h=self.size * .15,
                                 d=self.size * .15,
                                 ro=datatypes.Vector([0, 0, 1.5708]),
                                 tp=self.previusTag,
                                 mirrorConf=self.mirror_conf)

            attribute.setKeyableAttributes(ik_ctl, self.tr_params)
            self.ik_ctl.append(ik_ctl)

        # Curves -------------------------------------------
        self.mst_crv = curve.addCnsCurve(self.root, self.getName("mst_crv"),
                                         self.ik_ctl, 3)
        self.slv_crv = curve.addCurve(self.root, self.getName("slv_crv"),
                                      [datatypes.Vector()] * 10, False, 3)
        self.mst_crv.setAttr("visibility", False)
        self.slv_crv.setAttr("visibility", False)

        # Division -----------------------------------------
        # The user only define how many intermediate division he wants.
        # First and last divisions are an obligation.
        parentdiv = self.root
        parentctl = self.root
        self.div_cns = []
        self.fk_ctl = []
        self.fk_npo = []
        self.scl_transforms = []
        self.twister = []
        self.ref_twist = []

        parent_twistRef = primitive.addTransform(
            self.root, self.getName("reference"),
            transform.getTransform(self.root))

        self.jointList = []
        self.preiviousCtlTag = self.parentCtlTag
        for i in range(self.settings["fkNb"]):
            # References
            div_cns = primitive.addTransform(parentdiv,
                                             self.getName("%s_cns" % i))
            pm.setAttr(div_cns + ".inheritsTransform", False)
            self.div_cns.append(div_cns)
            parentdiv = div_cns

            if i in [0, self.settings["fkNb"] - 1] and False:
                fk_ctl = primitive.addTransform(
                    parentctl, self.getName("%s_loc" % i),
                    transform.getTransform(parentctl))

                fk_npo = fk_ctl
                if i in [self.settings["fkNb"] - 1]:
                    self.fk_ctl.append(fk_ctl)
            else:
                m = transform.getTransform(self.root)
                t = transform.getTransform(parentctl)
                m.inverse()
                fk_npo = primitive.addTransform(parentctl,
                                                self.getName("fk%s_npo" % (i)),
                                                t)

                fk_ctl = self.addCtl(fk_npo,
                                     "fk%s_ctl" % (i),
                                     transform.getTransform(parentctl),
                                     self.color_fk,
                                     "cube",
                                     w=self.size * .1,
                                     h=self.size * .1,
                                     d=self.size * .1,
                                     tp=self.preiviousCtlTag,
                                     mirrorConf=self.mirror_conf)

                attribute.setKeyableAttributes(self.fk_ctl)
                attribute.setRotOrder(fk_ctl, "ZXY")
                self.fk_ctl.append(fk_ctl)
                self.preiviousCtlTag = fk_ctl

            self.fk_npo.append(fk_npo)
            parentctl = fk_ctl
            scl_ref = primitive.addTransform(parentctl,
                                             self.getName("%s_scl_ref" % i),
                                             transform.getTransform(parentctl))

            self.scl_transforms.append(scl_ref)

            # Deformers (Shadow)
            self.jnt_pos.append([scl_ref, i])

            # Twist references (This objects will replace the spinlookup
            # slerp solver behavior)
            t = transform.getTransformLookingAt(
                self.guide.apos[0], self.guide.apos[-1],
                self.guide.blades["blade"].z * -1, "yx", self.negate)

            twister = primitive.addTransform(parent_twistRef,
                                             self.getName("%s_rot_ref" % i), t)

            ref_twist = primitive.addTransform(parent_twistRef,
                                               self.getName("%s_pos_ref" % i),
                                               t)

            ref_twist.setTranslation(datatypes.Vector(1.0, 0, 0),
                                     space="preTransform")

            self.twister.append(twister)
            self.ref_twist.append(ref_twist)

            for x in self.fk_ctl[:-1]:
                attribute.setInvertMirror(x, ["tx", "rz", "ry"])
    def addObjects(self):
        """Add all the objects needed to create the component."""

        t = transform.getTransformLookingAt(self.guide.apos[0],
                                            self.guide.apos[1],
                                            self.guide.blades["blade"].z * -1,
                                            "yx", self.negate)

        t2 = transform.setMatrixPosition(t, self.guide.apos[1])

        int_t = t
        self.preiviousCtlTag = self.parentCtlTag

        # FK Controlers ------------------------------------
        self.fk_ctl = []
        self.fk_npo = []
        parentctl = self.root
        blend_increment = 1.0 / (self.settings["division"] - 1)
        blend_val = 0.0
        for i in range(self.settings["division"]):
            fk_npo = primitive.addTransform(parentctl,
                                            self.getName("fk%s_npo" % (i)),
                                            int_t)

            self.fk_npo.append(fk_npo)

            fk_ctl = self.addCtl(fk_npo,
                                 "fk%s_ctl" % (i),
                                 int_t,
                                 self.color_fk,
                                 "cube",
                                 w=self.size,
                                 h=self.size * .05,
                                 d=self.size,
                                 tp=self.preiviousCtlTag)

            self.fk_ctl.append(fk_ctl)
            self.preiviousCtlTag = fk_ctl

            parentctl = fk_ctl

            blend_val = blend_val + blend_increment

            int_t = transform.getInterpolateTransformMatrix(t,
                                                            t2,
                                                            blend=blend_val)

        for x in self.fk_ctl:
            attribute.setKeyableAttributes(x)
            attribute.setRotOrder(x, "ZXY")
            attribute.setInvertMirror(x, ["tx", "rz", "ry"])

        # Ik Controlers ------------------------------------

        self.ik0_npo = primitive.addTransform(self.fk_ctl[0],
                                              self.getName("ik0_npo"), t)
        self.ik0_ctl = self.addCtl(self.ik0_npo,
                                   "ik0_ctl",
                                   t,
                                   self.color_ik,
                                   "compas",
                                   w=self.size,
                                   tp=self.parentCtlTag)

        attribute.setKeyableAttributes(self.ik0_ctl, self.tr_params)
        attribute.setRotOrder(self.ik0_ctl, "ZXY")
        attribute.setInvertMirror(self.ik0_ctl, ["tx", "ry", "rz"])

        t = transform.setMatrixPosition(t, self.guide.apos[1])
        self.ik1_npo = primitive.addTransform(self.fk_ctl[-1],
                                              self.getName("ik1_npo"), t)

        self.ik1_ctl = self.addCtl(self.ik1_npo,
                                   "ik1_ctl",
                                   t,
                                   self.color_ik,
                                   "compas",
                                   w=self.size,
                                   tp=self.ik0_ctl)

        attribute.setKeyableAttributes(self.ik1_ctl, self.tr_params)
        attribute.setRotOrder(self.ik1_ctl, "ZXY")
        attribute.setInvertMirror(self.ik1_ctl, ["tx", "ry", "rz"])

        # Tangent controllers -------------------------------
        if self.settings["centralTangent"]:
            vec_pos = vector.linearlyInterpolate(self.guide.apos[0],
                                                 self.guide.apos[1], .33)
            t = transform.setMatrixPosition(t, vec_pos)

            self.tan0_npo = primitive.addTransform(self.ik0_ctl,
                                                   self.getName("tan0_npo"), t)

            self.tan0_off = primitive.addTransform(self.tan0_npo,
                                                   self.getName("tan0_off"), t)

            self.tan0_ctl = self.addCtl(self.tan0_off,
                                        "tan0_ctl",
                                        t,
                                        self.color_ik,
                                        "sphere",
                                        w=self.size * .1,
                                        tp=self.ik0_ctl)

            attribute.setKeyableAttributes(self.tan0_ctl, self.t_params)
            vec_pos = vector.linearlyInterpolate(self.guide.apos[0],
                                                 self.guide.apos[1], .66)

            t = transform.setMatrixPosition(t, vec_pos)

            self.tan1_npo = primitive.addTransform(self.ik1_ctl,
                                                   self.getName("tan1_npo"), t)

            self.tan1_off = primitive.addTransform(self.tan1_npo,
                                                   self.getName("tan1_off"), t)

            self.tan1_ctl = self.addCtl(self.tan1_off,
                                        "tan1_ctl",
                                        t,
                                        self.color_ik,
                                        "sphere",
                                        w=self.size * .1,
                                        tp=self.ik0_ctl)

            attribute.setKeyableAttributes(self.tan1_ctl, self.t_params)

            # Tangent mid control
            vec_pos = vector.linearlyInterpolate(self.guide.apos[0],
                                                 self.guide.apos[1], .5)
            t = transform.setMatrixPosition(t, vec_pos)

            self.tan_npo = primitive.addTransform(self.tan0_npo,
                                                  self.getName("tan_npo"), t)

            self.tan_ctl = self.addCtl(self.tan_npo,
                                       "tan_ctl",
                                       t,
                                       self.color_fk,
                                       "sphere",
                                       w=self.size * .2,
                                       tp=self.ik1_ctl)

            attribute.setKeyableAttributes(self.tan_ctl, self.t_params)
            attribute.setInvertMirror(self.tan_ctl, ["tx"])

        else:
            vec_pos = vector.linearlyInterpolate(self.guide.apos[0],
                                                 self.guide.apos[1], .33)

            t = transform.setMatrixPosition(t, vec_pos)

            self.tan0_npo = primitive.addTransform(self.ik0_ctl,
                                                   self.getName("tan0_npo"), t)

            self.tan0_ctl = self.addCtl(self.tan0_npo,
                                        "tan0_ctl",
                                        t,
                                        self.color_ik,
                                        "sphere",
                                        w=self.size * .2,
                                        tp=self.ik0_ctl)

            attribute.setKeyableAttributes(self.tan0_ctl, self.t_params)

            vec_pos = vector.linearlyInterpolate(self.guide.apos[0],
                                                 self.guide.apos[1], .66)

            t = transform.setMatrixPosition(t, vec_pos)

            self.tan1_npo = primitive.addTransform(self.ik1_ctl,
                                                   self.getName("tan1_npo"), t)

            self.tan1_ctl = self.addCtl(self.tan1_npo,
                                        "tan1_ctl",
                                        t,
                                        self.color_ik,
                                        "sphere",
                                        w=self.size * .2,
                                        tp=self.ik1_ctl)

            attribute.setKeyableAttributes(self.tan1_ctl, self.t_params)

        attribute.setInvertMirror(self.tan0_ctl, ["tx"])
        attribute.setInvertMirror(self.tan1_ctl, ["tx"])

        # Curves -------------------------------------------
        self.mst_crv = curve.addCnsCurve(
            self.root, self.getName("mst_crv"),
            [self.ik0_ctl, self.tan0_ctl, self.tan1_ctl, self.ik1_ctl], 3)
        self.slv_crv = curve.addCurve(self.root, self.getName("slv_crv"),
                                      [datatypes.Vector()] * 10, False, 3)
        self.mst_crv.setAttr("visibility", False)
        self.slv_crv.setAttr("visibility", False)

        # Division -----------------------------------------
        # The user only define how many intermediate division he wants.
        # First and last divisions are an obligation.
        parentdiv = self.root
        parentctl = self.root
        self.div_cns = []
        self.scl_transforms = []
        self.twister = []
        self.ref_twist = []

        t = transform.getTransformLookingAt(self.guide.apos[0],
                                            self.guide.apos[1],
                                            self.guide.blades["blade"].z * -1,
                                            "yx", self.negate)

        parent_twistRef = primitive.addTransform(
            self.root, self.getName("reference"),
            transform.getTransform(self.root))

        self.jointList = []
        self.preiviousCtlTag = self.parentCtlTag
        for i in range(self.settings["division"]):

            # References
            div_cns = primitive.addTransform(parentdiv,
                                             self.getName("%s_cns" % i))
            pm.setAttr(div_cns + ".inheritsTransform", False)
            self.div_cns.append(div_cns)
            parentdiv = div_cns

            parentctl = div_cns
            scl_ref = primitive.addTransform(parentctl,
                                             self.getName("%s_scl_ref" % i),
                                             transform.getTransform(parentctl))

            self.scl_transforms.append(scl_ref)

            # Deformers (Shadow)
            self.jnt_pos.append([scl_ref, i])

            # Twist references (This objects will replace the spinlookup
            # slerp solver behavior)
            t = transform.getTransformLookingAt(
                self.guide.apos[0], self.guide.apos[1],
                self.guide.blades["blade"].z * -1, "yx", self.negate)

            twister = primitive.addTransform(parent_twistRef,
                                             self.getName("%s_rot_ref" % i), t)

            ref_twist = primitive.addTransform(parent_twistRef,
                                               self.getName("%s_pos_ref" % i),
                                               t)

            ref_twist.setTranslation(datatypes.Vector(1.0, 0, 0),
                                     space="preTransform")

            self.twister.append(twister)
            self.ref_twist.append(ref_twist)

        # Connections (Hooks) ------------------------------
        self.cnx0 = primitive.addTransform(self.root, self.getName("0_cnx"))
        self.cnx1 = primitive.addTransform(self.root, self.getName("1_cnx"))
Exemple #15
0
    def addObjects(self):

        self.normal = self.guide.blades["blade"].z * -1.

        # Ik Controlers ------------------------------------
        t = tra.getTransform(self.root)
        t = tra.setMatrixPosition(t, self.guide.pos["neck"])
        self.neck_cns = pri.addTransform(self.root, self.getName("neck_cns"),
                                         t)
        t = tra.getTransformLookingAt(self.guide.pos["neck"],
                                      self.guide.pos["eff0"], self.normal,
                                      "yx", self.negate)
        t = tra.setMatrixPosition(t, self.guide.pos["neck"])
        self.neck_npo = pri.addTransform(self.neck_cns,
                                         self.getName("neck_npo"), t)

        w = self.size * 0.5
        # for compatibility reason, this name is not neck_ctl, but ik_ctl
        self.neck_ctl = self.addCtl(self.neck_npo,
                                    "ik_ctl",
                                    t,
                                    self.color_ik,
                                    "compas",
                                    w=w)
        att.setKeyableAttributes(self.neck_ctl)
        att.setRotOrder(self.neck_ctl, "ZXY")
        self.jnt_pos.append([self.neck_ctl, 0])

        t = tra.getTransformLookingAt(self.guide.pos["head"],
                                      self.guide.pos["eff1"], self.normal,
                                      "yx", self.negate)
        self.head_pos_ref = pri.addTransform(self.neck_ctl,
                                             self.getName("head_pos_ref"), t)

        # TODO: Division -----------------------------------------

        # Head ---------------------------------------------
        t = tra.getTransform(self.root)
        t = tra.setMatrixPosition(t, self.guide.pos["head"])
        self.head_cns = pri.addTransform(self.root, self.getName("head_cns"),
                                         t)

        t = tra.getTransformLookingAt(self.guide.pos["head"],
                                      self.guide.pos["eff1"], self.normal,
                                      "yx", self.negate)
        self.head_npo = pri.addTransform(self.head_cns,
                                         self.getName("head_npo"), t)

        dist = vec.getDistance(self.guide.pos["head"], self.guide.pos["eff1"])
        w = self.size * 0.5
        h = dist
        d = self.size * 0.5
        po = dt.Vector(0, dist * 0.5, 0)

        self.head_ctl = self.addCtl(self.head_npo,
                                    "head_ctl",
                                    t,
                                    self.color_fk,
                                    "cube",
                                    w=w,
                                    h=h,
                                    d=d,
                                    po=po)
        att.setRotOrder(self.head_ctl, "ZXY")
        att.setInvertMirror(self.neck_ctl, ["tx", "ry", "rz"])
        att.setInvertMirror(self.head_ctl, ["tx", "ry", "rz"])

        self.jnt_pos.append([self.head_ctl, "head"])
Exemple #16
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

        self.div_count = len(self.guide.apos) - 5

        plane = [self.guide.apos[0], self.guide.apos[-4], self.guide.apos[-3]]
        self.normal = self.getNormalFromPos(plane)
        self.binormal = self.getBiNormalFromPos(plane)

        # Heel ---------------------------------------------
        # bank pivot

        t = transform.getTransformLookingAt(self.guide.pos["heel"],
                                            self.guide.apos[-4],
                                            self.normal,
                                            "xz",
                                            self.negate)

        t = transform.setMatrixPosition(t, self.guide.pos["inpivot"])

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

        self.in_piv = primitive.addTransform(
            self.in_npo, self.getName("in_piv"), t)

        t = transform.setMatrixPosition(t, self.guide.pos["outpivot"])

        self.out_piv = primitive.addTransform(
            self.in_piv, self.getName("out_piv"), t)

        # heel
        t = transform.getTransformLookingAt(self.guide.pos["heel"],
                                            self.guide.apos[-4],
                                            self.normal,
                                            "xz",
                                            self.negate)

        self.heel_loc = primitive.addTransform(
            self.out_piv, self.getName("heel_loc"), t)

        attribute.setRotOrder(self.heel_loc, "YZX")
        self.heel_ctl = self.addCtl(self.heel_loc,
                                    "heel_ctl",
                                    t,
                                    self.color_ik,
                                    "sphere",
                                    w=self.size * .1,
                                    tp=self.parentCtlTag)

        ymt_util.setKeyableAttributesDontLockVisibility(self.heel_ctl, self.r_params)

        # Tip ----------------------------------------------
        v = datatypes.Vector(self.guide.apos[1].x,
                             self.guide.apos[-1].y,
                             self.guide.apos[1].z)
        t = transform.setMatrixPosition(t, v)
        self.tip_ctl = self.addCtl(self.heel_ctl,
                                   "tip_ctl",
                                   t,
                                   self.color_ik,
                                   "circle",
                                   w=self.size,
                                   tp=self.heel_ctl)
        ymt_util.setKeyableAttributesDontLockVisibility(self.tip_ctl, self.r_params)

        # Roll ---------------------------------------------
        if self.settings["useRollCtl"]:
            t = transform.getTransformLookingAt(self.guide.pos["heel"],
                                                self.guide.apos[-4],
                                                self.normal,
                                                "xz",
                                                self.negate)
            t = transform.setMatrixPosition(t, self.guide.pos["root"])

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

            self.roll_ctl = self.addCtl(self.roll_np,
                                        "roll_ctl",
                                        t,
                                        self.color_ik,
                                        "cylinder",
                                        w=self.size * .5,
                                        h=self.size * .5,
                                        ro=datatypes.Vector(3.1415 * .5, 0, 0),
                                        tp=self.tip_ctl)

            ymt_util.setKeyableAttributesDontLockVisibility(self.roll_ctl, ["rx", "rz"])

        # Backward Controlers ------------------------------
        bk_pos = self.guide.apos[1:-3]
        bk_pos.reverse()
        parent = self.tip_ctl
        self.bk_ctl = []
        self.bk_loc = []
        self.previousTag = self.tip_ctl

        def _add_loc_ctl(i, t, parent):

            loc = primitive.addTransform(parent, self.getName("bk%s_loc" % i), t)
            self.bk_loc.append(loc)

            if 0 < i:
                return loc

            ctl = self.addCtl(loc,
                              "bk%s_ctl" % i,
                              t,
                              self.color_ik,
                              "sphere",
                              w=self.size * .15,
                              tp=self.previousTag)

            ymt_util.setKeyableAttributesDontLockVisibility(ctl, self.r_params)
            self.previousTag = ctl
            self.bk_ctl.append(ctl)

            return ctl

        for i, pos in enumerate(bk_pos):

            if i == 0:
                t = transform.getTransform(self.heel_ctl)
                t = transform.setMatrixPosition(t, bk_pos[0])

            else:
                dir = bk_pos[i - 1]
                t = transform.getTransformLookingAt(
                    pos, dir, self.normal, "xz", self.negate)

            parent = _add_loc_ctl(i, t, parent)

        # FK Reference ------------------------------------
        self.fk_ref = primitive.addTransformFromPos(self.bk_loc[-1],
                                                    self.getName("fk_ref"),
                                                    self.guide.apos[0])
        self.fk_npo = primitive.addTransform(
            self.fk_ref,
            self.getName("fk0_npo"),
            transform.getTransform(self.bk_loc[-1]))

        # Forward Controlers ------------------------------
        self.fk_ctl = []
        self.fk_loc = []
        parent = self.fk_npo
        self.previousTag = self.tip_ctl
        for i, bk_loc in enumerate(reversed(self.bk_loc[2:])):
            t = transform.getTransform(bk_loc)
            dist = vector.getDistance(self.guide.apos[i + 1],
                                      self.guide.apos[i + 2])

            fk_loc = primitive.addTransform(
                parent, self.getName("fk%s_loc" % i), t)

            po_vec = datatypes.Vector(dist * .5 * self.n_factor, 0, 0)
            fk_ctl = self.addCtl(fk_loc,
                                 "fk%s_ctl" % i,
                                 t,
                                 self.color_fk,
                                 "cube",
                                 w=dist,
                                 h=self.size * .5,
                                 d=self.size * .5,
                                 po=po_vec,
                                 tp=self.previousTag)

            self.previousTag = fk_ctl
            ymt_util.setKeyableAttributesDontLockVisibility(fk_ctl)
            self.jnt_pos.append([fk_ctl, i])

            parent = fk_ctl
            self.fk_ctl.append(fk_ctl)
            self.fk_loc.append(fk_loc)
Exemple #17
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

        # joint Description Names
        jd_names = ast.literal_eval(
            self.settings["jointNamesDescription_custom"])
        jdn_neck = jd_names[0]
        jdn_head = jd_names[1]

        self.normal = self.guide.blades["blade"].z * -1
        self.up_axis = pm.upAxis(q=True, axis=True)

        # Ik Controlers ------------------------------------
        if self.settings["IKWorldOri"]:
            t = datatypes.TransformationMatrix()
        else:
            t = transform.getTransformLookingAt(
                self.guide.pos["tan1"],
                self.guide.pos["neck"],
                self.normal,
                "yx",
                self.negate,
            )

        t = transform.setMatrixPosition(t, self.guide.pos["neck"])

        self.ik_off = primitive.addTransform(self.root, self.getName("ik_off"),
                                             t)
        # handle Z up orientation offset
        if self.up_axis == "z" and self.settings["IKWorldOri"]:
            self.ik_off.rx.set(90)
            t = transform.getTransform(self.ik_off)

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

        self.ik_ctl = self.addCtl(
            self.ik_cns,
            "ik_ctl",
            t,
            self.color_ik,
            "compas",
            w=self.size * 0.5,
            tp=self.parentCtlTag,
        )

        attribute.setKeyableAttributes(self.ik_ctl, self.tr_params)
        attribute.setRotOrder(self.ik_ctl, "ZXY")
        attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"])

        # Tangents -----------------------------------------
        if self.settings["tangentControls"]:
            t = transform.setMatrixPosition(t, self.guide.pos["tan1"])

            self.tan1_loc = primitive.addTransform(self.ik_ctl,
                                                   self.getName("tan1_loc"), t)

            self.tan1_ctl = self.addCtl(
                self.tan1_loc,
                "tan1_ctl",
                t,
                self.color_ik,
                "sphere",
                w=self.size * 0.2,
                tp=self.ik_ctl,
            )

            attribute.setKeyableAttributes(self.tan1_ctl, self.t_params)
            attribute.setInvertMirror(self.tan1_ctl, ["tx"])

            t = transform.getTransformLookingAt(
                self.guide.pos["root"],
                self.guide.pos["tan0"],
                self.normal,
                "yx",
                self.negate,
            )

            t = transform.setMatrixPosition(t, self.guide.pos["tan0"])

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

            self.tan0_ctl = self.addCtl(
                self.tan0_loc,
                "tan0_ctl",
                t,
                self.color_ik,
                "sphere",
                w=self.size * 0.2,
                tp=self.ik_ctl,
            )

            attribute.setKeyableAttributes(self.tan0_ctl, self.t_params)
            attribute.setInvertMirror(self.tan0_ctl, ["tx"])

            # Curves -------------------------------------------
            self.mst_crv = curve.addCnsCurve(
                self.root,
                self.getName("mst_crv"),
                [self.root, self.tan0_ctl, self.tan1_ctl, self.ik_ctl],
                3,
            )

            self.slv_crv = curve.addCurve(
                self.root,
                self.getName("slv_crv"),
                [datatypes.Vector()] * 10,
                False,
                3,
            )

            self.mst_crv.setAttr("visibility", False)

        else:
            t = transform.setMatrixPosition(t, self.guide.pos["tan1"])
            self.tan1_loc = primitive.addTransform(self.ik_ctl,
                                                   self.getName("tan1_loc"), t)

            t = transform.getTransformLookingAt(
                self.guide.pos["root"],
                self.guide.pos["tan0"],
                self.normal,
                "yx",
                self.negate,
            )

            t = transform.setMatrixPosition(t, self.guide.pos["tan0"])

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

            # Curves -------------------------------------------
            self.mst_crv = curve.addCnsCurve(
                self.root,
                self.getName("mst_crv"),
                [self.root, self.tan0_loc, self.tan1_loc, self.ik_ctl],
                3,
            )

            self.slv_crv = curve.addCurve(
                self.root,
                self.getName("slv_crv"),
                [datatypes.Vector()] * 10,
                False,
                3,
            )

        self.mst_crv.setAttr("visibility", False)
        self.slv_crv.setAttr("visibility", False)

        # Division -----------------------------------------
        # The user only define how many intermediate division he wants.
        # First and last divisions are an obligation.
        parentdiv = self.root
        parentctl = self.root
        self.div_cns = []
        self.fk_ctl = []
        self.fk_npo = []
        self.scl_npo = []

        self.twister = []
        self.ref_twist = []

        # adding 1 for the head
        self.divisions = self.settings["division"] + 1

        parent_twistRef = primitive.addTransform(
            self.root,
            self.getName("reference"),
            transform.getTransform(self.root),
        )

        t = transform.getTransformLookingAt(
            self.guide.pos["root"],
            self.guide.pos["neck"],
            self.normal,
            "yx",
            self.negate,
        )

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

        self.previousCtlTag = self.parentCtlTag
        for i in range(self.divisions):

            # References
            div_cns = primitive.addTransform(parentdiv,
                                             self.getName("%s_cns" % i), t)

            pm.setAttr(div_cns + ".inheritsTransform", False)
            self.div_cns.append(div_cns)
            parentdiv = div_cns

            scl_npo = primitive.addTransform(
                parentctl,
                self.getName("%s_scl_npo" % i),
                transform.getTransform(parentctl),
            )

            # Controlers (First and last one are fake)

            if i in [self.divisions - 1]:  # 0,
                fk_ctl = primitive.addTransform(
                    scl_npo,
                    self.getName("%s_loc" % i),
                    transform.getTransform(parentctl),
                )

                fk_npo = fk_ctl
            else:
                fk_npo = primitive.addTransform(
                    scl_npo,
                    self.getName("fk%s_npo" % i),
                    transform.getTransform(parentctl),
                )

                fk_ctl = self.addCtl(
                    fk_npo,
                    "fk%s_ctl" % i,
                    transform.getTransform(parentctl),
                    self.color_fk,
                    "cube",
                    w=self.size * 0.2,
                    h=self.size * 0.05,
                    d=self.size * 0.2,
                    tp=self.previousCtlTag,
                )

                attribute.setKeyableAttributes(self.fk_ctl)
                attribute.setRotOrder(fk_ctl, "ZXY")

                self.previousCtlTag = fk_ctl

            self.fk_ctl.append(fk_ctl)

            self.scl_npo.append(scl_npo)
            self.fk_npo.append(fk_npo)
            parentctl = fk_ctl

            if i != self.divisions - 1:
                self.jnt_pos.append(
                    [fk_ctl,
                     string.replaceSharpWithPadding(jdn_neck, i + 1)])

            t = transform.getTransformLookingAt(
                self.guide.pos["root"],
                self.guide.pos["neck"],
                self.guide.blades["blade"].z * -1,
                "yx",
                self.negate,
            )

            twister = primitive.addTransform(parent_twistRef,
                                             self.getName("%s_rot_ref" % i), t)

            ref_twist = primitive.addTransform(parent_twistRef,
                                               self.getName("%s_pos_ref" % i),
                                               t)

            ref_twist.setTranslation(datatypes.Vector(0.0, 0, 1.0),
                                     space="preTransform")

            self.twister.append(twister)
            self.ref_twist.append(ref_twist)

        for x in self.fk_ctl[:-1]:
            attribute.setInvertMirror(x, ["tx", "rz", "ry"])

        # Head ---------------------------------------------
        t = transform.getTransformLookingAt(
            self.guide.pos["head"],
            self.guide.pos["eff"],
            self.normal,
            "yx",
            self.negate,
        )

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

        dist = vector.getDistance(self.guide.pos["head"],
                                  self.guide.pos["eff"])

        self.head_ctl = self.addCtl(
            self.head_cns,
            "head_ctl",
            t,
            self.color_fk,
            "cube",
            w=self.size * 0.5,
            h=dist,
            d=self.size * 0.5,
            po=datatypes.Vector(0, dist * 0.5, 0),
            tp=self.previousCtlTag,
        )

        attribute.setRotOrder(self.head_ctl, "ZXY")
        attribute.setInvertMirror(self.head_ctl, ["tx", "rz", "ry"])

        self.jnt_pos.append([self.head_ctl, jdn_head])
Exemple #18
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

        self.WIP = self.options["mode"]

        self.normal = self.getNormalFromPos(self.guide.apos)

        self.length0 = vector.getDistance(self.guide.apos[0],
                                          self.guide.apos[1])
        self.length1 = vector.getDistance(self.guide.apos[1],
                                          self.guide.apos[2])
        self.length2 = vector.getDistance(self.guide.apos[2],
                                          self.guide.apos[3])

        # 1 bone chain for upv ref
        self.legChainUpvRef = primitive.add2DChain(
            self.root, self.getName("legUpvRef%s_jnt"),
            [self.guide.apos[0], self.guide.apos[2]], self.normal, False,
            self.WIP)
        self.legChainUpvRef[1].setAttr(
            "jointOrientZ",
            self.legChainUpvRef[1].getAttr("jointOrientZ") * -1)

        # extra neutral pose
        t = transform.getTransformFromPos(self.guide.apos[0])

        self.root_npo = primitive.addTransform(self.root,
                                               self.getName("root_npo"), t)
        self.root_ctl = self.addCtl(self.root_npo,
                                    "root_ctl",
                                    t,
                                    self.color_fk,
                                    "circle",
                                    w=self.length0 / 6,
                                    tp=self.parentCtlTag)

        # FK Controlers -----------------------------------
        t = transform.getTransformLookingAt(self.guide.apos[0],
                                            self.guide.apos[1], self.normal,
                                            "xz", self.negate)
        self.fk0_npo = primitive.addTransform(self.root_ctl,
                                              self.getName("fk0_npo"), t)
        self.fk0_ctl = self.addCtl(self.fk0_npo,
                                   "fk0_ctl",
                                   t,
                                   self.color_fk,
                                   "cube",
                                   w=self.length0,
                                   h=self.size * .1,
                                   d=self.size * .1,
                                   po=datatypes.Vector(
                                       .5 * self.length0 * self.n_factor, 0,
                                       0),
                                   tp=self.root_ctl)
        attribute.setKeyableAttributes(
            self.fk0_ctl, ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"])

        t = transform.getTransformLookingAt(self.guide.apos[1],
                                            self.guide.apos[2], self.normal,
                                            "xz", self.negate)
        self.fk1_npo = primitive.addTransform(self.fk0_ctl,
                                              self.getName("fk1_npo"), t)
        self.fk1_ctl = self.addCtl(self.fk1_npo,
                                   "fk1_ctl",
                                   t,
                                   self.color_fk,
                                   "cube",
                                   w=self.length1,
                                   h=self.size * .1,
                                   d=self.size * .1,
                                   po=datatypes.Vector(
                                       .5 * self.length1 * self.n_factor, 0,
                                       0),
                                   tp=self.fk0_ctl)

        attribute.setKeyableAttributes(
            self.fk1_ctl, ["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx"])

        t = transform.getTransformLookingAt(self.guide.apos[2],
                                            self.guide.apos[3], self.normal,
                                            "xz", self.negate)

        self.fk2_npo = primitive.addTransform(self.fk1_ctl,
                                              self.getName("fk2_npo"), t)

        self.fk2_ctl = self.addCtl(self.fk2_npo,
                                   "fk2_ctl",
                                   t,
                                   self.color_fk,
                                   "cube",
                                   w=self.length2,
                                   h=self.size * .1,
                                   d=self.size * .1,
                                   po=datatypes.Vector(
                                       .5 * self.length2 * self.n_factor, 0,
                                       0),
                                   tp=self.fk1_ctl)
        attribute.setKeyableAttributes(self.fk2_ctl)

        self.fk_ctl = [self.fk0_ctl, self.fk1_ctl, self.fk2_ctl]

        for x in self.fk_ctl:
            attribute.setInvertMirror(x, ["tx", "ty", "tz"])

        # IK Controlers -----------------------------------

        self.ik_cns = primitive.addTransformFromPos(self.root_ctl,
                                                    self.getName("ik_cns"),
                                                    self.guide.pos["ankle"])

        self.ikcns_ctl = self.addCtl(self.ik_cns,
                                     "ikcns_ctl",
                                     transform.getTransformFromPos(
                                         self.guide.pos["ankle"]),
                                     self.color_ik,
                                     "null",
                                     w=self.size * .12,
                                     tp=self.root_ctl)
        attribute.setInvertMirror(self.ikcns_ctl, ["tx"])

        m = transform.getTransformLookingAt(self.guide.pos["ankle"],
                                            self.guide.pos["eff"], self.x_axis,
                                            "zx", False)

        self.ik_ctl = self.addCtl(self.ikcns_ctl,
                                  "ik_ctl",
                                  transform.getTransformFromPos(
                                      self.guide.pos["ankle"]),
                                  self.color_ik,
                                  "cube",
                                  w=self.size * .12,
                                  h=self.size * .12,
                                  d=self.size * .12,
                                  tp=self.ikcns_ctl)
        attribute.setKeyableAttributes(self.ik_ctl)
        attribute.setRotOrder(self.ik_ctl, "XZY")
        attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"])

        # upv
        v = self.guide.apos[2] - self.guide.apos[0]
        v = self.normal ^ v
        v.normalize()
        v *= self.size * .5
        v += self.guide.apos[1]

        self.upv_cns = primitive.addTransformFromPos(self.ik_ctl,
                                                     self.getName("upv_cns"),
                                                     v)

        self.upv_ctl = self.addCtl(self.upv_cns,
                                   "upv_ctl",
                                   transform.getTransform(self.upv_cns),
                                   self.color_ik,
                                   "diamond",
                                   w=self.size * .12,
                                   tp=self.root_ctl)

        if self.settings["mirrorMid"]:
            if self.negate:
                self.upv_cns.rz.set(180)
                self.upv_cns.sy.set(-1)
        else:
            attribute.setInvertMirror(self.upv_ctl, ["tx"])
        attribute.setKeyableAttributes(self.upv_ctl, self.t_params)

        # References --------------------------------------
        self.ik_ref = primitive.addTransform(
            self.ik_ctl, self.getName("ik_ref"),
            transform.getTransform(self.ik_ctl))
        self.fk_ref = primitive.addTransform(
            self.fk_ctl[2], self.getName("fk_ref"),
            transform.getTransform(self.ik_ctl))

        # Chain --------------------------------------------
        # The outputs of the ikfk2bone solver
        self.bone0 = primitive.addLocator(
            self.root_ctl, self.getName("0_bone"),
            transform.getTransform(self.fk_ctl[0]))

        self.bone0_shp = self.bone0.getShape()
        self.bone0_shp.setAttr("localPositionX", self.n_factor * .5)
        self.bone0_shp.setAttr("localScale", .5, 0, 0)
        self.bone0.setAttr("sx", self.length0)
        self.bone0.setAttr("visibility", False)

        self.bone1 = primitive.addLocator(
            self.root_ctl, self.getName("1_bone"),
            transform.getTransform(self.fk_ctl[1]))

        self.bone1_shp = self.bone1.getShape()
        self.bone1_shp.setAttr("localPositionX", self.n_factor * .5)
        self.bone1_shp.setAttr("localScale", .5, 0, 0)
        self.bone1.setAttr("sx", self.length1)
        self.bone1.setAttr("visibility", False)

        tA = transform.getTransformLookingAt(self.guide.apos[0],
                                             self.guide.apos[1], self.normal,
                                             "xz", self.negate)
        tA = transform.setMatrixPosition(tA, self.guide.apos[1])
        tB = transform.getTransformLookingAt(self.guide.apos[1],
                                             self.guide.apos[2], self.normal,
                                             "xz", self.negate)
        t = transform.getInterpolateTransformMatrix(tA, tB)
        self.ctrn_loc = primitive.addTransform(self.root,
                                               self.getName("ctrn_loc"), t)
        self.eff_loc = primitive.addTransformFromPos(self.root_ctl,
                                                     self.getName("eff_loc"),
                                                     self.guide.apos[2])

        # tws_ref
        t = transform.getRotationFromAxis(datatypes.Vector(0, -1, 0),
                                          self.normal, "xz", self.negate)
        t = transform.setMatrixPosition(t, self.guide.pos["ankle"])

        self.tws_ref = primitive.addTransform(self.eff_loc,
                                              self.getName("tws_ref"), t)

        # Mid Controler ------------------------------------
        t = transform.getTransform(self.ctrn_loc)
        self.mid_cns = primitive.addTransform(self.ctrn_loc,
                                              self.getName("mid_cns"), t)
        self.mid_ctl = self.addCtl(self.mid_cns,
                                   "mid_ctl",
                                   t,
                                   self.color_ik,
                                   "sphere",
                                   w=self.size * .2,
                                   tp=self.root_ctl)
        if self.settings["mirrorMid"]:
            if self.negate:
                self.mid_cns.rz.set(180)
                self.mid_cns.sz.set(-1)
        else:
            attribute.setInvertMirror(self.mid_ctl, ["tx", "ty", "tz"])
        attribute.setKeyableAttributes(self.mid_ctl, self.t_params)

        # Twist references ---------------------------------
        x = datatypes.Vector(0, -1, 0)
        x = x * transform.getTransform(self.eff_loc)
        z = datatypes.Vector(self.normal.x, self.normal.y, self.normal.z)
        z = z * transform.getTransform(self.eff_loc)

        m = transform.getRotationFromAxis(x, z, "xz", self.negate)
        m = transform.setMatrixPosition(m,
                                        transform.getTranslation(self.ik_ctl))

        self.tws0_loc = primitive.addTransform(
            self.root_ctl, self.getName("tws0_loc"),
            transform.getTransform(self.fk_ctl[0]))
        self.tws0_rot = primitive.addTransform(
            self.tws0_loc, self.getName("tws0_rot"),
            transform.getTransform(self.fk_ctl[0]))

        self.tws1_loc = primitive.addTransform(
            self.ctrn_loc, self.getName("tws1_loc"),
            transform.getTransform(self.ctrn_loc))
        self.tws1_rot = primitive.addTransform(
            self.tws1_loc, self.getName("tws1_rot"),
            transform.getTransform(self.ctrn_loc))

        self.tws1A_npo = primitive.addTransform(self.mid_ctl,
                                                self.getName("tws1A_npo"), tA)
        self.tws1A_loc = primitive.addTransform(self.tws1A_npo,
                                                self.getName("tws1A_loc"), tA)
        self.tws1B_npo = primitive.addTransform(self.mid_ctl,
                                                self.getName("tws1B_npo"), tB)
        self.tws1B_loc = primitive.addTransform(self.tws1B_npo,
                                                self.getName("tws1B_loc"), tB)

        self.tws2_npo = primitive.addTransform(
            self.root, self.getName("tws2_npo"),
            transform.getTransform(self.fk_ctl[2]))
        self.tws2_loc = primitive.addTransform(
            self.tws2_npo, self.getName("tws2_loc"),
            transform.getTransform(self.fk_ctl[2]))
        self.tws2_rot = primitive.addTransform(
            self.tws2_npo, self.getName("tws2_rot"),
            transform.getTransform(self.fk_ctl[2]))

        # Roll twist chain ---------------------------------
        # Arm
        self.uplegChainPos = []
        ii = 1.0 / (self.settings["div0"] + 1)
        i = 0.0
        for p in range(self.settings["div0"] + 2):
            self.uplegChainPos.append(
                vector.linearlyInterpolate(self.guide.pos["root"],
                                           self.guide.pos["knee"],
                                           blend=i))
            i = i + ii

        self.uplegTwistChain = primitive.add2DChain(
            self.root, self.getName("uplegTwist%s_jnt"), self.uplegChainPos,
            self.normal, False, self.WIP)

        # Forearm
        self.lowlegChainPos = []
        ii = 1.0 / (self.settings["div1"] + 1)
        i = 0.0
        for p in range(self.settings["div1"] + 2):
            self.lowlegChainPos.append(
                vector.linearlyInterpolate(self.guide.pos["knee"],
                                           self.guide.pos["ankle"],
                                           blend=i))
            i = i + ii

        self.lowlegTwistChain = primitive.add2DChain(
            self.root, self.getName("lowlegTwist%s_jnt"), self.lowlegChainPos,
            self.normal, False, self.WIP)
        pm.parent(self.lowlegTwistChain[0], self.mid_ctl)

        # Hand Aux chain and nonroll
        self.auxChainPos = []
        ii = .5
        i = 0.0
        for p in range(3):
            self.auxChainPos.append(
                vector.linearlyInterpolate(self.guide.pos["ankle"],
                                           self.guide.pos["eff"],
                                           blend=i))
            i = i + ii
        t = self.root.getMatrix(worldSpace=True)

        self.aux_npo = primitive.addTransform(self.root,
                                              self.getName("aux_npo"), t)
        self.auxTwistChain = primitive.add2DChain(
            self.aux_npo, self.getName("auxTwist%s_jnt"),
            self.lowlegChainPos[:3], self.normal, False, self.WIP)
        # Non Roll join ref ---------------------------------
        self.uplegRollRef = primitive.add2DChain(
            self.root, self.getName("uplegRollRef%s_jnt"),
            self.uplegChainPos[:2], self.normal, False, self.WIP)

        self.lowlegRollRef = primitive.add2DChain(
            self.aux_npo, self.getName("lowlegRollRef%s_jnt"),
            self.lowlegChainPos[:2], self.normal, False, self.WIP)
        # Divisions ----------------------------------------
        # We have at least one division at the start, the end and one for the
        # elbow. + 2 for knee angle control
        self.divisions = self.settings["div0"] + self.settings["div1"] + 4

        self.div_cns = []
        for i in range(self.divisions):

            div_cns = primitive.addTransform(self.root_ctl,
                                             self.getName("div%s_loc" % i))

            self.div_cns.append(div_cns)

            self.jnt_pos.append([div_cns, i])

        # End reference ------------------------------------
        # To help the deformation on the ankle
        self.end_ref = primitive.addTransform(self.eff_loc,
                                              self.getName("end_ref"), m)
        for a in "xyz":
            self.end_ref.attr("s%s" % a).set(1.0)
        if self.negate:
            self.end_ref.attr("ry").set(-180.0)
        self.jnt_pos.append([self.end_ref, 'end'])

        # Tangent controls
        t = transform.getInterpolateTransformMatrix(self.fk_ctl[0],
                                                    self.tws1A_npo, .5)
        self.uplegTangentA_loc = primitive.addTransform(
            self.root_ctl, self.getName("uplegTangentA_loc"),
            self.fk_ctl[0].getMatrix(worldSpace=True))

        self.uplegTangentA_npo = primitive.addTransform(
            self.uplegTangentA_loc, self.getName("uplegTangentA_npo"), t)

        self.uplegTangentA_ctl = self.addCtl(self.uplegTangentA_npo,
                                             "uplegTangentA_ctl",
                                             t,
                                             self.color_ik,
                                             "circle",
                                             w=self.size * .2,
                                             ro=datatypes.Vector(
                                                 0, 0, 1.570796),
                                             tp=self.mid_ctl)

        if self.negate:
            self.uplegTangentA_npo.rz.set(180)
            self.uplegTangentA_npo.sz.set(-1)
        attribute.setKeyableAttributes(self.uplegTangentA_ctl, self.t_params)

        t = transform.getInterpolateTransformMatrix(self.fk_ctl[0],
                                                    self.tws1A_npo, .9)
        self.uplegTangentB_npo = primitive.addTransform(
            self.tws1A_loc, self.getName("uplegTangentB_npo"), t)

        self.uplegTangentB_ctl = self.addCtl(self.uplegTangentB_npo,
                                             "uplegTangentB_ctl",
                                             t,
                                             self.color_ik,
                                             "circle",
                                             w=self.size * .1,
                                             ro=datatypes.Vector(
                                                 0, 0, 1.570796),
                                             tp=self.mid_ctl)

        if self.negate:
            self.uplegTangentB_npo.rz.set(180)
            self.uplegTangentB_npo.sz.set(-1)
        attribute.setKeyableAttributes(self.uplegTangentB_ctl, self.t_params)

        tC = self.tws1B_npo.getMatrix(worldSpace=True)
        tC = transform.setMatrixPosition(tC, self.guide.apos[2])
        t = transform.getInterpolateTransformMatrix(self.tws1B_npo, tC, .1)
        self.lowlegTangentA_npo = primitive.addTransform(
            self.tws1B_loc, self.getName("lowlegTangentA_npo"), t)

        self.lowlegTangentA_ctl = self.addCtl(self.lowlegTangentA_npo,
                                              "lowlegTangentA_ctl",
                                              t,
                                              self.color_ik,
                                              "circle",
                                              w=self.size * .1,
                                              ro=datatypes.Vector(
                                                  0, 0, 1.570796),
                                              tp=self.mid_ctl)

        if self.negate:
            self.lowlegTangentA_npo.rz.set(180)
            self.lowlegTangentA_npo.sz.set(-1)
        attribute.setKeyableAttributes(self.lowlegTangentA_ctl, self.t_params)

        t = transform.getInterpolateTransformMatrix(self.tws1B_npo, tC, .5)

        self.lowlegTangentB_loc = primitive.addTransform(
            self.root, self.getName("lowlegTangentB_loc"), tC)

        self.lowlegTangentB_npo = primitive.addTransform(
            self.lowlegTangentB_loc, self.getName("lowlegTangentB_npo"), t)

        self.lowlegTangentB_ctl = self.addCtl(self.lowlegTangentB_npo,
                                              "lowlegTangentB_ctl",
                                              t,
                                              self.color_ik,
                                              "circle",
                                              w=self.size * .2,
                                              ro=datatypes.Vector(
                                                  0, 0, 1.570796),
                                              tp=self.mid_ctl)

        if self.negate:
            self.lowlegTangentB_npo.rz.set(180)
            self.lowlegTangentB_npo.sz.set(-1)
        attribute.setKeyableAttributes(self.lowlegTangentB_ctl, self.t_params)

        t = self.mid_ctl.getMatrix(worldSpace=True)
        self.kneeTangent_npo = primitive.addTransform(
            self.mid_ctl, self.getName("kneeTangent_npo"), t)

        self.kneeTangent_ctl = self.addCtl(self.kneeTangent_npo,
                                           "kneeTangent_ctl",
                                           t,
                                           self.color_fk,
                                           "circle",
                                           w=self.size * .25,
                                           ro=datatypes.Vector(0, 0, 1.570796),
                                           tp=self.mid_ctl)

        if self.negate:
            self.kneeTangent_npo.rz.set(180)
            self.kneeTangent_npo.sz.set(-1)
        attribute.setKeyableAttributes(self.kneeTangent_ctl, self.t_params)

        # match IK FK references
        self.match_fk0_off = self.add_match_ref(self.fk_ctl[1], self.root,
                                                "matchFk0_npo", False)

        self.match_fk0 = self.add_match_ref(self.fk_ctl[0], self.match_fk0_off,
                                            "fk0_mth")

        self.match_fk1_off = self.add_match_ref(self.fk_ctl[2], self.root,
                                                "matchFk1_npo", False)

        self.match_fk1 = self.add_match_ref(self.fk_ctl[1], self.match_fk1_off,
                                            "fk1_mth")

        self.match_fk2 = self.add_match_ref(self.fk_ctl[2], self.ik_ctl,
                                            "fk2_mth")

        self.match_ik = self.add_match_ref(self.ik_ctl, self.fk2_ctl, "ik_mth")

        self.match_ikUpv = self.add_match_ref(self.upv_ctl, self.fk0_ctl,
                                              "upv_mth")

        # add visual reference
        self.line_ref = icon.connection_display_curve(
            self.getName("visalRef"), [self.upv_ctl, self.mid_ctl])
Exemple #19
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

        self.normal = self.getNormalFromPos(self.guide.apos)
        self.binormal = self.getBiNormalFromPos(self.guide.apos)

        self.length0 = vector.getDistance(
            self.guide.apos[0], self.guide.apos[1])
        self.length1 = vector.getDistance(
            self.guide.apos[1], self.guide.apos[2])
        self.length2 = vector.getDistance(
            self.guide.apos[2], self.guide.apos[3])

        # FK Controlers -----------------------------------
        # *ms* set npo @ Tpose, to make the fk rotation work
        # best with rot order"yzx"

        self.fk_cns = primitive.addTransformFromPos(
            self.root, self.getName("fk_cns"), self.guide.apos[0])

        vec_offset = ((self.guide.apos[1] - self.guide.apos[0]) * [1, 0, 0])
        tpv = self.guide.apos[0] + vec_offset

        t = transform.getTransformLookingAt(self.guide.apos[0],
                                            self.guide.apos[1],
                                            self.normal, "xz",
                                            self.negate)

        # *ms* add FK isolation
        self.fk0_npo = primitive.addTransform(
            self.fk_cns, self.getName("fk0_npo"), t)

        t = transform.getTransformLookingAt(self.guide.apos[0],
                                            self.guide.apos[1],
                                            self.normal, "xz",
                                            self.negate)

        po_off = datatypes.Vector(.35 * self.length0 * self.n_factor, 0, 0)

        self.fk0_ctl = self.addCtl(self.fk0_npo,
                                   "fk0_ctl",
                                   t,
                                   self.color_fk,
                                   "cube",
                                   w=self.length0 * .7,
                                   h=self.size * .1,
                                   d=self.size * .1,
                                   po=po_off,
                                   tp=self.parentCtlTag)
        attribute.setKeyableAttributes(self.fk0_ctl)
        # *ms* add fk roll control Simage style
        po_off = datatypes.Vector(.85 * self.length0 * self.n_factor, 0, 0)
        self.fk0_roll_ctl = self.addCtl(self.fk0_ctl,
                                        "fk0_roll_ctl",
                                        t, self.color_fk,
                                        "cube", w=self.length0 * .3,
                                        h=self.size * .1,
                                        d=self.size * 0.1,
                                        po=po_off,
                                        tp=self.fk0_ctl)

        attribute.setRotOrder(self.fk0_roll_ctl, "YZX")
        attribute.setKeyableAttributes(self.fk0_roll_ctl, ["rx"])
        self.fk0_mtx = primitive.addTransform(
            self.root, self.getName("fk0_mtx"), t)

        t = transform.setMatrixPosition(t, self.guide.apos[1])

        self.fk1_ref = primitive.addTransform(
            self.fk0_roll_ctl, self.getName("fk1_ref"), t)

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

        t = transform.getTransformLookingAt(self.guide.apos[1],
                                            self.guide.apos[2],
                                            self.normal,
                                            "xz",
                                            self.negate)

        self.fk1_npo = primitive.addTransform(
            self.fk1_loc, self.getName("fk1_npo"), t)

        po_off = datatypes.Vector(.35 * self.length1 * self.n_factor, 0, 0)
        self.fk1_ctl = self.addCtl(self.fk1_npo,
                                   "fk1_ctl",
                                   t,
                                   self.color_fk,
                                   "cube",
                                   w=self.length1 * .7,
                                   h=self.size * .1,
                                   d=self.size * .1,
                                   po=po_off, tp=self.fk0_roll_ctl)

        attribute.setKeyableAttributes(self.fk1_ctl)

        self.fk1_mtx = primitive.addTransform(
            self.fk1_ctl, self.getName("fk1_mtx"), t)

        po_off = datatypes.Vector(.85 * self.length1 * self.n_factor, 0, 0)
        self.fk1_roll_ctl = self.addCtl(self.fk1_ctl,
                                        "fk1_roll_ctl",
                                        t,
                                        self.color_fk,
                                        "cube",
                                        w=self.length1 * .3,
                                        h=self.size * .1,
                                        d=self.size * .1,
                                        po=po_off, tp=self.fk1_ctl)
        attribute.setRotOrder(self.fk1_roll_ctl, "XYZ")
        attribute.setKeyableAttributes(self.fk1_roll_ctl, ["rx"])

        t = transform.getTransformLookingAt(self.guide.apos[2],
                                            self.guide.apos[3],
                                            self.normal,
                                            "xz",
                                            self.negate)
        # *ms* buffer object to feed into ikfk solver for hand seperation
        self.fk2_mtx = primitive.addTransform(self.fk1_roll_ctl,
                                              self.getName("fk2_mtx"),
                                              t)

        # fk2_loc is need to take the effector position + bone1 rotation
        t1 = transform.getTransformLookingAt(self.guide.apos[2],
                                             self.guide.apos[1],
                                             self.normal,
                                             "-xz",
                                             self.negate)

        self.fk2_loc = primitive.addTransform(
            self.root, self.getName("fk2_loc"), t1)

        self.fk2_npo = primitive.addTransform(self.fk2_loc,
                                              self.getName("fk2_npo"),
                                              t)
        po_off = datatypes.Vector(.5 * self.length2 * self.n_factor, 0, 0)
        self.fk2_ctl = self.addCtl(self.fk2_npo,
                                   "fk2_ctl",
                                   t,
                                   self.color_fk,
                                   "cube",
                                   w=self.length2,
                                   h=self.size * .1,
                                   d=self.size * .1,
                                   po=po_off,
                                   tp=self.fk1_roll_ctl)
        attribute.setKeyableAttributes(self.fk2_ctl)

        self.fk_ctl = [self.fk0_roll_ctl, self.fk1_mtx, self.fk2_ctl]
        self.fk_ctls = [self.fk0_ctl,
                        self.fk0_roll_ctl,
                        self.fk1_ctl,
                        self.fk1_roll_ctl,
                        self.fk2_ctl]

        for x in self.fk_ctls:
            attribute.setInvertMirror(x, ["tx", "ty", "tz"])

        # IK Controlers -----------------------------------

        self.ik_cns = primitive.addTransformFromPos(
            self.root, self.getName("ik_cns"), self.guide.pos["wrist"])

        self.ikcns_ctl = self.addCtl(
            self.ik_cns,
            "ikcns_ctl",
            transform.getTransformFromPos(self.guide.pos["wrist"]),
            self.color_ik,
            "null",
            w=self.size * .12, tp=self.parentCtlTag)
        attribute.setInvertMirror(self.ikcns_ctl, ["tx", "ty", "tz"])

        if self.negate:
            m = transform.getTransformLookingAt(self.guide.pos["wrist"],
                                                self.guide.pos["eff"],
                                                self.normal,
                                                "x-y",
                                                True)
        else:
            m = transform.getTransformLookingAt(self.guide.pos["wrist"],
                                                self.guide.pos["eff"],
                                                self.normal,
                                                "xy",
                                                False)
        self.ik_ctl = self.addCtl(self.ikcns_ctl,
                                  "ik_ctl",
                                  m,
                                  self.color_ik,
                                  "cube",
                                  w=self.size * .12,
                                  h=self.size * .12,
                                  d=self.size * .12,
                                  tp=self.ikcns_ctl)
        attribute.setKeyableAttributes(self.ik_ctl)
        attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"])

        # upv
        v = self.guide.apos[2] - self.guide.apos[0]
        v = self.normal ^ v
        v.normalize()
        v *= self.size * .5
        v += self.guide.apos[1]
        # *ms* auto up vector ------------------------------
        self.upv_cns = primitive.addTransformFromPos(self.root,
                                                     self.getName("upv_cns"),
                                                     self.guide.apos[0])
        self.upv_auv = primitive.addTransformFromPos(self.root,
                                                     self.getName("upv_auv"),
                                                     self.guide.apos[0])
        self.upv_mtx = primitive.addTransformFromPos(self.upv_cns,
                                                     self.getName("upv_mtx"),
                                                     self.guide.apos[0])

        self.upv_npo = primitive.addTransformFromPos(self.upv_mtx,
                                                     self.getName("upv_npo"),
                                                     v)
        self.upv_ctl = self.addCtl(self.upv_npo,
                                   "upv_ctl",
                                   transform.getTransform(self.upv_npo),
                                   self.color_ik,
                                   "diamond",
                                   w=self.size * .12,
                                   tp=self.parentCtlTag)
        attribute.setKeyableAttributes(self.upv_ctl, self.t_params)
        attribute.setInvertMirror(self.upv_ctl, ["tx"])

        # References --------------------------------------
        # Calculate  again the transfor for the IK ref. This way align with FK
        trnIK_ref = transform.getTransformLookingAt(self.guide.pos["wrist"],
                                                    self.guide.pos["eff"],
                                                    self.normal,
                                                    "xz",
                                                    self.negate)
        self.ik_ref = primitive.addTransform(self.ik_ctl,
                                             self.getName("ik_ref"),
                                             trnIK_ref)
        self.fk_ref = primitive.addTransform(self.fk_ctl[2],
                                             self.getName("fk_ref"),
                                             trnIK_ref)

        # Chain --------------------------------------------
        # take outputs of the ikfk2bone solver
        self.bone0 = primitive.addLocator(
            self.root,
            self.getName("0_bone"),
            transform.getTransform(self.fk_ctl[0]))

        self.bone0_shp = self.bone0.getShape()
        self.bone0_shp.setAttr("localPositionX", self.n_factor * .5)
        self.bone0_shp.setAttr("localScale", .5, 0, 0)
        self.bone0.setAttr("sx", self.length0)
        self.bone0.setAttr("visibility", False)

        self.bone1 = primitive.addLocator(
            self.root,
            self.getName("1_bone"),
            transform.getTransform(self.fk_ctl[1]))

        self.bone1_shp = self.bone1.getShape()
        self.bone1_shp.setAttr("localPositionX", self.n_factor * .5)
        self.bone1_shp.setAttr("localScale", .5, 0, 0)
        self.bone1.setAttr("sx", self.length1)
        self.bone1.setAttr("visibility", False)

        self.ctrn_loc = primitive.addTransformFromPos(self.root,
                                                      self.getName("ctrn_loc"),
                                                      self.guide.apos[1])
        # eff npo --- take the effector output of gear ik solver
        self.eff_npo = primitive.addTransformFromPos(self.root,
                                                     self.getName("eff_npo"),
                                                     self.guide.apos[2])
        # eff loc --- take the fk ik blend result
        self.eff_loc = primitive.addTransformFromPos(self.eff_npo,
                                                     self.getName("eff_loc"),
                                                     self.guide.apos[2])

        # Mid Controler ------------------------------------
        self.mid_ctl = self.addCtl(self.ctrn_loc,
                                   "mid_ctl",
                                   transform.getTransform(self.ctrn_loc),
                                   self.color_ik,
                                   "sphere",
                                   w=self.size * .2,
                                   tp=self.parentCtlTag)
        attribute.setInvertMirror(self.mid_ctl, ["tx", "ty", "tz"])
        # *ms* add elbow thickness

        # Roll join ref

        self.tws0_npo = primitive.addTransform(
            self.root,
            self.getName("tws0_npo"),
            transform.getTransform(self.fk_ctl[0]))
        self.tws0_loc = primitive.addTransform(
            self.tws0_npo,
            self.getName("tws0_loc"),
            transform.getTransform(self.fk_ctl[0]))
        self.tws0_rot = primitive.addTransform(
            self.tws0_loc,
            self.getName("tws0_rot"),
            transform.getTransform(self.fk_ctl[0]))

        self.tws1_npo = primitive.addTransform(
            self.ctrn_loc,
            self.getName("tws1_npo"),
            transform.getTransform(self.ctrn_loc))
        self.tws1_loc = primitive.addTransform(
            self.tws1_npo,
            self.getName("tws1_loc"),
            transform.getTransform(self.ctrn_loc))
        self.tws1_rot = primitive.addTransform(
            self.tws1_loc,
            self.getName("tws1_rot"),
            transform.getTransform(self.ctrn_loc))

        self.tws2_loc = primitive.addTransform(
            self.tws1_npo,
            self.getName("tws2_loc"),
            transform.getTransform(self.ctrn_loc))
        self.tws2_rot = primitive.addTransform(
            self.tws2_loc,
            self.getName("tws2_rot"),
            transform.getTransform(self.ctrn_loc))

        self.tws3_npo = primitive.addTransform(
            self.root,
            self.getName("tws3_npo"),
            transform.getTransform(self.fk_ctl[2]))
        self.tws3_loc = primitive.addTransform(
            self.tws3_npo,
            self.getName("tws3_loc"),
            transform.getTransform(self.fk_ctl[2]))
        self.tws3_rot = primitive.addTransform(
            self.tws3_loc,
            self.getName("tws3_rot"),
            transform.getTransform(self.fk_ctl[2]))

        # Divisions ----------------------------------------
        # We have at least one division at the start, the end and one for the
        # elbow. + 2 for elbow angle control
        # separate up and dn limb
        self.divisions = self.settings["div0"] + self.settings["div1"] + 3 + 2
        self.divisions0 = self.settings["div0"] + 2
        self.divisions1 = self.settings["div1"] + 2

        self.div_cns = []
        self.div_cnsUp = []
        self.div_cnsDn = []
        self.div_ctls = []

        self.div_org = primitive.addTransform(
            self.root,
            self.getName("div_org"),
            transform.getTransform(self.root))
        self.previousTag = self.parentCtlTag
        for i in range(self.divisions0):

            div_cns = primitive.addTransform(
                self.div_org, self.getName("div%s_loc" % i))

            if self.negate:
                div_ctl = self.addCtl(
                    div_cns,
                    self.getName("div%s_ctl" % i),
                    transform.getTransform(div_cns),
                    self.color_fk, "square", d=self.size * .05,
                    w=self.size * .1,
                    po=datatypes.Vector(0, self.size * -0.05, 0),
                    ro=datatypes.Vector(0, 0, datatypes.radians(90)),
                    tp=self.previousTag)
            else:
                div_ctl = self.addCtl(
                    div_cns,
                    self.getName("div%s_ctl" % i),
                    transform.getTransform(div_cns),
                    self.color_fk,
                    "square",
                    d=self.size * .05,
                    w=self.size * .1,
                    po=datatypes.Vector(0, self.size * 0.05, 0),
                    ro=datatypes.Vector(0, 0, datatypes.radians(90)),
                    tp=self.previousTag)
            attribute.setKeyableAttributes(div_ctl)
            self.previousTag = div_ctl
            self.div_cns.append(div_cns)
            self.div_cnsUp.append(div_cns)
            self.jnt_pos.append([div_ctl, i])
            self.div_ctls.append(div_ctl)
        # mid division
        d = self.divisions0
        self.div_mid = primitive.addTransform(
            self.div_org,
            self.getName("div%s_loc" % d),
            transform.getTransform(self.mid_ctl))
        if self.negate:
            self.div_mid_ctl = self.addCtl(
                self.div_mid,
                self.getName("div%s_ctl" % d),
                transform.getTransform(self.div_mid),
                self.color_fk,
                "square",
                d=self.size * .05,
                w=self.size * .1,
                po=datatypes.Vector(0, self.size * -0.05, 0),
                ro=datatypes.Vector(0, 0, datatypes.radians(90)),
                tp=self.previousTag)
        else:
            self.div_mid_ctl = self.addCtl(
                self.div_mid, self.getName("div%s_ctl" % d),
                transform.getTransform(self.div_mid),
                self.color_fk,
                "square",
                d=self.size * .05,
                w=self.size * .1,
                po=datatypes.Vector(0, self.size * 0.05, 0),
                ro=datatypes.Vector(0, 0, datatypes.radians(90)),
                tp=self.previousTag)
        attribute.setKeyableAttributes(self.div_mid_ctl)
        self.previousTag = div_ctl

        self.div_cns.append(self.div_mid)
        self.jnt_pos.append([self.div_mid_ctl, self.divisions0])
        self.div_ctls.append(self.div_mid_ctl)
        # down division
        for i in range(self.divisions1):

            dd = i + self.divisions1 + 1
            div_cns = primitive.addTransform(
                self.div_org, self.getName("div%s_loc" % dd))
            if self.negate:
                div_ctl = self.addCtl(
                    div_cns,
                    self.getName("div%s_ctl" % dd),
                    transform.getTransform(div_cns),
                    self.color_fk,
                    "square",
                    d=self.size * .05,
                    w=self.size * .1,
                    po=datatypes.Vector(0, self.size * -0.05, 0),
                    ro=datatypes.Vector(0, 0, datatypes.radians(90)),
                    tp=self.previousTag)
            else:
                div_ctl = self.addCtl(
                    div_cns,
                    self.getName("div%s_ctl" % dd),
                    transform.getTransform(div_cns),
                    self.color_fk,
                    "square",
                    d=self.size * .05,
                    w=self.size * .1,
                    po=datatypes.Vector(0, self.size * 0.05, 0),
                    ro=datatypes.Vector(0, 0, datatypes.radians(90)),
                    tp=self.previousTag)
            attribute.setKeyableAttributes(div_ctl)
            self.previousTag = div_ctl

            self.div_cns.append(div_cns)
            self.div_cnsDn.append(div_cns)
            self.jnt_pos.append([div_ctl, i + self.divisions0 + 1])
            self.div_ctls.append(div_ctl)

        # End reference ------------------------------------
        # To help the deformation on the wrist
        self.jnt_pos.append([self.eff_loc, 'end'])

        # match IK FK references

        self.match_fk0 = self.add_match_ref(self.fk_ctl[0],
                                            self.root,
                                            "fk0_mth")

        self.match_fk1 = self.add_match_ref(self.fk_ctl[1],
                                            self.root,
                                            "fk1_mth")

        self.match_fk2 = self.add_match_ref(self.fk_ctl[2],
                                            self.ik_ctl,
                                            "fk2_mth")

        self.match_ik = self.add_match_ref(self.ik_ctl,
                                           self.fk2_ctl,
                                           "ik_mth")

        self.match_ikUpv = self.add_match_ref(self.upv_ctl,
                                              self.fk0_roll_ctl,
                                              "upv_mth")

        # add visual reference
        self.line_ref = icon.connection_display_curve(
            self.getName("visalRef"), [self.upv_ctl, self.mid_ctl])
    def addObjects(self):
        """Add all the objects needed to create the component."""

        self.up_axis = pm.upAxis(q=True, axis=True)

        self.div_count = len(self.guide.apos) - 5

        plane = [self.guide.apos[0], self.guide.apos[-4], self.guide.apos[-3]]
        self.normal = self.getNormalFromPos(plane)
        self.binormal = self.getBiNormalFromPos(plane)

        # Heel ---------------------------------------------
        # bank pivot

        t = transform.getTransformLookingAt(self.guide.pos["heel"],
                                            self.guide.apos[-4], self.normal,
                                            "xz", self.negate)

        t = transform.setMatrixPosition(t, self.guide.pos["inpivot"])

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

        self.in_piv = primitive.addTransform(self.in_npo,
                                             self.getName("in_piv"), t)

        t = transform.setMatrixPosition(t, self.guide.pos["outpivot"])

        self.out_piv = primitive.addTransform(self.in_piv,
                                              self.getName("out_piv"), t)

        # heel
        t = transform.getTransformLookingAt(self.guide.pos["heel"],
                                            self.guide.apos[-4], self.normal,
                                            "xz", self.negate)

        self.heel_loc = primitive.addTransform(self.out_piv,
                                               self.getName("heel_loc"), t)

        attribute.setRotOrder(self.heel_loc, "YZX")
        self.heel_ctl = self.addCtl(self.heel_loc,
                                    "heel_ctl",
                                    t,
                                    self.color_ik,
                                    "sphere",
                                    w=self.size * .1,
                                    tp=self.parentCtlTag)

        attribute.setKeyableAttributes(self.heel_ctl, self.r_params)

        # Tip ----------------------------------------------
        if self.up_axis == "y":
            v = datatypes.Vector(self.guide.apos[-5].x,
                                 self.guide.pos["heel"].y,
                                 self.guide.apos[-5].z)
        else:
            v = datatypes.Vector(self.guide.apos[-5].x, self.guide.apos[-5].y,
                                 self.guide.pos["heel"].z)
        t = transform.setMatrixPosition(t, v)
        self.tip_ctl = self.addCtl(self.heel_ctl,
                                   "tip_ctl",
                                   t,
                                   self.color_ik,
                                   "circle",
                                   w=self.size,
                                   tp=self.heel_ctl)
        attribute.setKeyableAttributes(self.tip_ctl, self.r_params)

        # Roll ---------------------------------------------
        if self.settings["useRollCtl"]:
            t = transform.getTransformLookingAt(self.guide.pos["heel"],
                                                self.guide.apos[-4],
                                                self.normal, "xz", self.negate)
            t = transform.setMatrixPosition(t, self.guide.pos["root"])

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

            self.roll_ctl = self.addCtl(self.roll_np,
                                        "roll_ctl",
                                        t,
                                        self.color_ik,
                                        "cylinder",
                                        w=self.size * .5,
                                        h=self.size * .5,
                                        ro=datatypes.Vector(3.1415 * .5, 0, 0),
                                        tp=self.tip_ctl)

            attribute.setKeyableAttributes(self.roll_ctl, ["rx", "rz"])

        # Backward Controlers ------------------------------
        bk_pos = self.guide.apos[1:-3]
        bk_pos.reverse()
        parent = self.tip_ctl
        self.bk_ctl = []
        self.bk_loc = []
        self.previousTag = self.tip_ctl
        for i, pos in enumerate(bk_pos):

            if i == 0:
                t = transform.getTransform(self.heel_ctl)
                t = transform.setMatrixPosition(t, pos)
            else:
                direction = bk_pos[i - 1]
                t = transform.getTransformLookingAt(pos, direction,
                                                    self.normal, "xz",
                                                    self.negate)

            bk_loc = primitive.addTransform(parent,
                                            self.getName("bk%s_loc" % i), t)
            bk_ctl = self.addCtl(bk_loc,
                                 "bk%s_ctl" % i,
                                 t,
                                 self.color_ik,
                                 "sphere",
                                 w=self.size * .15,
                                 tp=self.previousTag)
            attribute.setKeyableAttributes(bk_ctl, self.r_params)
            self.previousTag = bk_ctl

            self.bk_loc.append(bk_loc)
            self.bk_ctl.append(bk_ctl)
            parent = bk_ctl

        # FK Reference ------------------------------------
        self.fk_ref = primitive.addTransformFromPos(self.bk_ctl[-1],
                                                    self.getName("fk_ref"),
                                                    self.guide.apos[0])
        self.fk_npo = primitive.addTransform(
            self.fk_ref, self.getName("fk0_npo"),
            transform.getTransform(self.bk_ctl[-1]))

        # Forward Controlers ------------------------------
        self.fk_ctl = []
        self.fk_loc = []
        parent = self.fk_npo
        self.previousTag = self.tip_ctl
        for i, bk_ctl in enumerate(reversed(self.bk_ctl[1:])):
            if i == len(self.bk_ctl) - 2:
                t = transform.getTransform(self.tip_ctl)
                v = transform.getTranslation(bk_ctl)
                t = transform.setMatrixPosition(t, v)
            else:
                t = transform.getTransform(bk_ctl)
            dist = vector.getDistance(self.guide.apos[i + 1],
                                      self.guide.apos[i + 2])

            fk_loc = primitive.addTransform(parent,
                                            self.getName("fk%s_loc" % i), t)

            po_vec = datatypes.Vector(dist * .5 * self.n_factor, 0, 0)
            fk_ctl = self.addCtl(fk_loc,
                                 "fk%s_ctl" % i,
                                 t,
                                 self.color_fk,
                                 "cube",
                                 w=dist,
                                 h=self.size * .5,
                                 d=self.size * .5,
                                 po=po_vec,
                                 tp=self.previousTag)

            self.previousTag = fk_ctl
            attribute.setKeyableAttributes(fk_ctl)
            if i:
                name = "ball" + str(i)
            else:
                name = "ball"
            self.jnt_pos.append([fk_ctl, name])

            parent = fk_ctl
            self.fk_ctl.append(fk_ctl)
            self.fk_loc.append(fk_loc)
    def addObjects(self):
        """Add all the objects needed to create the component."""

        # Auto bend with position controls  -------------------
        if self.settings["autoBend"]:
            self.autoBendChain = primitive.add2DChain(
                self.root, self.getName("autoBend%s_jnt"),
                [self.guide.apos[0], self.guide.apos[-1]],
                self.guide.blades["blade"].z * -1, False, True)

            for j in self.autoBendChain:
                j.drawStyle.set(2)

        # Ik Controlers ------------------------------------
        if self.settings["IKWorldOri"]:
            t = datatypes.TransformationMatrix()
            t = transform.setMatrixPosition(t, self.guide.apos[0])
        else:
            t = transform.getTransformLookingAt(
                self.guide.apos[0], self.guide.apos[-1],
                self.guide.blades["blade"].z * -1, "yx", self.negate)

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

        self.ik0_ctl = self.addCtl(self.ik0_npo,
                                   "ik0_ctl",
                                   t,
                                   self.color_ik,
                                   "compas",
                                   w=self.size,
                                   tp=self.parentCtlTag)

        attribute.setKeyableAttributes(self.ik0_ctl, self.tr_params)
        attribute.setRotOrder(self.ik0_ctl, "ZXY")
        attribute.setInvertMirror(self.ik0_ctl, ["tx", "ry", "rz"])

        # hip base joint
        # TODO: add option in setting for on/off
        if True:
            self.hip_lvl = primitive.addTransform(self.ik0_ctl,
                                                  self.getName("hip_lvl"), t)
            self.jnt_pos.append([self.hip_lvl, "hip"])

        t = transform.setMatrixPosition(t, self.guide.apos[-1])
        if self.settings["autoBend"]:
            self.autoBend_npo = primitive.addTransform(
                self.root, self.getName("spinePosition_npo"), t)

            self.autoBend_ctl = self.addCtl(self.autoBend_npo,
                                            "spinePosition_ctl",
                                            t,
                                            self.color_ik,
                                            "square",
                                            w=self.size,
                                            d=.3 * self.size,
                                            tp=self.parentCtlTag)

            attribute.setKeyableAttributes(self.autoBend_ctl,
                                           ["tx", "ty", "tz", "ry"])

            attribute.setInvertMirror(self.autoBend_ctl, ["tx", "ry"])

            self.ik1_npo = primitive.addTransform(self.autoBendChain[0],
                                                  self.getName("ik1_npo"), t)

            self.ik1autoRot_lvl = primitive.addTransform(
                self.ik1_npo, self.getName("ik1autoRot_lvl"), t)

            self.ik1_ctl = self.addCtl(self.ik1autoRot_lvl,
                                       "ik1_ctl",
                                       t,
                                       self.color_ik,
                                       "compas",
                                       w=self.size,
                                       tp=self.autoBend_ctl)
        else:
            t = transform.setMatrixPosition(t, self.guide.apos[-1])
            self.ik1_npo = primitive.addTransform(self.root,
                                                  self.getName("ik1_npo"), t)

            self.ik1_ctl = self.addCtl(self.ik1_npo,
                                       "ik1_ctl",
                                       t,
                                       self.color_ik,
                                       "compas",
                                       w=self.size,
                                       tp=self.ik0_ctl)

        attribute.setKeyableAttributes(self.ik1_ctl, self.tr_params)
        attribute.setRotOrder(self.ik1_ctl, "ZXY")
        attribute.setInvertMirror(self.ik1_ctl, ["tx", "ry", "rz"])

        # Tangent controllers -------------------------------
        if self.settings["centralTangent"]:
            # vec_pos = vector.linearlyInterpolate(self.guide.apos[0],
            #                                      self.guide.apos[-1],
            #                                      .33)
            vec_pos = self.guide.pos["tan0"]
            t = transform.setMatrixPosition(t, vec_pos)

            self.tan0_npo = primitive.addTransform(self.ik0_ctl,
                                                   self.getName("tan0_npo"), t)

            self.tan0_off = primitive.addTransform(self.tan0_npo,
                                                   self.getName("tan0_off"), t)

            self.tan0_ctl = self.addCtl(self.tan0_off,
                                        "tan0_ctl",
                                        t,
                                        self.color_ik,
                                        "sphere",
                                        w=self.size * .1,
                                        tp=self.ik0_ctl)

            attribute.setKeyableAttributes(self.tan0_ctl, self.t_params)
            # vec_pos = vector.linearlyInterpolate(self.guide.apos[0],
            #                                      self.guide.apos[-1],
            #                                      .66)
            vec_pos = self.guide.pos["tan1"]
            t = transform.setMatrixPosition(t, vec_pos)

            self.tan1_npo = primitive.addTransform(self.ik1_ctl,
                                                   self.getName("tan1_npo"), t)

            self.tan1_off = primitive.addTransform(self.tan1_npo,
                                                   self.getName("tan1_off"), t)

            self.tan1_ctl = self.addCtl(self.tan1_off,
                                        "tan1_ctl",
                                        t,
                                        self.color_ik,
                                        "sphere",
                                        w=self.size * .1,
                                        tp=self.ik0_ctl)

            attribute.setKeyableAttributes(self.tan1_ctl, self.t_params)

            # Tangent mid control
            vec_pos = vector.linearlyInterpolate(self.guide.apos[0],
                                                 self.guide.apos[-1], .5)
            t = transform.setMatrixPosition(t, vec_pos)

            self.tan_npo = primitive.addTransform(self.tan0_npo,
                                                  self.getName("tan_npo"), t)

            self.tan_ctl = self.addCtl(self.tan_npo,
                                       "tan_ctl",
                                       t,
                                       self.color_fk,
                                       "sphere",
                                       w=self.size * .2,
                                       tp=self.ik1_ctl)

            attribute.setKeyableAttributes(self.tan_ctl, self.t_params)
            attribute.setInvertMirror(self.tan_ctl, ["tx"])

        else:
            # vec_pos = vector.linearlyInterpolate(self.guide.apos[0],
            #                                      self.guide.apos[-1],
            #                                      .33)
            vec_pos = self.guide.pos["tan0"]
            t = transform.setMatrixPosition(t, vec_pos)

            self.tan0_npo = primitive.addTransform(self.ik0_ctl,
                                                   self.getName("tan0_npo"), t)

            self.tan0_ctl = self.addCtl(self.tan0_npo,
                                        "tan0_ctl",
                                        t,
                                        self.color_ik,
                                        "sphere",
                                        w=self.size * .2,
                                        tp=self.ik0_ctl)

            attribute.setKeyableAttributes(self.tan0_ctl, self.t_params)

            # vec_pos = vector.linearlyInterpolate(self.guide.apos[0],
            #                                      self.guide.apos[-1],
            #                                      .66)
            vec_pos = self.guide.pos["tan1"]
            t = transform.setMatrixPosition(t, vec_pos)

            self.tan1_npo = primitive.addTransform(self.ik1_ctl,
                                                   self.getName("tan1_npo"), t)

            self.tan1_ctl = self.addCtl(self.tan1_npo,
                                        "tan1_ctl",
                                        t,
                                        self.color_ik,
                                        "sphere",
                                        w=self.size * .2,
                                        tp=self.ik1_ctl)

            attribute.setKeyableAttributes(self.tan1_ctl, self.t_params)

        attribute.setInvertMirror(self.tan0_ctl, ["tx"])
        attribute.setInvertMirror(self.tan1_ctl, ["tx"])

        # Curves -------------------------------------------
        self.mst_crv = curve.addCnsCurve(
            self.root, self.getName("mst_crv"),
            [self.ik0_ctl, self.tan0_ctl, self.tan1_ctl, self.ik1_ctl], 3)
        self.slv_crv = curve.addCurve(self.root, self.getName("slv_crv"),
                                      [datatypes.Vector()] * 10, False, 3)
        self.mst_crv.setAttr("visibility", False)
        self.slv_crv.setAttr("visibility", False)

        # Division -----------------------------------------
        # The user only define how many intermediate division he wants.
        # First and last divisions are an obligation.
        parentdiv = self.root
        parentctl = self.root
        self.div_cns = []
        self.fk_ctl = []
        self.fk_npo = []
        self.scl_transforms = []
        self.twister = []
        self.ref_twist = []

        t = transform.getTransformLookingAt(self.guide.apos[0],
                                            self.guide.apos[-1],
                                            self.guide.blades["blade"].z * -1,
                                            "yx", self.negate)

        parent_twistRef = primitive.addTransform(
            self.root, self.getName("reference"),
            transform.getTransform(self.root))

        self.jointList = []
        self.preiviousCtlTag = self.parentCtlTag
        for i in range(self.settings["division"]):

            # References
            div_cns = primitive.addTransform(parentdiv,
                                             self.getName("%s_cns" % i))
            pm.setAttr(div_cns + ".inheritsTransform", False)
            self.div_cns.append(div_cns)
            parentdiv = div_cns

            # Controlers (First and last one are fake)
            # if i in [0]:
            # TODO: add option setting to add or not the first and
            #  last controller for the fk
            if i in [0, self.settings["division"] - 1] and False:
                # if i in [0, self.settings["division"] - 1]:
                fk_ctl = primitive.addTransform(
                    parentctl, self.getName("%s_loc" % i),
                    transform.getTransform(parentctl))

                fk_npo = fk_ctl
                if i in [self.settings["division"] - 1]:
                    self.fk_ctl.append(fk_ctl)
            else:
                m = transform.getTransform(self.root)
                t = transform.getTransform(parentctl)
                m.inverse()

                fk_npo = primitive.addTransform(parentctl,
                                                self.getName("fk%s_npo" % (i)),
                                                t)

                fk_ctl = self.addCtl(fk_npo,
                                     "fk%s_ctl" % (i),
                                     transform.getTransform(parentctl),
                                     self.color_fk,
                                     "cube",
                                     w=self.size,
                                     h=self.size * .05,
                                     d=self.size,
                                     tp=self.preiviousCtlTag)

                attribute.setKeyableAttributes(self.fk_ctl)
                attribute.setRotOrder(fk_ctl, "ZXY")
                self.fk_ctl.append(fk_ctl)
                self.preiviousCtlTag = fk_ctl

            self.fk_npo.append(fk_npo)
            parentctl = fk_ctl
            scl_ref = primitive.addTransform(parentctl,
                                             self.getName("%s_scl_ref" % i),
                                             transform.getTransform(parentctl))

            self.scl_transforms.append(scl_ref)

            # Deformers (Shadow)
            self.jnt_pos.append([scl_ref, i])

            # Twist references (This objects will replace the spinlookup
            # slerp solver behavior)
            t = transform.getTransformLookingAt(
                self.guide.apos[0], self.guide.apos[-1],
                self.guide.blades["blade"].z * -1, "yx", self.negate)

            twister = primitive.addTransform(parent_twistRef,
                                             self.getName("%s_rot_ref" % i), t)

            ref_twist = primitive.addTransform(parent_twistRef,
                                               self.getName("%s_pos_ref" % i),
                                               t)

            ref_twist.setTranslation(datatypes.Vector(1.0, 0, 0),
                                     space="preTransform")

            self.twister.append(twister)
            self.ref_twist.append(ref_twist)

            # TODO: update this part with the optiona FK controls update
            for x in self.fk_ctl[:-1]:
                attribute.setInvertMirror(x, ["tx", "rz", "ry"])

        # Connections (Hooks) ------------------------------
        self.cnx0 = primitive.addTransform(self.root, self.getName("0_cnx"))
        self.cnx1 = primitive.addTransform(self.root, self.getName("1_cnx"))
    def _addObjectsFkControl(self, i, parentdiv, parentctl, t, parent_twistRef):
        # References
        tm = datatypes.TransformationMatrix(t)
        tm.addRotation([0., 0., math.pi / -2.], 'XYZ', om.MSpace.kObject)  # TODO: align with convention
        tm.addRotation([0., math.pi / -2., 0], 'XYZ', om.MSpace.kObject)
        global_t  = datatypes.Matrix(tm)

        # global input
        div_cns = addTransform(parentdiv, self.getName("%s_cns" % i))
        div_cns_npo = addTransform(div_cns, self.getName("%s_cns_npo" % i))
        pm.setAttr(div_cns + ".inheritsTransform", False)
        div_cns.setMatrix(global_t, worldSpace=True)
        self.div_cns.append(div_cns)
        self.div_cns_npo.append(div_cns_npo)
        parentdiv = div_cns

        # t = getTransform(parentctl)
        if i == 0:
            p = parentctl
        else:
            # p = self.scl_transforms[i - 1]
            p = self.fk_local_in[i - 1]
        fk_npo = addTransform(p, self.getName("fk%s_npo" % (i)), global_t)

        # local input
        fk_local_npo = addTransform(fk_npo, self.getName("fk%s_local_npo" % i), global_t)
        fk_local_in = addTransform(fk_local_npo, self.getName("fk%s_local_in" % i), global_t)
        self.fk_local_in.append(fk_local_in)

        if i < len(self.guide.apos) - 1:
            h = (self.guide.apos[i] - self.guide.apos[i + 1]).length() * .8
        else:
            h = (self.guide.apos[-1] - self.guide.apos[0]).length() / (len(self.guide.apos) - 1)

        # FIXME: rotate by blade
        po = datatypes.Vector([0, h / 2., 0])

        fk_ctl = self.addCtl(
            fk_local_in,
            "fk%s_ctl" % (i),
            global_t,
            self.color_fk,
            "cube",
            w=h * .66,
            h=h,
            d=h * 0.3,
            # ro=datatypes.Vector([0, -math.pi / 2., 0]),
            po=po,
            tp=self.preiviousCtlTag,
            mirrorConf=self.mirror_conf)

        ymt_util.setKeyableAttributesDontLockVisibility(self.fk_ctl)
        attribute.setRotOrder(fk_ctl, "ZXY")
        self.fk_ctl.append(fk_ctl)
        self.preiviousCtlTag = fk_ctl

        self.fk_npo.append(fk_npo)
        self.fk_local_npo.append(fk_local_npo)
        parentctl = fk_ctl
        scl_ref = addTransform(parentctl, self.getName("%s_scl_ref" % i), getTransform(parentctl))
        self.scl_transforms.append(scl_ref)

        if i == 0 and self.settings["isSplitHip"]:
            t = self._getTransformWithRollByBlade(getTransform(self.guide.root))
            h = (self.guide.apos[-1] - self.guide.apos[0]).length() / (len(self.guide.apos) - 1)
            po = datatypes.Vector([0, self.size / len(self.guide.apos) * -.8, 0])
            hip_fk_local_in = addTransform(p, self.getName("hip_fk_local_in"), t)
            self.hip_fk_local_in = hip_fk_local_in

            self.fk_hip_ctl = self.addCtl(
                hip_fk_local_in,
                "fk_hip_ctl",
                t,
                self.color_fk,
                "cube",
                w=h * .66,
                h=h,
                d=h * 0.3,
                # ro=datatypes.Vector([0, -math.pi / 2., 0]),
                po=po,
                tp=self.preiviousCtlTag,
                mirrorConf=self.mirror_conf)
            hip_scl_ref = addTransform(self.fk_hip_ctl, self.getName("hip_scl_ref"), t)

        # Deformers (Shadow)
        if self.settings["addJoints"]:
            if self.settings["isSplitHip"]:
                if i == 0:
                    self.jnt_pos.append([hip_scl_ref, 0])

                self.jnt_pos.append([scl_ref, i + 1])

            else:
                self.jnt_pos.append([scl_ref, i])

        # Twist references (This objects will replace the spinlookup
        # slerp solver behavior)
        t = transform.getTransformLookingAt(
            self.guide.apos[0],
            self.guide.apos[-1],
            self.guide.blades["blade"].z * -1,
            "yx",
            self.negate)

        twister = addTransform(
            parent_twistRef, self.getName("%s_rot_ref" % i), t)

        ref_twist = addTransform(
            parent_twistRef, self.getName("%s_pos_ref" % i), t)

        ref_twist.setTranslation(
            datatypes.Vector(1.0, 0, 0), space="preTransform")

        self.twister.append(twister)
        self.ref_twist.append(ref_twist)

        for x in self.fk_ctl:
            attribute.setInvertMirror(x, ["tx", "rz", "ry"])
        attribute.setInvertMirror(self.fk_hip_ctl, ["tx", "rz", "ry"])

        return parentdiv, parentctl