Back to 'Basics On How To Create Your Own Node'
An example of how to build a node using one of the simpler node codes.
In addition, be sure to refer to the accompanying documentation for a detailed explanation of the steps involved.
"""One_Joint module is one of the basic nodes that simply creates a joint with a ctrl. """ from arise.data_types import node_data from arise.utils.matrix_utils import matrix_constraint from arise.utils.modules_utils import ( world_rotation, secondary_ctrls_setup, expose_rotation_order, create_grps, SECONDARY_COLOR, ) MAYA_VERSION = 2016 # the version of maya from which this module supports. AUTHER = "Etay Herz" # name of person who created this module. RIG_CATEGORY = "Basic" # either 'Basic', 'Cartoon', 'Vfx', 'Game' or 'All'. (used when filtering). RIG_TYPE = "All" # Biped, Car, Quadruped, All, ... (for filtering modules in lists). TAGS = ["basic", "simple", "prop", "joint", "ctrl"] TOOL_TIP = "Create either a ctrl, a joint, or both." CREATE_OPTIONS = ["Ctrl And Joint", "Only Ctrl", "Only Joint"] class One_Joint(node_data.NodeData): """One_Joint module is one of the basic nodes that simply creates a joint with a ctrl. """ sort_priority = 500 def __init__(self, parent, docs, icon, module_dict): node_data.NodeData.__init__( self, parent=parent, icon=icon, docs=docs, module_dict=module_dict ) def attributes_creation(self): """Here you add the module attributes. """ self.add_collapsible_layout(title="Settings", shown=True) self.creation_attr = self.add_radio_attribute( name="Create", items=CREATE_OPTIONS, default_value=0, annotation=( "'Ctrl And Joint' - creates a ctrl that drives a joint.\n" "'Only Ctrl' - skip the joint creation.\n" "'Only Joint' - skip the ctrl creation.\n" ), ) self.ctrls_scale_attr = self.add_float_attribute( name="Ctrls Scale", default_value=1.0, dynamic_attribute=False, writable=True, readable=True, promoted=False, annotation=( "Scale the node ctrl.\n" "Note that the attachments 'Ctrls Settings' and 'CtrlsShape' will override this." ), min_value=0.01, max_value=100, ) self.clean_transformations_attr = self.add_boolean_attribute( name="Clean Transformations", default_value=True, annotation=( "If checked, the zeroed pose will be the same as the bind pose;\n" "if unchecked, when zeroing the ctrls, they will align with a world axis specified in the " "following two attributes." ), ) items = ["+X", "+Y", "+Z", "-X", "-Y", "-Z"] self.world_orientation_attr = self.add_radio_attribute( name="World Orientation", items=items, default_value=items.index("+Y"), # Spine points up. annotation=( "The world axis the ctrls will align with when zeroed.\n" "Usually, this attribute's default value is the correct value." ), ) self.world_twist_attr = self.add_float_attribute( name="World Orient Twist", min_value=-360, max_value=360, annotation=( "Along with 'world Orientation', defines the ctrls zeroed pose.\n" "Usually, the default value of 0 is the correct value." ), ) self.expose_rotation_order_attr = self.add_boolean_attribute( name="Expose RotateOrder", default_value=True, annotation="Exposes the ctrls 'RotateOrder' attribute in the Channel Box.", ) self.secondary_ctrls_attr = self.add_boolean_attribute( name="Secondary Ctrls", default_value=False, annotation="Secondary ctrl is added under the ctrl to help prevent gimbal lock.", ) self.add_separator() self.is_skinning_attr = self.add_boolean_attribute( name="Skinning Joint", default_value=True, annotation="The joint will be tagged as a skinning joint", ) self.add_separator(title="Connections") self.driven_attr = self.add_driven_attribute(name="Input", annotation="Input") self.driver_attr = self.add_driver_attribute(name="Output", annotation="Output") self.close_layout() def evaluate_creation_methods(self): # REIMPLEMENTED! """Reimplemented to enable/disable attrs. """ no_ctrl = True if self.creation_attr.value == 2 else False no_jnt = True if self.creation_attr.value == 1 else False self.ctrls_scale_attr.set_disabled(no_ctrl) self.clean_transformations_attr.set_disabled(no_ctrl) self.world_orientation_attr.set_disabled(no_ctrl) self.world_twist_attr.set_disabled(no_ctrl) self.expose_rotation_order_attr.set_disabled(no_ctrl) self.secondary_ctrls_attr.set_disabled(no_ctrl) self.is_skinning_attr.set_disabled(no_jnt) if not no_ctrl: self.world_orientation_attr.set_disabled(True if self.clean_transformations_attr.value else False) self.world_twist_attr.set_disabled(True if self.clean_transformations_attr.value else False) node_data.NodeData.evaluate_creation_methods(self) def guides_creation(self): """Create guides based on attributes values. """ self.guide = self.add_guide(name="01", translation=[0, 0, 0], rotation=[0, 0, 0]) self.guide.shape = "sphere_with_arrow" self.guide.rotate_offset = [-90, 0, 0] def joints_creation(self): """Create joints based on attributes values and guides. (without positioning as this point). """ self.joint = None if self.creation_attr.value != 1: self.joint = self.add_joint( name="01", skinning_jnt=self.is_skinning_attr.value, tag_parent_jnt=None, radius=0.5, ) def ctrls_creation(self): """Create controls based on attributes values, guides and joints. (without positioning as this point). """ self.ctrl = None self.secondary_ctrl = None if self.creation_attr.value != 2: ctrls_mult = self.ctrls_scale_attr.value * 3.5 self.ctrl = self.add_ctrl(name="01", shape="circle", up_orient="+Y", size=1.2 * ctrls_mult) self.secondary_ctrl = None if self.secondary_ctrls_attr.value: self.secondary_ctrl = self.add_ctrl(name="01_secondary", shape="circle", size=1.0 * ctrls_mult) self.secondary_ctrl.color = SECONDARY_COLOR ctrls = [self.ctrl, self.secondary_ctrl] if self.secondary_ctrl else [self.ctrl] for ctrl in ctrls: for attr in ["scaleY", "scaleZ"]: ctrl.add_hidden_attr(attr) ctrl.add_locked_attr(attr) def rig_creation(self): """Using the attributes values, guides, joints, and ctrls, build the rig. """ if self.is_mirrored: self.module_grp.set_attr("scaleX", -1) no_ctrl = True if self.creation_attr.value == 2 else False no_jnt = True if self.creation_attr.value == 1 else False input_grp, output_grp = create_grps(self, ["input_grp", "output_grp"]) self.driven_attr.set_maya_object(input_grp) self.driver_attr.set_maya_object(output_grp) ctrl, ctrl_grp = None, None if not no_ctrl: ctrl, ctrl_grp = self._setup_ctrl() jnt, jnts_grp = None, None if not no_jnt: jnt, jnts_grp = self._setup_jnt() if not no_ctrl: matrix_constraint(ctrl.btm_ctrl, jnts_grp, maintain_offset=False) top_driver = ctrl_grp if ctrl_grp else jnts_grp btm_driven = jnt if jnt else ctrl.btm_ctrl input_grp.match_transformation_to(top_driver) matrix_constraint(input_grp, top_driver, maintain_offset=True) matrix_constraint(btm_driven, output_grp, maintain_offset=False) def _setup_ctrl(self): """Setup the ctrl. Returns: list -- of ctrl IoTransform and 'joints_grp' IoTransform """ ctrls_grp = create_grps(self, ["ctrls_grp"])[0] ctrl = self.ctrl.pointer ctrl.offset_grp.parent_relative(ctrls_grp) secondary_ctrls_setup([self.ctrl], [self.secondary_ctrl]) if self.expose_rotation_order_attr.value: expose_rotation_order([self.ctrl, self.secondary_ctrl]) ctrls_grp.set_translation(self.guide.world_transformations["translate"], space="world") world_rotation( obj=ctrl.offset_grp, aim_direction=self.world_orientation_attr.display_value, flip_x_direction=False, twist=self.world_twist_attr.value, ) if self.clean_transformations_attr.value: ctrl.offset_grp.set_matrix(self.guide.world_transformations["matrix"]) else: ctrl.set_matrix(self.guide.world_transformations["matrix"]) ctrl.offset_grp.set_scale([1, 1, 1]) # fix for when set_matrix gives -1 scaleX. ctrl.scale_attrs_connect() return ctrl, ctrls_grp def _setup_jnt(self): """Setup the joint. Returns: list -- of IoJoint and IoTransform 'joints_grp' """ jnts_grp = create_grps(self, ["jnts_grp"])[0] jnt_ptr = self.joint.pointer jnt_ptr.parent_relative(jnts_grp) jnts_grp.set_matrix(self.guide.world_transformations["matrix"]) jnts_grp.set_scale([1, 1, 1]) # fix for when set_matrix gives -1 scaleX. return jnt_ptr, jnts_grp
_____________________________________________
Get Arise at: https://www.ariserigging.com