Support UDIM images
This commit is contained in:
parent
4ebd535b5f
commit
843c34c3c0
@ -3,6 +3,10 @@
|
||||
This file logs the changes that are actually interesting to users (new features,
|
||||
changed functionality, fixed bugs).
|
||||
|
||||
# Version 1.11 (in development)
|
||||
|
||||
- Support UDIM images.
|
||||
|
||||
# Version 1.10 (2022-02-03)
|
||||
|
||||
- Avoid doubly-compressing ZStandard (Blender 3) compressed files.
|
||||
|
||||
@ -32,6 +32,7 @@ SEQ_TYPE_EFFECT = 8
|
||||
IMA_SRC_FILE = 1
|
||||
IMA_SRC_SEQUENCE = 2
|
||||
IMA_SRC_MOVIE = 3
|
||||
IMA_SRC_TILED = 6 # UDIM
|
||||
|
||||
# DNA_modifier_types.h
|
||||
eModifierType_Wave = 7
|
||||
|
||||
@ -555,7 +555,7 @@ class Packer:
|
||||
def _copy_asset_and_deps(self, asset_path: pathlib.Path, action: AssetAction):
|
||||
# Copy the asset itself, but only if it's not a sequence (sequences are
|
||||
# handled below in the for-loop).
|
||||
if "*" not in str(asset_path):
|
||||
if "*" not in str(asset_path) and '<UDIM>' not in asset_path.name:
|
||||
packed_path = action.new_path
|
||||
assert packed_path is not None
|
||||
read_path = action.read_from or asset_path
|
||||
|
||||
@ -96,11 +96,13 @@ def image(block: blendfile.BlendFileBlock) -> typing.Iterator[result.BlockUsage]
|
||||
cdefs.IMA_SRC_FILE,
|
||||
cdefs.IMA_SRC_SEQUENCE,
|
||||
cdefs.IMA_SRC_MOVIE,
|
||||
cdefs.IMA_SRC_TILED,
|
||||
}:
|
||||
log.debug("skiping image source type %s", image_source)
|
||||
return
|
||||
|
||||
pathname, field = block.get(b"name", return_field=True)
|
||||
is_sequence = image_source == cdefs.IMA_SRC_SEQUENCE
|
||||
is_sequence = image_source in {cdefs.IMA_SRC_SEQUENCE, cdefs.IMA_SRC_TILED}
|
||||
|
||||
yield result.BlockUsage(block, pathname, is_sequence, path_full_field=field)
|
||||
|
||||
|
||||
@ -39,6 +39,12 @@ def expand_sequence(path: pathlib.Path) -> typing.Iterator[pathlib.Path]:
|
||||
or the path of the first file in the sequence.
|
||||
"""
|
||||
|
||||
if "<UDIM>" in path.name: # UDIM tiles
|
||||
# Change <UDIM> marker to a glob pattern, then let the glob case handle it.
|
||||
# This assumes that all files that match the glob are actually UDIM
|
||||
# tiles; this could cause some false-positives.
|
||||
path = path.with_name(path.name.replace('<UDIM>', '*'))
|
||||
|
||||
if "*" in str(path): # assume it is a glob
|
||||
import glob
|
||||
|
||||
@ -46,7 +52,6 @@ def expand_sequence(path: pathlib.Path) -> typing.Iterator[pathlib.Path]:
|
||||
for fname in sorted(glob.glob(str(path), recursive=True)):
|
||||
yield pathlib.Path(fname)
|
||||
return
|
||||
|
||||
if not path.exists():
|
||||
raise DoesNotExist(path)
|
||||
|
||||
|
||||
BIN
tests/blendfiles/udim/cube_UDIM.color.1001.png
Normal file
BIN
tests/blendfiles/udim/cube_UDIM.color.1001.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 189 B |
BIN
tests/blendfiles/udim/cube_UDIM.color.1002.png
Normal file
BIN
tests/blendfiles/udim/cube_UDIM.color.1002.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 189 B |
BIN
tests/blendfiles/udim/cube_UDIM.color.1003.png
Normal file
BIN
tests/blendfiles/udim/cube_UDIM.color.1003.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 187 B |
BIN
tests/blendfiles/udim/v01_UDIM_BAT_debugging.blend
Normal file
BIN
tests/blendfiles/udim/v01_UDIM_BAT_debugging.blend
Normal file
Binary file not shown.
@ -366,6 +366,21 @@ class PackTest(AbstractPackTest):
|
||||
self.assertEqual(b"SQ000210.png", seq[b"name"])
|
||||
self.assertEqual(relpath, seq_strip[b"dir"])
|
||||
|
||||
def test_sequence_udim(self):
|
||||
# UDIM tiles are special, because the filename itself has a <UDIM>
|
||||
# marker in there and thus doesn't exist itself.
|
||||
ppath = self.blendfiles / "udim"
|
||||
infile = ppath / "v01_UDIM_BAT_debugging.blend"
|
||||
|
||||
with pack.Packer(infile, ppath, self.tpath) as packer:
|
||||
packer.strategise()
|
||||
packer.execute()
|
||||
|
||||
# The UDIM files should have been copied.
|
||||
self.assertTrue((self.tpath / "cube_UDIM.color.1001.png").exists())
|
||||
self.assertTrue((self.tpath / "cube_UDIM.color.1002.png").exists())
|
||||
self.assertTrue((self.tpath / "cube_UDIM.color.1003.png").exists())
|
||||
|
||||
def test_noop(self):
|
||||
ppath = self.blendfiles / "subdir"
|
||||
infile = ppath / "doubly_linked_up.blend"
|
||||
|
||||
@ -62,7 +62,6 @@ class AssetHoldingBlocksTest(AbstractTracerTest):
|
||||
self.assertEqual(965, len(self.bf.blocks))
|
||||
self.assertEqual(4, blocks_seen)
|
||||
|
||||
|
||||
class DepsTest(AbstractTracerTest):
|
||||
@staticmethod
|
||||
def field_name(field: dna.Field) -> typing.Optional[str]:
|
||||
@ -189,6 +188,19 @@ class DepsTest(AbstractTracerTest):
|
||||
actual = list(dep.files())
|
||||
self.assertEqual(actual, expected)
|
||||
|
||||
def test_seq_image_udim_sequence(self):
|
||||
expects = {
|
||||
b"IMcube_UDIM.color": Expect(
|
||||
'Image',
|
||||
'name[1024]',
|
||||
None,
|
||||
None,
|
||||
b'//cube_UDIM.color.<UDIM>.png',
|
||||
True,
|
||||
),
|
||||
}
|
||||
self.assert_deps("udim/v01_UDIM_BAT_debugging.blend", expects)
|
||||
|
||||
def test_block_cf(self):
|
||||
self.assert_deps(
|
||||
"alembic-user.blend",
|
||||
|
||||
@ -20,6 +20,14 @@ class ExpandFileSequenceTest(AbstractBlendFileTest):
|
||||
actual = list(file_sequence.expand_sequence(path))
|
||||
self.assertEqual(self.imgseq, actual)
|
||||
|
||||
def test_udim_sequence(self):
|
||||
path = self.blendfiles / "udim/cube_UDIM.color.<UDIM>.png"
|
||||
actual = list(file_sequence.expand_sequence(path))
|
||||
imgseq = [
|
||||
self.blendfiles / ("udim/cube_UDIM.color.%04d.png" % num) for num in range(1001, 1004)
|
||||
]
|
||||
self.assertEqual(imgseq, actual)
|
||||
|
||||
def test_nonexistent(self):
|
||||
path = self.blendfiles / "nonexistant"
|
||||
with self.assertRaises(file_sequence.DoesNotExist) as raises:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user