Example #1
0
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
Example #5
0
    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
Example #6
0
    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
Example #7
0
    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