Beispiel #1
0
def getSymmetricalTransform(t, axis="yz", fNegScale=False):
    """
    Get the symmetrical tranformation matrix from a define 2 axis mirror plane. exp:"yz".

    Args:
        t (matrix): The transformation matrix to mirror.
        axis (str): The mirror plane.
        fNegScale(bool):  This function is not yet implemented.

    Returns:
        matrix: The symmetrical tranformation matrix.
    """

    if axis == "yz":
        mirror = dt.TransformationMatrix(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0,
                                         0, 0, 0, 1)

    if axis == "xy":
        mirror = dt.TransformationMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0,
                                         0, 0, 0, 1)
    if axis == "zx":
        mirror = dt.TransformationMatrix(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0,
                                         0, 0, 0, 1)
    t *= mirror

    #TODO: getSymmetricalTransform: add freeze negative scaling procedure.

    return t
Beispiel #2
0
    def determineHanded(self, thumb, wrist):  #thumb, wrist
        handed = ""

        objectJoint = pc.ls(thumb, type="joint")[0]
        objWorldMat = objectJoint.attr("worldMatrix").get()
        objTransformationMat = dt.TransformationMatrix(objWorldMat)
        objectTrans = objTransformationMat.getTranslation('world')

        tarJoint = pc.ls(wrist, type="joint")[0]
        tarWorldMat = tarJoint.attr("worldMatrix").get()
        targetTransformationMat = dt.TransformationMatrix(tarWorldMat)
        targetTrans = targetTransformationMat.getTranslation('world')

        worldVector = dt.Vector(0, 0, 0)

        targetVector = (objectTrans - targetTrans)
        targetVector.normalize()

        targetUp = tarWorldMat[1][:3]
        targetUp.normalize()

        # find dot product between target and object
        dotProduct = dt.dot(targetUp, targetVector)

        if dotProduct > 0:
            handed = "R"
        if dotProduct <= 0:
            handed = "L"

        return handed
Beispiel #3
0
    def _add_rotate(cls, node, rotation):
        rotation = dt.EulerRotation([axis for axis in rotation])
        matrix = dt.TransformationMatrix()

        q = rotation.asQuaternion()
        matrix.addRotationQuaternion(q.x, q.y, q.z, q.w, space='object')
        cls._add_transformation(node, matrix)
Beispiel #4
0
def convert2TransformMatrix(tm):
    """
    Convert a transformation Matrix or a matrix to a transformation matrix in world space.

    Args:
        tm (matrix): The input matrix.

    Returns:
        matrix: The transformation matrix in worldSpace
    """
    if isinstance(tm, nt.Transform):
        tm = dt.TransformationMatrix(tm.getMatrix(worldSpace=True))
    if isinstance(tm, dt.Matrix):
        tm = dt.TransformationMatrix(tm)

    return tm
Beispiel #5
0
def matrix_normalize_scale(matrix):
    """
    Will normalize the scale in given four by four matrix to 1 or -1.

    Args:
        matrix(dt.Matrix): Four by four matrix.

    Return:
        dt.Matrix: The scale normalized matrix.

    """
    scale = matrix.scale
    tm = dt.TransformationMatrix(matrix)
    if scale[0] > 0:
        scale[0] = 1
    else:
        scale[0] = -1
    if scale[1] > 0:
        scale[1] = 1
    else:
        scale[1] = -1
    if scale[2] > 0:
        scale[2] = 1
    else:
        scale[2] = -1
    tm.setScale(scale, space="world")
    return dt.Matrix(tm)
Beispiel #6
0
def MTransform(item, target, attrs):
    Ipwm = item.getAttr('worldMatrix')
    if target.getParent():
        Tpim = target.getParent().getAttr('worldMatrix').inverse()
    else:
        Tpim = target.getAttr('parentInverseMatrix')
    prod = Ipwm * Tpim

    tMat = dt.TransformationMatrix(prod)
    translate = tMat.getTranslation('transform')
    quat_rotate = tMat.getRotationQuaternion()
    quat = dt.Quaternion(quat_rotate)
    euler = quat.asEulerRotation()
    rotate = map(math.degrees, euler)
    scale = tMat.getScale('transform')

    data = {}
    if 't' in attrs:
        data["translate"] = translate
    if 'r' in attrs:
        data["rotate"] = rotate
    if 'jo' in attrs:
        data["jointOrient"] = rotate
    if 's' in attrs:
        data["scale"] = scale
    for DItem in data.items():
        setKwargs(target, DItem[0], DItem[1])
Beispiel #7
0
    def _add_translate(cls, node, translation):
        if not isinstance(translation, list):
            translation = dt.Vector(translation)
        translation *= 100

        matrix = dt.TransformationMatrix()
        matrix.addTranslation(translation, space='world')
        cls._add_transformation(node, matrix)
Beispiel #8
0
    def test_world_position(self):
        """
        Test the world space position in translate and rotate.
        """
        ws_matrix_test_op_1 = datatypes.TransformationMatrix(
            self.test_op_1.get_main_op_ws_matrix()
        )
        test_ws_vec = datatypes.Vector(
            [27.820655082060398, -0.7524801847300928, -4.0237613976076]
        )
        test_ws_rotation = datatypes.EulerRotation(
            [1.934698909968065, -0.16331263127797427, 1.1967119606022243],
            unit="radians",
        )

        ws_matrix_test_op_1_subs = [
            datatypes.TransformationMatrix(matrix)
            for matrix in self.test_op_1.get_sub_op_nodes_ws_matrix()
        ]

        ws_vec_test_op_1_subs = [
            ts_matrix.getTranslation("world")
            for ts_matrix in ws_matrix_test_op_1_subs
        ]

        test_ws_vec_subs = [
            datatypes.Vector(
                [31.42623634611877, 8.432088910758539, -2.397884932907285]
            ),
            datatypes.Vector(
                [35.03181761017714, 17.61665800624717, -0.7720084682069708]
            ),
            datatypes.Vector(
                [38.637398874235515, 26.801227101735805, 0.8538679964933436]
            ),
        ]

        self.assertEqual(ws_vec_test_op_1_subs, test_ws_vec_subs)

        self.assertEqual(
            ws_matrix_test_op_1.getTranslation("world"), test_ws_vec
        )

        self.assertEqual(ws_matrix_test_op_1.getRotation(), test_ws_rotation)
Beispiel #9
0
 def test_control_curve_worldspace_orientation(self):
     """
     Test if the control curve in orientated in worldspace zero.
     """
     self.single_control.set_worldspace_orientation(True)
     self.single_control.build_from_operator()
     control_curve = self.single_control.controls[0]
     ws_matrix = control_curve.getMatrix(worldSpace=True)
     tm_matrix = dt.TransformationMatrix(ws_matrix)
     self.assertEqual(
         tm_matrix.getRotation(),
         dt.EulerRotation([0.0, -0.0, 0.0], unit="radians"),
     )
Beispiel #10
0
    def addLengthCtrl(self, crv):
        t = getTransform(self.guide.root)
        t = self._getTransformWithRollByBlade(t)
        cvs = crv.length()
        tm = datatypes.TransformationMatrix(t)
        tm.addTranslation([0.0, cvs * 0.01, cvs * 1.4], om.MSpace.kObject)

        local_t = datatypes.Matrix(tm)
        self.length_npo = addTransform(self.aim_npo, self.getName("length_npo"), local_t)
        self.length_in = addTransform(self.length_npo, self.getName("sacle_in"), local_t)
        size = self.size
        w = size
        h = size
        d = size
        self.length_ctl = self.addCtl(
            self.length_in,
            "length_ctl",
            local_t,
            self.color_ik,
            "arrow",
            w=w,
            h=h,
            d=d,
            ro=datatypes.Vector([-math.pi / 2., math.pi / 2., 0.])
        )

        self.fk_upvectors = []
        chain = getChainTransform2(self.guide.apos, self.normal, self.negate)
        for i, t in enumerate(chain):
            upv_npo = addTransform(self.length_in, self.getName("%s_fkupv_npo" % i), t)
            self.fk_upvectors.append(upv_npo)

        # global input
        self.scale_npo = addTransform(self.root, self.getName("scale_npo"), local_t)
        self.scale_in = addTransform(self.scale_npo, self.getName("sacle_in"), local_t)

        self.scale_ctl = self.addCtl(
            self.scale_in,
            "scale_ctl",
            local_t,
            self.color_ik,
            "cube",
            w=w*.2,
            h=h*.2,
            d=d*.2,
            ro=datatypes.Vector([-math.pi / 2., 0., 0.])
        )

        ymt_util.setKeyableAttributesDontLockVisibility(self.scale_ctl, self.s_params)
        ymt_util.setKeyableAttributesDontLockVisibility(self.length_ctl, ["tx", "ty", "tz"])
Beispiel #11
0
def matrix_reset_rotation(matrix):
    """
    Will reset the rotation values in four by four matrix to zero in worldspace.

    Args:
        matrix(dt.Matrix): Four by four matrix.

    Return:
        dt.Matrix: The matrix reset in rotation.

    """
    tm = dt.TransformationMatrix(matrix)
    tm.setRotation((0, 0, 0))
    return dt.Matrix(tm)
Beispiel #12
0
def getInterpolateTransformMatrix(t1, t2, blend=.5):
    """Interpolate 2 matrix.

    Arguments:
        t1 (matrix): Input matrix 1.
        t2 (matrix): Input matrix 2.
        blend (float): The blending value. Default 0.5

    Returns:
        matrix: The newly interpolated transformation matrix.

    >>> t = tra.getInterpolateTransformMatrix(self.fk_ctl[0],
                                              self.tws1A_npo,
                                              .3333)

    """
    # check if the input transforms are transformMatrix
    t1 = convert2TransformMatrix(t1)
    t2 = convert2TransformMatrix(t2)

    if (blend == 1.0):
        return t2
    elif (blend == 0.0):
        return t1

    # translate
    pos = vector.linearlyInterpolate(t1.getTranslation(space="world"),
                                     t2.getTranslation(space="world"),
                                     blend)

    # scale
    scaleA = datatypes.Vector(*t1.getScale(space="world"))
    scaleB = datatypes.Vector(*t2.getScale(space="world"))

    vs = vector.linearlyInterpolate(scaleA, scaleB, blend)

    # rotate
    q = quaternionSlerp(datatypes.Quaternion(t1.getRotationQuaternion()),
                        datatypes.Quaternion(t2.getRotationQuaternion()),
                        blend)

    # out
    result = datatypes.TransformationMatrix()

    result.setTranslation(pos, space="world")
    result.setRotationQuaternion(q.x, q.y, q.z, q.w)
    result.setScale([vs.x, vs.y, vs.z], space="world")

    return result
    def _getTransformWithRollByBlade(self, t):
        # t = getTransform(self.guide.root)
        a = self.guide.blades["blade"].y
        x = vector.Blade(t).x
        z = vector.Blade(t).z

        x = vecProjection(a, x)[0]
        z = vecProjection(a, z)[2]
        theta = math.atan2(x, z)
        roll = theta + math.pi

        tm = datatypes.TransformationMatrix(t)
        tm.addRotation([0., roll, 0], 'XYZ', om.MSpace.kObject)

        return datatypes.Matrix(tm)
Beispiel #14
0
    def translateBuffer(self, index, translation):
        if not isinstance(translation, list):
            translation = dt.Vector(translation)
        translation *= 100

        buffer = self.get_buffer_at(index)
        buffer_child = self.get_buffer_at(index - 1)
        if not buffer_child:
            buffer_child = self.control_curve

        matrix = dt.TransformationMatrix()
        matrix.addTranslation(translation, space='world')

        buffer.setMatrix(buffer.getMatrix(worldSpace=True) * matrix,
                         worldSpace=True)
        buffer_child.setMatrix(buffer_child.getMatrix() *
                               matrix.asMatrixInverse())
Beispiel #15
0
def setMatrixScale(m, scl=[1, 1, 1]):
    """Set the scale for a given matrix

    Arguments:
        in_m (matrix): The input Matrix.
        scl (list of float): The scale values for xyz

    Returns:
        matrix: The matrix with the new scale

    """
    tm = datatypes.TransformationMatrix(m)
    tm.setScale(scl, space="world")

    m = datatypes.Matrix(tm)

    return m
Beispiel #16
0
    def orientHandJointTo(self, target, object, handed):
        objectJoint = pc.ls(object, type="joint")[0]
        objWorldMat = objectJoint.attr("worldMatrix").get()
        objWorldPos = objWorldMat[3][:3]

        tarJoint = pc.ls(target, type="joint")[0]
        tarWorldMat = tarJoint.attr("worldMatrix").get()
        tarWorldPos = tarWorldMat[3][:3]

        wristJoint = pc.ls(self.wristJoint, type="joint")[0]
        wristWorldMat = wristJoint.attr("worldMatrix").get()
        wristWorldPos = wristWorldMat[3][:3]

        # get aim vector from object to target
        if handed == "L":
            aimVector = tarWorldPos - objWorldPos
        if handed == "R":
            aimVector = objWorldPos - tarWorldPos

        aimVector = dt.Vector(aimVector)
        aimVector.normalize()
        aimX = aimVector

        # get z axis used to rotate object around its z
        objUpVector = dt.Vector(objWorldMat[2][:3])

        # find dot product of objUpVector and aimX to help get up vector of aimX
        dotProduct = dt.dot(objUpVector, aimX)

        # construct rotation matrix
        aimRotationMat = dt.Matrix(3)
        aimRotationMat[0] = aimX
        aimRotationMat[1] = dt.Vector(wristWorldMat[1][:3])
        aimRotationMat[2] = dt.Vector(wristWorldMat[2][:3])

        # convert rotation matrix to Euler angles
        aimRotationTransMat = dt.TransformationMatrix(aimRotationMat)
        aimRotationQuaternion = aimRotationTransMat.getRotationQuaternion()

        # set object rotation to final aim rotation vector
        objectJoint.setOrientation(aimRotationQuaternion)
Beispiel #17
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            # Controlers (First and last one are fake)
            # if i in [0]:
            # TODO: add option setting to add or not the first and
            #  last controller for the fk
            if i in [0, self.settings["division"] - 1] and False:
                # if i in [0, self.settings["division"] - 1]:
                fk_ctl = primitive.addTransform(
                    parentctl, self.getName("%s_loc" % i),
                    transform.getTransform(parentctl))

                fk_npo = fk_ctl
                if i in [self.settings["division"] - 1]:
                    self.fk_ctl.append(fk_ctl)
            else:
                m = transform.getTransform(self.root)
                t = transform.getTransform(parentctl)
                m.inverse()

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

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

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

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

            self.scl_transforms.append(scl_ref)

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

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

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

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

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

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

            # TODO: update this part with the optiona FK controls update
            for x in self.fk_ctl[:-1]:
                attribute.setInvertMirror(x, ["tx", "rz", "ry"])

        # Connections (Hooks) ------------------------------
        self.cnx0 = primitive.addTransform(self.root, self.getName("0_cnx"))
        self.cnx1 = primitive.addTransform(self.root, self.getName("1_cnx"))
Beispiel #18
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])
Beispiel #19
0
def addJnt(obj=False,
           parent=False,
           noReplace=False,
           grp=None,
           jntName=None,
           *args):
    """Create one joint for each selected object.

    Args:
        obj (bool or dagNode, optional): The object to drive the new
            joint. If False will use the current selection.
        parent (bool or dagNode, optional): The parent for the joint.
            If False will try to parent to jnt_org. If jnt_org doesn't
            exist will parent the joint under the obj
        noReplace (bool, optional): If True will add the extension
            "_jnt" to the new joint name
        grp (pyNode or None, optional): The set to add the new joint.
            If none will use "rig_deformers_grp"
        *args: Maya's dummy

    Returns:
        pyNode: The New created joint.

    """
    if not obj:
        oSel = pm.selected()
    else:
        oSel = [obj]

    for obj in oSel:
        if not parent:
            try:
                oParent = pm.PyNode("jnt_org")
            except TypeError:
                oParent = obj
        else:
            oParent = parent
        if not jntName:
            if noReplace:
                jntName = "_".join(obj.name().split("_")) + "_jnt"
            else:
                jntName = "_".join(obj.name().split("_")[:-1]) + "_jnt"
        jnt = primitive.addJoint(oParent, jntName, transform.getTransform(obj))

        if grp:
            grp.add(jnt)
        else:
            try:
                defSet = pm.PyNode("rig_deformers_grp")
                pm.sets(defSet, add=jnt)
            except TypeError:
                pm.sets(n="rig_deformers_grp")
                defSet = pm.PyNode("rig_deformers_grp")
                pm.sets(defSet, add=jnt)

        jnt.setAttr("segmentScaleCompensate", False)
        jnt.setAttr("jointOrient", 0, 0, 0)
        try:
            cns_m = applyop.gear_matrix_cns(obj, jnt)
            # setting the joint orient compensation in order to have clean
            # rotation channels
            m = cns_m.drivenRestMatrix.get()
            tm = datatypes.TransformationMatrix(m)
            r = datatypes.degrees(tm.getRotation())
            jnt.attr("jointOrientX").set(r[0])
            jnt.attr("jointOrientY").set(r[1])
            jnt.attr("jointOrientZ").set(r[2])
        except RuntimeError:
            for axis in ["tx", "ty", "tz", "rx", "ry", "rz"]:
                jnt.attr(axis).set(0.0)

    return jnt
    def _addObjectsFkControl(self, i, parentdiv, parentctl, t, parent_twistRef):
        # References
        tm = datatypes.TransformationMatrix(t)
        tm.addRotation([0., 0., math.pi / -2.], 'XYZ', om.MSpace.kObject)  # TODO: align with convention
        tm.addRotation([0., math.pi / -2., 0], 'XYZ', om.MSpace.kObject)
        global_t  = datatypes.Matrix(tm)

        # global input
        div_cns = addTransform(parentdiv, self.getName("%s_cns" % i))
        div_cns_npo = addTransform(div_cns, self.getName("%s_cns_npo" % i))
        pm.setAttr(div_cns + ".inheritsTransform", False)
        div_cns.setMatrix(global_t, worldSpace=True)
        self.div_cns.append(div_cns)
        self.div_cns_npo.append(div_cns_npo)
        parentdiv = div_cns

        # t = getTransform(parentctl)
        if i == 0:
            p = parentctl
        else:
            # p = self.scl_transforms[i - 1]
            p = self.fk_local_in[i - 1]
        fk_npo = addTransform(p, self.getName("fk%s_npo" % (i)), global_t)

        # local input
        fk_local_npo = addTransform(fk_npo, self.getName("fk%s_local_npo" % i), global_t)
        fk_local_in = addTransform(fk_local_npo, self.getName("fk%s_local_in" % i), global_t)
        self.fk_local_in.append(fk_local_in)

        if i < len(self.guide.apos) - 1:
            h = (self.guide.apos[i] - self.guide.apos[i + 1]).length() * .8
        else:
            h = (self.guide.apos[-1] - self.guide.apos[0]).length() / (len(self.guide.apos) - 1)

        # FIXME: rotate by blade
        po = datatypes.Vector([0, h / 2., 0])

        fk_ctl = self.addCtl(
            fk_local_in,
            "fk%s_ctl" % (i),
            global_t,
            self.color_fk,
            "cube",
            w=h * .66,
            h=h,
            d=h * 0.3,
            # ro=datatypes.Vector([0, -math.pi / 2., 0]),
            po=po,
            tp=self.preiviousCtlTag,
            mirrorConf=self.mirror_conf)

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

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

        if i == 0 and self.settings["isSplitHip"]:
            t = self._getTransformWithRollByBlade(getTransform(self.guide.root))
            h = (self.guide.apos[-1] - self.guide.apos[0]).length() / (len(self.guide.apos) - 1)
            po = datatypes.Vector([0, self.size / len(self.guide.apos) * -.8, 0])
            hip_fk_local_in = addTransform(p, self.getName("hip_fk_local_in"), t)
            self.hip_fk_local_in = hip_fk_local_in

            self.fk_hip_ctl = self.addCtl(
                hip_fk_local_in,
                "fk_hip_ctl",
                t,
                self.color_fk,
                "cube",
                w=h * .66,
                h=h,
                d=h * 0.3,
                # ro=datatypes.Vector([0, -math.pi / 2., 0]),
                po=po,
                tp=self.preiviousCtlTag,
                mirrorConf=self.mirror_conf)
            hip_scl_ref = addTransform(self.fk_hip_ctl, self.getName("hip_scl_ref"), t)

        # Deformers (Shadow)
        if self.settings["addJoints"]:
            if self.settings["isSplitHip"]:
                if i == 0:
                    self.jnt_pos.append([hip_scl_ref, 0])

                self.jnt_pos.append([scl_ref, i + 1])

            else:
                self.jnt_pos.append([scl_ref, i])

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

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

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

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

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

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

        return parentdiv, parentctl
Beispiel #21
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

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

        # 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_cns = primitive.addTransform(
            self.root, self.getName("ik_cns"), t)

        self.ik_ctl = self.addCtl(self.ik_cns,
                                  "ik_ctl",
                                  t,
                                  self.color_ik,
                                  "compas",
                                  w=self.size * .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 * .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 * .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 = []

        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.settings["division"]):

            # 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.settings["division"] - 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 * .2,
                                     h=self.size * .05,
                                     d=self.size * .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

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

            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 * .5,
                                    h=dist, d=self.size * .5,
                                    po=datatypes.Vector(0, dist * .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, "head"])
Beispiel #22
0
 def _add_scale(cls, node, scale):
     matrix = dt.TransformationMatrix()
     matrix.addScale(scale, space='world')
     cls._add_transformation(node, matrix)
Beispiel #23
0
    def addObjects(self):
        """Add all the objects needed to create the component."""

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            t = transform.getTransform(parentctl)

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

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

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

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

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

            self.scl_transforms.append(scl_ref)

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

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

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

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

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

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

        # Connections (Hooks) ------------------------------
        self.cnx0 = primitive.addTransform(self.root, self.getName("0_cnx"))
        self.cnx1 = primitive.addTransform(self.root, self.getName("1_cnx"))
        self.jnt_pos.append([self.cnx1, "spine_" + str(i + 2).zfill(2)])