Esempio n. 1
0
def _gen_two_frame_fwd(int_list):
    """
    Given a list of integers, create list of Frame pairs, moving
    though the original list in a forward direction.

    :param int_list: List of frame numbers.
    :type int_list: List of int

    :returns: List of integer pairs.
    :rtype: [[int, int], ...]
    """
    if len(int_list) == 1:
        num = int_list[0]
        batch_list = [[frame.Frame(num), frame.Frame(num)]]
        return batch_list
    end = len(int_list) - 1
    batch_list = []
    for i in range(end):
        s = i
        e = i + 2
        tmp_list = int_list[s:e]
        frm_list = []
        for j, num in enumerate(tmp_list):
            frm = frame.Frame(num)
            frm_list.append(frm)
        batch_list.append(frm_list)
    return batch_list
Esempio n. 2
0
    def test_set_data(self):
        f1 = frame.Frame(10)
        f1_data = f1.get_data()

        f2 = frame.Frame(3147)
        f2.set_data(f1_data)
        f2_data = f2.get_data()
        self.assertEqual(f1_data, f2_data)
    def test_is_valid(self):
        """
        Collection validation.
        Once all pieces are connected, the collection is valid.
        """
        x = collection.Collection()
        x.create_node('myCollection')
        self.assertFalse(x.is_valid())

        # Solver
        sol = solver.Solver()
        x.add_solver(sol)
        self.assertFalse(x.is_valid())

        # Solver (with frame)
        f = frame.Frame(1)
        sol.add_frame(f)
        self.assertFalse(x.is_valid())

        # Marker / Bundle
        cam_tfm = maya.cmds.createNode('transform', name='camera1')
        cam_shp = maya.cmds.createNode('camera', name='cameraShape1')
        cam = camera.Camera(shape=cam_shp)
        bnd = bundle.Bundle().create_node()
        mkr = marker.Marker().create_node(cam=cam, bnd=bnd)
        x.add_marker(mkr)
        self.assertFalse(x.is_valid())

        # Attribute
        node = bnd.get_node()
        attr = attribute.Attribute(node=node, attr='translateX')
        x.add_attribute(attr)
        self.assertTrue(x.is_valid())
Esempio n. 4
0
    def test_set_tags(self):
        f = frame.Frame(10)
        f.set_tags(['tag'])
        self.assertEqual(f.get_tags(), ['tag'])

        f.set_tags([])
        self.assertEqual(f.get_tags(), [])
Esempio n. 5
0
    def test_set_number(self):
        f1 = frame.Frame(10)
        f1.set_number(3147)
        self.assertEqual(f1.get_number(), 3147)

        f1.set_number(24)
        self.assertEqual(f1.get_number(), 24)
Esempio n. 6
0
 def get_single_frame(self):
     value = self._data.get('single_frame',
                            const.SOLVER_STD_SINGLE_FRAME_DEFAULT_VALUE)
     frm = None
     if value is not None:
         frm = frame.Frame(value)
     return frm
Esempio n. 7
0
    def test_add_tag(self):
        f = frame.Frame(10)
        f.add_tag('primary')
        self.assertEqual(f.get_tags(), ['normal', 'primary'])

        f.set_tags([])
        f.add_tag('tag')
        self.assertEqual(f.get_tags(), ['tag'])
Esempio n. 8
0
    def test_init(self):
        f1 = frame.Frame(10)
        self.assertIs(f1.get_number(), 10)

        f2 = frame.Frame(10.0)
        self.assertIs(f2.get_number(), 10.0)

        self.assertRaises(AssertionError, frame.Frame, 'string')
        self.assertRaises(AssertionError, frame.Frame, None)

        f3 = frame.Frame(10.0)
        self.assertEqual(f3.get_tags(), ['normal'])

        f4 = frame.Frame(10.0, primary=True)
        self.assertEqual(f4.get_tags(), ['primary'])

        f5 = frame.Frame(10.0, secondary=True)
        self.assertEqual(f5.get_tags(), ['secondary'])
Esempio n. 9
0
    def get_single_frame(self):
        """
        Get Single Frame value.

        :rtype: Frame or None
        """
        value = self._data.get('single_frame',
                               const.SOLVER_STD_SINGLE_FRAME_DEFAULT_VALUE)
        frm = None
        if value is not None:
            frm = frame.Frame(value)
        return frm
Esempio n. 10
0
    def get_frame_list(self):
        """
        Get frame objects attached to the solver.

        :return: frame objects.
        :rtype: list of frame.Frame
        """
        frame_list_data = self._data.get('frame_list')
        if frame_list_data is None:
            return []
        frm_list = []
        for f in frame_list_data:
            frm = frame.Frame(0)
            frm.set_data(f)  # Override the frame number
            frm_list.append(frm)
        return frm_list
Esempio n. 11
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
Esempio n. 12
0
 def get_frame_list(self):
     return [frame.Frame(1)]
Esempio n. 13
0
    def test_get_tags(self):
        f = frame.Frame(10, primary=False)
        self.assertEqual(f.get_tags(), ['normal'])

        f = frame.Frame(10, primary=True)
        self.assertEqual(f.get_tags(), ['primary'])
Esempio n. 14
0
    def test_get_number(self):
        f1 = frame.Frame(10)
        self.assertIs(f1.get_number(), 10)

        f2 = frame.Frame(10.0)
        self.assertIs(f2.get_number(), 10.0)
Esempio n. 15
0
    def test_get_data(self):
        f1 = frame.Frame(10)
        self.assertEqual(f1.get_data(), {'number': 10, 'tags': ['normal']})

        f2 = frame.Frame(10.0, tags=['myTag'])
        self.assertEqual(f2.get_data(), {'number': 10, 'tags': ['myTag']})
Esempio n. 16
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