def make_switch_utility(switch, tags=None): """ Create a 'plusMinusAverage' shading node to connect constraint weighting. Ensure switch has IKFK attribute. :param switch: Switch controller we want to build off of. :param tags: add str attrs(keys), example: dict{'Region': 'Arm', 'Side': 'R', 'Type': 'IK'} :return: Utility PyNode. """ log.info('*make_switch_utility*') # Check if ctrl has IKFK attr if not switch.hasAttr('IKFK'): switch.addAttr(consts.ALL['IKFK'], attributeType='float', keyable=True, maxValue=1, minValue=0) # UTILITY NAME switch_info = naming_utils.ItemInfo(switch) switch_utility_name = naming_utils.concatenate([ switch_info.side, switch_info.base_name, switch_info.joint_name, consts.ALL['IKFK'], consts.ALL['Utility'] ]) # CREATE/GET SWITCH UTILITY if not pymel.objExists(switch_utility_name): switch_utility = pymel.shadingNode('plusMinusAverage', name=switch_utility_name, asUtility=True) else: switch_utility = pymel.PyNode(switch_utility_name) # Add Tags to Switch Utility naming_utils.add_tags(switch_utility, tags) # Setattr switch_utility.operation.set(2) switch_utility.input1D[0].set(1) # Connect Attr try: switch.IKFK.connect(switch_utility.input1D[1]) except Exception as ex: log.warning(ex) return switch_utility
def create_offset_groups(objects, net=None, name=None): """ Parents Each object to a group node with the object's transforms. :param objects: list of pymel transforms to group. :return: List of offset groups. """ log.info('create_offset_groups: {}'.format(objects)) if not isinstance(objects, list): objects = [objects] offset_groups = [] for transform in objects: log.info(transform) info = naming_utils.ItemInfo(transform) if name: grp_name = naming_utils.concatenate([ info.side, info.base_name, info.joint_name, info.utility, info.index, info.type, name ]) else: grp_name = naming_utils.concatenate([ info.side, info.base_name, info.joint_name, info.utility, info.index, info.type, consts.ALL['GRP'] ]) transform_parent = transform.getParent() transform_matrix = transform.getMatrix(worldSpace=True) new_group = pymel.group(empty=True, name=grp_name) new_group.rotateOrder.set(transform.rotateOrder.get()) new_group.setMatrix(transform_matrix, worldSpace=True) if net: naming_utils.add_tags(new_group, tags={'Network': net.name()}) if transform_parent: new_group.setParent(transform_parent) new_group.addChild(transform) offset_groups.append(new_group) return offset_groups
def rebuild_joint_chain(joint_list, name, net): """ Duplicate joints and match hierachy :param joint_list: Single chain of joints :param name: Additional suffix :param net: network node to connect message output to :return: New joint chain """ log.info('rebuild_joint_chain: {}, {}, {}'.format(joint_list, name, net)) new_joints = [] for jnt in joint_list: info = naming_utils.ItemInfo(jnt) new_name = naming_utils.concatenate( [info.side, info.base_name, info.joint_name, info.index, name]) # Getting joint hierarchy. jnt_children = jnt.getChildren() jnt_parent = jnt.getParent() # Unparent joint. jnt.setParent(None) for child in jnt_children: child.setParent(None) # Make Joint new_jnt = pymel.duplicate(jnt, name=new_name)[0] pymel.select(None) # Re-Parent original jnt.setParent(jnt_parent) for child in jnt_children: child.setParent(jnt) new_joints.append(new_jnt) # Tags naming_utils.add_tags(new_jnt, tags={ 'Network': net.name(), 'Utility': name }) # Rebuild Hierarchy if jnt_parent and jnt_parent in joint_list: # If a parent FK jnt exists, parent this fk jnt to it. new_parent_name = new_jnt.name().replace(jnt.name(), jnt_parent.name()) # FK joints try: new_parent_jnt = pymel.PyNode(new_parent_name) new_jnt.setParent(new_parent_jnt) except pymel.MayaNodeError: pass # Couldn't find a parent. Move on. if jnt_children: for jnt_child in jnt_children: new_child_name = new_jnt.name().replace( jnt.name(), jnt_child.name()) # FK joints try: new_child_jnt = pymel.PyNode(new_child_name) new_child_jnt.setParent(new_jnt) except pymel.MayaNodeError: pass # Couldn't find a parent. Move on. return new_joints
def info_index(self): info = naming_utils.ItemInfo(self.name()) return info.index
def base_name(self): info = naming_utils.ItemInfo(self.name()) return info.base_name
def joint_name(self): info = naming_utils.ItemInfo(self.name()) return info.joint_name
def name_info(self): return naming_utils.ItemInfo(self)
def create_ctrl(jnt=None, network=None, attr=None, tags=None, axis='', shape='Circle', size=1.0, name=None, offset=False, mirrored=False): """ :param jnt: This will set ctrl orientation to jnt specified. :param network: This will add a tag for network specified. :param attr: This will connect the ctrl message to the net attr specified. :param tags: :param axis: This will rotate the ctrl shape by 90 or -90 degrees based on axis, ie '-z', 'x' :param shape: Shape to import based on file name, ie "Cube01" :param size: :param name: :param offset: Create an Offset Group for the ctrl :param mirrored: Scale by -X :return: Ctrl Node. """ if not name and jnt: info = naming_utils.ItemInfo(jnt) name = naming_utils.concatenate( [info.side, info.base_name, info.joint_name, 'CTRL']) elif not name: name = 'Ctrl' ctrl = virtual_classes.CtrlNode() pymel.rename(ctrl, name) ctrl.set_shape(shape) if mirrored: ctrl.setScale((-1, 1, 1)) ctrl.freeze_transform() if tags: naming_utils.add_tags(ctrl, tags) if network: naming_utils.add_tags(ctrl, {'Network': network}) naming_utils.add_tags(ctrl, {'Type': 'CTRL'}) # Shape Scale Attr ctrl.addAttr('shapeSize', attributeType='float') ctrl.shapeSize.set(size) # Shape Axis ctrl.addAttr('shapeAxis', dataType='string') ctrl.shapeAxis.set(axis) if jnt: ctrl.rotateOrder.set(jnt.rotateOrder.get()) ctrl.setMatrix(jnt.getMatrix(worldSpace=True), worldSpace=True) ctrl.setScale((size, size, size)) pymel.makeIdentity(apply=True, scale=True) if offset: joint_utils.create_offset_groups(ctrl, name=naming_utils.concatenate( [ctrl.name(), 'Offset'])) if attr: idx = attr.getNumElements() ctrl.message.connect(attr[idx]) if axis: ctrl.set_axis(axis) return ctrl