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