Exemple #1
0
def getMatrixFromVector(forward, up=None, forward_axis='z', location=None):
    """
    Creates a rotation from given forward direction and up direction. Which is then used to calculate a matrix.

    Args:
        forward (Any): Vector that faces forward.

        up (Any): Vector that faces up. If none given will use scene up axis.

        forward_axis (string): What local vector will face forward in the matrix.

        location (Any): Where the matrix should be in world space. If none given, will be at origin.

    Returns:
        (pm.nodetypes.Matrix): Matrix calculated from given forward vector.
    """
    scene_up = pm.upAxis(axis=True, q=True)
    scene_up = convert.axisToVector(scene_up)
    up = convert.toVector(up, invalid_default=scene_up)

    right = forward.cross(up).normal()
    up = right.cross(forward).normal()
    matrix = []

    if forward_axis == 'x':
        matrix = [forward.get(), up.get(), right.get()]
    elif forward_axis == 'y':
        matrix = [up.get(), forward.get(), right.get()]
    elif forward_axis == 'z':
        matrix = [(right * -1).get(), up.get(), forward.get()]

    location = convert.toVector(location, invalid_default=True)
    matrix.append(location)
    return pm.dt.Matrix(*matrix)
Exemple #2
0
def calcOutVector(start, middle, end):
    '''
    Given the lead joint of 3, determine the vector pointing directly away along the xz plane.
    
    ..  todo::
        Gracefully handle if the ik is on the xz plane already.
    '''

    s = dt.Vector(xform(start, q=1, ws=1, t=1))
    m = dt.Vector(xform(middle, q=1, ws=1, t=1))
    e = dt.Vector(xform(end, q=1, ws=1, t=1))

    up = s - e

    if upAxis(q=True, ax=True) == 'y':
        kneeScale = (m.y - e.y) / up.y if up.y else 0.0
    else:
        kneeScale = (m.z - e.z) / up.z if up.z else 0.0

    modifiedUp = kneeScale * up
    newPos = modifiedUp + e

    outFromKnee = m - newPos

    angleBetween = (m - s).angle(e - m)

    log.TooStraight.check(angleBetween)

    outFromKnee.normalize()

    return outFromKnee
Exemple #3
0
    def create_rig(self, parent):

        # -- We're given the skeleton component instance, so we can
        # -- utilise the find method to find the joint we need to build
        # -- a control against
        root_joint = self.find_first('RootJoint')

        # -- Create a transform to use as a control
        root_control = crab.create.control(
            description='Rig%s' % self.options.description,
            side=self.options.side,
            parent=parent,
            match_to=root_joint,
            shape='cog',
            lock_list=self.options.lock,
            hide_list=self.options.hide,
        )

        location_control = crab.create.control(
            description='%s' % self.options.description,
            side=self.options.side,
            parent=root_control,
            match_to=root_control,
            shape='arrow_x',
            lock_list=self.options.lock,
            hide_list=self.options.hide,
        )
        print('---')
        if pm.upAxis(q=True, axis=True).upper() == 'Y':
            crab.utils.shapes.spin(location_control, y=-90)

        # -- All joints should have a binding. The binding allows crab
        # -- to know what control parent to utilise when building skeletal
        # -- components.
        # -- The act of binding also constrains the skeleton joint to the
        # -- control
        self.bind(
            root_joint,
            root_control,
            constrain=False,
        )

        # -- Constrain the joint to the location
        pm.parentConstraint(
            location_control,
            root_joint,
            mo=False,
        )

        # -- Constrain the joint to the location
        pm.scaleConstraint(
            location_control,
            root_joint,
            mo=False,
        )

        # -- Select our tip joint
        pm.select(root_control)

        return True
Exemple #4
0
def get_likely_mirror_plane(node):
    """
    Looks at the worldspace transform of a node and returns a mirror
    plane string of either XY, YZ or XZ
    
    The worldspace translation of the node is used to determine this.
    
    :param node: Node to test
    :type node: pm.nt.Transform
    
    :return: str
    """
    position = [abs(n) for n in node.getTranslation(node, worldSpace=True)]

    # -- We're only interested in a two dimensional plane, so pop
    # -- out the Y axis
    if pm.upAxis(q=True, axis=True) == 'y':
        position.pop(1)

    else:
        position.pop(2)

    # -- Of the X and Z plane, get the prominent one
    prominent_axis = position.index(max(position))

    if prominent_axis == 0:
        return 'YZ'

    else:
        return 'XZ'
Exemple #5
0
def refine_from_up_axis(position, up_axis='z'):
    """
    This will take a position vector, and alter it if the up axis is 
    set to Z. This is because it is assumed that all shapes are drawn
    within a Y-Up orientation.
    
    :param position: List of length3
     
    :return: List of length 3 
    """
    # -- Get the current axis setting
    current_up_axis = pm.upAxis(q=True, axis=True)

    # -- If we're working in the same axis space as the stored shape
    # -- then we can simply return the list as it is
    if current_up_axis == up_axis:
        return position

    # -- We now have to wrangle the data
    altered_position = [
        position[0],
        position[2],
        position[1] * -1,
    ]

    return altered_position
Exemple #6
0
def calcOutVector(start, middle, end):
    '''
    Given the lead joint of 3, determine the vector pointing directly away along the xz plane.
    
    ..  todo::
        Gracefully handle if the ik is on the xz plane already.
    '''

    s = dt.Vector(xform(start, q=1, ws=1, t=1))
    m = dt.Vector(xform(middle, q=1, ws=1, t=1))
    e = dt.Vector(xform(end, q=1, ws=1, t=1))

    up = s - e

    if upAxis(q=True, ax=True) == 'y':
        kneeScale = (m.y - e.y) / up.y if up.y else 0.0
    else:
        kneeScale = (m.z - e.z) / up.z if up.z else 0.0

    modifiedUp = kneeScale * up
    newPos = modifiedUp + e

    outFromKnee = m - newPos
    outFromKnee.normalize()

    # If we are halfway to the x/z plane, lerp between the old formula and a new one
    testUp = dt.Vector(up)
    if testUp.y < 0:
        testUp.y *= -1.0

    angleToVertical = dt.Vector(0, 1, 0).angle(testUp)

    if angleToVertical > _45_DEGREES:
        # Calculate a point perpendicular to the line created by the start and end
        # going through the middle
        theta = up.angle(m - e)

        distToMidpoint = math.cos(theta) * (m - e).length()

        midPoint = distToMidpoint * up.normal() + e

        altOutFromKnee = m - midPoint

        altOutFromKnee.normalize()

        # lerp between the vectors
        percent = (
            angleToVertical - _45_DEGREES
        ) / _45_DEGREES  # 45 to up axis will favor old, on y axis favors new
        outFromKnee = slerp(outFromKnee, altOutFromKnee, percent)

    angleBetween = (m - s).angle(e - m)

    log.TooStraight.check(angleBetween)

    outFromKnee.normalize()

    return outFromKnee
Exemple #7
0
def read(node):
    """
    Looks at all the NurbsCurve shape nodes under  the given node
    and attempts to read them
    """
    shapes = list()

    # -- If we have a transform, add any nurbs curves
    # -- from it
    for shape in node.getShapes():
        if isinstance(shape, pm.nt.NurbsCurve):
            shapes.append(shape)

    if not shapes:
        return None

    # -- Define out output data. Right now we're only storing
    # -- cv's, but we wrap it in a dict so we can expand it
    # -- later without compatibility issues.
    data = dict(
        node=node.name(),
        curves=list(),
        up_axis=pm.upAxis(q=True, axis=True),
    )

    # -- Cycle the shapes and store thm
    for shape in shapes:

        node_data = dict(cvs=list(),
                         form=shape.f.get(),
                         degree=shape.degree(),
                         knots=shape.getKnots())

        # -- Collect the positional data to an accuracy that is
        # -- reasonable.
        for cv in shape.getCVs():
            node_data['cvs'].append([round(value, 5) for value in cv])

        data['curves'].append(node_data)

    return data
Exemple #8
0
def resolve_translation(vector):
    """
    This assumes a list of length 3 in the order of X, Y, Z where Y is considered the
    'up axis'. If the up axis of the application is indeed Y, then the vector is returned
    untouched. However, if the up-axis is Z then the vector is mutated.

    :param vector: Translation vector
    :type vector: list(x, y, z)

    :return: list(float, float, float)
    """

    if pm.upAxis(q=True, axis=True) == 'y':
        return vector

    return [
        vector[2],
        vector[0],
        vector[1],

    ]
Exemple #9
0
def getMatrixFromVector(forward, up=None, forward_axis='z', location=None):
    """
    Creates a rotation from given forward direction and up direction. Which is then used to calculate a matrix.

    Args:
        forward (Any): Vector that faces forward.

        up (Any): Vector that faces up. If none given will use scene up axis.

        forward_axis (string): What local vector will face forward in the matrix.

        location (Any): Where the matrix should be in world space. If none given, will be at origin.

    Returns:
        (pm.nodetypes.Matrix): Matrix calculated from given forward vector.
    """
    if isinstance(up, (list, tuple)):
        up = pm.dt.Vector(up)
    elif isinstance(up, str):
        up = pm.dt.Vector(convert.axisToVector(up))
    elif isinstance(up, pm.dt.Vector):
        pass
    else:
        up = pm.upAxis(axis=True, q=True)
        up = pm.dt.Vector(convert.axisToVector(up))

    right = forward.cross(up).normal()
    up = right.cross(forward).normal()
    coordinates = []

    if forward_axis == 'x':
        coordinates = [forward.get(), up.get(), right.get()]
    elif forward_axis == 'y':
        coordinates = [up.get(), forward.get(), right.get()]
    elif forward_axis == 'z':
        coordinates = [(right * -1).get(), up.get(), forward.get()]

    location = convert.toVector(location, invalid_zero=True)
    coordinates.append(location)
    return pm.dt.Matrix(*coordinates)
Exemple #10
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 #11
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.blade_normal = self.guide.blades["blade"].z * -1
        self.blade_binormal = self.guide.blades["blade"].x

        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.armChainUpvRef = primitive.add2DChain(
            self.root,
            self.getName("armUpvRef%s_jnt"),
            [self.guide.apos[0], self.guide.apos[2]],
            self.normal,
            False,
            self.WIP,
        )

        negateOri = self.armChainUpvRef[1].getAttr("jointOrientZ") * -1
        self.armChainUpvRef[1].setAttr("jointOrientZ", negateOri)

        # 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"]:
            x = datatypes.Vector(1, 0, 0)
            if self.negate:
                z_dir = -1
            else:
                z_dir = 1

            if self.up_axis == "y":
                z = datatypes.Vector(0, z_dir, 0)
            else:
                z = datatypes.Vector(0, 0, z_dir)

            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, self.getName("fk0_npo"), t_npo
        )
        vec_po = datatypes.Vector(0.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 * 0.1,
            d=self.size * 0.1,
            po=vec_po,
            tp=self.parentCtlTag,
        )

        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
        )

        vec_po = datatypes.Vector(0.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 * 0.1,
            d=self.size * 0.1,
            po=vec_po,
            tp=self.fk0_ctl,
        )

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

        if self.settings["use_blade"]:
            t = transform.getTransformLookingAt(
                self.guide.apos[2],
                self.guide.apos[3],
                self.blade_normal,
                "x-z",
                self.negate,
            )
        else:
            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.fk1_ctl), self.guide.apos[2]
            )

        else:
            t_npo = t

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

        vec_po = datatypes.Vector(0.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 * 0.1,
            d=self.size * 0.1,
            po=vec_po,
            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 upv ---------------------------------

        # create tip point
        self.tip_ref = primitive.addTransform(
            self.armChainUpvRef[0],
            self.getName("tip_ref"),
            self.armChainUpvRef[0].getMatrix(worldSpace=True),
        )

        # create interpolate obj
        self.interpolate_lvl = primitive.addTransform(
            self.armChainUpvRef[0],
            self.getName("int_lvl"),
            self.armChainUpvRef[0].getMatrix(worldSpace=True),
        )

        # create roll npo and ctl
        self.roll_ctl_npo = primitive.addTransform(
            self.root,
            self.getName("roll_ctl_npo"),
            self.armChainUpvRef[0].getMatrix(worldSpace=True),
        )
        if self.negate:
            off_x = -1.5708
        else:
            off_x = 1.5708
        off_y = 1.5708

        self.roll_ctl = self.addCtl(
            self.roll_ctl_npo,
            "roll_ctl",
            transform.getTransform(self.roll_ctl_npo),
            self.color_ik,
            "compas",
            w=self.size * 0.3,
            ro=datatypes.Vector([off_x, off_y, 0]),
            tp=self.parentCtlTag,
        )
        attribute.setKeyableAttributes(self.roll_ctl, ["rx"])
        # create upv control
        v = self.guide.apos[2] - self.guide.apos[0]
        v = self.normal ^ v
        v.normalize()
        v *= self.size * 0.8
        v += self.guide.apos[1]

        self.upv_cns = primitive.addTransformFromPos(
            self.root, 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 * 0.12,
            tp=self.parentCtlTag,
        )

        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)

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

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

        t = transform.getTransformFromPos(self.guide.pos["wrist"])
        self.ikcns_ctl = self.addCtl(
            self.ik_cns,
            "ikcns_ctl",
            t,
            self.color_ik,
            "null",
            w=self.size * 0.12,
            tp=self.parentCtlTag,
        )

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

        if self.settings["use_blade"]:
            normal = self.blade_normal
            axis_ref1 = "xz"
            axis_ref2 = "x-z"
        else:
            normal = self.normal
            axis_ref1 = "x-y"
            axis_ref2 = "xy"

        if self.negate:

            m = transform.getTransformLookingAt(
                self.guide.pos["wrist"],
                self.guide.pos["eff"],
                normal,
                axis_ref1,
                True,
            )
        else:

            m = transform.getTransformLookingAt(
                self.guide.pos["wrist"],
                self.guide.pos["eff"],
                normal,
                axis_ref2,
                False,
            )

        self.ik_ctl = self.addCtl(
            self.ikcns_ctl,
            "ik_ctl",
            m,
            self.color_ik,
            "cube",
            w=self.size * 0.12,
            h=self.size * 0.12,
            d=self.size * 0.12,
            tp=self.roll_ctl,
        )

        if self.settings["mirrorIK"]:
            if self.negate:
                self.ik_cns.sx.set(-1)
                self.ik_ctl.ry.set(self.ik_ctl.ry.get() * -1)
                self.ik_ctl.rz.set(self.ik_ctl.rz.get() * -1)
        else:
            attribute.setInvertMirror(self.ik_ctl, ["tx", "ry", "rz"])
        attribute.setKeyableAttributes(self.ik_ctl)
        self.ik_ctl_ref = primitive.addTransform(
            self.ik_ctl, self.getName("ikCtl_ref"), m
        )

        # IK rotation controls
        if self.settings["ikTR"]:
            self.ikRot_npo = primitive.addTransform(
                self.root, self.getName("ikRot_npo"), m
            )
            self.ikRot_cns = primitive.addTransform(
                self.ikRot_npo, self.getName("ikRot_cns"), m
            )
            self.ikRot_ctl = self.addCtl(
                self.ikRot_cns,
                "ikRot_ctl",
                m,
                self.color_ik,
                "sphere",
                w=self.size * 0.12,
                tp=self.ik_ctl,
            )

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

        # References --------------------------------------
        # Calculate  again the transfor for the IK ref. This way align with FK

        if self.settings["use_blade"]:
            normal = self.blade_normal
            axis_ref = "x-z"
        else:
            normal = self.normal
            axis_ref = "xz"
        trnIK_ref = transform.getTransformLookingAt(
            self.guide.pos["wrist"],
            self.guide.pos["eff"],
            normal,
            axis_ref,
            self.negate,
        )
        self.ik_ref = primitive.addTransform(
            self.ik_ctl_ref, self.getName("ik_ref"), trnIK_ref
        )
        self.fk_ref = primitive.addTransform(
            self.fk_ctl[2], self.getName("fk_ref"), trnIK_ref
        )

        # Chain --------------------------------------------
        # The 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 * 0.5)
        self.bone0_shp.setAttr("localScale", 0.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 * 0.5)
        self.bone1_shp.setAttr("localScale", 0.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]
        )
        self.eff_loc = primitive.addTransformFromPos(
            self.root, self.getName("eff_loc"), self.guide.apos[2]
        )

        if self.settings["use_blade"]:
            # set the offset rotation for the hand
            self.off_t = transform.getTransformLookingAt(
                self.guide.pos["wrist"],
                self.guide.pos["eff"],
                self.blade_normal,
                axis="xy",
                negate=self.negate,
            )
            self.eff_jnt_off = primitive.addTransform(
                self.eff_loc, self.getName("eff_off"), self.off_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 * 0.2,
            tp=self.parentCtlTag,
        )

        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)
            self.mid_ctl_twst_npo = primitive.addTransform(
                self.mid_ctl, self.getName("mid_twst_npo"), t
            )
            self.mid_ctl_twst_ref = primitive.addTransform(
                self.mid_ctl_twst_npo, self.getName("mid_twst_ref"), t
            )
        else:
            self.mid_ctl_twst_ref = self.mid_ctl
            attribute.setInvertMirror(self.mid_ctl, ["tx", "ty", "tz"])

        # Roll join ref
        self.rollRef = primitive.add2DChain(
            self.root,
            self.getName("rollChain"),
            self.guide.apos[:2],
            self.normal,
            self.negate,
        )
        for x in self.rollRef:
            x.setAttr("visibility", False)

        if self.settings["div0"]:
            twst0_parent = self.rollRef[0]
        else:
            twst0_parent = self.root

        self.tws0_loc = primitive.addTransform(
            twst0_parent,
            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_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_loc,
            self.getName("tws2_rot"),
            transform.getTransform(self.fk_ctl[2]),
        )

        # 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, 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 * 0.15,
                    d=self.size * 0.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

            # joint Description Name
            jd_names = ast.literal_eval(
                self.settings["jointNamesDescription_custom"]
            )
            jdn_upperarm = jd_names[0]
            jdn_lowerarm = jd_names[1]
            jdn_upperarm_twist = jd_names[2]
            jdn_lowerarm_twist = jd_names[3]
            jdn_hand = jd_names[4]

            # setting the joints
            if i == 0:
                self.jnt_pos.append([driver, jdn_upperarm])
                current_parent = "root"
                twist_name = jdn_upperarm_twist
                twist_idx = 1
                increment = 1
            elif i == self.settings["div0"] + 1:
                self.jnt_pos.append([driver, jdn_lowerarm, current_parent])
                twist_name = jdn_lowerarm_twist
                current_parent = "elbow"
                twist_idx = self.settings["div1"]
                increment = -1
            else:
                self.jnt_pos.append(
                    [
                        driver,
                        string.replaceSharpWithPadding(twist_name, twist_idx),
                        current_parent,
                    ]
                )
                twist_idx += increment

        if self.settings["use_blade"]:
            eff_loc = self.eff_jnt_off
        else:
            eff_loc = self.eff_loc
        self.jnt_pos.append([eff_loc, jdn_hand, 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"
        )

        if self.settings["ikTR"]:
            reference = self.ikRot_ctl

            self.match_ikRot = self.add_match_ref(
                self.ikRot_ctl, self.fk2_ctl, "ikRot_mth"
            )
        else:
            reference = self.ik_ctl

        self.match_fk2 = self.add_match_ref(
            self.fk_ctl[2], reference, "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 #12
0
 def __init__(self):
     super(ShapeMirrorLeftToRightTool, self).__init__()
     self.options.axis = 'X' if pm.upAxis(q=True, axis=True).upper() == 'Y' else 'Y'
     self.options.selection_only = False
Exemple #13
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 #14
0
from pymel.core import createNode, group, hide, ikHandle, joint, move, rotate, select, xform, upAxis

import pdil

from ..cardRigging import MetaControl, OutputControls, colorParity
from .._core import config
from .._lib import space
from .._lib2 import controllerShape
from .. import enums
from .. import log
from .. import node

from . import _util as util

MAYA_UP = upAxis(q=True, ax=True)


@util.adds('tiptoe', 'heelRaise', 'toeTap', 'ballPivot')
@util.defaultspec(
    {
        'shape': 'disc',
        'size': 15,
        'color': 'blue 0.22',
        'align': MAYA_UP
    },
    toeControl={
        'shape': 'sphere',
        'size': 10,
        'color': 'blue 0.22'
    },
Exemple #15
0
def rig(
    eyeMesh=None,
    edgeLoop="",
    blinkH=20,
    namePrefix="eye",
    offset=0.05,
    rigidLoops=2,
    falloffLoops=4,
    headJnt=None,
    doSkin=True,
    parent_node=None,
    ctlName="ctl",
    sideRange=False,
    customCorner=False,
    intCorner=None,
    extCorner=None,
    ctlSet=None,
    defSet=None,
    upperVTrack=0.02,
    upperHTrack=0.01,
    lowerVTrack=0.02,
    lowerHTrack=0.01,
    aim_controller="",
    deformers_group="",
    everyNVertex=1,
):
    """Create eyelid and eye rig

    Args:
        eyeMesh (TYPE): Description
        edgeLoop (TYPE): Description
        blinkH (TYPE): Description
        namePrefix (TYPE): Description
        offset (TYPE): Description
        rigidLoops (TYPE): Description
        falloffLoops (TYPE): Description
        headJnt (TYPE): Description
        doSkin (TYPE): Description
        parent_node (None, optional): Description
        ctlName (str, optional): Description
        sideRange (bool, optional): Description
        customCorner (bool, optional): Description
        intCorner (None, optional): Description
        extCorner (None, optional): Description
        ctlSet (None, optional): Description
        defSet (None, optional): Description
        upperVTrack (None, optional): Description
        upperHTrack (None, optional): Description
        lowerVTrack (None, optional): Description
        lowerHTrack (None, optional): Description
        aim_controller (None, optional): Description
        deformers_group (None, optional): Description
        everyNVertex (int, optional): Will create a joint every N vertex

    No Longer Returned:
        TYPE: Description
    """

    ##########################################
    # INITIAL SETUP
    ##########################################
    up_axis = pm.upAxis(q=True, axis=True)
    if up_axis == "z":
        z_up = True
    else:
        z_up = False

    # getters
    edgeLoopList = get_edge_loop(edgeLoop)
    eyeMesh = get_eye_mesh(eyeMesh)

    # checkers
    if not edgeLoopList or not eyeMesh:
        return
    if doSkin:
        if not headJnt:
            pm.displayWarning("Please set the Head Jnt or unCheck "
                              "Compute Topological Autoskin")
            return

    # Convert data
    blinkH = blinkH / 100.0

    # Initial Data
    bboxCenter = meshNavigation.bboxCenter(eyeMesh)

    extr_v = meshNavigation.getExtremeVertexFromLoop(edgeLoopList, sideRange,
                                                     z_up)
    upPos = extr_v[0]
    lowPos = extr_v[1]
    inPos = extr_v[2]
    outPos = extr_v[3]
    edgeList = extr_v[4]
    vertexList = extr_v[5]

    # Detect the side L or R from the x value
    if inPos.getPosition(space="world")[0] < 0.0:
        side = "R"
        inPos = extr_v[3]
        outPos = extr_v[2]
        normalPos = outPos
        npw = normalPos.getPosition(space="world")
        normalVec = npw - bboxCenter
    else:
        side = "L"
        normalPos = outPos
        npw = normalPos.getPosition(space="world")
        normalVec = bboxCenter - npw

    # Manual Vertex corners
    if customCorner:
        if intCorner:
            try:
                if side == "R":
                    inPos = pm.PyNode(extCorner)
                else:
                    inPos = pm.PyNode(intCorner)
            except pm.MayaNodeError:
                pm.displayWarning("%s can not be found" % intCorner)
                return
        else:
            pm.displayWarning("Please set the internal eyelid corner")
            return

        if extCorner:
            try:
                normalPos = pm.PyNode(extCorner)
                npw = normalPos.getPosition(space="world")
                if side == "R":
                    outPos = pm.PyNode(intCorner)
                    normalVec = npw - bboxCenter
                else:
                    outPos = pm.PyNode(extCorner)
                    normalVec = bboxCenter - npw
            except pm.MayaNodeError:
                pm.displayWarning("%s can not be found" % extCorner)
                return
        else:
            pm.displayWarning("Please set the external eyelid corner")
            return

    # Check if we have prefix:
    if namePrefix:
        namePrefix = string.removeInvalidCharacter(namePrefix)
    else:
        pm.displayWarning("Prefix is needed")
        return

    def setName(name, ind=None):
        namesList = [namePrefix, side, name]
        if ind is not None:
            namesList[1] = side + str(ind)
        name = "_".join(namesList)
        return name

    if pm.ls(setName("root")):
        pm.displayWarning("The object %s already exist in the scene. Please "
                          "choose another name prefix" % setName("root"))
        return

    ##########################################
    # CREATE OBJECTS
    ##########################################

    # Eye root
    eye_root = primitive.addTransform(None, setName("root"))
    eyeCrv_root = primitive.addTransform(eye_root, setName("crvs"))

    # Eyelid Main crvs
    try:
        upEyelid_edge = meshNavigation.edgeRangeInLoopFromMid(
            edgeList, upPos, inPos, outPos)
        up_crv = curve.createCurveFromOrderedEdges(upEyelid_edge,
                                                   inPos,
                                                   setName("upperEyelid"),
                                                   parent=eyeCrv_root)
        upCtl_crv = curve.createCurveFromOrderedEdges(upEyelid_edge,
                                                      inPos,
                                                      setName("upCtl_crv"),
                                                      parent=eyeCrv_root)
        pm.rebuildCurve(upCtl_crv, s=2, rt=0, rpo=True, ch=False)

        lowEyelid_edge = meshNavigation.edgeRangeInLoopFromMid(
            edgeList, lowPos, inPos, outPos)
        low_crv = curve.createCurveFromOrderedEdges(lowEyelid_edge,
                                                    inPos,
                                                    setName("lowerEyelid"),
                                                    parent=eyeCrv_root)
        lowCtl_crv = curve.createCurveFromOrderedEdges(lowEyelid_edge,
                                                       inPos,
                                                       setName("lowCtl_crv"),
                                                       parent=eyeCrv_root)

        pm.rebuildCurve(lowCtl_crv, s=2, rt=0, rpo=True, ch=False)

    except UnboundLocalError:
        if customCorner:
            pm.displayWarning("This error is maybe caused because the custom "
                              "Corner vertex is not part of the edge loop")
        pm.displayError(traceback.format_exc())
        return

    # blendshape  curves. All crv have 30 point to allow blendshape connect
    upDriver_crv = curve.createCurveFromCurve(up_crv,
                                              setName("upDriver_crv"),
                                              nbPoints=30,
                                              parent=eyeCrv_root)
    upDriver_crv.attr("lineWidth").set(5)
    lowDriver_crv = curve.createCurveFromCurve(low_crv,
                                               setName("lowDriver_crv"),
                                               nbPoints=30,
                                               parent=eyeCrv_root)
    lowDriver_crv.attr("lineWidth").set(5)

    upRest_target_crv = curve.createCurveFromCurve(
        up_crv, setName("upRest_target_crv"), nbPoints=30, parent=eyeCrv_root)
    lowRest_target_crv = curve.createCurveFromCurve(
        low_crv,
        setName("lowRest_target_crv"),
        nbPoints=30,
        parent=eyeCrv_root)
    upProfile_target_crv = curve.createCurveFromCurve(
        up_crv,
        setName("upProfile_target_crv"),
        nbPoints=30,
        parent=eyeCrv_root,
    )
    lowProfile_target_crv = curve.createCurveFromCurve(
        low_crv,
        setName("lowProfile_target_crv"),
        nbPoints=30,
        parent=eyeCrv_root,
    )

    # mid driver
    midUpDriver_crv = curve.createCurveFromCurve(up_crv,
                                                 setName("midUpDriver_crv"),
                                                 nbPoints=30,
                                                 parent=eyeCrv_root)
    midLowDriver_crv = curve.createCurveFromCurve(low_crv,
                                                  setName("midLowDriver_crv"),
                                                  nbPoints=30,
                                                  parent=eyeCrv_root)

    # curve that define the close point of the eyelid
    closeTarget_crv = curve.createCurveFromCurve(up_crv,
                                                 setName("closeTarget_crv"),
                                                 nbPoints=30,
                                                 parent=eyeCrv_root)

    eyeCrv_root.attr("visibility").set(False)

    # localBBOX
    localBBox = eyeMesh.getBoundingBox(invisible=True, space="world")
    wRadius = abs((localBBox[0][0] - localBBox[1][0]))
    dRadius = abs((localBBox[0][1] - localBBox[1][1]) / 1.7)

    # Groups
    if not ctlSet:
        ctlSet = "rig_controllers_grp"
    try:
        ctlSet = pm.PyNode(ctlSet)
    except pm.MayaNodeError:
        pm.sets(n=ctlSet, em=True)
        ctlSet = pm.PyNode(ctlSet)
    if not defSet:
        defSet = "rig_deformers_grp"
    try:
        defset = pm.PyNode(defSet)
    except pm.MayaNodeError:
        pm.sets(n=defSet, em=True)
        defset = pm.PyNode(defSet)

    # Calculate center looking at
    averagePosition = (upPos.getPosition(space="world") + lowPos.getPosition(
        space="world") + inPos.getPosition(space="world") +
                       outPos.getPosition(space="world")) / 4

    if z_up:
        axis = "zx"
    else:
        axis = "z-x"
    t = transform.getTransformLookingAt(bboxCenter,
                                        averagePosition,
                                        normalVec,
                                        axis=axis,
                                        negate=False)

    over_npo = primitive.addTransform(eye_root, setName("center_lookatRoot"),
                                      t)

    center_lookat = primitive.addTransform(over_npo, setName("center_lookat"),
                                           t)

    if side == "R":
        over_npo.attr("rx").set(over_npo.attr("rx").get() * -1)
        over_npo.attr("ry").set(over_npo.attr("ry").get() + 180)
        over_npo.attr("sz").set(-1)
    t = transform.getTransform(over_npo)

    # Tracking
    # Eye aim control
    t_arrow = transform.getTransformLookingAt(
        bboxCenter,
        averagePosition,
        upPos.getPosition(space="world"),
        axis="zy",
        negate=False,
    )

    radius = abs((localBBox[0][0] - localBBox[1][0]) / 1.7)

    arrow_ctl = None
    arrow_npo = None
    if aim_controller:
        arrow_ctl = pm.PyNode(aim_controller)
    else:
        arrow_npo = primitive.addTransform(eye_root, setName("aim_npo"),
                                           t_arrow)
        arrow_ctl = icon.create(
            arrow_npo,
            setName("aim_%s" % ctlName),
            t_arrow,
            icon="arrow",
            w=1,
            po=datatypes.Vector(0, 0, radius),
            color=4,
        )
    if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost":
        pass
    else:
        pm.sets(ctlSet, add=arrow_ctl)
    attribute.setKeyableAttributes(arrow_ctl, params=["rx", "ry", "rz"])
    attribute.addAttribute(arrow_ctl, "isCtl", "bool", keyable=False)

    # tracking custom trigger
    if side == "R":
        tt = t_arrow
    else:
        tt = t
    aimTrigger_root = primitive.addTransform(center_lookat,
                                             setName("aimTrigger_root"), tt)
    # For some unknown reason the right side gets scewed rotation values
    mgear.core.transform.resetTransform(aimTrigger_root)
    aimTrigger_lvl = primitive.addTransform(aimTrigger_root,
                                            setName("aimTrigger_lvl"), tt)
    # For some unknown reason the right side gets scewed rotation values
    mgear.core.transform.resetTransform(aimTrigger_lvl)
    aimTrigger_lvl.attr("tz").set(1.0)
    aimTrigger_ref = primitive.addTransform(aimTrigger_lvl,
                                            setName("aimTrigger_ref"), tt)
    # For some unknown reason the right side gets scewed rotation values
    mgear.core.transform.resetTransform(aimTrigger_ref)
    aimTrigger_ref.attr("tz").set(0.0)
    # connect  trigger with arrow_ctl
    pm.parentConstraint(arrow_ctl, aimTrigger_ref, mo=True)

    # Blink driver controls
    if z_up:
        trigger_axis = "tz"
        ro_up = [0, 1.57079633 * 2, 1.57079633]
        ro_low = [0, 0, 1.57079633]
        po = [0, offset * -1, 0]
        low_pos = 2  # Z
    else:
        trigger_axis = "ty"
        ro_up = (1.57079633, 1.57079633, 0)
        ro_low = [1.57079633, 1.57079633, 1.57079633 * 2]
        po = [0, 0, offset]
        low_pos = 1  # Y

    # upper ctl
    p = upRest_target_crv.getCVs(space="world")[15]
    ut = transform.setMatrixPosition(datatypes.Matrix(), p)
    npo = primitive.addTransform(over_npo, setName("upBlink_npo"), ut)

    up_ctl = icon.create(
        npo,
        setName("upBlink_ctl"),
        ut,
        icon="arrow",
        w=2.5,
        d=2.5,
        ro=datatypes.Vector(ro_up[0], ro_up[1], ro_up[2]),
        po=datatypes.Vector(po[0], po[1], po[2]),
        color=4,
    )
    attribute.setKeyableAttributes(up_ctl, [trigger_axis])
    pm.sets(ctlSet, add=up_ctl)

    # use translation of the object to drive the blink
    blink_driver = primitive.addTransform(up_ctl, setName("blink_drv"), ut)

    # lowe ctl
    p_low = lowRest_target_crv.getCVs(space="world")[15]
    p[low_pos] = p_low[low_pos]
    lt = transform.setMatrixPosition(ut, p)
    npo = primitive.addTransform(over_npo, setName("lowBlink_npo"), lt)

    low_ctl = icon.create(
        npo,
        setName("lowBlink_ctl"),
        lt,
        icon="arrow",
        w=1.5,
        d=1.5,
        ro=datatypes.Vector(ro_low[0], ro_low[1], ro_low[2]),
        po=datatypes.Vector(po[0], po[1], po[2]),
        color=4,
    )
    attribute.setKeyableAttributes(low_ctl, [trigger_axis])
    pm.sets(ctlSet, add=low_ctl)

    # Controls lists
    upControls = []
    trackLvl = []
    track_corner_lvl = []
    corner_ctl = []
    ghost_ctl = []

    # upper eyelid controls
    upperCtlNames = ["inCorner", "upInMid", "upMid", "upOutMid", "outCorner"]
    cvs = upCtl_crv.getCVs(space="world")
    if side == "R" and not sideRange:
        # if side == "R":
        cvs = [cv for cv in reversed(cvs)]
        # offset = offset * -1
    for i, cv in enumerate(cvs):
        if utils.is_odd(i):
            color = 14
            wd = 0.3
            icon_shape = "circle"
            params = ["tx", "ty", "tz"]
        else:
            color = 4
            wd = 0.6
            icon_shape = "circle"
            params = [
                "tx",
                "ty",
                "tz",
                "ro",
                "rx",
                "ry",
                "rz",
                "sx",
                "sy",
                "sz",
            ]

        t = transform.setMatrixPosition(t, cvs[i])
        npo = primitive.addTransform(center_lookat,
                                     setName("%s_npo" % upperCtlNames[i]), t)
        npoBase = npo
        # track for corners and mid point level
        if i in [0, 2, 4]:
            # we add an extra level to input the tracking ofset values
            npo = primitive.addTransform(npo,
                                         setName("%s_trk" % upperCtlNames[i]),
                                         t)
            if i == 2:
                trackLvl.append(npo)
            else:
                track_corner_lvl.append(npo)

        if i in [1, 2, 3]:
            ctl = primitive.addTransform(npo,
                                         setName("%s_loc" % upperCtlNames[i]),
                                         t)
            # ghost controls
            if i == 2:
                gt = transform.setMatrixPosition(
                    t, transform.getPositionFromMatrix(ut))
            else:
                gt = t
            npo_g = primitive.addTransform(
                up_ctl, setName("%sCtl_npo" % upperCtlNames[i]), gt)
            ctl_g = icon.create(
                npo_g,
                setName("%s_%s" % (upperCtlNames[i], ctlName)),
                gt,
                icon=icon_shape,
                w=wd,
                d=wd,
                ro=datatypes.Vector(1.57079633, 0, 0),
                po=datatypes.Vector(0, 0, offset),
                color=color,
            )
            # define the ctl_param to recive the ctl configuration
            ctl_param = ctl_g
            ghost_ctl.append(ctl_g)
            # connect local SRT
            rigbits.connectLocalTransform([ctl_g, ctl])
        else:
            ctl = icon.create(
                npo,
                setName("%s_%s" % (upperCtlNames[i], ctlName)),
                t,
                icon=icon_shape,
                w=wd,
                d=wd,
                ro=datatypes.Vector(1.57079633, 0, 0),
                po=datatypes.Vector(0, 0, offset),
                color=color,
            )
            # define the ctl_param to recive the ctl configuration
            ctl_param = ctl
        attribute.addAttribute(ctl_param, "isCtl", "bool", keyable=False)
        attribute.add_mirror_config_channels(ctl_param)
        node.add_controller_tag(ctl_param, over_npo)
        if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost":
            pass
        else:
            pm.sets(ctlSet, add=ctl_param)
        attribute.setKeyableAttributes(ctl_param, params)
        upControls.append(ctl)
        # add corner ctls to corner ctl list for tracking
        if i in [0, 4]:
            corner_ctl.append(ctl)
        # if side == "R":
        #     npoBase.attr("ry").set(180)
        #     npoBase.attr("sz").set(-1)
    # adding parent constraints to odd controls
    for i, ctl in enumerate(upControls):
        if utils.is_odd(i):
            cns_node = pm.parentConstraint(upControls[i - 1],
                                           upControls[i + 1],
                                           ctl.getParent(),
                                           mo=True)
            # Make the constraint "noFlip"
            cns_node.interpType.set(0)

    # adding parent constraint ghost controls
    cns_node = pm.parentConstraint(ghost_ctl[1],
                                   upControls[0],
                                   ghost_ctl[0].getParent(),
                                   mo=True)
    cns_node.interpType.set(0)
    cns_node = pm.parentConstraint(ghost_ctl[1],
                                   upControls[-1],
                                   ghost_ctl[2].getParent(),
                                   mo=True)
    cns_node.interpType.set(0)
    # lower eyelid controls
    lowControls = [upControls[0]]
    lowerCtlNames = [
        "inCorner",
        "lowInMid",
        "lowMid",
        "lowOutMid",
        "outCorner",
    ]

    cvs = lowCtl_crv.getCVs(space="world")
    if side == "R" and not sideRange:
        cvs = [cv for cv in reversed(cvs)]
    for i, cv in enumerate(cvs):
        # we skip the first and last point since is already in the uper eyelid
        if i in [0, 4]:
            continue
        if utils.is_odd(i):
            color = 14
            wd = 0.3
            icon_shape = "circle"
            params = ["tx", "ty", "tz"]
        else:
            color = 4
            wd = 0.6
            icon_shape = "circle"
            params = [
                "tx",
                "ty",
                "tz",
                "ro",
                "rx",
                "ry",
                "rz",
                "sx",
                "sy",
                "sz",
            ]

        t = transform.setMatrixPosition(t, cvs[i])
        npo = primitive.addTransform(center_lookat,
                                     setName("%s_npo" % lowerCtlNames[i]), t)
        npoBase = npo
        if i in [1, 2, 3]:
            if i == 2:
                # we add an extra level to input the tracking ofset values
                npo = primitive.addTransform(
                    npo, setName("%s_trk" % lowerCtlNames[i]), t)
                trackLvl.append(npo)
            ctl = primitive.addTransform(npo,
                                         setName("%s_loc" % lowerCtlNames[i]),
                                         t)
            # ghost controls
            if i == 2:
                gt = transform.setMatrixPosition(
                    t, transform.getPositionFromMatrix(lt))
            else:
                gt = t
            # ghost controls
            npo_g = primitive.addTransform(
                low_ctl, setName("%sCtl_npo" % lowerCtlNames[i]), gt)
            ctl_g = icon.create(
                npo_g,
                setName("%s_%s" % (lowerCtlNames[i], ctlName)),
                gt,
                icon=icon_shape,
                w=wd,
                d=wd,
                ro=datatypes.Vector(1.57079633, 0, 0),
                po=datatypes.Vector(0, 0, offset),
                color=color,
            )
            # define the ctl_param to recive the ctl configuration
            ctl_param = ctl_g
            ghost_ctl.append(ctl_g)
            # connect local SRT
            rigbits.connectLocalTransform([ctl_g, ctl])
        else:
            ctl = icon.create(
                npo,
                setName("%s_%s" % (lowerCtlNames[i], ctlName)),
                t,
                icon=icon_shape,
                w=wd,
                d=wd,
                ro=datatypes.Vector(1.57079633, 0, 0),
                po=datatypes.Vector(0, 0, offset),
                color=color,
            )
            # define the ctl_param to recive the ctl configuration
            ctl_param = ctl
        attribute.addAttribute(ctl_param, "isCtl", "bool", keyable=False)
        attribute.add_mirror_config_channels(ctl_param)

        lowControls.append(ctl)
        if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost":
            pass
        else:
            pm.sets(ctlSet, add=ctl_param)
        attribute.setKeyableAttributes(ctl_param, params)
        # mirror behaviout on R side controls
        # if side == "R":
        #     npoBase.attr("ry").set(180)
        #     npoBase.attr("sz").set(-1)
    for lctl in reversed(lowControls[1:]):
        node.add_controller_tag(lctl, over_npo)
    lowControls.append(upControls[-1])

    # adding parent constraints to odd controls
    for i, ctl in enumerate(lowControls):
        if utils.is_odd(i):
            cns_node = pm.parentConstraint(
                lowControls[i - 1],
                lowControls[i + 1],
                ctl.getParent(),
                mo=True,
            )
            # Make the constraint "noFlip"
            cns_node.interpType.set(0)

    # adding parent constraint ghost controls
    cns_node = pm.parentConstraint(ghost_ctl[4],
                                   upControls[0],
                                   ghost_ctl[3].getParent(),
                                   mo=True)
    cns_node.interpType.set(0)
    cns_node = pm.parentConstraint(ghost_ctl[4],
                                   upControls[-1],
                                   ghost_ctl[5].getParent(),
                                   mo=True)
    cns_node.interpType.set(0)
    ##########################################
    # OPERATORS
    ##########################################
    # Connecting control crvs with controls
    applyop.gear_curvecns_op(upCtl_crv, upControls)
    applyop.gear_curvecns_op(lowCtl_crv, lowControls)

    # adding wires
    w1 = pm.wire(up_crv, w=upDriver_crv)[0]
    w2 = pm.wire(low_crv, w=lowDriver_crv)[0]

    w3 = pm.wire(upProfile_target_crv, w=upCtl_crv)[0]
    w4 = pm.wire(lowProfile_target_crv, w=lowCtl_crv)[0]

    if z_up:
        trigger_axis = "tz"
    else:
        trigger_axis = "ty"

    # connect blink driver
    pm.pointConstraint(low_ctl, blink_driver, mo=False)
    rest_val = blink_driver.attr(trigger_axis).get()

    up_div_node = node.createDivNode(up_ctl.attr(trigger_axis), rest_val)
    low_div_node = node.createDivNode(low_ctl.attr(trigger_axis),
                                      rest_val * -1)

    # contact driver
    minus_node = node.createPlusMinusAverage1D(
        [rest_val, blink_driver.attr(trigger_axis)], operation=2)
    contact_div_node = node.createDivNode(minus_node.output1D, rest_val)

    # wire tension
    for w in [w1, w2, w3, w4]:
        w.dropoffDistance[0].set(100)

    # TODO: what is the best solution?
    # trigger using proximity
    # remap_node = pm.createNode("remapValue")
    # contact_div_node.outputX >> remap_node.inputValue
    # remap_node.value[0].value_Interp.set(2)
    # remap_node.inputMin.set(0.995)
    # reverse_node = node.createReverseNode(remap_node.outColorR)
    # for w in [w1, w2]:
    #     reverse_node.outputX >> w.scale[0]

    # trigger at starting movement for up and low
    # up
    remap_node = pm.createNode("remapValue")
    up_ctl.attr(trigger_axis) >> remap_node.inputValue
    remap_node.value[0].value_Interp.set(2)
    remap_node.inputMax.set(rest_val / 8)
    reverse_node = node.createReverseNode(remap_node.outColorR)
    reverse_node.outputX >> w1.scale[0]
    # low
    remap_node = pm.createNode("remapValue")
    low_ctl.attr(trigger_axis) >> remap_node.inputValue
    remap_node.value[0].value_Interp.set(2)
    remap_node.inputMin.set((rest_val / 8) * -1)
    remap_node.outColorR >> w2.scale[0]

    # mid position drivers blendshapes
    bs_midUpDrive = pm.blendShape(
        lowRest_target_crv,
        upProfile_target_crv,
        midUpDriver_crv,
        n="midUpDriver_blendShape",
    )

    bs_midLowDrive = pm.blendShape(
        upRest_target_crv,
        lowProfile_target_crv,
        midLowDriver_crv,
        n="midlowDriver_blendShape",
    )

    bs_closeTarget = pm.blendShape(
        midUpDriver_crv,
        midLowDriver_crv,
        closeTarget_crv,
        n="closeTarget_blendShape",
    )

    pm.connectAttr(
        up_div_node.outputX,
        bs_midUpDrive[0].attr(lowRest_target_crv.name()),
    )

    pm.connectAttr(
        low_div_node.outputX,
        bs_midLowDrive[0].attr(upRest_target_crv.name()),
    )

    pm.setAttr(bs_closeTarget[0].attr(midUpDriver_crv.name()), 0.5)
    pm.setAttr(bs_closeTarget[0].attr(midLowDriver_crv.name()), 0.5)

    # Main crv drivers
    bs_upBlink = pm.blendShape(
        lowRest_target_crv,
        closeTarget_crv,
        upProfile_target_crv,
        upDriver_crv,
        n="upBlink_blendShape",
    )
    bs_lowBlink = pm.blendShape(
        upRest_target_crv,
        closeTarget_crv,
        lowProfile_target_crv,
        lowDriver_crv,
        n="lowBlink_blendShape",
    )

    # blink contact connections
    cond_node_up = node.createConditionNode(contact_div_node.outputX, 1, 3, 0,
                                            up_div_node.outputX)
    pm.connectAttr(
        cond_node_up.outColorR,
        bs_upBlink[0].attr(lowRest_target_crv.name()),
    )

    cond_node_low = node.createConditionNode(contact_div_node.outputX, 1, 3, 0,
                                             low_div_node.outputX)
    pm.connectAttr(
        cond_node_low.outColorR,
        bs_lowBlink[0].attr(upRest_target_crv.name()),
    )

    cond_node_close = node.createConditionNode(contact_div_node.outputX, 1, 2,
                                               1, 0)
    cond_node_close.colorIfFalseR.set(0)
    pm.connectAttr(
        cond_node_close.outColorR,
        bs_upBlink[0].attr(closeTarget_crv.name()),
    )

    pm.connectAttr(
        cond_node_close.outColorR,
        bs_lowBlink[0].attr(closeTarget_crv.name()),
    )

    pm.setAttr(bs_upBlink[0].attr(upProfile_target_crv.name()), 1)
    pm.setAttr(bs_lowBlink[0].attr(lowProfile_target_crv.name()), 1)

    # joints root
    jnt_root = primitive.addTransformFromPos(eye_root,
                                             setName("joints"),
                                             pos=bboxCenter)
    if deformers_group:
        deformers_group = pm.PyNode(deformers_group)
        pm.parentConstraint(eye_root, jnt_root, mo=True)
        pm.scaleConstraint(eye_root, jnt_root, mo=True)
        deformers_group.addChild(jnt_root)

    # head joint
    if headJnt:
        try:
            headJnt = pm.PyNode(headJnt)
            jnt_base = headJnt
        except pm.MayaNodeError:
            pm.displayWarning("Aborted can not find %s " % headJnt)
            return
    else:
        # Eye root
        jnt_base = jnt_root

    eyeTargets_root = primitive.addTransform(eye_root, setName("targets"))

    eyeCenter_jnt = rigbits.addJnt(arrow_ctl,
                                   jnt_base,
                                   grp=defset,
                                   jntName=setName("center_jnt"))

    # Upper Eyelid joints ##################################################

    cvs = up_crv.getCVs(space="world")
    upCrv_info = node.createCurveInfoNode(up_crv)

    # aim constrain targets and joints
    upperEyelid_aimTargets = []
    upperEyelid_jnt = []
    upperEyelid_jntRoot = []

    if z_up:
        axis = "zy"
        wupVector = [0, 0, 1]
    else:
        axis = "-yz"
        wupVector = [0, 1, 0]

    for i, cv in enumerate(cvs):
        if i % everyNVertex:
            continue

        # aim targets
        trn = primitive.addTransformFromPos(eyeTargets_root,
                                            setName("upEyelid_aimTarget", i),
                                            pos=cv)
        upperEyelid_aimTargets.append(trn)
        # connecting positions with crv
        pm.connectAttr(upCrv_info + ".controlPoints[%s]" % str(i),
                       trn.attr("translate"))

        # joints
        jntRoot = primitive.addJointFromPos(jnt_root,
                                            setName("upEyelid_jnt_base", i),
                                            pos=bboxCenter)
        jntRoot.attr("radius").set(0.08)
        jntRoot.attr("visibility").set(False)
        upperEyelid_jntRoot.append(jntRoot)
        applyop.aimCns(jntRoot,
                       trn,
                       axis=axis,
                       wupObject=jnt_root,
                       wupVector=wupVector)

        jnt_ref = primitive.addJointFromPos(jntRoot,
                                            setName("upEyelid_jnt_ref", i),
                                            pos=cv)
        jnt_ref.attr("radius").set(0.08)
        jnt_ref.attr("visibility").set(False)

        jnt = rigbits.addJnt(jnt_ref,
                             jnt_base,
                             grp=defset,
                             jntName=setName("upEyelid_jnt", i))
        upperEyelid_jnt.append(jnt)

    # Lower Eyelid joints ##################################################

    cvs = low_crv.getCVs(space="world")
    lowCrv_info = node.createCurveInfoNode(low_crv)

    # aim constrain targets and joints
    lowerEyelid_aimTargets = []
    lowerEyelid_jnt = []
    lowerEyelid_jntRoot = []

    for i, cv in enumerate(cvs):
        if i in [0, len(cvs) - 1]:
            continue

        if i % everyNVertex:
            continue

        # aim targets
        trn = primitive.addTransformFromPos(eyeTargets_root,
                                            setName("lowEyelid_aimTarget", i),
                                            pos=cv)
        lowerEyelid_aimTargets.append(trn)
        # connecting positions with crv
        pm.connectAttr(lowCrv_info + ".controlPoints[%s]" % str(i),
                       trn.attr("translate"))

        # joints
        jntRoot = primitive.addJointFromPos(jnt_root,
                                            setName("lowEyelid_base", i),
                                            pos=bboxCenter)
        jntRoot.attr("radius").set(0.08)
        jntRoot.attr("visibility").set(False)
        lowerEyelid_jntRoot.append(jntRoot)
        applyop.aimCns(jntRoot,
                       trn,
                       axis=axis,
                       wupObject=jnt_root,
                       wupVector=wupVector)

        jnt_ref = primitive.addJointFromPos(jntRoot,
                                            setName("lowEyelid_jnt_ref", i),
                                            pos=cv)
        jnt_ref.attr("radius").set(0.08)
        jnt_ref.attr("visibility").set(False)

        jnt = rigbits.addJnt(jnt_ref,
                             jnt_base,
                             grp=defset,
                             jntName=setName("lowEyelid_jnt", i))
        lowerEyelid_jnt.append(jnt)

    # Adding channels for eye tracking
    upVTracking_att = attribute.addAttribute(up_ctl,
                                             "vTracking",
                                             "float",
                                             upperVTrack,
                                             minValue=0)
    upHTracking_att = attribute.addAttribute(up_ctl,
                                             "hTracking",
                                             "float",
                                             upperHTrack,
                                             minValue=0)

    lowVTracking_att = attribute.addAttribute(low_ctl,
                                              "vTracking",
                                              "float",
                                              lowerVTrack,
                                              minValue=0)
    lowHTracking_att = attribute.addAttribute(low_ctl,
                                              "hTracking",
                                              "float",
                                              lowerHTrack,
                                              minValue=0)

    # vertical tracking connect
    up_mult_node = node.createMulNode(upVTracking_att,
                                      aimTrigger_ref.attr("ty"))
    low_mult_node = node.createMulNode(lowVTracking_att,
                                       aimTrigger_ref.attr("ty"))
    # remap to use the low or the up eyelid as driver contact base on
    # the eyetrack trigger direction
    uT_remap_node = pm.createNode("remapValue")
    aimTrigger_ref.attr("ty") >> uT_remap_node.inputValue
    uT_remap_node.inputMax.set(0.1)
    uT_remap_node.inputMin.set(-0.1)
    up_mult_node.outputX >> uT_remap_node.outputMax
    low_mult_node.outputX >> uT_remap_node.outputMin
    # up
    u_remap_node = pm.createNode("remapValue")
    contact_div_node.outputX >> u_remap_node.inputValue
    u_remap_node.value[0].value_Interp.set(2)
    u_remap_node.inputMin.set(0.9)
    up_mult_node.outputX >> u_remap_node.outputMin
    uT_remap_node.outColorR >> u_remap_node.outputMax

    # low
    l_remap_node = pm.createNode("remapValue")
    contact_div_node.outputX >> l_remap_node.inputValue
    l_remap_node.value[0].value_Interp.set(2)
    l_remap_node.inputMin.set(0.9)
    low_mult_node.outputX >> l_remap_node.outputMin
    uT_remap_node.outColorR >> l_remap_node.outputMax

    # up connect and turn down to low when contact
    pm.connectAttr(u_remap_node.outColorR, trackLvl[0].attr("ty"))

    pm.connectAttr(l_remap_node.outColorR, trackLvl[1].attr("ty"))

    # horizontal tracking connect
    mult_node = node.createMulNode(upHTracking_att, aimTrigger_ref.attr("tx"))
    # Correct right side horizontal tracking
    # if side == "R":
    #     mult_node = node.createMulNode(mult_node.attr("outputX"), -1)
    pm.connectAttr(mult_node + ".outputX", trackLvl[0].attr("tx"))

    mult_node = node.createMulNode(lowHTracking_att, aimTrigger_ref.attr("tx"))
    # Correct right side horizontal tracking
    # if side == "R":
    #     mult_node = node.createMulNode(mult_node.attr("outputX"), -1)
    pm.connectAttr(mult_node + ".outputX", trackLvl[1].attr("tx"))

    # adding channels for corner tracking
    # track_corner_lvl
    for i, ctl in enumerate(corner_ctl):
        VTracking_att = attribute.addAttribute(ctl,
                                               "vTracking",
                                               "float",
                                               0.1,
                                               minValue=0)
        if z_up:
            mult_node = node.createMulNode(VTracking_att, up_ctl.tz)
            mult_node2 = node.createMulNode(VTracking_att, low_ctl.tz)
            plus_node = node.createPlusMinusAverage1D(
                [mult_node.outputX, mult_node2.outputX])

            mult_node3 = node.createMulNode(plus_node.output1D, -1)
            pm.connectAttr(mult_node3.outputX, track_corner_lvl[i].attr("ty"))
        else:
            mult_node = node.createMulNode(VTracking_att, up_ctl.ty)
            mult_node2 = node.createMulNode(VTracking_att, low_ctl.ty)
            plus_node = node.createPlusMinusAverage1D(
                [mult_node.outputX, mult_node2.outputX])

            pm.connectAttr(plus_node.output1D, track_corner_lvl[i].attr("ty"))

    ###########################################
    # Reparenting
    ###########################################
    if parent_node:
        try:
            if isinstance(parent_node, string_types):
                parent_node = pm.PyNode(parent_node)
            parent_node.addChild(eye_root)
        except pm.MayaNodeError:
            pm.displayWarning("The eye rig can not be parent to: %s. Maybe "
                              "this object doesn't exist." % parent_node)

    ###########################################
    # Auto Skinning
    ###########################################
    if doSkin:
        # eyelid vertex rows
        totalLoops = rigidLoops + falloffLoops
        vertexLoopList = meshNavigation.getConcentricVertexLoop(
            vertexList, totalLoops)
        vertexRowList = meshNavigation.getVertexRowsFromLoops(vertexLoopList)

        # we set the first value 100% for the first initial loop
        skinPercList = [1.0]
        # we expect to have a regular grid topology
        for r in range(rigidLoops):
            for rr in range(2):
                skinPercList.append(1.0)
        increment = 1.0 / float(falloffLoops)
        # we invert to smooth out from 100 to 0
        inv = 1.0 - increment
        for r in range(falloffLoops):
            for rr in range(2):
                if inv < 0.0:
                    inv = 0.0
                skinPercList.append(inv)
            inv -= increment

        # this loop add an extra 0.0 indices to avoid errors
        for r in range(10):
            for rr in range(2):
                skinPercList.append(0.0)

        # base skin
        geo = pm.listRelatives(edgeLoopList[0], parent=True)[0]
        # Check if the object has a skinCluster
        objName = pm.listRelatives(geo, parent=True)[0]

        skinCluster = skin.getSkinCluster(objName)
        if not skinCluster:
            skinCluster = pm.skinCluster(headJnt,
                                         geo,
                                         tsb=True,
                                         nw=2,
                                         n="skinClsEyelid")

        eyelidJoints = upperEyelid_jnt + lowerEyelid_jnt
        pm.progressWindow(title="Auto skinning process",
                          progress=0,
                          max=len(eyelidJoints))
        firstBoundary = False
        for jnt in eyelidJoints:
            pm.progressWindow(e=True, step=1, status="\nSkinning %s" % jnt)
            skinCluster.addInfluence(jnt, weight=0)
            v = meshNavigation.getClosestVertexFromTransform(geo, jnt)

            for row in vertexRowList:

                if v in row:
                    it = 0  # iterator
                    inc = 1  # increment
                    for i, rv in enumerate(row):
                        try:
                            perc = skinPercList[it]
                            t_val = [(jnt, perc), (headJnt, 1.0 - perc)]
                            pm.skinPercent(skinCluster,
                                           rv,
                                           transformValue=t_val)
                            if rv.isOnBoundary():
                                # we need to compare with the first boundary
                                # to check if the row have inverted direction
                                # and offset the value
                                if not firstBoundary:
                                    firstBoundary = True
                                    firstBoundaryValue = it

                                else:
                                    if it < firstBoundaryValue:
                                        it -= 1
                                    elif it > firstBoundaryValue:
                                        it += 1
                                inc = 2
                        except IndexError:
                            continue

                        it = it + inc
        pm.progressWindow(e=True, endProgress=True)

        # Eye Mesh skinning
        skinCluster = skin.getSkinCluster(eyeMesh)
        if not skinCluster:
            skinCluster = pm.skinCluster(eyeCenter_jnt,
                                         eyeMesh,
                                         tsb=True,
                                         nw=1,
                                         n="skinClsEye")
Exemple #16
0
def up_axis():
    return pm.upAxis(q=True, axis=True)
    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)
Exemple #18
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[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.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"])

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

        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=0.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 * 0.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 * 0.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], 0.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 * 0.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 * 0.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 * 0.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
        # handle Z up orientation offset
        # parentctl = primitive.addTransform(
        #     parentctl,
        #     self.getName("fk0_off"),
        #     transform.getTransform(parentctl))
        # if self.up_axis == "z":
        #     parentctl.rx.set(90)

        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 * 0.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])
            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)

            # 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"))
Exemple #19
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

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

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

        # 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, 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 * 0.1,
            d=self.size * 0.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, jdn_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=0.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 * 0.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 * 0.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], 0.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 * 0.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 * 0.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 * 0.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 * 0.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, string.replaceSharpWithPadding(jdn_spine, i + 1)]
            )

            # 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, string.replaceSharpWithPadding(jdn_spine, i + 2)]
        )