def _get_selection_input(): """ :return: """ sel = pm.ls(selection=True, type='transform') robots = mimic_utils.get_robot_roots() # Exception handling if not sel: raise MimicError('Nothing selected; ' \ 'select a valid robot control and external axis controller') if not robots: raise MimicError('No robot selected; ' \ 'select a valid robot') if len(robots) > 1: raise MimicError('Too many robots selected; ' \ 'select a single robot') if len(sel) > 2: raise MimicError('Too many selections; ' \ 'select a single robot control, ' \ 'and single external axis controller') if len(sel) == 1: raise MimicError('Not enough selections; ' \ 'select a single robot control, ' \ 'and single tool control') # find which selected object is the external axis controller if not mimic_utils.get_robot_roots(0, [sel[0]]): external_axis_CTRL = sel[0] else: external_axis_CTRL = sel[1] robot = robots[0] return robot, external_axis_CTRL
def add_mFIZ_node(*args): """ Connects mFIZ node to robot as Digital Outputs """ sel = pm.ls(selection=True, type='transform') robots = mimic_utils.get_robot_roots() # Exception handling if not sel: pm.warning('Nothing selected; ' \ 'select a valid robot control and mFIZ controller') return if not robots: pm.warning('No robot selected; ' \ 'select a valid robot') return if len(robots) > 1: pm.warning('Too many robots selected; ' \ 'select a single robot') return if len(sel) > 2: pm.warning('Too many selections; ' \ 'select a single robot control, and single mFIZ controller') return if len(sel) == 1: pm.warning('Not enough selections; ' \ 'select a single robot control, and single mFIZ controller') return robot = robots[0] # Find which selected object is the mFIZ controller if not mimic_utils.get_robot_roots(sel=[sel[0]]): mFIZ_ctrl = sel[0] else: mFIZ_ctrl = sel[1] # Check if mFIZ_ctrl selection is actually an mFIZ controller if not mFIZ_utils.is_mFIZ_ctrl(mFIZ_ctrl): pm.warning('No mFIZ controller selected; ' \ 'select a valid mFIZ controller') return # Wheeew...now that that's done we can get to work... # Add Focus, Iris, Zoom as Digital Outputs to the robot _add_mFIZ_attrs_as_outputs(robot) # Create an mFIZ remap node to remap FIZ values from 0 - 1 to 16-bit integers remap_node = _add_mFIZ_remap_node() # Connect mFIZ controller attributes to remap node, and remap node to robot IOs _connect_remap_node(robot, mFIZ_ctrl, remap_node)
def list_axes(*args): """ :param args: :return: """ # Clear previus UI list clear_external_axis_list() # Check viewport robot selection # If robots are selected, list all external axes on selected robots selected_robots = mimic_utils.get_robot_roots() if selected_robots: robots = selected_robots # If no robots are selected, list all axes in the scene else: robots_in_scene = mimic_utils.get_robot_roots(all_robots=True) # If there are no robots in the scene, raise an exception if not robots_in_scene: raise MimicError('No robots in scene') else: robots = robots_in_scene # Keep track of selected robots without axes for a heads-up message selected_robots_without_axes = [] # For each robots, get a list of all its external axes for robot in robots: robots_external_axes = get_external_axis_names(robot) # If we're only looking at selected robots, check if each selected # robot has external axes. If not, add it to a list to display in # a heads up message if selected_robots: if not robots_external_axes: selected_robots_without_axes.append(robot) # Update Mimic UI with list of external axes for axis in robots_external_axes: append_string = robot + ': ' + axis pm.textScrollList('tsl_externalAxes', edit=True, append=append_string) if selected_robots_without_axes: robot_list_str = '' for each in selected_robots_without_axes: robot_list_str += each + ', ' pm.headsUpMessage('{} has no External Axes' .format(robot_list_str))
def list_ios(*args): """ If no robot is selected, prints list of all IO in scene to Mimic UI If robot is selected, prints IOs assigned to that robot to Mimic UI :param args: required by Maya to call a function from UI button :return: """ # Clear previous UI list clear_io_list() # Check viewport robot selection # If robots are selected, list all IOs on selected robots selected_robots = mimic_utils.get_robot_roots() if selected_robots: robots = selected_robots # If no robots are selected, list all IOs in the scene else: robots_in_scene = mimic_utils.get_robot_roots(all_robots=True) # If there are no robots in the scene, raise an exception if not robots_in_scene: raise MimicError('No robots in scene') else: robots = robots_in_scene # Keep track of selected robots without IOs for a heads-up message selected_robots_without_ios = [] # For each robots, get a list of all its IOs for robot in robots: robots_ios = get_io_names(robot) # If we're only looking at selected robots, check if each selected # robot has IOs. If not, add it to a list to display in # a heads up message if selected_robots: if not robots_ios: selected_robots_without_ios.append(robot) # Update Mimic UI with list of IOs for io in robots_ios: append_string = robot + ': ' + io pm.textScrollList('tsl_ios', edit=True, append=append_string) if selected_robots_without_ios: robot_list_str = '' for each in selected_robots_without_ios: robot_list_str += each + ', ' pm.headsUpMessage('{} has no IOs'.format(robot_list_str))
def io_selected(*args): """ Command that is called when an io is selected in IO list in Mimic UI, which gets the IO name and info, and updates the IO Mimic UI accordingly Selects the io controller in Maya's viewport :param args: required by Maya to call a function from UI button :return: """ # Get the selected item from the Mimic UI selection = pm.textScrollList('tsl_ios', selectItem=True, query=True)[0] # Split the selection into the robot's name and the IO name robot_str, io_name = selection.split(': ') # Get selected io' settings pm.select(robot_str) robot = mimic_utils.get_robot_roots()[0] io_info = get_io_info(robot, io_name) # Switch Mimic UI to Update IO Mode and populate it with the # selected io' info update_io_UI(io_info) # Select the robot that the IO is assigned to target_CTRL = mimic_utils.get_target_ctrl_path(robot) pm.select(target_CTRL)
def remove_io(*args): """ Removes IO from the robot it's attached to by deleting all of its attributes. The io controller and models are preserved. This function just breaks the connection between the robot and the io controller :param args: required by Maya to call a function from UI button required by Maya UI :return: """ # Get the selected item from the Mimic UI selection = pm.textScrollList('tsl_ios', selectItem=True, query=True)[0] # Split the selection into the robot's name and the IO name robot_str, io_name = selection.split(': ') pm.select(robot_str) robot = mimic_utils.get_robot_roots()[0] target_CTRL = mimic_utils.get_target_ctrl_path(robot) parent_attribute = '{}.io_{}'.format(target_CTRL, io_name) # Delete IO attribute on the robot controller pm.deleteAttr(parent_attribute) # Clear the io from the Mimic UI selection and reset the UI pm.textScrollList('tsl_ios', edit=True, removeItem=selection) if not pm.textScrollList('tsl_ios', query=True, numberOfItems=True): reset_io_UI() pm.select(target_CTRL) pm.headsUpMessage('IO \'{}\' removed successfully from {}'.format( io_name, robot))
def axis_selected(*args): """ :param args: :return: """ # Get the selected item from the Mimic UI selection = pm.textScrollList('tsl_externalAxes', selectItem=True, query=True)[0] # Split the selection into the robot's name and the external axis name robot_str, axis_name = selection.split(': ') # Get selected axis' settings pm.select(robot_str) robot = mimic_utils.get_robot_roots()[0] axis_info = get_external_axis_info(robot, axis_name) # Switch Mimic UI to Update External Axis Mode and populate it with the # selected axis' info update_external_axis_UI(axis_info) # Select the external axis controller in the viewport axis_CTRL = axis_info['Driving Controller'] pm.select(axis_CTRL)
def axis_selected(*args): """ Command that is called when an axis is selected in external axis list in Mimic UI, which gets the external axis name and info, and updates the external axis Mimic UI accordingly Selets the axis controller in Maya's viewport :param args: required by Maya to call a function from UI button :return: """ # Get the selected item from the Mimic UI selection = pm.textScrollList('tsl_externalAxes', selectItem=True, query=True)[0] # Split the selection into the robot's name and the external axis name robot_str, axis_name = selection.split(': ') # Get selected axis' settings pm.select(robot_str) robot = mimic_utils.get_robot_roots()[0] axis_info = get_external_axis_info(robot, axis_name) # Switch Mimic UI to Update External Axis Mode and populate it with the # selected axis' info update_external_axis_UI(axis_info) # Select the external axis controller in the viewport axis_CTRL = axis_info['Driving Controller'] pm.select(axis_CTRL)
def update_io(*args): """ Updates an IO based on user inputs in Mimic UI. :param args: required by Maya to call a function from UI button """ # Get the selected item from the Mimic UI selection = pm.textScrollList('tsl_ios', selectItem=True, query=True)[0] # Split the selection into the robot's name and the IO name robot_str, io_name = selection.split(': ') pm.select(robot_str) robot = mimic_utils.get_robot_roots()[0] io_params = _get_io_params() io_number = io_params['IO Number'] postproc_id = io_params['Postproc ID'] io_type = io_params['Type'] ignore_in_postproc = io_params['Ignore'] target_CTRL = mimic_utils.get_target_ctrl_path(robot) # Set all IO attributes accordingly io_parent_attribute = target_CTRL + '.' + io_name # Check that the IO number is unique if io_number == pm.getAttr(io_parent_attribute + '_ioNumber'): pass else: _check_io_number(robot, io_number) # Set all appropriate attributes on the robot # If the robot is referenced, Maya will throw an exceptrion when it # tries to lock an attribute try: pm.setAttr(io_parent_attribute + '_ioNumber', lock=False) except: pass pm.setAttr(io_parent_attribute + '_ioNumber', io_number) try: pm.setAttr(io_parent_attribute + '_ioNumber', lock=True) except: pass pm.setAttr(io_parent_attribute + '_postprocID', postproc_id) pm.setAttr(io_parent_attribute + '_ignore', ignore_in_postproc) pm.headsUpMessage('{}: IO \'{}\' successfully updated'.format( robot, io_name)) pm.select(target_CTRL)
def _get_selection_input(): """ Takes Maya's viewport selection and filters it to a robot and external axis controller. Raises exception of selection criteria is not met :return robot: str, root node of robot in Maya viewport selection :return external_axis_CTRL: str, name of external axis controller selected in Maya's viewport """ sel = pm.ls(selection=True, type='transform') robots = mimic_utils.get_robot_roots() # Exception handling if not sel: raise MimicError('Nothing selected; ' \ 'select a valid robot control and external axis controller') if not robots: raise MimicError('No robot selected; ' \ 'select a valid robot') if len(robots) > 1: raise MimicError('Too many robots selected; ' \ 'select a single robot') if len(sel) > 2: raise MimicError('Too many selections; ' \ 'select a single robot control, ' \ 'and single external axis controller') if len(sel) == 1: raise MimicError('Not enough selections; ' \ 'select a single robot control, ' \ 'and single tool control') # find which selected object is the external axis controller if not mimic_utils.get_robot_roots(0, [sel[0]]): external_axis_CTRL = sel[0] else: external_axis_CTRL = sel[1] robot = robots[0] return robot, external_axis_CTRL
def _get_selection_input(): """ Takes Maya's viewport selection and filters it to a robot. Raises exception of selection criteria is not met :return robot: str, root node of robot in Maya viewport selection """ sel = pm.ls(selection=True, type='transform') robots = mimic_utils.get_robot_roots() # Exception handling if not robots: raise MimicError('No robot selected; ' \ 'select a valid robot') if len(robots) > 1: raise MimicError('Too many robots selected; ' \ 'select a single robot') robot = robots[0] return robot
def remove_external_axis(*args): """ Removes external axis from the robot it's attached to by deleting all of its attributes. The axis controller and models are preserved. This function just breaks the connection between the robot and the axis :param *args: required by Maya UI :return: """ # Get the selected item from the Mimic UI selection = pm.textScrollList('tsl_externalAxes', selectItem=True, query=True)[0] # Split the selection into the robot's name and the external axis name robot_str, axis_name = selection.split(': ') pm.select(robot_str) robot = mimic_utils.get_robot_roots()[0] target_CTRL = mimic_utils.get_target_ctrl_path(robot) parent_attribute = '{}.externalAxis_{}'.format(target_CTRL, axis_name) # Remove connections between the axis controller and the robot external_axis_attribute_path = target_CTRL + '.' + axis_name external_axis_CTRL, driving_attribute = _get_external_axis_connections( external_axis_attribute_path) driving_axis = driving_attribute[-1] # Prep transformation string for Maya's limit attributes if 'translate' in driving_attribute: driving_attribute_trunc = 'Trans' else: driving_attribute_trunc = 'Rot' _enable_external_axis_limits(external_axis_CTRL, driving_attribute_trunc, driving_axis, enable=False) # Delete External Axis attribute on the robot controller pm.deleteAttr(parent_attribute) # Clear the axis from the Mimic UI selection and reset the UI pm.textScrollList('tsl_externalAxes', edit=True, removeItem=selection) if not pm.textScrollList('tsl_externalAxes', query=True, numberOfItems=True): reset_external_axis_UI() ''' # NEEDS Attention. This deletes parent constraint even if the axis # being removed isn't the one the robot is attached to if _check_if_robot_is_attached_to_external_axis(robot): pm.delete('{}|robot_GRP|local_CTRL|' \ 'localCTRL_externalAxisCTRL_parentConstraint' .format(robot)) pm.setAttr('{}|robot_GRP|local_CTRL.visibility'.format(robot), 1) ''' pm.select(target_CTRL) pm.headsUpMessage('External Axis \'{}\' removed successfully from {}' .format(axis_name, robot))
def update_external_axis(*args): """ Update external axis in Mimic. :param args: :return: """ # Get the selected item from the Mimic UI selection = pm.textScrollList('tsl_externalAxes', selectItem=True, query=True)[0] # Split the selection into the robot's name and the external axis name robot_str, axis_name = selection.split(': ') pm.select(robot_str) robot = mimic_utils.get_robot_roots()[0] external_axis_params = _get_external_axis_params() axis_number = external_axis_params['Axis Number'] driving_attribute = external_axis_params['Driving Attribute'] position_limit_min = external_axis_params['Position Limit Min'] position_limit_max = external_axis_params['Position Limit Max'] velocity_limit = external_axis_params['Velocity Limit'] attach_robot_to_external = external_axis_params['Attach'] ingnore_in_postproc = external_axis_params['Ignore'] target_CTRL = mimic_utils.get_target_ctrl_path(robot) # Set all External Axis attributes accordingly axis_parent_attribute = target_CTRL + '.' + axis_name # Check that the external axis number is unique if axis_number == pm.getAttr(axis_parent_attribute + '_axisNumber'): pass else: _check_external_axis_number(robot, axis_number) # If attach to robot is true, parent the robot's local control to the # external axis controller if attach_robot_to_external: # Check if the robot is already attached to an external axis controller if _check_if_robot_is_attached_to_external_axis(robot): raise MimicError('{} is already attached to an external ' \ 'axis controller'.format(robot)) # Get and check the proper controllers from viewport selection _, external_axis_CTRL = _get_selection_input() _attach_robot_to_external_axis(robot, external_axis_CTRL) # Check if our driving attribute needs to be updated. If not, do nothing # If so, update the connection axis_attribute_name = target_CTRL + '.{}'.format(axis_name) external_axis_CTRL, old_driving_attribute = _get_external_axis_connections(axis_attribute_name) if old_driving_attribute == driving_attribute: pass else: # Connect position attribute to driving attribute old_driving_attribute_path = external_axis_CTRL + '.' + old_driving_attribute new_driving_attribute_path = external_axis_CTRL + '.' + driving_attribute destination_attribute_name = axis_parent_attribute + '_position' pm.disconnectAttr(old_driving_attribute_path, destination_attribute_name) pm.connectAttr(new_driving_attribute_path, destination_attribute_name) # Update the external axis' position/rotation limits # Find the original driving attribute and disable it's axis limits _clear_external_axis_CTRL_limits(robot, external_axis_CTRL, old_driving_attribute, axis_name) _set_external_axis_CTRL_limits(robot, external_axis_CTRL, external_axis_params) # If the driving attribute is a translate attribute, we convert the user # input from millimeters to Maya's default unit of centimeters if 'translate' in driving_attribute: position_limit_min = position_limit_min / 10 position_limit_max = position_limit_max / 10 # Set all appropriate attributes on the robot # If the robot is referenced, Maya will throw an exceptrion when it # tries to lock an attribute try: pm.setAttr(axis_parent_attribute + '_axisNumber', lock=False) except: pass pm.setAttr(axis_parent_attribute + '_axisNumber', axis_number) try: pm.setAttr(axis_parent_attribute + '_axisNumber', lock=True) except: pass pm.setAttr(axis_parent_attribute + '_axisMin', position_limit_min) pm.setAttr(axis_parent_attribute + '_axisMax', position_limit_max) pm.setAttr(axis_parent_attribute + '_maxVelocity', velocity_limit) pm.setAttr(axis_parent_attribute + '_ignore', ingnore_in_postproc) # Select the external axis pm.select(external_axis_CTRL) pm.headsUpMessage('{}: Axis \'{}\' successfully updated' .format(robot, axis_name))