def updateInfo(self): s = time.time() is_running = mmapi.is_solver_running() if is_running is True: return anm_count = 0 stc_count = 0 lck_count = 0 col = lib_state.get_active_collection() if col is not None: attr_list = col.get_attribute_list() attr_state_list = [attr.get_state() for attr in attr_list] anm_count = attr_state_list.count(mmapi.ATTR_STATE_ANIMATED) stc_count = attr_state_list.count(mmapi.ATTR_STATE_STATIC) lck_count = attr_state_list.count(mmapi.ATTR_STATE_LOCKED) text = ( 'Animated {anm} | Static {stc} | Locked {lck}' ).format(anm=anm_count, stc=stc_count, lck=lck_count) self.ui.info_label.setText(text) e = time.time() LOG.debug('updateInfo: %r', e - s) return
def updateInfo(self): is_running = mmapi.is_solver_running() if is_running is True: return cam_list = set() mkr_list = set() bnd_list = set() text = 'Camera {cam} | Markers {mkr} | Bundles {bnd}' col = lib_state.get_active_collection() if col is not None: marker_list = col.get_marker_list() for mkr in marker_list: mkr_node = mkr.get_node() mkr_list.add(mkr_node) cam = mkr.get_camera() cam_shp_node = cam.get_shape_node() cam_list.add(cam_shp_node) bnd = mkr.get_bundle() if bnd is not None: bnd_node = bnd.get_node() bnd_list.add(bnd_node) text = text.format( cam=len(cam_list), mkr=len(mkr_list), bnd=len(bnd_list), ) self.ui.info_label.setText(text) return
def removeClicked(self): """ Remove the selected nodes or node attributes from the output attributes data model. """ col = lib_state.get_active_collection() if col is None: return sel = lib_maya_utils.get_scene_selection() ui_nodes = lib_uiquery.get_selected_ui_nodes(self.treeView, self.filterModel) attr_list = lib_uiquery.convert_ui_nodes_to_nodes(ui_nodes, 'data') lib_attr.remove_attr_from_collection(attr_list, col) # Remove Callbacks callback_manager = self.callback_manager if callback_manager is not None: lib_attr.remove_callbacks_from_attributes(attr_list, callback_manager) self.dataChanged.emit() self.viewUpdated.emit() # Restore selection. lib_maya_utils.set_scene_selection(sel) return
def updateModel(self): is_running = mmapi.is_solver_running() if is_running is True: return col = lib_state.get_active_collection() if col is not None: tab_name = self.getSolverTabValue(col) tab_name = tab_name.lower() idx = self._tab_name_to_index_map.get(tab_name, None) if idx is None: msg = 'Solver tab name is not valid: %r' % tab_name raise ValueError(msg) self.tabWidget.setCurrentIndex(idx) idx = self.tabWidget.currentIndex() tab_widget = self._getTabWidget(idx) tab_widget.updateModel() widgets = [ tab_widget, self.info_label, ] _populateWidgetsEnabled(widgets) self.updateInfo() return
def run_solve(override_current_frame=None): """ Run the solver for the active collection. If the Solver UI is found, the window will update and show progress messages. This function is strongly dependant on the Solver UI. The following state information is set via the Solver UI. - Active Collection - Log Level - Refresh Viewport :param override_current_frame: Before running the solver, change the "override current frame" state to this value. :type override_current_frame: bool """ assert (override_current_frame is None or isinstance(override_current_frame, bool)) if override_current_frame is None: override_current_frame = False col = lib_state.get_active_collection() if col is None: msg = 'No active Collection found. Skipping solve.' LOG.warning(msg) return log_level = lib_state.get_log_level() layout = None win = solver_window.SolverWindow.get_instance() win_valid = uiutils.isValidQtObject(win) if win is None and win_valid: msg = 'Could not get window.' LOG.warning(msg) else: layout = win.getSubForm() # Set 'override current frame' value. tab = lib_col_state.get_solver_tab_from_collection(col) prev_value = None if override_current_frame is True: prev_value = __get_override_current_frame_value(col, tab) __set_override_current_frame_value(col, layout, tab, override_current_frame) # Run Solver options = lib_col.gather_execute_options() lib_col.run_solve_ui( col, options, log_level, win, ) # Restore previous value. if override_current_frame is True: __set_override_current_frame_value(col, layout, tab, prev_value) return
def removeClicked(self): col = lib_state.get_active_collection() if col is None: return sel = lib_maya_utils.get_scene_selection() ui_nodes = lib_uiquery.get_selected_ui_nodes( self.treeView, self.filterModel ) nodes = lib_uiquery.convert_ui_nodes_to_nodes(ui_nodes, 'marker') lib_marker.remove_markers_from_collection(nodes, col) # Remove Callbacks callback_manager = self.callback_manager if callback_manager is not None: lib_marker.remove_callbacks_from_markers( nodes, callback_manager ) self.dataChanged.emit() self.viewUpdated.emit() # Restore selection. lib_maya_utils.set_scene_selection(sel) return
def apply(self): """ This button launches a solve, but can also be used to cancel a solve. """ running_state = lib_state.get_solver_is_running_state() if running_state is True: # Cancel out of a running solve if the user presses # the button again. lib_state.set_solver_user_interrupt_state(True) return undo_id = 'mmSolver: ' undo_id += str(datetime.datetime.isoformat(datetime.datetime.now())) undo_id += ' ' undo_id += str(uuid.uuid4()) with tools_utils.tool_context(use_undo_chunk=True, undo_chunk_name=undo_id, restore_current_frame=False, pre_update_frame=False, post_update_frame=False, use_dg_evaluation_mode=True, disable_viewport=False): block = self.blockSignals(True) try: mmapi.set_solver_running(True) options = lib_collection.gather_execute_options() log_level = lib_state.get_log_level() col = lib_state.get_active_collection() lib_collection.run_solve_ui(col, options, log_level, self) finally: mmapi.set_solver_running(False) self.blockSignals(block) return
def rootFramesTextEntered(self): """ Run when the rootFrames_lineEdit text is has been entered (for example the user presses the <Enter> key to confirm the field value). """ text = self.rootFrames_lineEdit.text() col = lib_state.get_active_collection() if col is None: return # Round-trip conversion will make sure there are no syntax # errors given by the user. int_list = convert_types.stringToIntList(text) frames_string = convert_types.intListToString(int_list) if len(int_list) < 2: msg = 'Must have at least 2 root frames to solve.' LOG.warn(msg) msg = 'WARNING: ' + msg self.sendWarning.emit(msg) else: msg = const.STATUS_READY self.sendWarning.emit(msg) # Save the integer list, but present the user with a string. self.rootFrames_lineEdit.setText(frames_string) self.setRootFramesValue(col, frames_string) self.rootFramesChanged.emit() return
def objectAddClicked(self): col = lib_state.get_active_collection() if col is None: msg = 'Cannot add markers, active collection is not defined.' LOG.warning(msg) return sel = lib_maya_utils.get_scene_selection() mkr_list = lib_maya_utils.get_markers_from_selection() if len(mkr_list) == 0: msg = 'Please select objects, found no markers.' LOG.warning(msg) return lib_marker.add_markers_to_collection(mkr_list, col) def update_func(): if uiutils.isValidQtObject(self) is False: return self.updateObjectToggleButtons() self.updateObjectColumnVisibility() self.updateObjectModel() self.updateSolveValidState() return # Add Callbacks callback_manager = self.getCallbackManager() if callback_manager is not None: lib_marker.add_callbacks_to_markers(mkr_list, update_func, callback_manager) update_func() # Restore selection. lib_maya_utils.set_scene_selection(sel) return
def updateModel(self): self.frameRange_widget.updateModel() self.rootFrames_widget.updateModel() col = lib_state.get_active_collection() if col is None: return range_type = self.frameRange_widget.getRangeTypeValue(col) global_solve = self.getGlobalSolveValue(col) only_root_frames = self.getOnlyRootFramesValue(col) eval_obj_conns = self.getEvalObjectRelationshipsValue(col) eval_complex_graphs = self.getEvalComplexGraphsValue(col) global_solve_enabled = True only_root_frames_enabled = True eval_obj_conns_enabled = True eval_complex_graphs_enabled = True frameRange_enabled = True rootFrames_enabled = True if range_type == const.RANGE_TYPE_CURRENT_FRAME_VALUE: global_solve_enabled = False only_root_frames_enabled = False eval_obj_conns_enabled = True eval_complex_graphs_enabled = False frameRange_enabled = True rootFrames_enabled = False else: if global_solve is True: only_root_frames_enabled = False only_root_frames = False eval_obj_conns_enabled = True eval_complex_graphs_enabled = False rootFrames_enabled = True frameRange_enabled = True if only_root_frames is True: global_solve_enabled = False global_solve = False frameRange_enabled = False rootFrames_enabled = True eval_obj_conns_enabled = True eval_complex_graphs_enabled = True block = self.blockSignals(True) self.globalSolve_checkBox.setChecked(global_solve) self.globalSolve_checkBox.setEnabled(global_solve_enabled) self.onlyRootFrames_checkBox.setChecked(only_root_frames) self.onlyRootFrames_checkBox.setEnabled(only_root_frames_enabled) self.evalObjectRelationships_checkBox.setChecked(eval_obj_conns) self.evalObjectRelationships_checkBox.setEnabled(eval_obj_conns_enabled) self.evalComplexGraphs_checkBox.setChecked(eval_complex_graphs) self.evalComplexGraphs_checkBox.setEnabled(eval_complex_graphs_enabled) self.frameRange_widget.setEnabled(frameRange_enabled) self.rootFrames_widget.setEnabled(rootFrames_enabled) self.blockSignals(block) self.setGlobalSolveValue(col, global_solve) self.setOnlyRootFramesValue(col, only_root_frames) self.setEvalObjectRelationshipsValue(col, eval_obj_conns) self.setEvalComplexGraphsValue(col, eval_complex_graphs) return
def removeCollectionNode(self): col = lib_state.get_active_collection() if col is None: LOG.warning('No active collection to delete.') return cols = lib_col.get_collections() prev_col = lib_col.get_previous_collection(cols, col) steps = lib_col.get_solver_steps_from_collection(col) for step in steps: lib_col.remove_solver_step_from_collection(col, step) lib_col.delete_collection(col) lib_state.set_active_collection(prev_col) self.updateDynamicWindowTitle() self.updateStatusWithSolveResult() self.updateCollectionModel() self.updateObjectToggleButtons() self.updateObjectColumnVisibility() self.updateObjectModel() self.updateAttributeToggleButtons() self.updateAttributeColumnVisibility() self.updateAttributeModel() self.updateSolverModel() self.updateSolveValidState() return
def renameCollectionNode(self): col = lib_state.get_active_collection() if col is None: LOG.warning('No active collection to rename. Skipping rename.') return node_name = col.get_node() title = 'Rename Collection node' msg = 'Enter new node name' new_name = lib_maya_utils.prompt_for_new_node_name( title, msg, node_name) if new_name is not None: lib_col.rename_collection(col, new_name) self.updateDynamicWindowTitle() self.updateStatusWithSolveResult() self.updateCollectionModel() self.updateObjectToggleButtons() self.updateObjectColumnVisibility() self.updateObjectModel() self.updateAttributeToggleButtons() self.updateAttributeColumnVisibility() self.updateAttributeModel() self.updateSolverModel() self.updateSolveValidState() return
def attrAddClicked(self): attr_list = lib_maya_utils.get_selected_maya_attributes() if len(attr_list) == 0: msg = 'Please select attributes in the channel box, none where found.' LOG.warning(msg) return col = lib_state.get_active_collection() if col is None: msg = 'Cannot add attributes, active collection is not defined.' LOG.warning(msg) return lib_attr.add_attributes_to_collection(attr_list, col) def update_func(): self.updateAttributeModel() self.updateSolveValidState() self.setStatusLine(const.STATUS_READY) return # Add Callbacks callback_manager = self.getCallbackManager() if callback_manager is not None: lib_attr.add_callbacks_to_attributes( attr_list, update_func, callback_manager, ) update_func() return
def objectAddClicked(self): mkr_list = lib_maya_utils.get_markers_from_selection() if len(mkr_list) == 0: msg = 'Please select objects, found no markers.' LOG.warning(msg) return col = lib_state.get_active_collection() if col is None: msg = 'Cannot add markers, active collection is not defined.' LOG.warning(msg) return lib_marker.add_markers_to_collection(mkr_list, col) def update_func(): self.updateObjectModel() self.updateSolveValidState() self.setStatusLine(const.STATUS_READY) return # Add Callbacks callback_manager = self.getCallbackManager() if callback_manager is not None: lib_marker.add_callbacks_to_markers( mkr_list, update_func, callback_manager ) update_func() return
def run_connect_markers_to_active_collection(**kwargs): import mmSolver.tools.userpreferences.constant as userprefs_const import mmSolver.tools.userpreferences.lib as userprefs_lib # Enable a toggle to turn on or off this affect. config = userprefs_lib.get_config() key = userprefs_const.REG_EVNT_ADD_NEW_MKR_TO_KEY run_event = userprefs_lib.get_value(config, key) if run_event == userprefs_const.REG_EVNT_ADD_NEW_MKR_TO_NONE_VALUE: return LOG.debug("run_connect_markers_to_active_collection: %s", kwargs) s = time.time() import mmSolver.api as mmapi import mmSolver.tools.solver.lib.state as state_lib mmapi.load_plugin() col = state_lib.get_active_collection() if col is None: return mkr = kwargs.get('mkr') if isinstance(mkr, list): col.add_marker_list(mkr) elif isinstance(mkr, mmapi.Marker): col.add_marker(mkr) e = time.time() LOG.debug("run_connect_markers_to_active_collection: time=%s", e - s) return
def populateModel(self, model): valid = uiutils.isValidQtObject(model) if valid is False: return col = lib_state.get_active_collection() attr_list = [] show_anm = const.ATTRIBUTE_TOGGLE_ANIMATED_DEFAULT_VALUE show_stc = const.ATTRIBUTE_TOGGLE_STATIC_DEFAULT_VALUE show_lck = const.ATTRIBUTE_TOGGLE_LOCKED_DEFAULT_VALUE if col is not None: attr_list = lib_attr.get_attributes_from_collection(col) show_anm = lib_col.get_attribute_toggle_animated_from_collection( col) show_stc = lib_col.get_attribute_toggle_static_from_collection(col) show_lck = lib_col.get_attribute_toggle_locked_from_collection(col) def update_func(): if uiutils.isValidQtObject(self) is False: return self.dataChanged.emit() return # Add Callbacks # # When querying attributes, we must make sure they have a Maya # callback attached to the node to update the UI. callback_manager = self.callback_manager if callback_manager is not None: lib_attr.add_callbacks_to_attributes(attr_list, update_func, callback_manager) root = convert_to_ui.attributesToUINodes(col, attr_list, show_anm, show_stc, show_lck) model.setRootNode(root) return
def addClicked(self): col = lib_state.get_active_collection() if col is None: msg = 'Cannot add markers, active collection is not defined.' LOG.warning(msg) return sel = lib_maya_utils.get_scene_selection() mkr_list = lib_maya_utils.get_markers_from_selection() if len(mkr_list) == 0: msg = 'Please select objects, found no markers.' LOG.warning(msg) return lib_marker.add_markers_to_collection(mkr_list, col) # Add Callbacks callback_manager = self.callback_manager if callback_manager is not None: lib_marker.add_callbacks_to_markers( mkr_list, callback_manager ) # Restore selection. lib_maya_utils.set_scene_selection(sel) return
def updateModel(self): """ Refresh the name_comboBox with the current Maya scene state. """ col = lib_state.get_active_collection() if col is None: return roots_enabled = True roots_string = self.getRootFramesValue(col) if roots_string is None: frame = lib_maya_utils.get_current_frame() start, end = utils_time.get_maya_timeline_range_inner() int_list = list(set([start, frame, end])) roots_string = convert_types.intListToString(int_list) self.setRootFramesValue(col, roots_string) else: int_list = convert_types.stringToIntList(roots_string) roots_string = convert_types.intListToString(int_list) assert roots_string is not None block = self.blockSignals(True) self.rootFrames_lineEdit.setEnabled(roots_enabled) self.rootFrames_lineEdit.setText(roots_string) self.blockSignals(block) return
def addClicked(self): col = lib_state.get_active_collection() if col is None: msg = 'Cannot add markers, active collection is not defined.' LOG.warning(msg) return sel = lib_maya_utils.get_scene_selection() mkr_list = lib_maya_utils.get_markers_from_selection() if len(mkr_list) == 0: msg = 'Please select objects, found no markers.' LOG.warning(msg) return lib_marker.add_markers_to_collection(mkr_list, col) def update_func(): if uiutils.isValidQtObject(self) is False: return self.dataChanged.emit() self.viewUpdated.emit() return # Add Callbacks callback_manager = self.callback_manager if callback_manager is not None: lib_marker.add_callbacks_to_markers(mkr_list, update_func, callback_manager) update_func() # Restore selection. lib_maya_utils.set_scene_selection(sel) return
def apply(self): """ This button launches a solve, but can also be used to cancel a solve. """ running_state = lib_state.get_solver_is_running_state() if running_state is True: # Cancel out of a running solve if the user presses # the button again. lib_state.set_solver_user_interrupt_state(True) return undo_id = 'mmSolver: ' undo_id += str(datetime.datetime.isoformat(datetime.datetime.now())) undo_id += ' ' undo_id += str(uuid.uuid4()) with undo_utils.undo_chunk_context(undo_id): block = self.blockSignals(True) try: mmapi.set_solver_running(True) options = lib_collection.gather_execute_options() log_level = lib_state.get_log_level() col = lib_state.get_active_collection() lib_collection.run_solve_ui(col, options, log_level, self) finally: mmapi.set_solver_running(False) self.blockSignals(block) return
def apply(self): self.setStatusLine(const.STATUS_EXECUTING) try: refresh_state = lib_state.get_refresh_viewport_state() log_level = lib_state.get_log_level() self.progressBar.setValue(0) self.progressBar.show() col = lib_state.get_active_collection() if col is None: msg = 'No active collection.' self.setStatusLine('ERROR: ' + msg) LOG.error(msg) ok = lib_collection.compile_collection(col) if ok is not True: msg = 'Cannot execute solver, collection is not valid.' msg += 'collection=%r' self.setStatusLine('Warning: ' + msg) LOG.warning(msg, col) else: lib_collection.execute_collection( col, log_level=log_level, refresh=refresh_state, prog_fn=self.progressBar.setValue, status_fn=self.setStatusLine, ) finally: self.progressBar.setValue(100) self.progressBar.hide() self.setStatusLine(const.STATUS_FINISHED) return
def attrRemoveClicked(self): col = lib_state.get_active_collection() if col is None: return sel = lib_maya_utils.get_scene_selection() ui_nodes = lib_uiquery.get_selected_ui_nodes( self.attribute_treeView, self.attribute_filterModel ) attr_list = lib_uiquery.convert_ui_nodes_to_nodes(ui_nodes, 'data') lib_attr.remove_attr_from_collection(attr_list, col) # Remove Callbacks callback_manager = self.getCallbackManager() if callback_manager is not None: lib_attr.remove_callbacks_from_attributes( attr_list, callback_manager ) self.updateAttributeModel() self.updateSolveValidState() # Restore selection. lib_maya_utils.set_scene_selection(sel) return
def updateStatusWithSolveResult(self): col = lib_state.get_active_collection() if col is None: return info_fn = self.setSolveInfoLine solres_list = col.get_last_solve_results() timestamp = col.get_last_solve_timestamp() total_time = col.get_last_solve_duration() msg = 'No solve performed.' if (len(solres_list) == 0): info_fn(msg) if timestamp is None: timestamp = time.time() if total_time is None: total_time = 0.0 # We don't want to log every time we open the UI. log = None lib_collection.log_solve_results(log, solres_list, timestamp=timestamp, total_time=total_time, status_fn=info_fn) return
def populateOverrideCurrentFrame(self): cur_frame = False col = lib_state.get_active_collection() if col is not None: cur_frame = lib_col.get_override_current_frame_from_collection(col) self.overrideCurrentFrame_checkBox.setChecked(cur_frame) return
def objectRemoveClicked(self): col = lib_state.get_active_collection() if col is None: return sel = lib_maya_utils.get_scene_selection() ui_nodes = lib_uiquery.get_selected_ui_nodes( self.object_treeView, self.object_filterModel ) nodes = lib_uiquery.convert_ui_nodes_to_nodes(ui_nodes, 'marker') lib_marker.remove_markers_from_collection(nodes, col) # Remove Callbacks callback_manager = self.getCallbackManager() if callback_manager is not None: lib_marker.remove_callbacks_from_markers( nodes, callback_manager ) self.updateObjectToggleButtons() self.updateObjectModel() self.updateSolveValidState() # Restore selection. lib_maya_utils.set_scene_selection(sel) return
def populateAttributeModel(self, model): valid = uiutils.isValidQtObject(model) if valid is False: return col = lib_state.get_active_collection() attr_list = [] if col is not None: attr_list = lib_attr.get_attributes_from_collection(col) def update_func(): if uiutils.isValidQtObject(self) is False: return self.updateAttributeModel() return # Add Callbacks # # When querying attributes, we must make sure they have a Maya # callback attached to the node to update the UI. callback_manager = self.getCallbackManager() if callback_manager is not None: lib_attr.add_callbacks_to_attributes( attr_list, update_func, callback_manager ) root = convert_to_ui.attributesToUINodes(attr_list) model.setRootNode(root) return
def updateModel(self): """ Refresh the name_comboBox with the current Maya scene state. """ self.populateModel(self.model) index = None col = lib_state.get_active_collection() if col is None: cols = lib_col.get_collections() if len(cols) > 0: # If there is no active collection, but there are # collections already created, we make sure the first # collection is marked active. col = cols[0] lib_state.set_active_collection(col) else: index = self.getActiveIndex(self.model, col) block = self.blockSignals(True) if index is not None: self.name_comboBox.setCurrentIndex(index) self.nameChanged.emit() self.blockSignals(block) return
def removeActiveNode(self): """ Delete the currently active collection. """ col = lib_state.get_active_collection() if col is None: LOG.warning('No active collection to delete.') return title = 'Remove Collection?' text = 'Would you like to remove the current Collection?' text += '\n\nRemove "' + str(col.get_node()) + '"?' clicked_button = QtWidgets.QMessageBox.question(self, title, text) if clicked_button != QtWidgets.QMessageBox.Yes: LOG.warn('User cancelled operation.') return cols = lib_col.get_collections() prev_col = lib_col.get_previous_collection(cols, col) steps = lib_col.get_solver_steps_from_collection(col) for step in steps: lib_col.remove_solver_step_from_collection(col, step) lib_col.delete_collection(col) lib_state.set_active_collection(prev_col) self.itemRemoved.emit() self.itemChanged.emit() self.nameChanged.emit() return
def collectionSelectClicked(self): col = lib_state.get_active_collection() if col is None: LOG.warning('No active collection to select.') return lib_col.select_collection(col) self.updateDynamicWindowTitle() return
def evalComplexGraphsValueToggled(self, value): col = lib_state.get_active_collection() if col is None: return self.setEvalComplexGraphsValue(col, value) self.evalComplexGraphsChanged.emit() self.dataChanged.emit() return