Exemple #1
0
    def change_operator_index(self, index):
        """
        Change the operator index.

        Args:
            index(int): The index.

        """
        for node in self.all_container_nodes:
            new_name = strings.replace_index_numbers(str(node), index)
            strings.string_checkup(new_name, _LOGGER)
            node.rename(new_name)
        self.set_component_index(index)
Exemple #2
0
 def __init__(
     self,
     comp_name=None,
     comp_side=None,
     comp_index=0,
     component_container=None,
 ):
     """
     Args
         comp_name(str): The rig component name.
         comp_side(str): The component side.
         comp_index(int): The component index.
         component_container(pmc.PyNode()): A component container to pass.
     """
     super(CompContainer, self).__init__(
         container_node=component_container, content_root_node=True
     )
     self.name = "M_ROOT_name_component_0_GRP"
     self.meta_nd_name = constants.COMP_META_NODE_NAME
     self.icon = os.path.normpath(
         "{}/components_logo.png".format(constants.ICONS_PATH)
     )
     if comp_name and comp_side:
         self.meta_nd_name = self.meta_nd_name.replace("COMP", comp_name)
         self.name = (
             self.name.replace("M", comp_side)
             .replace("name", comp_name)
             .replace("0", str(comp_index))
         )
         self.name = strings.string_checkup(self.name)
         self.container_content_root_name = self.container_content_root_name.replace(
             "M", comp_side
         ).replace(
             "content_root", "{}_content_root".format(comp_name)
         )
Exemple #3
0
    def change_operator_side(self, side):
        """
        Change the operator side.

        Args:
            side(str): String to replace.

        """
        search = "^[MRL]_"
        replace = "{}_".format(side)
        for node in self.all_container_nodes:
            new_name = strings.regex_search_and_replace(
                str(node), search, replace)
            strings.string_checkup(new_name, _LOGGER)
            node.rename(new_name)
        self.set_component_side(side)
Exemple #4
0
    def rename_operator_nodes(self, name):
        """
        Change operator and Component name. Search string is the Component
        name in the meta data.

        Args:
            name(str): String to replace.

        """
        name = strings.normalize_string(name, _LOGGER)
        component_name = self.get_component_name()
        search = "_{}_".format(component_name)
        replace = "_{}_".format(name)
        if component_name:
            for node in self.all_container_nodes:
                new_name = str(node).replace(search, replace)
                strings.string_checkup(new_name, _LOGGER)
                node.rename(new_name)
        self.set_component_name(name)
Exemple #5
0
def create_IK(
    name,
    solver="ikSCsolver",
    start_jnt=None,
    end_jnt=None,
    parent=None,
    snap=True,
    sticky=False,
    weight=1,
    po_weight=1,
):
    """
    Create a IK. Default is a single chain IK.
    Args:
            name(str): The IK name. You should follow
            the JoMRS naming convention. If not it will throw some
            warnings.
            solver(str): The solver of the IK.
            start_jnt(dagNode): The start joint of the chain.
            end_jnt(dagNode): The end joint of the chain.
            parent(dagNode): The parent for the IK_handle.
            snap(bool): Enable/Disalbe snap option of the IK.
            sticky(bool): Enable/Disalbe stickieness option of the IK.
            weight(float): Set handle weight.
            po_weight(float): Set the poleVector weight.
    Return:
    """
    data = {}
    name = strings.string_checkup(name, _LOGGER)
    data["n"] = name
    data["solver"] = solver
    data["sj"] = start_jnt
    data["ee"] = end_jnt
    ik_handle = pmc.ikHandle(**data)
    pmc.rename(ik_handle[1], str(end_jnt) + "_EFF")
    if parent:
        parent.addChild(ik_handle[0])
    ik_handle[0].visibility.set(0)
    if snap is False:
        ik_handle[0].snapEnable.set(0)
    if sticky:
        ik_handle[0].stickiness.set(1)
    ik_handle[0].attr("weight").set(weight)
    ik_handle[0].attr("po_weight").set(po_weight)
    logger.log(
        level="info", message=solver + ' "' + name + '" created', logger=_LOGGER
    )
    return ik_handle
Exemple #6
0
def convert_to_skeleton(
    root_node=None,
    prefix="M_BND",
    suffix="JNT",
    typ="BND",
    buffer_grp=True,
    inverse_scale=True,
):
    """
    Convert a hierarchy of transform nodes into a joint skeleton.
    By default it is a BND joint hierarchy with a buffer group.
    The hierarchy has disconnected inverse scale plugs.
    Args:
            root_node(dagnode): The root_node of the transform
            hierarchy.
            prefix(str): The prefix of the joints.
            suffix(str): The suffix of the joints.
            typ(str): The joint types.
            buffer_grp(bool): Creates a buffer group for the
            hierarchy.
            inverse_scale(bool): Disconnect the inverse scale
            plugs of the joints.
    Return:
            list: The new created joint hierarchy.
    """
    result = []
    hierarchy = descendants(root_node=root_node)
    if hierarchy:
        for tra in range(len(hierarchy)):
            name = "{}_{}_{}".format(prefix, str(tra), suffix)
            name = strings.string_checkup(name, _LOGGER)
            jnt = create_joint(name=name, node=hierarchy[tra], typ=typ)
            result.append(jnt)
    temp = result[:]
    for node in hierarchy:
        if len(temp) > 1:
            temp[-2].addChild(temp[-1])
            temp.remove(temp[-1])
    if buffer_grp:
        buffer_grp = create_buffer_grp(node=result[0])
        result.insert(0, buffer_grp)
    if inverse_scale:
        for node in result:
            try:
                node.inverseScale.disconnect()
            except:
                continue
    return result
Exemple #7
0
    def __init__(self, rig_name=None, rig_container=None):
        """
        Args
            rig_name(str): The rig name.
            rig_container(pmc.PyNode()): A rig container to pass.

        """
        super(RigContainer, self).__init__()
        self.meta_nd_name = constants.RIG_META_NODE_NAME
        self.name = constants.RIG_ROOT_NODE
        self.icon = os.path.normpath("{}/rig_hierarchy_logo.png".format(
            constants.ICONS_PATH))
        self.container = rig_container
        if not self.container:
            if rig_name:
                self.name = self.name.replace("name", rig_name)
                self.name = strings.string_checkup(self.name)
Exemple #8
0
def space_locator_on_position(node, buffer_grp=True):
    """
    Create a spaceLocator on the position of a node.
    Args:
            node(dagnode): The match transform node.
            buffer_grp(bool): Create a buffer group for the locator.
    Return:
            list: The buffer group, the locator node.
    """
    result = []
    name = strings.string_checkup(str(node) + "_0_LOC", _LOGGER)
    loc = pmc.spaceLocator(n=name)
    loc.setMatrix(node.getMatrix(worldSpace=True), worldSpace=True)
    result.append(loc)
    if buffer_grp:
        buffer_grp = create_buffer_grp(loc)
        result.insert(0, buffer_grp)
    return result
Exemple #9
0
def create_joint(
    name="M_BND_0_JNT",
    typ="BND",
    node=None,
    orient_match_rotation=True,
    match_matrix=None,
):
    """
    Create a joint node with a specific typ.
    By Default it creates a 'BND' joint and match the jointOrient with
    the rotation of a node.
    Args:
            name(str): The name of the node. Try to use the JoMRS
            naming convention. If not it will throw a warning.
            typ(str): Typ of the joint. Valid is: [BND, DRV, FK, IK]
            node(dagnode): The node for transformation match.
            orient_match_rotation(bool): Enable the match of the joint
            orientation with the rotation of the node.
            match_matrix(matrix): The matrix to match
    Return:
            tuple: The created joint node.
    """
    name = strings.string_checkup(name, _LOGGER)
    data = [
        {"typ": "BND", "radius": 1, "overrideColor": 17},
        {"typ": "DRV", "radius": 2.5, "overrideColor": 18},
        {"typ": "FK", "radius": 1.5, "overrideColor": 4},
        {"typ": "IK", "radius": 2, "overrideColor": 6},
    ]
    jnt = pmc.createNode("joint", n=name)
    for util in data:
        if util["typ"] == typ:
            jnt.overrideEnabled.set(1)
            jnt.radius.set(util["radius"])
            jnt.overrideColor.set(util["overrideColor"])
    if node:
        jnt.setMatrix(node.getMatrix(worldSpace=True), worldSpace=True)
    if orient_match_rotation:
        jnt.jointOrient.set(jnt.rotate.get())
        jnt.rotate.set(0, 0, 0)
    if match_matrix:
        jnt.setMatrix(match_matrix, worldSpace=True)
    return jnt
Exemple #10
0
def create_ref_transform(
    name, side, index, buffer_grp=False, match_matrix=None, child=None
):
    """
    Create a reference transform.
    Args:
            name(str): Name for the ref node.
            side(str): The side. Valid values are "M", "R", "L".
            index(int): The index number.
            buffer_grp(bool): Enable buffer grp.
            match_matrix(matrix): The match matrix.
            child(dagnode): Child of node.

    Example:
            >>> create_ref_transform('test', 'M', 0, True,
            >>> [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
            >>> 0.0, 0.0, 0.0, 1.0], pmc.PyNode('your_node'))

    Return:
            The new ref node.
    """
    valid_sides = ["L", "R", "M"]
    if side not in valid_sides:
        raise AttributeError(
            'Chosen side is not valid. Valid values are ["L", "R", "M"]'
        )
    name = "{}_REF_{}_{}_GRP".format(side, name, str(index))
    name = strings.string_checkup(name, logger_=_LOGGER)
    ref_trs = pmc.createNode("transform", n=name)
    if match_matrix:
        ref_trs.setMatrix(match_matrix, worldSpace=True)
    if buffer_grp:
        create_buffer_grp(node=ref_trs)
    if child:
        ref_trs.addChild(child)
    return ref_trs
Exemple #11
0
    def _postCreateVirtual(
        cls,
        newNode,
        type=constants.META_TYPE,
        god_meta_name=constants.META_GOD_ND_NAME,
        connection_types=constants.DEFAULT_CONNECTION_TYPES,
    ):
        """
        This is called after creation, pymel/cmds allowed.
        It will create a set of attributes. And the important check up tag for
        the meta node.
        Args:
                newNode(pmc.PyNode()): The new node.
                tag(str): The specific creation tag.
                type(str): The meta node type.
                god_meta_name(str): The name of the god meta node.
        """
        MetaNode._postCreateVirtual(newNode)
        try:
            god_mata_nd = pmc.PyNode(god_meta_name)
        except:
            god_mata_nd = GodMetaNode()
        newNode.attr(type).set(cls.SUBNODE_TYPE)
        god_mata_nd.add_meta_node(newNode)
        name = "{}_METAND".format(str(newNode))
        name = strings.string_checkup(name, logger_=_LOGGER)
        newNode.rename(name)

        container_nd_attr = {
            "name": constants.CONTAINER_NODE_ATTR_NAME,
            "attrType": "message",
            "keyable": False,
            "channelBox": False,
        }

        input_ws_matrix_offset_nd_attr = {
            "name": constants.INPUT_WS_MATRIX_OFFSET_ND,
            "attrType": "message",
            "keyable": False,
            "multi": True,
        }

        bnd_root_node_attr = {
            "name": constants.BND_JNT_ROOT_ND_ATTR,
            "attrType": "message",
            "keyable": False,
        }

        container_type_attr = {
            "name": constants.META_CONTAINER_TYPE_ATTR,
            "attrType": "string",
            "keyable": False,
        }

        container_meta_param_list = [
            container_nd_attr,
            input_ws_matrix_offset_nd_attr,
            bnd_root_node_attr,
            container_type_attr,
        ]

        for attr_ in container_meta_param_list:
            attributes.add_attr(node=newNode, **attr_)
Exemple #12
0
    def _postCreateVirtual(
        cls,
        newNode,
        type=constants.META_TYPE,
        god_meta_name=constants.META_GOD_ND_NAME,
    ):
        """
        This is called after creation, pymel/cmds allowed.
        It will create a set of attributes. And the important check up tag for
        the meta node.
        Args:
                newNode(pmc.PyNode()): The new node.
                tag(str): The specific creation tag.
                type(str): The meta node type.
                god_meta_name(str): The name of the god meta node.
        """
        MetaNode._postCreateVirtual(newNode)
        try:
            god_mata_nd = pmc.PyNode(god_meta_name)
        except:
            god_mata_nd = GodMetaNode()
        newNode.attr(type).set(cls.SUBNODE_TYPE)
        god_mata_nd.add_meta_node(newNode)
        name = "{}_METAND".format(str(newNode))
        name = strings.string_checkup(name, logger_=_LOGGER)
        newNode.rename(name)

        connection_type_attr = {
            "name": constants.META_DEFAULT_CONNECTION_TYPES,
            "attrType": "string",
            "keyable": False,
            "channelBox": False,
            "value": constants.DEFAULT_CONNECTION_TYPES,
        }

        sub_operator_connection = {
            "name": constants.SUB_OP_MESSAGE_ATTR_NAME,
            "attrType": "message",
            "keyable": False,
            "channelBox": False,
        }

        main_operator_connection = {
            "name": constants.MAIN_OP_MESSAGE_ATTR_NAME,
            "attrType": "message",
            "keyable": False,
            "channelBox": False,
        }

        ws_output_index_attr = {
            "name": constants.OUTPUT_WS_PORT_INDEX,
            "attrType": "long",
            "keyable": False,
            "defaultValue": 1,
        }

        parent_ws_output_index_attr = {
            "name": constants.PARENT_OUTPUT_WS_PORT_INDEX,
            "attrType": "long",
            "keyable": False,
            "defaultValue": 0,
        }

        sub_node_param_list = [
            connection_type_attr,
            sub_operator_connection,
            main_operator_connection,
            ws_output_index_attr,
            parent_ws_output_index_attr,
        ]

        for attr_ in sub_node_param_list:
            attributes.add_attr(node=newNode, **attr_)
Exemple #13
0
    def _postCreateVirtual(
        cls,
        newNode,
        type=constants.META_TYPE,
        god_meta_name=constants.META_GOD_ND_NAME,
        connection_types=constants.DEFAULT_CONNECTION_TYPES,
    ):
        """
        This is called after creation, pymel/cmds allowed.
        It will create a set of attributes. And the important check up tag for
        the meta node.
        Args:
                newNode(pmc.PyNode()): The new node.
                tag(str): The specific creation tag.
                type(str): The meta node type.
                god_meta_name(str): The name of the god meta node.
        """
        MetaNode._postCreateVirtual(newNode)
        try:
            god_mata_nd = pmc.PyNode(god_meta_name)
        except:
            god_mata_nd = GodMetaNode()
        newNode.attr(type).set(cls.SUBNODE_TYPE)
        god_mata_nd.add_meta_node(newNode)
        name = "{}_METAND".format(str(newNode))
        name = strings.string_checkup(name, logger_=_LOGGER)
        newNode.rename(name)

        comp_name_attr = {
            "name": constants.META_MAIN_COMP_NAME,
            "attrType": "string",
            "keyable": False,
            "channelBox": False,
        }

        comp_type_attr = {
            "name": constants.META_MAIN_COMP_TYPE,
            "attrType": "string",
            "keyable": False,
            "channelBox": False,
        }

        comp_side_attr = {
            "name": constants.META_MAIN_COMP_SIDE,
            "attrType": "string",
            "keyable": False,
            "channelBox": False,
        }

        comp_index_attr = {
            "name": constants.META_MAIN_COMP_INDEX,
            "attrType": "long",
            "keyable": False,
            "channelBox": False,
            "defaultValue": 0,
        }

        connection_type_attr = {
            "name": constants.META_DEFAULT_CONNECTION_TYPES,
            "attrType": "string",
            "keyable": False,
            "channelBox": False,
            "value": constants.DEFAULT_CONNECTION_TYPES,
        }

        ik_spaces_ref_attr = {
            "name": constants.META_MAIN_IK_SPACES,
            "attrType": "string",
            "keyable": False,
            "channelBox": False,
        }

        fk_spaces_ref_attr = {
            "name": constants.META_MAIN_FK_SPACES,
            "attrType": "string",
            "keyable": False,
            "channelBox": False,
        }

        ik_pvec_spaces_ref_attr = {
            "name": constants.META_MAIN_IK_PVEC_SPACES,
            "attrType": "string",
            "keyable": False,
            "channelBox": False,
        }

        main_operator_connection = {
            "name": constants.MAIN_OP_MESSAGE_ATTR_NAME,
            "attrType": "message",
            "keyable": False,
            "channelBox": False,
        }

        connect_nd_attr = {
            "name": constants.META_MAIN_CONNECT_ND,
            "attrType": "string",
            "keyable": False,
            "channelBox": False,
        }

        rig_build_class_ref = {
            "name": constants.META_MAIN_RIG_BUILD_CLASS_REF,
            "attrType": "string",
            "keyable": False,
            "channelBox": False,
        }

        parent_nd_attr = {
            "name": constants.META_MAIN_PARENT_ND,
            "attrType": "message",
            "keyable": False,
            "channelBox": False,
        }

        child_nd_attr = {
            "name": constants.META_MAIN_CHILD_ND,
            "attrType": "message",
            "keyable": False,
            "channelBox": False,
            "multi": True,
        }

        component_defined_attr = {
            "name": constants.META_COMPONENT_DEFINED_ATTR,
            "attrType": "string",
            "keyable": False,
            "channelBox": False,
        }

        ws_output_index_attr = {
            "name": constants.OUTPUT_WS_PORT_INDEX,
            "attrType": "long",
            "keyable": False,
            "defaultValue": 0,
        }

        parent_ws_output_index_attr = {
            "name": constants.PARENT_OUTPUT_WS_PORT_INDEX,
            "attrType": "long",
            "keyable": False,
            "defaultValue": 0,
        }

        main_node_param_list = [
            comp_name_attr,
            comp_type_attr,
            comp_side_attr,
            comp_index_attr,
            connection_type_attr,
            ik_spaces_ref_attr,
            fk_spaces_ref_attr,
            ik_pvec_spaces_ref_attr,
            main_operator_connection,
            connect_nd_attr,
            rig_build_class_ref,
            parent_nd_attr,
            child_nd_attr,
            component_defined_attr,
            ws_output_index_attr,
            parent_ws_output_index_attr,
        ]

        for attr_ in main_node_param_list:
            attributes.add_attr(node=newNode, **attr_)
Exemple #14
0
    def _postCreateVirtual(
        cls,
        newNode,
        type=constants.META_TYPE,
        god_meta_name=constants.META_GOD_ND_NAME,
    ):
        """
        This is called after creation, pymel/cmds allowed.
        It will create a set of attributes. And the important check up tag for
        the meta node.
        Args:
                newNode(pmc.PyNode()): The new node.
                tag(str): The specific creation tag.
                type(str): The meta node type.
                god_meta_name(str): The name of the god meta node.
        """
        MetaNode._postCreateVirtual(newNode)
        try:
            god_mata_nd = pmc.PyNode(god_meta_name)
        except:
            god_mata_nd = GodMetaNode()
        newNode.attr(type).set(cls.SUBNODE_TYPE)
        god_mata_nd.add_meta_node(newNode)
        name = "{}_METAND".format(str(newNode))
        name = strings.string_checkup(name, logger_=_LOGGER)
        newNode.rename(name)

        rigname_attr = {
            "name": constants.META_ROOT_RIG_NAME,
            "attrType": "string",
            "keyable": False,
            "value": "None",
        }

        l_rig_color_attr = {
            "name": constants.META_LEFT_RIG_COLOR,
            "attrType": "long",
            "keyable": False,
            "defaultValue": 13,
            "minValue": 0,
            "maxValue": 31,
        }

        l_rig_sub_color_attr = {
            "name": constants.META_LEFT_RIG_SUB_COLOR,
            "attrType": "long",
            "keyable": False,
            "defaultValue": 18,
            "minValue": 0,
            "maxValue": 31,
        }

        r_rig_color_attr = {
            "name": constants.META_RIGHT_RIG_COLOR,
            "attrType": "long",
            "keyable": False,
            "defaultValue": 6,
            "minValue": 0,
            "maxValue": 31,
        }

        r_rig_sub_color_attr = {
            "name": constants.META_RIGHT_RIG_SUB_COLOR,
            "attrType": "long",
            "keyable": False,
            "defaultValue": 9,
            "minValue": 0,
            "maxValue": 31,
        }

        m_rig_color_attr = {
            "name": constants.META_MID_RIG_COLOR,
            "attrType": "long",
            "keyable": False,
            "defaultValue": 17,
            "minValue": 0,
            "maxValue": 31,
        }

        m_rig_sub_color_attr = {
            "name": constants.META_MID_RIG_SUB_COLOR,
            "attrType": "long",
            "keyable": False,
            "defaultValue": 11,
            "minValue": 0,
            "maxValue": 31,
        }

        root_op_nd_attr = {
            "name": constants.ROOT_OP_MESSAGE_ATTR_NAME,
            "attrType": "message",
            "keyable": False,
            "channelBox": False,
        }

        main_meta_nodes_array_attr = {
            "name": constants.ROOT_META_ND_ARRAY_PLUG_NAME,
            "attrType": "message",
            "keyable": False,
            "channelBox": False,
            "multi": True,
        }

        root_node_param_list = [
            rigname_attr,
            l_rig_color_attr,
            l_rig_sub_color_attr,
            r_rig_color_attr,
            r_rig_sub_color_attr,
            m_rig_color_attr,
            m_rig_sub_color_attr,
            root_op_nd_attr,
            main_meta_nodes_array_attr,
        ]
        for attr_ in root_node_param_list:
            attributes.add_attr(node=newNode, **attr_)
Exemple #15
0
def create_motion_path(
    name="M_test_0_MPND",
    curve_shape=None,
    target=None,
    position=1,
    world_up_type="objectUp",
    up_vec_obj=None,
    aim_axes="x",
    up_axes="y",
    follow=True,
    world_up_vector=[0, 0, 1],
):
    """
    Create a motionPath node. By default the world_up_type is objectUp. The
    aim_axes is 'x' and the upAxes is 'y'. Follow mode is enabled.
    Args:
            name(str): The name of the node. Try to use the JoMRS
            naming convention. If not it will throw a warning.
            curve_shape(dagnode): The curve shape node for the motion path.
            target(dagnode): The node to attach on the curve.
            position(float): The position of the the target.
            world_up_type(str): The upvector mode for the node.
            Valis is: [sceneUp, objectUp, objectRotationUp, vector, normal]
            up_vec_obj(dagnode): The transform for the up vector.
            aim_axes(str): The aim axes. Valis is [x, y, z]
            up_axes(str): The up axes. Valis is [x, y, z]
            follow(bool): Enable the aim and up axes of the node.
            world_up_vector(list): The axes for the world up vector.
    Return:
            tuple: The created motion path node.
    """
    axes = ["X", "Y", "Z"]
    name = strings.string_checkup(name, _LOGGER)
    mpnd = pmc.createNode("motionPath", n=name)
    mpnd.fractionMode.set(1)
    mpnd.uValue.set(position)
    curve_shape.worldSpace[0].connect(mpnd.geometryPath)
    if target:
        for axe in axes:
            mpnd.attr("rotate" + axe).connect(
                target.attr("rotate" + axe), force=True
            )
            mpnd.attr(axe.lower() + "Coordinate").connect(
                target.attr("translate" + axe), force=True
            )
    if follow:
        if aim_axes == "x":
            value = 0
        elif aim_axes == "y":
            value = 1
        elif aim_axes == "z":
            value = 2
        if up_axes == "x":
            value_ = 0
        elif up_axes == "y":
            value_ = 1
        elif up_axes == "z":
            value_ = 2
        if world_up_type == "sceneUp":
            value__ = 0
        elif world_up_type == "objectUp":
            value__ = 1
        elif world_up_type == "objectRotationUp":
            value__ = 2
        elif world_up_type == "vector":
            value__ = 3
        elif world_up_type == "normal":
            value__ = 4
        if value__ == 1 or value__ == 2:
            if up_vec_obj:
                up_vec_obj.worldMatrix.connect(mpnd.worldUpMatrix, force=True)
            else:
                logger.log(
                    level="error",
                    message="You need a upvector transform",
                    logger=_LOGGER,
                )
        if value__ == 2 or value__ == 3:
            mpnd.worldUpVectorX.set(world_up_vector[0])
            mpnd.worldUpVectorY.set(world_up_vector[1])
            mpnd.worldUpVectorZ.set(world_up_vector[2])
        mpnd.follow.set(1)
        mpnd.frontAxis.set(value)
        mpnd.upAxis.set(value_)
        mpnd.worldUpType.set(value__)
    else:
        mpnd.follow.set(0)
    return mpnd
Exemple #16
0
def create_spline_ik(
    name,
    start_jnt=None,
    end_jnt=None,
    parent=None,
    curve_parent=None,
    curve=None,
    snap=True,
    sticky=False,
    weight=1,
    po_weight=1,
):
    """
    Create a splineIK.
    Args:
            name(str): The spline IK name. You should follow the
            JoMRS naming convention. If not it will throw some
            warnings.
            start_jnt(dagNode): The start joint of the chain.
            end_jnt(dagNode): The end joint of the chain.
            parent(dagNode): The parent for the IK_handle.
            snap(bool): Enable/Disalbe snap option of the IK.
            sticky(bool): Enable/Disalbe stickieness option of the IK.
            weight(float): Set handle weight.
            po_weight(float): Set the poleVector weight.
    Return:
            list(dagnodes): the ik Handle, the effector,
            the spline ik curve shape.
    """
    result = []
    data = {}
    name = strings.string_checkup(name, _LOGGER)
    data["n"] = name
    data["solver"] = "ikSplineSolver"
    data["createCurve"] = False
    data["sj"] = start_jnt
    data["ee"] = end_jnt
    if curve is not None:
        data["c"] = curve
    else:
        data["createCurve"] = True
    ik_handle = pmc.ikHandle(**data)
    pmc.rename(ik_handle[1], str(end_jnt) + "_EFF")
    result.extend(ik_handle)
    if curve:
        pmc.rename(curve, str(curve) + "_CRV")
        shape = curve.getShape()
        result.append(shape)
    else:
        pmc.rename(ik_handle[2], str(ik_handle[2] + "_CRV"))
        shape = pmc.PyNode(ik_handle[2]).getShape()
        result[2] = shape
    if parent:
        parent.addChild(result[0])
    if curve_parent:
        curve_parent.addChild(result[2].getParent())
    result[2].getParent().visibility.set(0)
    attributes.lock_and_hide_attributes(result[2].getParent())
    result[0].visibility.set(0)
    if snap is False:
        result[0].snapEnable.set(0)
    if sticky:
        result[0].stickiness.set(1)
    result[0].attr("weight").set(weight)
    result[0].attr("po_weight").set(po_weight)
    logger.log(
        level="info", message='Spline IK "' + name + '" created', logger=_LOGGER
    )
    return result