Normalize unused paths in packed linked blends
This commit is contained in:
@@ -142,6 +142,8 @@ class Packer:
|
||||
self._top_level_paths = set() # type: typing.Set[pathlib.Path]
|
||||
self._output_path = None # type: typing.Optional[pathlib.PurePath]
|
||||
self._output_paths = [] # type: typing.List[pathlib.PurePath]
|
||||
self._rewrite_targets = {} # type: typing.Dict[int, pathlib.PurePath]
|
||||
"""Destinations keyed by usage identity for path-only rewrites."""
|
||||
|
||||
# Filled by execute()
|
||||
self._file_transferer = None # type: typing.Optional[transfer.FileTransferer]
|
||||
@@ -303,6 +305,70 @@ class Packer:
|
||||
self._output_path = self._output_paths[0] # backward compat
|
||||
self._find_new_paths()
|
||||
self._group_rewrites()
|
||||
self._normalise_linked_blend_paths()
|
||||
|
||||
def _normalise_linked_blend_paths(self) -> None:
|
||||
"""Make absolute paths in copied libraries portable.
|
||||
|
||||
Dependency tracing intentionally visits only datablocks used by the
|
||||
top-level blend files. Linked blend files are nevertheless copied in
|
||||
full, so unused datablocks can otherwise retain absolute paths such as
|
||||
``R:/project/asset.vdb``. Normalize those paths to their expected pack
|
||||
locations without adding the referenced files to the pack.
|
||||
"""
|
||||
if self.relative_only:
|
||||
return
|
||||
|
||||
linked_blends = [
|
||||
path
|
||||
for path, action in self._actions.items()
|
||||
if path not in self._top_level_paths
|
||||
and path.suffix.lower() == ".blend"
|
||||
and action.new_path is not None
|
||||
]
|
||||
def usage_key(usage: result.BlockUsage) -> typing.Tuple:
|
||||
field_names: typing.Tuple[bytes, ...]
|
||||
if usage.path_full_field is not None:
|
||||
field_names = (usage.path_full_field.name.name_full,)
|
||||
else:
|
||||
assert usage.path_dir_field is not None
|
||||
assert usage.path_base_field is not None
|
||||
field_names = (
|
||||
usage.path_dir_field.name.name_full,
|
||||
usage.path_base_field.name.name_full,
|
||||
)
|
||||
return usage.block.addr_old, field_names
|
||||
|
||||
for bfile_path in linked_blends:
|
||||
action = self._actions[bfile_path]
|
||||
existing_usages = {usage_key(usage) for usage in action.rewrites}
|
||||
for usage in trace.local_deps(bfile_path):
|
||||
key = usage_key(usage)
|
||||
if key in existing_usages:
|
||||
continue
|
||||
if usage.asset_path.is_blendfile_relative():
|
||||
continue
|
||||
|
||||
asset_path = usage.abspath
|
||||
if self.keep_hierarchy:
|
||||
asset_pp = self._target_path / bpathlib.strip_root(asset_path)
|
||||
elif self._path_in_project(asset_path):
|
||||
asset_pp = self._target_path / asset_path.relative_to(self.project)
|
||||
else:
|
||||
asset_pp = (
|
||||
self._target_path
|
||||
/ "_outside_project"
|
||||
/ bpathlib.strip_root(asset_path)
|
||||
)
|
||||
|
||||
log.info(
|
||||
"Normalizing uncopied path in %s: %s",
|
||||
bfile_path,
|
||||
usage.asset_path,
|
||||
)
|
||||
action.rewrites.append(usage)
|
||||
self._rewrite_targets[id(usage)] = pathlib.Path(asset_pp)
|
||||
existing_usages.add(key)
|
||||
|
||||
def _visit_sequence(self, asset_path: pathlib.Path, usage: result.BlockUsage):
|
||||
assert usage.is_sequence
|
||||
@@ -543,8 +609,10 @@ class Packer:
|
||||
for usage in action.rewrites:
|
||||
self._check_aborted()
|
||||
assert isinstance(usage, result.BlockUsage)
|
||||
asset_pp = self._actions[usage.abspath].new_path
|
||||
assert isinstance(asset_pp, pathlib.Path)
|
||||
asset_pp = self._rewrite_targets.get(id(usage))
|
||||
if asset_pp is None:
|
||||
asset_pp = self._actions[usage.abspath].new_path
|
||||
assert isinstance(asset_pp, pathlib.PurePath)
|
||||
|
||||
log.debug(" - %s is packed at %s", usage.asset_path, asset_pp)
|
||||
relpath = bpathlib.BlendPath.mkrelative(asset_pp, bfile_pp)
|
||||
|
||||
Reference in New Issue
Block a user