コード例 #1
0
    def compile(self, col, mkr_list, attr_list, withtest=False):
        assert isinstance(withtest, bool)

        # Options to affect how the solve is constructed.
        use_single_frame = self.get_use_single_frame()
        single_frame = self.get_single_frame()
        frame_list = self.get_frame_list()
        anim_iter_num = self.get_anim_iteration_num()
        lineup_iter_num = self.get_lineup_iteration_num()
        use_euler_filter = self._use_euler_filter
        precomputed_data = self.get_precomputed_data()

        if use_single_frame is True:
            # Single frame solve
            sol = solverstep.SolverStep()
            sol.set_max_iterations(lineup_iter_num)
            sol.set_frame_list([single_frame])
            sol.set_attributes_use_animated(True)
            sol.set_attributes_use_static(False)
            sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
            sol.set_use_smoothness(False)
            sol.set_use_stiffness(False)
            sol.set_precomputed_data(precomputed_data)
            for action, vaction in sol.compile(col,
                                               mkr_list,
                                               attr_list,
                                               withtest=withtest):
                yield (action, vaction)
        else:
            # Multiple frame solve, per-frame
            vaction_cache = api_compile.create_compile_solver_cache()
            for i, frm in enumerate(frame_list):
                is_first_frame = i == 0
                one_frame_list = [frm]
                sol = solverstep.SolverStep()
                sol.set_max_iterations(anim_iter_num)
                sol.set_frame_list(one_frame_list)
                sol.set_attributes_use_animated(True)
                sol.set_attributes_use_static(False)
                sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
                sol.set_use_smoothness(not is_first_frame)
                sol.set_use_stiffness(not is_first_frame)
                sol.set_precomputed_data(precomputed_data)

                generator = api_compile.compile_solver_with_cache(
                    sol, col, mkr_list, attr_list, withtest, vaction_cache)
                for action, vaction in generator:
                    yield action, vaction

            # Perform an euler filter on all unlocked rotation attributes.
            if use_euler_filter is True:
                generator = solverutils.compile_euler_filter(
                    attr_list, withtest)
                for action, vaction in generator:
                    yield action, vaction

        return
コード例 #2
0
def _compile_single_frame(mkr_list,
                          attr_list,
                          single_frame,
                          block_iter_num,
                          lineup_iter_num,
                          auto_attr_blocks,
                          test,
                          verbose):
    if auto_attr_blocks is True:
        meta_mkr_list, meta_attr_list = _split_mkr_attr_into_categories(
            mkr_list,
            attr_list
        )
        for new_mkr_list, new_attr_list in zip(meta_mkr_list, meta_attr_list):
            sol = solverstep.SolverStep()
            sol.set_verbose(verbose)
            sol.set_max_iterations(block_iter_num)
            sol.set_frame_list([single_frame])
            sol.set_attributes_use_animated(True)
            sol.set_attributes_use_static(True)
            sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)

            cache = api_compile.create_compile_solver_cache()
            generator = api_compile.compile_solver_with_cache(
                sol, new_mkr_list, new_attr_list, test, cache
            )
            for action, vaction in generator:
                yield action, vaction

    # Single frame solve
    sol = solverstep.SolverStep()
    sol.set_verbose(verbose)
    sol.set_max_iterations(lineup_iter_num)
    sol.set_frame_list([single_frame])
    sol.set_attributes_use_animated(True)
    sol.set_attributes_use_static(True)
    sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
    cache = api_compile.create_compile_solver_cache()
    generator = api_compile.compile_solver_with_cache(
        sol, mkr_list, attr_list, test, cache
    )
    for action, vaction in generator:
        yield action, vaction
    return
コード例 #3
0
    def compile(self, mkr_list, attr_list, withtest=False):
        assert isinstance(withtest, bool)

        # Options to affect how the solve is constructed.
        use_single_frame = self.get_use_single_frame()
        single_frame = self.get_single_frame()
        frame_list = self.get_frame_list()
        anim_iter_num = self.get_anim_iteration_num()
        lineup_iter_num = self.get_lineup_iteration_num()
        verbose = True

        actions = []
        if use_single_frame is True:
            # Single frame solve
            sol = solverstep.SolverStep()
            sol.set_verbose(verbose)
            sol.set_max_iterations(lineup_iter_num)
            sol.set_frame_list([single_frame])
            sol.set_attributes_use_animated(True)
            sol.set_attributes_use_static(False)
            sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)

            for action, vaction in sol.compile(mkr_list,
                                               attr_list,
                                               withtest=withtest):
                yield (action, vaction)
        else:
            # Multiple frame solve, per-frame
            vaction_cache = api_compile.create_compile_solver_cache()
            for frm in frame_list:
                one_frame_list = [frm]
                sol = solverstep.SolverStep()
                sol.set_verbose(verbose)
                sol.set_max_iterations(anim_iter_num)
                sol.set_frame_list(one_frame_list)
                sol.set_attributes_use_animated(True)
                sol.set_attributes_use_static(False)
                sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)

                generator = api_compile.compile_solver_with_cache(
                    sol, mkr_list, attr_list, withtest, vaction_cache)
                for action, vaction in generator:
                    yield action, vaction
        return
コード例 #4
0
def _compile_multi_inbetween_frames(mkr_list,
                                    attr_list,
                                    all_frame_list,
                                    global_solve,
                                    anim_iter_num,
                                    test,
                                    verbose):
    if global_solve is True:
        # Do Global Solve with all frames.
        sol = solverstep.SolverStep()
        sol.set_verbose(verbose)
        sol.set_max_iterations(anim_iter_num)
        sol.set_frame_list(all_frame_list)
        sol.set_attributes_use_animated(True)
        sol.set_attributes_use_static(True)
        sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)

        cache = api_compile.create_compile_solver_cache()
        generator = api_compile.compile_solver_with_cache(
            sol, mkr_list, attr_list, test, cache
        )
        for action, vaction in generator:
            yield action, vaction
    else:
        cache = api_compile.create_compile_solver_cache()
        for frm in all_frame_list:
            one_frame_list = [frm]
            sol = solverstep.SolverStep()
            sol.set_verbose(verbose)
            sol.set_max_iterations(anim_iter_num)
            sol.set_frame_list(one_frame_list)
            sol.set_attributes_use_animated(True)
            sol.set_attributes_use_static(False)
            sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
            generator = api_compile.compile_solver_with_cache(
                sol, mkr_list, attr_list, test, cache
            )
            for action, vaction in generator:
                yield action, vaction
    return
コード例 #5
0
    def _load_solver_list(self):
        """
        Get all Solvers from the attribute data on the Collection.

        :return: List of Solver objects.
        :rtype: list of Solver
        """
        solver_list = []
        attr = const.COLLECTION_ATTR_LONG_NAME_SOLVER_LIST
        attr_data = self._get_attr_data(attr)
        if isinstance(attr_data, list) is False:
            return solver_list
        for item in attr_data:
            if isinstance(item, dict) is False:
                continue
            sol = solverstep.SolverStep(data=item)
            solver_list.append(sol)
        return solver_list
コード例 #6
0
def _compile_multi_root_frames(mkr_list,
                               attr_list,
                               batch_frame_list,
                               root_iter_num,
                               withtest,
                               verbose):
    # Solve root frames.
    for frm_list in batch_frame_list:
        # Get root markers
        root_mkr_list, non_root_mkr_list = _filter_mkr_list_by_frame_list(
            mkr_list,
            frm_list
        )
        assert len(root_mkr_list) > 0

        mkr_attr_map = markerutils.find_marker_attr_mapping(
            root_mkr_list,
            attr_list
        )
        root_attr_list = []
        for i, mkr in enumerate(root_mkr_list):
            for j, attr in enumerate(attr_list):
                x = mkr_attr_map[i][j]
                if x is True and attr not in root_attr_list:
                    root_attr_list.append(attr)

        sol = solverstep.SolverStep()
        sol.set_verbose(verbose)
        sol.set_max_iterations(root_iter_num)
        sol.set_frame_list(frm_list)
        sol.set_attributes_use_animated(True)
        sol.set_attributes_use_static(True)
        sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)

        cache = api_compile.create_compile_solver_cache()
        generator = api_compile.compile_solver_with_cache(
            sol, root_mkr_list, root_attr_list, withtest, cache,
        )
        for action, vaction in generator:
            yield action, vaction
        return
コード例 #7
0
def _compile_single_frame(col, mkr_list, attr_list, single_frame,
                          block_iter_num, lineup_iter_num, auto_attr_blocks,
                          precomputed_data, withtest, verbose):
    """
    Compile to Actions for a solve of a single frame.

    :param mkr_list:
        Markers to be solved with.
    :type mkr_list: [Marker, ..]

    :param attr_list:
        Attributes to be solved.
    :type attr_list: [Attribute, ..]

    :param single_frame:
        The Frame to solve on.
    :type single_frame: Frame

    :param auto_attr_blocks:
        Split attributes into stages (based on categories) to be
        solved together.
    :type auto_attr_blocks: bool

    :param block_iter_num:
        How many iterations to perform for attribute categories.
    :type block_iter_num: int

    :param lineup_iter_num:
        pass
    :type lineup_iter_num: int

    :param withtest:
        Should validation tests be generated?
    :type withtest: bool

    :param verbose:
        Print out more detail than usual.
    :type verbose: bool

    :return:
        Yields a generator of two Actions. First Action is for solving,
        the second Action is for validation of inputs.
    :rtype: (Action, Action)
    """
    if auto_attr_blocks is True:
        meta_mkr_list, meta_attr_list = _split_mkr_attr_into_categories(
            mkr_list, attr_list)
        for new_mkr_list, new_attr_list in zip(meta_mkr_list, meta_attr_list):
            sol = solverstep.SolverStep()
            sol.set_max_iterations(block_iter_num)
            sol.set_frame_list([single_frame])
            sol.set_attributes_use_animated(True)
            sol.set_attributes_use_static(True)
            sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
            sol.set_use_smoothness(False)
            sol.set_use_stiffness(False)
            sol.set_precomputed_data(precomputed_data)

            cache = api_compile.create_compile_solver_cache()
            generator = api_compile.compile_solver_with_cache(
                sol, col, new_mkr_list, new_attr_list, withtest, cache)
            for action, vaction in generator:
                yield action, vaction

    # Single frame solve
    sol = solverstep.SolverStep()
    sol.set_max_iterations(lineup_iter_num)
    sol.set_frame_list([single_frame])
    sol.set_attributes_use_animated(True)
    sol.set_attributes_use_static(True)
    sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
    sol.set_use_smoothness(False)
    sol.set_use_stiffness(False)
    sol.set_precomputed_data(precomputed_data)

    cache = api_compile.create_compile_solver_cache()
    generator = api_compile.compile_solver_with_cache(sol, col, mkr_list,
                                                      attr_list, withtest,
                                                      cache)
    for action, vaction in generator:
        yield action, vaction
    return
コード例 #8
0
def _compile_multi_frame(col, mkr_list, attr_list, root_frame_list, frame_list,
                         auto_attr_blocks, block_iter_num, only_root_frames,
                         root_iter_num, anim_iter_num, global_solve,
                         root_frame_strategy, triangulate_bundles,
                         use_euler_filter, precomputed_data, withtest,
                         verbose):
    """
    Generate Actions to solve multiple-frames.

    :param mkr_list:
        Markers to be solved with.
    :type mkr_list: [Marker, ..]

    :param attr_list:
        Attributes to be solved.
    :type attr_list: [Attribute, ..]

    :param root_frame_list:
        Frames to solve static and animated attributes.
    :type root_frame_list: [[Frame, ..], ..]

    :param frame_list:
        Frames to solve animated attributes.
    :type frame_list: [Frame, ..]

    :param auto_attr_blocks:
        Split attributes into stages (based on categories) to be
        solved together.
    :type auto_attr_blocks: bool

    :param block_iter_num:
        How many iterations to perform for attribute categories.
    :type block_iter_num: int

    :param only_root_frames:
        Only solve the root frames.
    :param only_root_frames: bool

    :param root_iter_num:
        Number of iterations for root frame solves.
    :type root_iter_num: int

    :param anim_iter_num:
        Number of iterations for animated attribute solves.
    :type anim_iter_num: int

    :param global_solve:
        Should all frames be solved together, both animated and static
        attributes?
    :type global_solve: bool

    :param root_frame_strategy:
        The strategy ordering of root frames and how to solve them.
        Value must be one in ROOT_FRAME_STRATEGY_VALUE_LIST
    :type root_frame_strategy:

    :param triangulate_bundles:
        If True, unlocked bundles will be triangulated before being
        further refined by the solver processes.
    :type triangulate_bundles: bool

    :param use_euler_filter:
        Perform a Euler Filter after solving? A Euler filter will make
        sure no two keyframes rotate by more than 180 degrees, which
        will remove "Euler Flipping".
    :type use_euler_filter: bool

    :param withtest:
        Should validation tests be generated?
    :type withtest: bool

    :param verbose:
        Print out more detail than usual.
    :type verbose: bool

    :return:
        Yields a generator of two Actions. First Action is for solving,
        the second Action is for validation of inputs.
    :rtype: (Action, Action)
    """
    root_frame_list_num = [x.get_number() for x in root_frame_list]
    frame_list_num = [x.get_number() for x in frame_list]
    non_root_frame_list_num = set(frame_list_num) - set(root_frame_list_num)
    non_root_frame_list = [frame.Frame(x) for x in non_root_frame_list_num]

    all_frame_list_num = list(set(frame_list_num + root_frame_list_num))
    all_frame_list_num = list(sorted(all_frame_list_num))
    all_frame_list = [frame.Frame(x) for x in all_frame_list_num]
    start_frame = all_frame_list[0]
    end_frame = all_frame_list[-1]

    # 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.
    if triangulate_bundles is True:
        sol = solvertriangulate.SolverTriangulate()
        # sol.root_frame_list = root_frame_list_num
        cache = api_compile.create_compile_solver_cache()
        generator = api_compile.compile_solver_with_cache(
            sol, col, mkr_list, attr_list, withtest, cache)
        for action, vaction in generator:
            yield action, vaction

    # Solver root frames, breaking attributes into little blocks
    # to solve.
    root_mkr_list, non_root_mkr_list = _filter_mkr_list_by_frame_list(
        mkr_list, root_frame_list)
    if len(root_mkr_list) == 0:
        # TODO: Test we have enough markers to solve with, if not warn
        #  the user.
        # action = api_action.Action(func='pass', args=[], kwargs={})
        # vaction = api_action.Action(func='', args=[], kwargs={})
        # yield action, vaction
        LOG.warn("Not enough Markers given for root frames.")
        return
    if auto_attr_blocks is True:
        meta_mkr_list, meta_attr_list = _split_mkr_attr_into_categories(
            root_mkr_list, attr_list)
        for new_mkr_list, new_attr_list in zip(meta_mkr_list, meta_attr_list):
            sol = solverstep.SolverStep()
            sol.set_max_iterations(block_iter_num)
            sol.set_frame_list(root_frame_list)
            sol.set_attributes_use_animated(True)
            sol.set_attributes_use_static(True)
            sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
            sol.set_use_smoothness(False)
            sol.set_use_stiffness(False)
            sol.set_precomputed_data(precomputed_data)

            cache = api_compile.create_compile_solver_cache()
            generator = api_compile.compile_solver_with_cache(
                sol, col, new_mkr_list, new_attr_list, withtest, cache)
            for action, vaction in generator:
                yield action, vaction

    # TODO: Create a list of markers specially for root frames.
    #  Loop over all given markers, determine which markers have 2
    #  or more root frames, only use those markers for root frame
    #  computation. Overall, we must filter out all markers that
    #  cannot/should not be used for different solves.
    #
    # TODO: We must make sure to allow the solver to detect that
    #  not enough markers are being used, and warn the user.
    #
    # TODO: All markers that do not have enough root frames to solve
    #  correctly, but the Bundle is still in the solver, then it should
    #  be triangulated after the initial root frame solve is performed.
    #
    # TODO: Run the solver multiple times for a hierarchy. First,
    #  solve DAG level 0 nodes, then add DAG level 1, then level 2,
    #  etc. This will allow us to incrementally add solving of
    #  hierarchy, without getting the optimiser confused which
    #  attributes to solve first to get a stable solve.

    if root_frame_strategy == const.ROOT_FRAME_STRATEGY_GLOBAL_VALUE:
        # Global solve of root frames.
        sol = solverstep.SolverStep()
        sol.set_max_iterations(root_iter_num)
        sol.set_frame_list(root_frame_list)
        sol.set_attributes_use_animated(True)
        sol.set_attributes_use_static(True)
        sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
        sol.set_use_smoothness(False)
        sol.set_use_stiffness(False)
        sol.set_precomputed_data(precomputed_data)

        cache = api_compile.create_compile_solver_cache()
        generator = api_compile.compile_solver_with_cache(
            sol, col, root_mkr_list, attr_list, withtest, cache)
        for action, vaction in generator:
            yield action, vaction
    else:
        # Get the order of frames to solve with.
        batch_frame_list = []
        if root_frame_strategy == const.ROOT_FRAME_STRATEGY_FWD_PAIR_VALUE:
            # Two frames at a time, moving forward, plus a global solve
            # at the end.
            batch_frame_list = _gen_two_frame_fwd(root_frame_list_num)
            batch_frame_list.append(root_frame_list)
        elif root_frame_strategy == const.ROOT_FRAME_STRATEGY_FWD_PAIR_AND_GLOBAL_VALUE:
            # Two frames at a time, moving forward.
            batch_frame_list = _gen_two_frame_fwd(root_frame_list_num)
        else:
            # TODO: Root frame ordering can be determined by the
            #  count of markers available at each frame. After we
            #  have an ordering of these frames, we can solve the
            #  frames incrementally, starting with the first
            #  highest, then add the next highest, etc. This
            #  should ensure stability of the solver is maximum.
            raise NotImplementedError
        generator = _compile_multi_root_frames(col, mkr_list, attr_list,
                                               batch_frame_list, root_iter_num,
                                               precomputed_data, withtest,
                                               verbose)
        for action, vaction in generator:
            yield action, vaction

    # Clear out all the frames between the solved root frames, this
    # helps us use the new solve root frames to hint the 'in-between'
    # frame solve.
    generator = _compile_remove_inbetween_frames(attr_list,
                                                 non_root_frame_list,
                                                 start_frame, end_frame,
                                                 withtest, verbose)
    for action, vaction in generator:
        yield action, vaction
    if only_root_frames is True:
        return

    # Perform an euler filter on all unlocked rotation attributes.
    if use_euler_filter is True:
        generator = solverutils.compile_euler_filter(attr_list, withtest)
        for action, vaction in generator:
            yield action, vaction

    generator = _compile_multi_inbetween_frames(
        col,
        mkr_list,
        attr_list,
        all_frame_list,
        global_solve,
        anim_iter_num,
        precomputed_data,
        withtest,
        verbose,
    )
    for action, vaction in generator:
        yield action, vaction
    return
コード例 #9
0
def _compile_multi_inbetween_frames(col, mkr_list, attr_list, all_frame_list,
                                    global_solve, anim_iter_num,
                                    precomputed_data, withtest, verbose):
    """
    Solve only animated attributes on frames between the root frames.

    :param mkr_list:
        Markers to be solved with.
    :type mkr_list: [Marker, ..]

    :param attr_list:
        Attributes to be solved.
    :type attr_list: [Attribute, ..]

    :param all_frame_list:
        List of Frames to be solved.
    :type all_frame_list: [Frame, ..]

    :param global_solve:
        If True, all attributes and frames will be solved as a single
        solve, rather than one solve per-frame.
    :type global_solve: bool

    :param anim_iter_num:
        Number of iterations for solving animated attributes.
    :type anim_iter_num: int

    :param withtest:
        Should validation tests be generated?
    :type withtest: bool

    :param verbose:
        Print out more detail than usual.
    :type verbose: bool

    :return:
        Yields a generator of two Actions. First Action is for solving,
        the second Action is for validation of inputs.
    :rtype: (Action, Action)
    """
    if global_solve is True:
        # Do Global Solve with all frames.
        sol = solverstep.SolverStep()
        sol.set_max_iterations(anim_iter_num)
        sol.set_frame_list(all_frame_list)
        sol.set_attributes_use_animated(True)
        sol.set_attributes_use_static(True)
        sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
        sol.set_use_smoothness(False)
        sol.set_use_stiffness(False)
        sol.set_precomputed_data(precomputed_data)

        cache = api_compile.create_compile_solver_cache()
        generator = api_compile.compile_solver_with_cache(
            sol, col, mkr_list, attr_list, withtest, cache)
        for action, vaction in generator:
            yield action, vaction
    else:
        cache = api_compile.create_compile_solver_cache()
        for i, frm in enumerate(all_frame_list):
            is_first_frame = i == 0
            one_frame_list = [frm]
            sol = solverstep.SolverStep()
            sol.set_max_iterations(anim_iter_num)
            sol.set_frame_list(one_frame_list)
            sol.set_attributes_use_animated(True)
            sol.set_attributes_use_static(False)
            sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
            sol.set_use_smoothness(not is_first_frame)
            sol.set_use_stiffness(not is_first_frame)
            sol.set_precomputed_data(precomputed_data)

            generator = api_compile.compile_solver_with_cache(
                sol, col, mkr_list, attr_list, withtest, cache)
            for action, vaction in generator:
                yield action, vaction
    return
コード例 #10
0
def _compile_multi_root_frames(col, mkr_list, attr_list, batch_frame_list,
                               root_iter_num, precomputed_data, withtest,
                               verbose):
    """
    Compile actions for solving Root frames.

    :param mkr_list:
        List of Markers to use for Root frames.
    :type mkr_list: [Marker, ..]

    :param attr_list:
        List of Attributes to use for Root frames.
    :type attr_list: [Attribute, ..]

    :param batch_frame_list:
        List of frame lists to be computed successively.
    :type batch_frame_list: [[int, ..], ..]

    :param root_iter_num:
        Number of iterations to use, when solving root frames.
    :type root_iter_num: int

    :param withtest:
        Compile the test/validation Action, as well as the solve Action?
    :type withtest: bool

    :param verbose:
        Print out more detail to 'stderr'.
    :type verbose: bool

    :return:
        Yields two Actions at each iteration; first Action is for
        solving, second Action is to validate the inputs given.
    :rtype: (Action, Action or None)
    """
    # Solve root frames.
    for frm_list in batch_frame_list:
        # Get root markers
        root_mkr_list, non_root_mkr_list = _filter_mkr_list_by_frame_list(
            mkr_list, frm_list)
        assert len(root_mkr_list) > 0

        mkr_attr_map = markerutils.find_marker_attr_mapping(
            root_mkr_list, attr_list)
        root_attr_list = []
        for i, mkr in enumerate(root_mkr_list):
            for j, attr in enumerate(attr_list):
                x = mkr_attr_map[i][j]
                if x is True and attr not in root_attr_list:
                    root_attr_list.append(attr)

        sol = solverstep.SolverStep()
        sol.set_max_iterations(root_iter_num)
        sol.set_frame_list(frm_list)
        sol.set_attributes_use_animated(True)
        sol.set_attributes_use_static(True)
        sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
        sol.set_use_smoothness(False)
        sol.set_use_stiffness(False)
        sol.set_precomputed_data(precomputed_data)

        cache = api_compile.create_compile_solver_cache()
        generator = api_compile.compile_solver_with_cache(
            sol, col, root_mkr_list, root_attr_list, withtest, cache)
        for action, vaction in generator:
            yield action, vaction
        return
コード例 #11
0
def _compile_multi_inbetween_frames(col, mkr_list, attr_list, all_frame_list,
                                    global_solve, eval_complex_graphs,
                                    anim_iter_num, remove_unused_objects,
                                    precomputed_data, withtest, verbose):
    """
    Solve only animated attributes on frames between the root frames.

    :param mkr_list:
        Markers to be solved with.
    :type mkr_list: [Marker, ..]

    :param attr_list:
        Attributes to be solved.
    :type attr_list: [Attribute, ..]

    :param all_frame_list:
        List of Frames to be solved.
    :type all_frame_list: [Frame, ..]

    :param global_solve:
        If True, all attributes and frames will be solved as a single
        solve, rather than one solve per-frame.
    :type global_solve: bool

    :param eval_complex_graphs:
        If True, the solve will try to trigger evalation of complex
        node graphs (such as Mesh Rivets), by changing the timeEvalMode
        of the mmSolver command.
    :type eval_complex_graphs: bool

    :param anim_iter_num:
        Number of iterations for solving animated attributes.
    :type anim_iter_num: int

    :param remove_unused_objects:
        Should objects that are detected as 'unused' be removed from
        the solver?
    :type remove_unused_objects: bool

    :param withtest:
        Should validation tests be generated?
    :type withtest: bool

    :param verbose:
        Print out more detail than usual.
    :type verbose: bool

    :return:
        Yields a generator of two Actions. First Action is for solving,
        the second Action is for validation of inputs.
    :rtype: (Action, Action)
    """
    assert isinstance(global_solve, bool)
    assert isinstance(eval_complex_graphs, bool)
    assert isinstance(anim_iter_num, int)
    assert isinstance(remove_unused_objects, bool)
    assert isinstance(precomputed_data, dict)
    assert isinstance(withtest, bool)
    assert isinstance(verbose, bool)

    if global_solve is True:
        # Do Global Solve with all frames.
        sol = solverstep.SolverStep()
        sol.set_max_iterations(anim_iter_num)
        sol.set_frame_list(all_frame_list)
        sol.set_attributes_use_animated(True)
        sol.set_attributes_use_static(True)
        sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
        sol.set_use_smoothness(False)
        sol.set_use_stiffness(False)
        sol.set_remove_unused_markers(remove_unused_objects)
        sol.set_remove_unused_attributes(remove_unused_objects)
        sol.set_precomputed_data(precomputed_data)

        cache = api_compile.create_compile_solver_cache()
        generator = api_compile.compile_solver_with_cache(
            sol, col, mkr_list, attr_list, withtest, cache)
        for action, vaction in generator:
            yield action, vaction
    else:
        cache = api_compile.create_compile_solver_cache()
        for i, frm in enumerate(all_frame_list):
            is_first_frame = i == 0
            one_frame_list = [frm]
            time_eval_mode = const.TIME_EVAL_MODE_DEFAULT
            if eval_complex_graphs is True:
                time_eval_mode = const.TIME_EVAL_MODE_SET_TIME

            sol = solverstep.SolverStep()
            sol.set_max_iterations(anim_iter_num)
            sol.set_frame_list(one_frame_list)
            sol.set_attributes_use_animated(True)
            sol.set_attributes_use_static(False)
            sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
            sol.set_use_smoothness(not is_first_frame)
            sol.set_use_stiffness(not is_first_frame)
            sol.set_remove_unused_markers(remove_unused_objects)
            sol.set_remove_unused_attributes(remove_unused_objects)
            sol.set_time_eval_mode(time_eval_mode)
            sol.set_precomputed_data(precomputed_data)

            generator = api_compile.compile_solver_with_cache(
                sol, col, mkr_list, attr_list, withtest, cache)
            for action, vaction in generator:
                yield action, vaction
    return
コード例 #12
0
def _compile_multi_frame(mkr_list,
                         attr_list,
                         root_frame_list,
                         frame_list,
                         auto_attr_blocks,
                         block_iter_num,
                         only_root_frames,
                         root_iter_num,
                         anim_iter_num,
                         global_solve,
                         root_frame_strategy,
                         triangulate_bundles,
                         test,
                         verbose):
    assert len(root_frame_list) >= 2
    assert len(frame_list) >= 2
    root_frame_list_num = [x.get_number() for x in root_frame_list]
    frame_list_num = [x.get_number() for x in frame_list]
    non_root_frame_list_num = set(frame_list_num) - set(root_frame_list_num)
    non_root_frame_list = [frame.Frame(x) for x in non_root_frame_list_num]

    all_frame_list_num = list(set(frame_list_num + root_frame_list_num))
    all_frame_list_num = list(sorted(all_frame_list_num))
    all_frame_list = [frame.Frame(x) for x in all_frame_list_num]
    start_frame = all_frame_list[0]
    end_frame = all_frame_list[-1]

    # 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.
    if triangulate_bundles is True:
        sol = solvertriangulate.SolverTriangulate()
        # sol.root_frame_list = root_frame_list_num
        cache = api_compile.create_compile_solver_cache()
        generator = api_compile.compile_solver_with_cache(
            sol, mkr_list, attr_list, test, cache
        )
        for action, vaction in generator:
            yield action, vaction

    # Solver root frames, breaking attributes into little blocks
    # to solve.
    root_mkr_list, non_root_mkr_list = _filter_mkr_list_by_frame_list(
        mkr_list,
        root_frame_list
    )
    if auto_attr_blocks is True:
        meta_mkr_list, meta_attr_list = _split_mkr_attr_into_categories(
            root_mkr_list,
            attr_list
        )
        for new_mkr_list, new_attr_list in zip(meta_mkr_list, meta_attr_list):
            sol = solverstep.SolverStep()
            sol.set_verbose(verbose)
            sol.set_max_iterations(block_iter_num)
            sol.set_frame_list(root_frame_list)
            sol.set_attributes_use_animated(True)
            sol.set_attributes_use_static(True)
            sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)

            cache = api_compile.create_compile_solver_cache()
            generator = api_compile.compile_solver_with_cache(
                sol, new_mkr_list, new_attr_list, test, cache
            )
            for action, vaction in generator:
                yield action, vaction

    # TODO: Create a list of markers specially for root frames.
    #  Loop over all given markers, determine which markers have 2
    #  or more root frames, only use those markers for root frame
    #  computation. Overall, we must filter out all markers that
    #  cannot/should not be used for different solves.
    #
    # TODO: We must make sure to allow the solver to detect that
    #  not enough markers are being used, and warn the user.
    #
    # TODO: All markers that do not have enough root frames to solve
    #  correctly, but the Bundle is still in the solver, then it should
    #  be triangulated after the initial root frame solve is performed.
    #
    # TODO: Run the solver multiple times for a hierarchy. First,
    #  solve DAG level 0 nodes, then add DAG level 1, then level 2,
    #  etc. This will allow us to incrementally add solving of
    #  hierarchy, without getting the optimiser confused which
    #  attributes to solve first to get a stable solve.

    if root_frame_strategy == const.ROOT_FRAME_STRATEGY_GLOBAL_VALUE:
        # Global solve of root frames.
        sol = solverstep.SolverStep()
        sol.set_verbose(verbose)
        sol.set_max_iterations(root_iter_num)
        sol.set_frame_list(root_frame_list)
        sol.set_attributes_use_animated(True)
        sol.set_attributes_use_static(True)
        sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)

        cache = api_compile.create_compile_solver_cache()
        generator = api_compile.compile_solver_with_cache(
            sol, root_mkr_list, attr_list, test, cache
        )
        for action, vaction in generator:
            yield action, vaction
    else:
        # Get the order of frames to solve with.
        batch_frame_list = []
        if root_frame_strategy == const.ROOT_FRAME_STRATEGY_FWD_PAIR_VALUE:
            # Two frames at a time, moving forward, plus a global solve
            # at the end.
            batch_frame_list = _gen_two_frame_fwd(root_frame_list_num)
            batch_frame_list.append(root_frame_list)
        elif root_frame_strategy == const.ROOT_FRAME_STRATEGY_FWD_PAIR_AND_GLOBAL_VALUE:
            # Two frames at a time, moving forward.
            batch_frame_list = _gen_two_frame_fwd(root_frame_list_num)
        else:
            # TODO: Root frame ordering can be determined by the
            #  count of markers available at each frame. After we
            #  have an ordering of these frames, we can solve the
            #  frames incrementally, starting with the first
            #  highest, then add the next highest, etc. This
            #  should ensure stability of the solver is maximum.
            raise NotImplementedError
        generator = _compile_multi_root_frames(
            mkr_list,
            attr_list,
            batch_frame_list,
            root_iter_num,
            test,
            verbose
        )
        for action, vaction in generator:
            yield action, vaction

    # Clear out all the frames between the solved root frames, this
    # helps us use the new solve root frames to hint the 'in-between'
    # frame solve.
    generator = _compile_remove_inbetween_frames(
        attr_list,
        non_root_frame_list,
        start_frame,
        end_frame,
        test,
        verbose
    )
    for action, vaction in generator:
        yield action, vaction
    if only_root_frames is True:
        return

    generator = _compile_multi_inbetween_frames(
        mkr_list,
        attr_list,
        all_frame_list,
        global_solve,
        anim_iter_num,
        test,
        verbose,
    )
    for action, vaction in generator:
        yield action, vaction
    return
コード例 #13
0
    def compile(self, col, mkr_list, attr_list, withtest=False):
        assert isinstance(withtest, bool)

        # Options to affect how the solve is constructed.
        use_single_frame = self.get_use_single_frame()
        single_frame = self.get_single_frame()
        frame_list = self.get_frame_list()
        anim_iter_num = self.get_anim_iteration_num()
        lineup_iter_num = self.get_lineup_iteration_num()
        use_euler_filter = self._use_euler_filter
        eval_object_relationships = self.get_eval_object_relationships()
        remove_unused_objects = eval_object_relationships
        eval_complex_graphs = self.get_eval_complex_graphs()
        precomputed_data = self.get_precomputed_data()

        # Pre-calculate the 'affects' relationship.
        if eval_object_relationships is True:
            generator = solverutils.compile_solver_affects(
                col, mkr_list, attr_list, precomputed_data, withtest)
            for action, vaction in generator:
                yield action, vaction
        else:
            generator = solverutils.compile_reset_used_hints(
                col, mkr_list, attr_list)
            for action, vaction in generator:
                yield action, vaction

        if use_single_frame is True:
            # Single frame solve
            sol = solverstep.SolverStep()
            sol.set_max_iterations(lineup_iter_num)
            sol.set_frame_list([single_frame])
            sol.set_attributes_use_animated(True)
            sol.set_attributes_use_static(False)
            sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
            sol.set_use_smoothness(False)
            sol.set_use_stiffness(False)
            sol.set_remove_unused_markers(remove_unused_objects)
            sol.set_remove_unused_attributes(remove_unused_objects)
            sol.set_precomputed_data(precomputed_data)
            for action, vaction in sol.compile(col,
                                               mkr_list,
                                               attr_list,
                                               withtest=withtest):
                yield action, vaction
        else:
            # Multiple frame solve, per-frame
            vaction_cache = api_compile.create_compile_solver_cache()
            for i, frm in enumerate(frame_list):
                is_first_frame = i == 0
                one_frame_list = [frm]
                time_eval_mode = const.TIME_EVAL_MODE_DEFAULT
                if eval_complex_graphs is True:
                    time_eval_mode = const.TIME_EVAL_MODE_SET_TIME

                sol = solverstep.SolverStep()
                sol.set_max_iterations(anim_iter_num)
                sol.set_frame_list(one_frame_list)
                sol.set_attributes_use_animated(True)
                sol.set_attributes_use_static(False)
                sol.set_auto_diff_type(const.AUTO_DIFF_TYPE_FORWARD)
                sol.set_use_smoothness(not is_first_frame)
                sol.set_use_stiffness(not is_first_frame)
                sol.set_time_eval_mode(time_eval_mode)
                sol.set_remove_unused_markers(remove_unused_objects)
                sol.set_remove_unused_attributes(remove_unused_objects)
                sol.set_precomputed_data(precomputed_data)

                generator = api_compile.compile_solver_with_cache(
                    sol, col, mkr_list, attr_list, withtest, vaction_cache)
                for action, vaction in generator:
                    yield action, vaction

            # Perform an euler filter on all unlocked rotation attributes.
            if use_euler_filter is True:
                generator = solverutils.compile_euler_filter(
                    attr_list, withtest)
                for action, vaction in generator:
                    yield action, vaction

        return