def add_sub_meta_node(self, node): """ Add a sub meta node to the main meta node as message attr connection. Args: node(pmc.PyNode()): The node to add. """ new_attribute = {} ud_attr = self.listAttr(ud=True) ud_attr = [str(attr_).split(".")[1] for attr_ in ud_attr] meta_plug = [ attr_ for attr_ in ud_attr if re.search(constants.SUB_META_ND_PLUG, attr_) ] if not meta_plug: count = "0" else: count = str(int(meta_plug[-1][-1]) + 1) new_attribute["name"] = "{}_{}".format( constants.SUB_META_ND_PLUG, count ) new_attribute["attrType"] = "message" new_attribute["keyable"] = False new_attribute["channelBox"] = False new_attribute["input"] = node.message new_attribute["disconnectBehaviour"] = 0 attributes.add_attr(node=self, **new_attribute)
def create_root_op_node(self): """ Execute the operators root/god node creation. Return: pmc.PyNode(): The created dagnode. """ # Create a asset container as root node. icon = os.path.normpath("{}/root_operator_logo.png".format( constants.ICONS_PATH)) container_node = mayautils.ContainerNode(constants.OP_ROOT_NAME, icon) container_node.create_container(meta_nd=False) self.op_root_nd = container_node.container self.op_root_nd.rename( strings.normalize_suffix_1(self.op_root_nd.name(), _LOGGER)) for attr_ in self.op_root_nd_param_list: attributes.add_attr(node=self.op_root_nd, **attr_) # Create the meta node for the root node. self.root_meta_nd = meta.RootOpMetaNode( n=constants.ROOT_OP_META_NODE_NAME) self.root_meta_nd.rename( strings.normalize_suffix_1(self.root_meta_nd.name(), _LOGGER)) # add root meta nd to container node. self.op_root_nd.addNode(self.root_meta_nd) # Connect root meta node with root node and visa versa. self.root_meta_nd.message.connect( self.op_root_nd.attr(constants.ROOT_OP_META_ND_ATTR_NAME)) self.root_meta_nd.set_root_op_nd(self.op_root_nd) self.root_meta_nd.set_uuid("{}-{}".format( str(uuid.uuid4()), constants.OP_ROOT_ND_UUID_SUFFIX))
def create_container(self, meta_nd=True): """ Create the actual container node with a icon. Args: meta_nd(bool): Enable/Disable meta node creation. """ self.container = pmc.nt.Container(n=self.name) self.container.iconName.set(self.icon) if self.content_root_node: self.container_content_root = pmc.createNode( "transform", n=self.container_content_root_name ) self.container.addNode( self.container_content_root, ish=True, ihb=True, iha=True, inc=True, ) for attr_ in self.container_attr_list: attributes.add_attr(node=self.container, **attr_) if meta_nd: self.meta_nd = meta.ContainerMetaNode(n=self.meta_nd_name) self.meta_nd.rename( strings.normalize_suffix_1(self.meta_nd.name(), _LOGGER) ) self.meta_nd.add_container_node(self.container) self.container.addNode(self.meta_nd) self.set_uuid()
def add_component_defined_attributes(self): """ Add Component specific attributes to operator. And fill the cd_attributes list for meta data. """ self.bnd_joint = { "name": self.BND_JNT_ATTR_NAME, "attrType": "bool", "keyable": False, "channelBox": False, } self.world_space_orientation_attr = { "name": self.WS_ORIENTATION_ATTR_NAME, "attrType": "bool", "keyable": False, "channelBox": False, "defaultValue": True, } # Add the attributes to the main_meta_nd of the operator. cd_attributes_list = [ self.bnd_joint, self.world_space_orientation_attr ] for attr_ in cd_attributes_list: attributes.add_attr(node=self.main_meta_nd, **attr_) # It is important to append all user defined attributes to this list. # So they are registered as meta data in the meta node., # Please append the attributes name not the the attribute dict. cd_attributes_ref_list = [ self.BND_JNT_ATTR_NAME, self.WS_ORIENTATION_ATTR_NAME, ] for reg_attr in cd_attributes_ref_list: self.cd_attributes.append(reg_attr)
def add_component_defined_attributes(self): """ Add Component specific attributes to operator. And fill the cd_attributes list for meta data. """ self.control_shapes_attr = { "name": self.CONTROL_SHAPE_ATTR_NAME, "enum": [data["shape"] for data in self.CONTROL_SHAPES], "keyable": False, "hidden": False, "writable": True, "channelBox": False, } self.bnd_joint = { "name": self.BND_JNT_ATTR_NAME, "attrType": "bool", "keyable": False, "channelBox": False, } self.world_space_orientation_attr = { "name": self.WS_ORIENTATION_ATTR_NAME, "attrType": "bool", "keyable": False, "channelBox": False, } # Add the attributes to the main_meta_nd of the operator. attributes.add_enum_attribute(node=self.main_meta_nd, **self.control_shapes_attr) cd_attributes_list = [ self.bnd_joint, self.world_space_orientation_attr ] for lock_attr in self.LOCK_TRANSFORMATION_ATTRIBUTES: attributes_dic = { "name": lock_attr, "attrType": "bool", "keyable": False, "channelBox": False, } cd_attributes_list.append(attributes_dic) for attr_ in cd_attributes_list: attributes.add_attr(node=self.main_meta_nd, **attr_) # It is important to append all user defined attributes to this list. # So they are registered as meta data in the meta node., # Please append the attributes name not the the attribute dict. cd_attributes_ref_list = [ self.CONTROL_SHAPE_ATTR_NAME, self.BND_JNT_ATTR_NAME, self.WS_ORIENTATION_ATTR_NAME, ] cd_attributes_ref_list.extend(self.LOCK_TRANSFORMATION_ATTRIBUTES) for reg_attr in cd_attributes_ref_list: self.cd_attributes.append(reg_attr)
def create_output_os_matrix_port(self, name): """ Create a output port for os matrix connection. Args: name(str): Name of the attribute. """ attributes.add_attr( self.component_root.container_content.get("output"), name="{}_output_os_matrix".format(name), attrType="matrix", keyable=False, hidden=True, )
def matrix_constraint_ui_grp_(source): """ Creates the the UI node for the matrix constraint and parent it under a specified node. Args: source(dagnode): The source node. parent(dagnode): The parent for the UI GRP. Return: tuple: The UI_GRP node. """ ui_grp = pmc.createNode( "transform", n=str(source) + "_matrixConstraint_UI_GRP" ) attributes.add_attr(node=ui_grp, name="offset_matrix", attrType="matrix") attributes.lock_and_hide_attributes(node=ui_grp) source.addChild(ui_grp) return ui_grp
def create_sub_operator(self, name, side, index, count, scale, match): """ Create the sub operators node. Args: name(str): Operators name. side(str): Side. Valid values are [L, R, M] index(int): Operators index. count(int): The sub_op_nd count. scale(float): Scale value. match(pmc.PyNode()): Object to snap for. """ instance = "_op_{}_{}_{}".format(name, str(index), str(count)) sub_op_nd_name = constants.SUB_OP_ROOT_NODE_NAME.replace( "M_", "{}_".format(side)) sub_op_nd_name = sub_op_nd_name.replace("_op_0", instance) self.joint_control = curves.JointControl() sub_op_node = self.joint_control.create_curve( name=sub_op_nd_name, match=match, scale=scale, buffer_grp=False, color_index=self.SUB_ND_COLOR_INDEX, )[0] for attr_ in self.sub_node_param_list: attributes.add_attr(node=sub_op_node, **attr_) self.sub_meta_nd = meta.SubOpMetaNode( n=sub_op_nd_name.replace("_CON", "")) self.main_meta_nd.add_sub_meta_node(node=self.sub_meta_nd) # Section to set meta data connections. self.sub_meta_nd.set_operator_nd(sub_op_node) self.sub_meta_nd.message.connect( sub_op_node.attr(constants.SUB_OP_META_ND_ATTR_NAME)) if self.main_op_nd: self.sub_meta_nd.set_main_op_nd(self.main_op_nd) if self.root_meta_nd: self.root_meta_nd.message.connect( sub_op_node.attr(constants.ROOT_OP_META_ND_ATTR_NAME)) self.sub_operators.append(sub_op_node) self.linear_curve_drivers.append(sub_op_node) self.sub_meta_nd.set_ws_output_index(count + 1)
def create_comp_container(self): """ Create the component container. """ self.create_container() self.create_container_content_from_list(self.CONTENT_GROUPS) attributes.add_attr( self.container_content.get("input"), name=constants.INPUT_WS_PORT_NAME, attrType="matrix", multi=True, keyable=False, hidden=True, ) attributes.add_attr( self.container_content.get("output"), name=constants.OUTPUT_WS_PORT_NAME, attrType="matrix", multi=True, keyable=False, hidden=True, ) attributes.add_attr( self.container_content.get("output"), name=constants.BND_OUTPUT_WS_PORT_NAME, attrType="matrix", multi=True, keyable=False, hidden=True, ) self.set_container_type(constants.COMPONENT_CONTAINER_TYPE)
def add_ud_port( self, component_port="input", name=None, type_="float", minValue=0, maxValue=1, value=1, ): """ Add user defined port to the input or output port of a rig Component. By Default it add a float value to the input port with a given name, with a min value of 0.0 a max value of 1.0 and a value of 1.0. Args: component_port(str): The rig components port. name(str): The port name. type_(str): The port typ. minValue(float or int): The minimal port value. maxValue(float or int): The maximum port value. value(float or int or str): The port value. """ valid_ports = ["input", "output"] if component_port not in valid_ports: raise AttributeError( 'Chosen port not valid. Valid values are ["input", "output"]' ) node = self.component_root.container_content.get("input") if component_port == "output": node = self.component_root.container_content.get("output") attributes.add_attr( node=node, name=name, attrType=type_, minValue=minValue, maxValue=maxValue, value=value, )
def create_main_op_node(self, local_rotate_axes=True, match=None): """ Execute the main operator node creation. Args: local_rotate_axes(bool): Enable local rotate axes. match(pmc.PyNode): Node to snap for Return: pmc.PyNode(): The created main operator node. """ main_op_curve = curves.DiamondControl() main_op_node = main_op_curve.create_curve( color_index=self.COLOR_INDEX, name=self.main_op_nd_name, local_rotate_axes=local_rotate_axes, buffer_grp=False, match=match, ) self.main_op_nd = main_op_node[0] self.lra_node_buffer_grp = main_op_node[1] self.lra_node = main_op_node[2] attributes.add_attr(node=self.lra_node, **self.lra_op_attr) attributes.add_attr(node=self.lra_node_buffer_grp, **self.lra_op_attr) for attr_ in self.main_node_param_list: attributes.add_attr(node=self.main_op_nd, **attr_) # Connect main operator node with main meta node. self.set_main_meta_nd() self.main_meta_nd.set_uuid("{}-{}".format( str(uuid.uuid4()), constants.MAIN_OP_ND_UUID_SUFFIX))
def constraint_ui_node_(constraint=None, target=None): """ Create a contraint UI node to uncycle the constraint graph. Args: constraint(constraintNode): The constraint to work with. target(dagnode): The target node. Return: tuple: The created UI node. """ if target and constraint: if not isinstance(target, list): target = [target] constraint_ui = pmc.createNode( "transform", n="{}{}".format(str(constraint), "_UI_GRP") ) constraint.addChild(constraint_ui) attributes.lock_and_hide_attributes(node=constraint_ui) for x in range(len(target)): long_name = "{}_{}".format(str(target[x]), "W" + str(x)) attributes.add_attr( node=constraint_ui, name=long_name, attr_type="float", minValue=0, maxValue=1, keyable=True, ) constraint_ui.attr(long_name).set(1) constraint_ui.attr(long_name).connect( constraint.target[x].targetWeight, force=True ) for ud_attr in constraint.listAttr(ud=True): pmc.deleteAttr(ud_attr) else: logger.log( level="error", message="source and constraint needed for" " constraint_UI_node", logger=_LOGGER, ) return constraint_ui
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_)