Support UDIM images

This commit is contained in:
Sybren A. Stüvel 2022-02-18 15:39:23 +01:00
parent 4ebd535b5f
commit 843c34c3c0
12 changed files with 51 additions and 4 deletions

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

View File

@ -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"

View File

@ -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",

View File

@ -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: