def _compile_remove_inbetween_frames(attr_list, non_root_frame_list, start_frame, end_frame, test, verbose): # Solve in-between frames attr_names = [x.get_name() for x in attr_list] # Solver for all other frames. for frm in non_root_frame_list: frame_num = frm.get_number() func = 'maya.cmds.cutKey' args = attr_names kwargs = {'time': (frame_num, frame_num)} action = api_action.Action( func=func, args=args, kwargs=kwargs) yield action, None # Change all attribute keyframes to linear tangents. func = 'maya.cmds.keyTangent' kwargs = { 'inTangentType': 'linear', 'outTangentType': 'linear', 'time': (start_frame.get_number() - 1, end_frame.get_number() + 1)} action = api_action.Action( func=func, args=attr_names, kwargs=kwargs) yield action, None
def _compile_remove_inbetween_frames(attr_list, non_root_frame_list, start_frame, end_frame, withtest, verbose): """ Compile actions to delete keyframes for all attributes with-in a specific start/end frame range. :param attr_list: List of Attributes. :type attr_list: [Attribute, ..] :param non_root_frame_list: pass :type non_root_frame_list: [[int, ..], ..] :param start_frame: pass :type start_frame: Frame :param end_frame: pass :type end_frame: Frame :param withtest: Compile the test/validation Action, as well as the solve Action? :type withtest: bool :param verbose: Print out more detail to 'stdout'. :type verbose: bool :return: Yields an Action and None, at each iteration. :rtype: (Action, None) """ assert isinstance(withtest, bool) assert isinstance(verbose, bool) # Solve in-between frames attr_names = [x.get_name() for x in attr_list] # Solver for all other frames. for frm in non_root_frame_list: frame_num = frm.get_number() func = 'maya.cmds.cutKey' args = attr_names kwargs = {'time': (frame_num, frame_num)} action = api_action.Action(func=func, args=args, kwargs=kwargs) yield action, None # Change all attribute keyframes to linear tangents. func = 'maya.cmds.keyTangent' kwargs = { 'inTangentType': 'linear', 'outTangentType': 'linear', 'time': (start_frame.get_number() - 1, end_frame.get_number() + 1) } action = api_action.Action(func=func, args=attr_names, kwargs=kwargs) yield action, None
def compile_reset_used_hints(col, mkr_list, attr_list): func = 'mmSolver._api.solveraffects.reset_marker_used_hints' mkr_nodes = [mkr.get_node() for mkr in mkr_list] args = [mkr_nodes] kwargs = {} action = api_action.Action(func=func, args=args, kwargs=kwargs) yield action, None func = 'mmSolver._api.solveraffects.reset_attr_used_hints' node_attr_list = [attr.get_name() for attr in attr_list] args = [col.get_node(), node_attr_list] kwargs = {} action = api_action.Action(func=func, args=args, kwargs=kwargs) yield action, None return
def compile_euler_filter(attr_list, withtest): """ Compile a Euler filter to run on all rotation attributes, for *all* frames. :param attr_list: List of Attributes. :type attr_list: [Attribute, ..] :param withtest: Compile the test/validation Action, as well as the solve Action? :type withtest: bool :return: Yields an Action and None, at each iteration. :rtype: (Action, None) """ for attr in attr_list: attr_type = attr.get_attribute_type() if attr_type is None: continue if attr_type.endswith('Angle') is False: continue # Don't modify non-animated attributes (this includes # locked attributes). animated = attr.is_animated() if animated is False: continue node_name = attr.get_node() attr_name = attr.get_attr() func = 'mmSolver.utils.animcurve.euler_filter_plug' args = [node_name, attr_name] kwargs = {} action = api_action.Action( func=func, args=args, kwargs=kwargs) yield action, None return
def compile(self, mkr_list, attr_list, withtest=False): """ Compiles data given into flags for a single run of 'mmSolver'. :param self: The solver to compile :type self: Solver :param mkr_list: Markers to measure :type mkr_list: list of Marker :param attr_list: Attributes to solve for :type attr_list: list of Attribute :return: List of SolverActions to be performed one after the other. :rtype: [SolverAction, ..] """ assert isinstance(self, solverbase.SolverBase) assert isinstance(mkr_list, list) assert isinstance(attr_list, list) assert self.get_frame_list_length() > 0 func = 'maya.cmds.mmSolver' args = [] kwargs = dict() kwargs['camera'] = [] kwargs['marker'] = [] kwargs['attr'] = [] kwargs['frame'] = [] # Get Markers and Cameras markers, cameras = api_compile.markersAndCameras_compile_flags(mkr_list) if len(markers) == 0 and len(cameras) == 0: LOG.warning('No Markers or Cameras found!') return elif len(markers) == 0: LOG.warning('No Markers found!') return elif len(cameras) == 0: LOG.warning('No Cameras found!') return # Get Attributes use_animated = self.get_attributes_use_animated() use_static = self.get_attributes_use_static() attrs = api_compile.attributes_compile_flags(attr_list, use_animated, use_static) if len(attrs) == 0: LOG.warning('No Attributes found!') return # Get Frames frm_list = self.get_frame_list() frame_use_tags = self.get_frames_use_tags() frames = api_compile.frames_compile_flags(frm_list, frame_use_tags) if len(frames) == 0: LOG.warning('No Frames found!') return kwargs['marker'] = markers kwargs['camera'] = cameras kwargs['attr'] = attrs kwargs['frame'] = frames solver_type = self.get_solver_type() if solver_type is not None: kwargs['solverType'] = solver_type iterations = self.get_max_iterations() if iterations is not None: kwargs['iterations'] = iterations verbose = self.get_verbose() if verbose is not None: kwargs['verbose'] = verbose delta_factor = self.get_delta_factor() if delta_factor is not None: kwargs['delta'] = delta_factor auto_diff_type = self.get_auto_diff_type() if auto_diff_type is not None: kwargs['autoDiffType'] = auto_diff_type tau_factor = self.get_tau_factor() if tau_factor is not None: kwargs['tauFactor'] = tau_factor gradient_error_factor = self.get_gradient_error_factor() if gradient_error_factor is not None: kwargs['epsilon1'] = gradient_error_factor parameter_error_factor = self.get_parameter_error_factor() if parameter_error_factor is not None: kwargs['epsilon2'] = parameter_error_factor error_factor = self.get_error_factor() if error_factor is not None: kwargs['epsilon3'] = error_factor kwargs['robustLossType'] = const.ROBUST_LOSS_TYPE_TRIVIAL_VALUE kwargs['robustLossScale'] = 1.0 # TODO: Add 'robustLossType' flag. # TODO: Add 'robustLossScale' flag. # TODO: Add 'autoParamScaling' flag. # TODO: Add 'debugFile' flag. # # Add a debug file flag to the mmSolver command, only # # triggered during debug mode. # # TODO: Wrap this in another function. # if logging.DEBUG >= LOG.getEffectiveLevel(): # debug_file = maya.cmds.file(query=True, sceneName=True) # debug_file = os.path.basename(debug_file) # debug_file, ext = os.path.splitext(debug_file) # debug_file_path = os.path.join( # os.path.expandvars('${TEMP}'), # debug_file + '_' + str(i).zfill(6) + '.log' # ) # if len(debug_file) > 0 and debug_file_path is not None: # kwargs['debugFile'] = debug_file_path action = api_action.Action( func=func, args=args, kwargs=kwargs ) # Check the inputs and outputs are valid. vaction = None if withtest is True: assert api_action.action_func_is_mmSolver(action) is True vfunc = func vargs = list(args) vkwargs = kwargs.copy() remove_keys = ['debugFile', 'verbose'] for key in remove_keys: if key in vkwargs: del vkwargs[key] vkwargs['printStatistics'] = ['inputs'] vaction = api_action.Action( func=vfunc, args=vargs, kwargs=vkwargs ) yield action, vaction
def compile(self, col, mkr_list, attr_list, withtest=False): """ Compiles data given into flags for a single run of 'mmSolver'. :param self: The solver to compile :type self: Solver :param col: The collection to compile. :type col: Collection :param mkr_list: Markers to measure :type mkr_list: list of Marker :param attr_list: Attributes to solve for :type attr_list: list of Attribute :return: Yields a tuple of two Actions at each iteration. First action is the solver action, second action is for validation of the solve. :rtype: (Action, Action) """ assert isinstance(self, solverbase.SolverBase) assert isinstance(mkr_list, list) assert isinstance(attr_list, list) func = 'maya.cmds.mmSolverAffects' args = [] kwargs = dict() kwargs['camera'] = [] kwargs['marker'] = [] kwargs['attr'] = [] kwargs['mode'] = 'addAttrsToMarkers' # Get precomputed data to reduce re-querying Maya for data. precomputed_data = self.get_precomputed_data() mkr_state_values = precomputed_data.get( solverbase.MARKER_STATIC_VALUES_KEY) attr_state_values = precomputed_data.get( solverbase.ATTR_STATIC_VALUES_KEY) # Get Markers and Cameras markers, cameras = api_compile.markersAndCameras_compile_flags( mkr_list, mkr_static_values=mkr_state_values) if len(markers) == 0 and len(cameras) == 0: LOG.warning('No Markers or Cameras found!') return elif len(markers) == 0: LOG.warning('No Markers found!') return elif len(cameras) == 0: LOG.warning('No Cameras found!') return # Get Attributes # # NOTE: time is not a factor for the calculation of 'affects' # relationships, therefore use_animated and use_static are # True, to ensure all attributes (that are not locked) are # calculated. use_animated = True use_static = True attrs = api_compile.attributes_compile_flags( col, attr_list, use_animated, use_static, attr_static_values=attr_state_values) if len(attrs) == 0: LOG.warning('No Attributes found!') return kwargs['marker'] = markers kwargs['camera'] = cameras kwargs['attr'] = attrs action = api_action.Action(func=func, args=args, kwargs=kwargs) yield action, action # Query and set 'used solver object' values on nodes. func = _runAndSetUsedSolveObjects args = [col.get_node()] action = api_action.Action(func=func, args=args, kwargs=kwargs) yield action, action
def compile(self, col, mkr_list, attr_list, withtest=False): actions = [] # TODO: Triangulate the (open) bundles here. We triangulate all # valid bundles after the root frames have solved. # # NOTE: Bundle triangulation can only happen if the camera # is not nodal. # # NOTE: We currently assume the camera is NOT nodal. valid_bnd_node_list = [] for mkr in mkr_list: bnd = mkr.get_bundle() bnd_node = bnd.get_node() valid_bnd_node_list.append(bnd_node) valid_node_list = collections.defaultdict(int) for attr in attr_list: assert isinstance(attr, attribute.Attribute) is True attr_name = attr.get_attr() if attr_name not in BUNDLE_ATTR_NAMES: continue attr_node = attr.get_node() if attr_node not in valid_bnd_node_list: continue obj_type = api_utils.get_object_type(attr_node) if obj_type == const.OBJECT_TYPE_BUNDLE: valid_node_list[attr_node] += 1 for node, count in valid_node_list.items(): if count != 3: continue bnd = bundle.Bundle(node=node) bnd_node = bnd.get_node() mkr_node_list = [x.get_node() for x in mkr_list] bnd_mkr_list = [x for x in bnd.get_marker_list() if x.get_node() in mkr_node_list] bnd_mkr_node_list = [x.get_node() for x in bnd_mkr_list] bnd_cam_node_list = [x.get_camera().get_transform_node() for x in bnd_mkr_list] bnd_mkr_frm_list = [_get_marker_first_last_frame_list(x, self.root_frame_list) for x in bnd_mkr_node_list] bnd_mkr_cam_frm_list = zip( bnd_mkr_node_list, bnd_cam_node_list, bnd_mkr_frm_list ) # TODO: We must detect if the newly calculated position is # behind the camera, if so, we reject the new values. args = [bnd_node, bnd_mkr_cam_frm_list] kwargs = {} action = api_action.Action( _triangulate_bundle, args=args, kwargs=kwargs ) LOG.debug('adding _triangulate_bundle: func=%r', _triangulate_bundle, args, kwargs ) # actions.append(action) yield action, None return
def compile(self, col, mkr_list, attr_list, withtest=False): """ Compiles data given into flags for a single run of 'mmSolver'. :param self: The solver to compile :type self: Solver :param col: The collection to compile. :type col: Collection :param mkr_list: Markers to measure :type mkr_list: list of Marker :param attr_list: Attributes to solve for :type attr_list: list of Attribute :return: Yields a tuple of two Actions at each iteration. First action is the solver action, second action is for validation of the solve. :rtype: (Action, Action) """ assert isinstance(self, solverbase.SolverBase) assert isinstance(mkr_list, list) assert isinstance(attr_list, list) assert self.get_frame_list_length() > 0 func = 'maya.cmds.mmSolver' args = [] kwargs = dict() kwargs['camera'] = [] kwargs['marker'] = [] kwargs['attr'] = [] kwargs['frame'] = [] # Get precomputed data to reduce re-querying Maya for data. precomputed_data = self.get_precomputed_data() mkr_state_values = precomputed_data.get( solverbase.MARKER_STATIC_VALUES_KEY) attr_state_values = precomputed_data.get( solverbase.ATTR_STATIC_VALUES_KEY) attr_stiff_state_values = precomputed_data.get( solverbase.ATTR_STIFFNESS_STATIC_VALUES_KEY) attr_smooth_state_values = precomputed_data.get( solverbase.ATTR_SMOOTHNESS_STATIC_VALUES_KEY) # Get Markers and Cameras markers, cameras = api_compile.markersAndCameras_compile_flags( mkr_list, mkr_static_values=mkr_state_values) if len(markers) == 0 and len(cameras) == 0: LOG.warning('No Markers or Cameras found!') return elif len(markers) == 0: LOG.warning('No Markers found!') return elif len(cameras) == 0: LOG.warning('No Cameras found!') return # Get Attributes use_animated = self.get_attributes_use_animated() use_static = self.get_attributes_use_static() attrs = api_compile.attributes_compile_flags( col, attr_list, use_animated, use_static, attr_static_values=attr_state_values) if len(attrs) == 0: LOG.warning('No Attributes found!') return # Stiffness Attribute Flags stiff_flags = None use_stiffness = self.get_use_stiffness() if use_stiffness is True: stiff_flags = api_compile.attr_stiffness_compile_flags( col, attr_list, attr_static_values=attr_state_values, attr_stiff_static_values=attr_stiff_state_values, ) # Smoothness Attribute Flags smooth_flags = None use_smoothness = self.get_use_smoothness() if use_smoothness is True: smooth_flags = api_compile.attr_smoothness_compile_flags( col, attr_list, attr_static_values=attr_state_values, attr_smooth_static_values=attr_smooth_state_values, ) # Get Frames frm_list = self.get_frame_list() frame_use_tags = self.get_frames_use_tags() frames = api_compile.frames_compile_flags(frm_list, frame_use_tags) if len(frames) == 0: LOG.warning('No Frames found!') return kwargs['marker'] = markers kwargs['camera'] = cameras kwargs['attr'] = attrs kwargs['frame'] = frames if stiff_flags: kwargs['attrStiffness'] = stiff_flags if smooth_flags: kwargs['attrSmoothness'] = smooth_flags solver_type = self.get_solver_type() if solver_type is not None: kwargs['solverType'] = solver_type iterations = self.get_max_iterations() if iterations is not None: kwargs['iterations'] = iterations verbose = self.get_verbose() if verbose is not None: kwargs['verbose'] = verbose delta_factor = self.get_delta_factor() if delta_factor is not None: kwargs['delta'] = delta_factor auto_diff_type = self.get_auto_diff_type() if auto_diff_type is not None: kwargs['autoDiffType'] = auto_diff_type tau_factor = self.get_tau_factor() if tau_factor is not None: kwargs['tauFactor'] = tau_factor gradient_error_factor = self.get_gradient_error_factor() if gradient_error_factor is not None: kwargs['epsilon1'] = gradient_error_factor parameter_error_factor = self.get_parameter_error_factor() if parameter_error_factor is not None: kwargs['epsilon2'] = parameter_error_factor error_factor = self.get_error_factor() if error_factor is not None: kwargs['epsilon3'] = error_factor kwargs['robustLossType'] = const.ROBUST_LOSS_TYPE_TRIVIAL_VALUE kwargs['robustLossScale'] = 1.0 kwargs['timeEvalMode'] = self.get_time_eval_mode() value = self.get_remove_unused_markers() if value is not None: kwargs['removeUnusedMarkers'] = value value = self.get_remove_unused_attributes() if value is not None: kwargs['removeUnusedAttributes'] = value # TODO: Add 'robustLossType' flag. # TODO: Add 'robustLossScale' flag. # TODO: Add 'autoParamScaling' flag. # TODO: Add 'debugFile' flag. # # Add a debug file flag to the mmSolver command, only # # triggered during debug mode. # # TODO: Wrap this in another function. # if logging.DEBUG >= LOG.getEffectiveLevel(): # debug_file = maya.cmds.file(query=True, sceneName=True) # debug_file = os.path.basename(debug_file) # debug_file, ext = os.path.splitext(debug_file) # debug_file_path = os.path.join( # os.path.expandvars('${TEMP}'), # debug_file + '_' + str(i).zfill(6) + '.log' # ) # if len(debug_file) > 0 and debug_file_path is not None: # kwargs['debugFile'] = debug_file_path action = api_action.Action(func=func, args=args, kwargs=kwargs) # Check the inputs and outputs are valid. vaction = None if withtest is True: assert api_action.action_func_is_mmSolver(action) is True vfunc = func vargs = list(args) vkwargs = kwargs.copy() remove_keys = ['debugFile', 'verbose'] for key in remove_keys: if key in vkwargs: del vkwargs[key] vkwargs['printStatistics'] = ['inputs'] vaction = api_action.Action(func=vfunc, args=vargs, kwargs=vkwargs) yield action, vaction