Sybren A. Stüvel 09a0866c14 Cache open blend files
This simplifies blend file handling, ensuring that blend files are only
opened once. Otherwise it would be harder to handle things like dependency
diamonds (libraries that are referenced via multiple paths through multiple
other libraries).
2018-03-07 17:13:47 +01:00

45 lines
1.4 KiB
Python

import logging
import pathlib
import typing
from blender_asset_tracer import blendfile, bpathlib
from . import result, blocks2assets, file2blocks
log = logging.getLogger(__name__)
codes_to_skip = {
# These blocks never have external assets:
b'ID', b'WM', b'SN',
# These blocks are skipped for now, until we have proof they point to
# assets otherwise missed:
b'GR', b'WO', b'BR', b'LS',
}
def deps(bfilepath: pathlib.Path) -> typing.Iterator[result.BlockUsage]:
"""Open the blend file and report its dependencies.
:param bfilepath: File to open.
"""
bfile = blendfile.open_cached(bfilepath)
for block in asset_holding_blocks(file2blocks.iter_blocks(bfile)):
yield from blocks2assets.iter_assets(block)
def asset_holding_blocks(blocks: typing.Iterable[blendfile.BlendFileBlock]) \
-> typing.Iterator[blendfile.BlendFileBlock]:
"""Generator, yield data blocks that could reference external assets."""
for block in blocks:
assert isinstance(block, blendfile.BlendFileBlock)
code = block.code
# The longer codes are either arbitrary data or data blocks that
# don't refer to external assets. The former data blocks will be
# visited when we hit the two-letter datablocks that use them.
if len(code) > 2 or code in codes_to_skip:
continue
yield block