Support particle simulation point cache data
Also see https://developer.blender.org/T53562
This commit is contained in:
parent
86af05e823
commit
8ae400acbe
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,3 +7,4 @@ __pycache__
|
|||||||
/.coverage
|
/.coverage
|
||||||
|
|
||||||
/tests/blendfiles/cache_ocean/
|
/tests/blendfiles/cache_ocean/
|
||||||
|
/tests/blendfiles/T53562/blendcache_bam_pack_bug/
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import typing
|
|||||||
|
|
||||||
from blender_asset_tracer import blendfile, bpathlib
|
from blender_asset_tracer import blendfile, bpathlib
|
||||||
from blender_asset_tracer.blendfile import iterators
|
from blender_asset_tracer.blendfile import iterators
|
||||||
from . import result, cdefs
|
from . import result, cdefs, modifier_walkers
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -105,20 +105,14 @@ def _from_block_ob(block: blendfile.BlendFileBlock) -> typing.Iterator[result.Bl
|
|||||||
mods = block.get_pointer((b'modifiers', b'first'))
|
mods = block.get_pointer((b'modifiers', b'first'))
|
||||||
for mod_idx, block_mod in enumerate(iterators.listbase(mods, next_path=(b'modifier', b'next'))):
|
for mod_idx, block_mod in enumerate(iterators.listbase(mods, next_path=(b'modifier', b'next'))):
|
||||||
block_name = b'%s.modifiers[%d]' % (ob_idname, mod_idx)
|
block_name = b'%s.modifiers[%d]' % (ob_idname, mod_idx)
|
||||||
log.debug('Tracing modifier %s', block_name.decode())
|
|
||||||
|
|
||||||
mod_type = block_mod[b'modifier', b'type']
|
mod_type = block_mod[b'modifier', b'type']
|
||||||
if mod_type == cdefs.eModifierType_Ocean:
|
log.debug('Tracing modifier %s, type=%d', block_name.decode(), mod_type)
|
||||||
if block_mod[b'cached']:
|
|
||||||
path, field = block_mod.get(b'cachepath', return_field=True)
|
|
||||||
# The path indicates the directory containing the cached files.
|
|
||||||
yield result.BlockUsage(block_mod, path, is_sequence=True, path_full_field=field,
|
|
||||||
block_name=block_name)
|
|
||||||
|
|
||||||
elif mod_type == cdefs.eModifierType_MeshCache:
|
try:
|
||||||
path, field = block_mod.get(b'filepath', return_field=True)
|
mod_handler = modifier_walkers.modifier_handlers[mod_type]
|
||||||
yield result.BlockUsage(block_mod, path, is_sequence=False, path_full_field=field,
|
except KeyError:
|
||||||
block_name=block_name)
|
continue
|
||||||
|
yield from mod_handler(block_mod, block_name)
|
||||||
|
|
||||||
|
|
||||||
def _from_block_sc(block: blendfile.BlendFileBlock) -> typing.Iterator[result.BlockUsage]:
|
def _from_block_sc(block: blendfile.BlendFileBlock) -> typing.Iterator[result.BlockUsage]:
|
||||||
|
|||||||
@ -34,6 +34,7 @@ IMA_SRC_SEQUENCE = 2
|
|||||||
IMA_SRC_MOVIE = 3
|
IMA_SRC_MOVIE = 3
|
||||||
|
|
||||||
# DNA_modifier_types.h
|
# DNA_modifier_types.h
|
||||||
|
eModifierType_ParticleSystem = 19
|
||||||
eModifierType_Ocean = 39
|
eModifierType_Ocean = 39
|
||||||
eModifierType_MeshCache = 46
|
eModifierType_MeshCache = 46
|
||||||
|
|
||||||
@ -45,4 +46,10 @@ PART_DRAW_GR = 8
|
|||||||
# Object.transflag
|
# Object.transflag
|
||||||
OB_DUPLIGROUP = 1 << 8
|
OB_DUPLIGROUP = 1 << 8
|
||||||
|
|
||||||
CACHE_LIBRARY_SOURCE_CACHE = 1
|
# DNA_object_force_types.h
|
||||||
|
PTCACHE_DISK_CACHE = 64
|
||||||
|
PTCACHE_EXTERNAL = 512
|
||||||
|
|
||||||
|
# BKE_pointcache.h
|
||||||
|
PTCACHE_EXT = b'.bphys'
|
||||||
|
PTCACHE_PATH = b'blendcache_'
|
||||||
|
|||||||
64
blender_asset_tracer/tracer/modifier_walkers.py
Normal file
64
blender_asset_tracer/tracer/modifier_walkers.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
"""Modifier handling code used in block_walkers.py
|
||||||
|
|
||||||
|
The _modifier_xxx() functions all yield result.BlockUsage objects for external
|
||||||
|
files used by the modifiers.
|
||||||
|
"""
|
||||||
|
import typing
|
||||||
|
|
||||||
|
from blender_asset_tracer import blendfile, bpathlib
|
||||||
|
from . import result, cdefs
|
||||||
|
|
||||||
|
|
||||||
|
def _modifier_filepath(modifier: blendfile.BlendFileBlock, block_name: bytes) \
|
||||||
|
-> typing.Iterator[result.BlockUsage]:
|
||||||
|
"""Just yield the 'filepath' field."""
|
||||||
|
path, field = modifier.get(b'filepath', return_field=True)
|
||||||
|
yield result.BlockUsage(modifier, path, path_full_field=field, block_name=block_name)
|
||||||
|
|
||||||
|
|
||||||
|
def _modifier_ocean(modifier: blendfile.BlendFileBlock, block_name: bytes) \
|
||||||
|
-> typing.Iterator[result.BlockUsage]:
|
||||||
|
if not modifier[b'cached']:
|
||||||
|
return
|
||||||
|
|
||||||
|
path, field = modifier.get(b'cachepath', return_field=True)
|
||||||
|
# The path indicates the directory containing the cached files.
|
||||||
|
yield result.BlockUsage(modifier, path, is_sequence=True, path_full_field=field,
|
||||||
|
block_name=block_name)
|
||||||
|
|
||||||
|
|
||||||
|
def _modifier_particle_system(modifier: blendfile.BlendFileBlock, block_name: bytes) \
|
||||||
|
-> typing.Iterator[result.BlockUsage]:
|
||||||
|
psys = modifier.get_pointer(b'psys')
|
||||||
|
if psys is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
pointcache = psys.get_pointer(b'pointcache')
|
||||||
|
if pointcache is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
flag = pointcache[b'flag']
|
||||||
|
|
||||||
|
if flag & cdefs.PTCACHE_DISK_CACHE:
|
||||||
|
# See ptcache_path() in pointcache.c
|
||||||
|
name, field = pointcache.get(b'name', return_field=True)
|
||||||
|
path = b'//%b%b/%b_*%b' % (
|
||||||
|
cdefs.PTCACHE_PATH,
|
||||||
|
modifier.bfile.filepath.stem.encode(),
|
||||||
|
name,
|
||||||
|
cdefs.PTCACHE_EXT)
|
||||||
|
bpath = bpathlib.BlendPath(path)
|
||||||
|
yield result.BlockUsage(pointcache, bpath, path_full_field=field,
|
||||||
|
is_sequence=True, block_name=block_name)
|
||||||
|
|
||||||
|
if flag & cdefs.PTCACHE_EXTERNAL:
|
||||||
|
path, field = pointcache.get(b'path', return_field=True)
|
||||||
|
yield result.BlockUsage(pointcache, path, path_full_field=field,
|
||||||
|
is_sequence=True, block_name=block_name)
|
||||||
|
|
||||||
|
|
||||||
|
modifier_handlers = {
|
||||||
|
cdefs.eModifierType_ParticleSystem: _modifier_particle_system,
|
||||||
|
cdefs.eModifierType_Ocean: _modifier_ocean,
|
||||||
|
cdefs.eModifierType_MeshCache: _modifier_filepath,
|
||||||
|
}
|
||||||
@ -8,7 +8,9 @@ class BlockUsage:
|
|||||||
:ivar block_name: an identifying name for this block. Defaults to the ID
|
:ivar block_name: an identifying name for this block. Defaults to the ID
|
||||||
name of the block.
|
name of the block.
|
||||||
:ivar block:
|
:ivar block:
|
||||||
:ivar asset_path:
|
:ivar asset_path: The path of the asset, if is_sequence=False. Otherwise
|
||||||
|
it can be either a glob pattern (must contain a * byte), a directory,
|
||||||
|
or the path of the first file in the sequence.
|
||||||
:ivar is_sequence: Indicates whether this file is alone (False), the
|
:ivar is_sequence: Indicates whether this file is alone (False), the
|
||||||
first of a sequence (True, and the path points to a file), or a
|
first of a sequence (True, and the path points to a file), or a
|
||||||
directory containing a sequence (True, and path points to a directory).
|
directory containing a sequence (True, and path points to a directory).
|
||||||
|
|||||||
BIN
tests/blendfiles/T53562/bam_pack_bug.blend
Normal file
BIN
tests/blendfiles/T53562/bam_pack_bug.blend
Normal file
Binary file not shown.
@ -196,3 +196,10 @@ class DepsTest(AbstractTracerTest):
|
|||||||
'Image', 'name[1024]', None, None,
|
'Image', 'name[1024]', None, None,
|
||||||
b'//textures/Textures/Buildings/buildings_roof_04-color.png', False),
|
b'//textures/Textures/Buildings/buildings_roof_04-color.png', False),
|
||||||
}, recursive=True)
|
}, recursive=True)
|
||||||
|
|
||||||
|
def test_sim_data(self):
|
||||||
|
self.assert_deps('T53562/bam_pack_bug.blend', {
|
||||||
|
b'OBEmitter.modifiers[0]': Expect(
|
||||||
|
'PointCache', 'name[64]', None, None,
|
||||||
|
b'//blendcache_bam_pack_bug/particles_*.bphys', True),
|
||||||
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user