示例#1
0
def _union_sequence(images):
    if not images:
        return None
    rng = image_range(images[0])
    seq = Sequence.create(*rng)
    for image in images[1:]:
        rng = image_range(image)
        other = Sequence.create(*rng)
        seq = seq.union(other)
    return seq
 def test_glob_dedups_when_many_files_match(self):
     glob.populate(Sequence.create("1-20").expand("/some/file.####.exr"))
     d = PathList()
     files = ["/some/file.*.exr", "/some/*.exr"]
     d.add(*files)
     d.glob()
     self.assertEqual(len(d), 20)
 def test_glob_when_files_match_with_questoion_mark(self):
     glob.populate(Sequence.create("1-20").expand("/some/file.####.exr"))
     d = PathList()
     file = "/some/file.00?0.exr"
     d.add(file)
     d.glob()
     self.assertEqual(len(d), 2)
 def test_self_glob_when_files_match(self):
     glob.populate(Sequence.create("1-20").expand("/some/file.####.exr"))
     d = DependencyList()
     file = "/some/file.*.exr"
     d.add(file, must_exist=False)
     d.glob()
     self.assertEqual(len(d), 20)
 def test_glob_when_files_dont_match(self):
     glob.populate(Sequence.create("1-20").expand("/other/file.####.exr"))
     d = PathList()
     file = "/some/file.*.exr"
     d.add(file)
     d.glob()
     self.assertEqual(len(d), 0)
示例#6
0
    def test_two_the_same_substitution(self):

        template = "/path/%(frame)d/image.%(frame)04d.tif"
        result = list(Sequence.permutations(template, frame="0-20x2"))
        self.assertIn("/path/8/image.0008.tif", result)
        self.assertIn("/path/12/image.0012.tif", result)
        self.assertEqual(len(result), 11)
示例#7
0
def scout_frame_sequence(node):
    """Generate Sequence from value in scout_frames parm."""
    try:
        spec = node.parm("scout_frames").eval()
        return Sequence.create(spec)
    except (ValueError, TypeError):
        return None
 def test_counts_from_1_to_10(self):
     s = Sequence.create("1-10")
     ss = s.subsample(1)
     self.assertEqual(len(ss), 1)
     self.assertEqual(list(ss), [6])
     ss = s.subsample(2)
     self.assertEqual(len(ss), 2)
     self.assertEqual(list(ss), [3, 8])
     ss = s.subsample(3)
     self.assertEqual(len(ss), 3)
     self.assertEqual(list(ss), [2, 6, 9])
     ss = s.subsample(4)
     self.assertEqual(len(ss), 4)
     self.assertEqual(list(ss), [2, 4, 7, 9])
     ss = s.subsample(5)
     self.assertEqual(len(ss), 5)
     self.assertEqual(list(ss), [2, 4, 6, 8, 10])
     ss = s.subsample(6)
     self.assertEqual(len(ss), 6)
     self.assertEqual(list(ss), [1, 3, 5, 6, 8, 10])
     ss = s.subsample(7)
     self.assertEqual(len(ss), 7)
     self.assertEqual(list(ss), [1, 3, 4, 6, 7, 8, 10])
     ss = s.subsample(8)
     self.assertEqual(len(ss), 8)
     self.assertEqual(list(ss), [1, 2, 4, 5, 6, 7, 9, 10])
     ss = s.subsample(9)
     self.assertEqual(len(ss), 9)
     self.assertEqual(list(ss), [1, 2, 3, 4, 6, 7, 8, 9, 10])
     ss = s.subsample(10)
     self.assertEqual(len(ss), 10)
     self.assertEqual(list(ss), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
     ss = s.subsample(11)
     self.assertEqual(len(ss), 10)
     self.assertEqual(list(ss), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
示例#9
0
 def test_resolve_one_template_to_many_filenames(self):
     s = Sequence.create("1-5")
     template = "image.{frame:02d}.exr"
     result = s.expand_dollar_f(template)
     self.assertEqual(len(result), 5)
     self.assertIn("image.02.exr", result)
     self.assertIn("image.05.exr", result)
示例#10
0
    def _get_sources(self):
        """
        Get the images/layers, along with associated Sequence objects.

        If we are not rendering a custom range, then the sequence for
        each image may be different.

        Returns:
            list of dict: elements contain an image along with the Sequence that
            represents the image range.
        """

        images = ix.api.OfObjectArray()
        self.node.get_attribute("images_and_layers").get_values(images)

        use_custom = self.node.get_attribute("use_custom_frames").get_bool()

        # cast to list because OfObjectArray is true even when empty.
        if not list(images):
            ix.log_error(
                "No render images. Please reference one or more image items")
        seq = self.sequence["main"]
        result = []
        for image in images:
            if not use_custom:
                seq = Sequence.create(*frames_ui.image_range(image))
            result.append({"image": image, "sequence": seq})
        return result
示例#11
0
def scout_frame_sequence(obj):
    """Generate Sequence from value in scout_frames attribute."""
    try:
        spec = obj.get_attribute("scout_frames").get_string()
        return Sequence.create(spec)
    except (ValueError, TypeError):
        return None
示例#12
0
 def test_counts_from_1_to_10(self):
     s = Sequence.create("1-10")
     ss = s.subsample(1)
     self.assertEqual(len(ss), 1)
     self.assertEqual(list(ss), [6])
     ss = s.subsample(2)
     self.assertEqual(len(ss), 2)
     self.assertEqual(list(ss), [3, 8])
     ss = s.subsample(3)
     self.assertEqual(len(ss), 3)
     self.assertEqual(list(ss), [2, 6, 9])
     ss = s.subsample(4)
     self.assertEqual(len(ss), 4)
     self.assertEqual(list(ss), [2, 4, 7, 9])
     ss = s.subsample(5)
     self.assertEqual(len(ss), 5)
     self.assertEqual(list(ss), [2, 4, 6, 8, 10])
     ss = s.subsample(6)
     self.assertEqual(len(ss), 6)
     self.assertEqual(list(ss), [1, 3, 5, 6, 8, 10])
     ss = s.subsample(7)
     self.assertEqual(len(ss), 7)
     self.assertEqual(list(ss), [1, 3, 4, 6, 7, 8, 10])
     ss = s.subsample(8)
     self.assertEqual(len(ss), 8)
     self.assertEqual(list(ss), [1, 2, 4, 5, 6, 7, 9, 10])
     ss = s.subsample(9)
     self.assertEqual(len(ss), 9)
     self.assertEqual(list(ss), [1, 2, 3, 4, 6, 7, 8, 9, 10])
     ss = s.subsample(10)
     self.assertEqual(len(ss), 10)
     self.assertEqual(list(ss), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
     ss = s.subsample(11)
     self.assertEqual(len(ss), 10)
     self.assertEqual(list(ss), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    def test_two_the_same_substitution(self):

        template = "/path/%(frame)d/image.%(frame)04d.tif"
        result = list(Sequence.permutations(template, frame="0-20x2"))
        self.assertIn("/path/8/image.0008.tif", result)
        self.assertIn("/path/12/image.0012.tif", result)
        self.assertEqual(len(result), 11)
    def test_one_substitution(self):

        template = "image.%(frame)04d.tif"
        result = list(Sequence.permutations(template, frame="0-20x2"))
        self.assertIn("image.0008.tif", result)
        self.assertIn("image.0012.tif", result)
        self.assertEqual(len(result), 11)
示例#15
0
    def test_one_substitution(self):

        template = "image.%(frame)04d.tif"
        result = list(Sequence.permutations(template, frame="0-20x2"))
        self.assertIn("image.0008.tif", result)
        self.assertIn("image.0012.tif", result)
        self.assertEqual(len(result), 11)
示例#16
0
 def test_three_substitutions(self):
     template = "image_%(uval)02d_%(vval)02d.%(frame)04d.tif"
     kw = {"uval": "1-2", "vval": "1-2", "frame": "10-11"}
     result = list(Sequence.permutations(template, **kw))
     self.assertIn("image_01_01.0010.tif", result)
     self.assertIn("image_02_02.0011.tif", result)
     self.assertIn("image_02_01.0010.tif", result)
     self.assertEqual(len(result), 8)
 def test_chunk_count(self):
     s = Sequence.create("1-100")
     s.chunk_size = 7
     self.assertEqual(s.chunk_count(), 15)
     s.chunk_size = 15
     self.assertEqual(s.chunk_count(), 7)
     s.chunk_size = 10
     self.assertEqual(s.chunk_count(), 10)
示例#18
0
 def test_best_chunk_size(self):
     s = Sequence.create("1-100")
     s.chunk_size = 76
     self.assertEqual(s.best_chunk_size(), 50)
     s.chunk_size = 37
     self.assertEqual(s.best_chunk_size(), 34)
     s.chunk_size = 100
     self.assertEqual(s.best_chunk_size(), 100)
 def test_best_chunk_size(self):
     s = Sequence.create("1-100")
     s.chunk_size = 76
     self.assertEqual(s.best_chunk_size(), 50)
     s.chunk_size = 37
     self.assertEqual(s.best_chunk_size(), 34)
     s.chunk_size = 100
     self.assertEqual(s.best_chunk_size(), 100)
示例#20
0
 def test_chunk_count(self):
     s = Sequence.create("1-100")
     s.chunk_size = 7
     self.assertEqual(s.chunk_count(), 15)
     s.chunk_size = 15
     self.assertEqual(s.chunk_count(), 7)
     s.chunk_size = 10
     self.assertEqual(s.chunk_count(), 10)
    def test_include_parts_of_sequence_that_exist(self):
        seq = Sequence.create("96-105")
        result = [
            f for f in dependency_scan.fetch(
                self.node, seq, 3) if f.startswith("/path/to/shader3")]

        self.assertIn("/path/to/shader3/tex.0097.jpg", result)
        self.assertEqual(len(result), 5)
 def test_create_chunks_cycle(self):
     s = Sequence.create("1-100")
     s.chunk_size = 10
     s.chunk_strategy = "cycle"
     chunks = s.chunks()
     self.assertEqual(list(chunks[0]), list(range(1, 100, 10)))
     s.chunk_size = 7
     chunks = s.chunks()
     self.assertEqual(list(chunks[0]), list(range(1, 100, 15)))
示例#23
0
 def test_create_chunks_cycle(self):
     s = Sequence.create("1-100")
     s.chunk_size = 10
     s.chunk_strategy = "cycle"
     chunks = s.chunks()
     self.assertEqual(list(chunks[0]), list(range(1, 100, 10)))
     s.chunk_size = 7
     chunks = s.chunks()
     self.assertEqual(list(chunks[0]), list(range(1, 100, 15)))
示例#24
0
    def test_include_parts_of_sequence_that_exist(self):
        seq = Sequence.create("96-105")
        result = [
            f for f in dependency_scan.fetch(self.node, seq, 3)
            if f.startswith("/path/to/shader3")
        ]

        self.assertIn("/path/to/shader3/tex.0097.jpg", result)
        self.assertEqual(len(result), 5)
示例#25
0
 def test_resolve_many_templates_to_many_filenames(self):
     s = Sequence.create("1-3")
     templates = [
         "/folder_1/image.$2F.exr", "/folder_2/image.$2F.exr",
         "/folder_3/image.$2F.exr"
     ]
     result = s.expand_dollar_f(*templates)
     self.assertEqual(len(result), 3)
     self.assertIn("/folder_2/image.02.exr", result)
     self.assertIn("/folder_3/image.03.exr", result)
示例#26
0
def initialize(data):
    """Generate list of files from fixture data."""
    global FILES
    for item in data["files"]:
        if item.get("params"):
            for fn in Sequence.permutations(item["path"], **item["params"]):
                FILES.append(fn)
        else:
            FILES.append(item["path"])
    FILES = sorted(set(FILES))
def _attribute_sequence(attr, **kw):
    """Get the sequence associated with a filename attribute.

    Many attributes have an associated sequence_mode attribute, which
    when set to 1 signifies varying frames, and makes availabel start,
    end, and offset attributes to help specify the sequence.

    If the keyword intersector is given, then work out the intersection
    with it. Why? Because during dependency scanning, we can optimize
    the number of frames to upload if we use only those frames specified
    in the sequence attribute, and intersect them with the frame range
    specified in the job node.
    """
    intersector = kw.get("intersector")

    obj = attr.get_parent_object()
    mode_attr = obj.attribute_exists("sequence_mode")
    if not (mode_attr and mode_attr.get_long()):
        ix.log_error("Attribute is not a sequence mode")

    global_frame_rate = ix.application.get_prefs(
        ix.api.AppPreferences.MODE_APPLICATION).get_long_value(
            "animation", "frames_per_second")
    attr_frame_rate = obj.get_attribute("frame_rate").get_long()
    if not attr_frame_rate == global_frame_rate:
        ix.log_error(
            "Can't get attribute sequence when global \
            fps is different from fps on the attribute")

    start = obj.get_attribute("start_frame").get_long()
    end = obj.get_attribute("end_frame").get_long()



    if intersector:
        # If there's a frame offset on the attribute, then we need to 
        # do the intersection in the context of that offset.
        offset = obj.get_attribute("frame_offset").get_long()
        return Sequence.create(start, end, 1).offset(
            offset).intersection(intersector).offset(-offset)

    return Sequence.create(start, end, 1)
示例#28
0
def range_frame_sequence(node):
    """Generate Sequence from value in the standard range parmTuple."""
    try:
        chunk = _chunk_parameters(node)
        start, end, step = node.parmTuple("fs").eval()
        return Sequence.create(
            start, end, step,
            chunk_size=chunk["size"],
            chunk_strategy=chunk["strategy"])
    except (ValueError, TypeError):
        return None
示例#29
0
def custom_frame_sequence(obj):
    """Generate Sequence from the value in custom_frames attribute."""
    try:

        spec = obj.get_attribute("custom_frames").get_string()
        seq = Sequence.create(
            spec, chunk_size=obj.get_attribute("chunk_size").get_long()
        )
        return seq
    except (ValueError, TypeError):
        return None
示例#30
0
def _union_sequence(images):
    """
    Computes the Sequence that is the union of frame ranges of all provided
    images.

    Args:
        images (list of OfObject): The images to consider.

    Returns:
        Sequence: The union Sequence.
    """
    if not images:
        return None
    rng = image_range(images[0])
    seq = Sequence.create(*rng)
    for image in images[1:]:
        rng = image_range(image)
        other = Sequence.create(*rng)
        seq = seq.union(other)
    return seq
示例#31
0
def custom_frame_sequence(node):
    """Generate Sequence from value in custom_range parm."""
    try:
        spec = node.parm("custom_range").eval()
        chunk = _chunk_parameters(node)
        return Sequence.create(
            spec,
            chunk_size=chunk["size"],
            chunk_strategy=chunk["strategy"]
        )
    except (ValueError, TypeError):
        return None
示例#32
0
def validate_scout_range(node, **_):
    """Set valid tickmark for scout range spec.

    TODO Currently we only validate that the spec produces
    valid frames. We should also validate that at least one
    scout frame exist in the main frame range.
    """
    takes.enable_for_current(node, "scout_valid")
    spec = node.parm("scout_frames").eval()
    valid = Sequence.is_valid_spec(spec)
    node.parm("scout_valid").set(valid)
    update_frame_stats_message(node)
 def test_three_substitutions(self):
     template = "image_%(uval)02d_%(vval)02d.%(frame)04d.tif"
     kw = {
         "uval": "1-2",
         "vval": "1-2",
         "frame": "10-11"
     }
     result = list(Sequence.permutations(template, **kw))
     self.assertIn("image_01_01.0010.tif", result)
     self.assertIn("image_02_02.0011.tif", result)
     self.assertIn("image_02_01.0010.tif", result)
     self.assertEqual(len(result), 8)
示例#34
0
def scout_frame_sequence(obj):
    """
    Generate Sequence from value in scout_frames attribute.

    Args:
        obj (ConductorJob): Item whose attribute to get parameters from.

    Returns:
        Sequence: Sequence that represents scout frames.
    """
    try:
        spec = obj.get_attribute("scout_frames").get_string()
        return Sequence.create(spec)
    except (ValueError, TypeError):
        return None
示例#35
0
    def _get_sequence(self):
        """Create the sequence object.

        In a simulation job, there is no need to duplicate the frame
        range section in the conductor::job node. Therefore it is
        hidden, and instead the frame range comes directly from the
        driver node. Scout frames will be None.
        """
        start, end, step = [
            self._source["node"].parm(parm).eval() for parm in [
                'f1', 'f2', 'f3']
        ]
        sequence = Sequence.create(start, end, step)

        return {
            "main": sequence,
            "scout": None
        }
示例#36
0
def validate_custom_range(node, **_):
    """Set valid tickmark for custom range spec.

    A custom range is valid when it is a comma separated
    list of arithmetic progressions. These can can be
    formatted as single numbers or ranges with a hyphen and
    optionally a step value delimited by an x. Example,
    1,7,10-20,30-60x3,1001, Spaces and trailing commas are
    allowed, but not letters or other non numeric
    characters.
    """
    takes.enable_for_current(node, "custom_valid")
    spec = node.parm("custom_range").eval()
    valid = Sequence.is_valid_spec(spec)
    node.parm("custom_valid").set(valid)

    update_frame_stats_message(node)
    uistate.update_button_state(node)
示例#37
0
def custom_frame_sequence(obj):
    """
    Generates the custom_frames sequence.

    Returns:
        Sequence: A Sequence object that represents the value in custom_frames.
        It may be a comma-separated list of progressions. Example
        1,7,10-20,30-60x3,1001.
    """
    try:

        spec = obj.get_attribute("custom_frames").get_string()
        seq = Sequence.create(
            spec, chunk_size=obj.get_attribute("chunk_size").get_long()
        )
        return seq
    except (ValueError, TypeError):
        return None
示例#38
0
def initialize(data):
    """Generate nodes, types, and files from fixture data."""
    global NODES
    global NODE_TYPES
    global FILES
    global GVARS

    GVARS.update(data["gvars"])

    type_names = list(set([n["type"] for n in data["nodes"]]))
    for t in type_names:
        NODE_TYPES[t] = NodeType(t)

    for item in data["nodes"]:
        NODES[item["name"]] = Node(item)

    for item in data["files"]:
        if item.get("params"):
            for fn in Sequence.permutations(item["path"], **item["params"]):
                FILES.append({"path": fn, "type": item["type"]})
        else:
            FILES.append(item)
示例#39
0
    def _get_sources(self):
        """Get the images, along with associated Sequence objects.

        If we are not rendering a custom range, then the sequence for
        each image may be different.
        """

        images = ix.api.OfObjectArray()
        self.node.get_attribute("images").get_values(images)

        use_custom = self.node.get_attribute("use_custom_frames").get_bool()

        # cast to list because OfObjectArray is true even when empty.
        if not list(images):
            ix.log_error(
                "No render images. Please reference one or more image items")
        seq = self.sequence["main"]
        result = []
        for image in images:
            if not use_custom:
                seq = Sequence.create(*frames_ui.image_range(image))
            result.append({"image": image, "sequence": seq})
        return result
 def test_create_from_start_end_strings(self):
     s = Sequence.create("1-5")
     self.assertEqual(s.start, 1)
     self.assertEqual(s.end, 5)
     self.assertEqual(s.step, 1)
 def test_spec_range(self):
      s = Sequence.create( 0, 10 )
      self.assertEqual(s.to(":","%",";"), "0:10")
 def test_spec_step_range(self):
      s = Sequence.create(1, 9, 2)
      self.assertEqual(s.to(":","%",";"), "1:9%2")
 def test_complex_add_spaces(self):
      s = Sequence.create( "1-10, 14, 20-48x4")
      self.assertEqual(s.to(":","%","; "), "1:10; 14; 20:48%4")
 def test_is_progression_method(self):
     s = Sequence.create([1, 3, 5, 7, 9])
     self.assertTrue(s.is_progression())
     s = Sequence.create([1, 3, 5, 7, 9, 10])
     self.assertFalse(s.is_progression())
 def test_negative_number(self):
     with self.assertRaises(ValueError):
         Sequence.create(-1)
 def test_negative_end(self):
     with self.assertRaises(ValueError):
         Sequence.create(1, -10, 1)
 def test_negative_step(self):
     with self.assertRaises(ValueError):
         Sequence.create(1, 10, -1)
 def test_negative_end_str(self):
     with self.assertRaises(ValueError):
         Sequence.create("10--30")
 def test_bad_spec(self):
     with self.assertRaises(ValueError):
         Sequence.create("f")
 def test_bad_spec_step(self):
     with self.assertRaises(ValueError):
         Sequence.create("1-10xf")
 def test_create_from_start_only(self):
     s = Sequence.create(1)
     self.assertEqual(s.start, 1)
     self.assertEqual(s.end, 1)
     self.assertEqual(s.step, 1)
 def test_create_from_start_end_ints(self):
     s = Sequence.create(1, 5)
     self.assertEqual(s.start, 1)
     self.assertEqual(s.end, 5)
     self.assertEqual(s.step, 1)
 def setUp(self):
     self.seq = Sequence.create("1-10")
     self.node = hou.node("job1")