def reparent_under_node(): """ Re-parent the selection under the last selected node. """ frame = maya.cmds.currentTime(query=True) nodes = maya.cmds.ls(selection=True, long=True, type='transform') or [] if len(nodes) < 2: msg = ('Not enough objects selected, ' 'select at least 1 child and 1 parent node.') LOG.warn(msg) return try: viewport.viewport_turn_off() children = nodes[:-1] parent = nodes[-1] children_tfm_nodes = [tfm_utils.TransformNode(node=n) for n in children] parent_tfm_node = tfm_utils.TransformNode(node=parent) lib.reparent(children_tfm_nodes, parent_tfm_node, sparse=True) children = [tn.get_node() for tn in children_tfm_nodes] maya.cmds.select(children, replace=True) finally: viewport.viewport_turn_on() # Trigger Maya to refresh. maya.cmds.currentTime(frame, update=True) maya.cmds.refresh(currentView=True, force=False) return
def unparent_to_world(): """ Un-parent the selected nodes into world space. """ frame = maya.cmds.currentTime(query=True) nodes = maya.cmds.ls(selection=True, long=True, type='transform') or [] if len(nodes) == 0: msg = ('Not enough objects selected, ' 'select at least 1 transform node.') LOG.warn(msg) return try: viewport.viewport_turn_off() tfm_nodes = [tfm_utils.TransformNode(node=n) for n in nodes] lib.reparent(tfm_nodes, None, sparse=True) nodes = [tn.get_node() for tn in tfm_nodes] maya.cmds.select(nodes, replace=True) finally: viewport.viewport_turn_on() # Trigger Maya to refresh. maya.cmds.currentTime(frame, update=True) maya.cmds.refresh(currentView=True, force=False) return
def main(): """ Convert all selected transforms into 2D markers under a camera. """ # Get camera model_editor = utils_viewport.get_active_model_editor() if model_editor is None: msg = 'Please select an active 3D viewport.' LOG.warning(msg) return cam_tfm, cam_shp = utils_viewport.get_viewport_camera(model_editor) if cam_shp is None: LOG.error('Please select an active viewport to get a camera.') return if utils_camera.is_startup_cam(cam_shp) is True: LOG.error("Cannot create Markers in 'persp' camera.") return # Get transforms nodes = maya.cmds.ls( selection=True, long=True, type='transform', ) or [] if len(nodes) == 0: LOG.warning('Please select one or more transform nodes.') return mmapi.load_plugin() try: utils_viewport.viewport_turn_off() # Compute the Marker Data. start_frame, end_frame = utils_time.get_maya_timeline_range_outer() mkr_data_list = lib.convert_nodes_to_marker_data_list( cam_tfm, cam_shp, nodes, start_frame, end_frame, ) # Get Camera cam = mmapi.Camera(shape=cam_shp) # Get or create Marker Group. mkr_grp = None mkr_grp_nodes = maya.cmds.ls( cam_tfm, dag=True, long=True, type='mmMarkerGroupTransform') or [] mkr_grp_nodes = sorted(mkr_grp_nodes) if len(mkr_grp_nodes) == 0: mkr_grp = mmapi.MarkerGroup().create_node(cam=cam) else: mkr_grp = mmapi.MarkerGroup(node=mkr_grp_nodes[0]) # Create Marker nodes mkr_list = mayareadfile.create_nodes( mkr_data_list, cam=cam, mkr_grp=mkr_grp, with_bundles=True, ) mkr_nodes = [mkr.get_node() for mkr in mkr_list] finally: utils_viewport.viewport_turn_on() if len(mkr_nodes) > 0: maya.cmds.select(mkr_nodes, replace=True) return
def tool_context(use_undo_chunk=None, undo_chunk_name=None, restore_current_frame=None, pre_update_frame=None, post_update_frame=None, use_dg_evaluation_mode=None, disable_viewport=None, disable_viewport_mode=None): """ Create a temporary tool context. If arguments are not given, the most stable and performant path is used. Arguments are used to remove ambiguity and force specific behaviour, and should therefore only be used when sure it is appropriate in your specific usage. The context is allowed to change default values dynamically, for example based on Maya version used or if a GUI is available. Example usage: >>> with tool_context() as tool_ctx: ... # do something with Maya ... maya.cmds.createNode('transform') :param use_undo_chunk: Treat the commands inside this context as a single "chunk" of operations. This makes undo'ing faster, so we don't need to undo many small changes. :type use_undo_chunk: bool or None :param undo_chunk_name: The name of the undo chunk. This is displayed to the user in the Script Editor when undo'ing. This name is expected to be unique each time. Using the date/time or a UUID for this name may be helpful. :type undo_chunk_name: str or None :param restore_current_frame: Keep track of the current frame at the start of the context, then restore to the correct frame number at the end of the context. :type restore_current_frame: bool or None :param pre_update_frame: Before starting the context functions, make sure the current frame is updated to help trigger Maya to evaluate. :type pre_update_frame: bool or None :param post_update_frame: After finishing the context functions tell Maya to update the frame number to help trigger Maya evaluate attributes and nodes. NOTE: This function only works if `restore_current_frame` is True. :type post_update_frame: bool or None :param use_dg_evaluation_mode: Changes Maya's Evaluation mode to DG mode for the duration of the context then reset to whatever preference the user has (in the "Settings/Preferences" window). Using DG Evaluation can dramatically speed up evaluation across time for many tools in mmSolver (as tested on Maya 2017). :type use_dg_evaluation_mode: bool or None :param disable_viewport: Turn off the Viewport inside the context function, and enable it once the context finishes. This can be used to dramatically speed up functions that cause the Maya viewport to update many times. :type disable_viewport: bool or None :param disable_viewport_mode: Use the given technique to disable and re-enable the Maya viewport (using the "disable_viewport" flag). :type disable_viewport_mode: mmSolver.utils.constant.DISABLE_VIEWPORT_MODE_*_VALUE :return: Yields (returns) a unique context hash id. """ # Defaults if use_undo_chunk is None: use_undo_chunk = True if undo_chunk_name is None: undo_chunk_name = str(uuid.uuid4()) assert isinstance(undo_chunk_name, str) if pre_update_frame is None: pre_update_frame = False if post_update_frame is None: post_update_frame = False if restore_current_frame is None: restore_current_frame = True if disable_viewport is None: disable_viewport = True if use_dg_evaluation_mode is None: # Force DG mode, because it evaluates with DG Context faster # (in Maya 2017). # # TODO: Test that DG mode is actually faster in Maya versions # other than 2017. use_dg_evaluation_mode = True # Save current state. current_frame = maya.cmds.currentTime(query=True) undo_state = maya.cmds.undoInfo(query=True, state=True) current_eval_mode = maya.cmds.evaluationManager(query=True, mode=True) # TRY... if disable_viewport is True: viewport_utils.viewport_turn_off(mode=disable_viewport_mode) if use_dg_evaluation_mode is True: # 'off' == turn off the Parallel mode. maya.cmds.evaluationManager(mode='off') if pre_update_frame is True: maya.cmds.currentTime(current_frame, edit=True, update=True) if use_undo_chunk is True and undo_state is True: maya.cmds.undoInfo(openChunk=True, chunkName=undo_chunk_name) yield undo_chunk_name # FINALLY, restore original state. if use_undo_chunk is True and undo_state is True: maya.cmds.undoInfo(closeChunk=True, chunkName=undo_chunk_name) if restore_current_frame is True: maya.cmds.currentTime(current_frame, edit=True, update=post_update_frame) if use_dg_evaluation_mode is True: maya.cmds.evaluationManager(mode=current_eval_mode[0]) if disable_viewport is True: viewport_utils.viewport_turn_on(mode=disable_viewport_mode)