Asset Pipeline v2 #145

Closed
Nick Alberelli wants to merge 431 commits from (deleted):feature/asset-pipeline-v2 into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
3 changed files with 89 additions and 72 deletions
Showing only changes of commit 80a1b88132 - Show all commits

View File

@ -1,6 +1,6 @@
import bpy import bpy
from . import asset_suffix, transferable_data, id_remap from . import asset_suffix, datablocks, transferable_data
from pathlib import Path from pathlib import Path
@ -67,7 +67,7 @@ def merge_task_layer(
transferable_data.apply_transfer_data(context, transfer_data, target_col) transferable_data.apply_transfer_data(context, transfer_data, target_col)
id_remap.remap_external_datablocks(context) datablocks.remap_datablocks_outside_scene(context.scene)
bpy.ops.outliner.orphans_purge( bpy.ops.outliner.orphans_purge(
do_local_ids=True, do_linked_ids=False, do_recursive=True do_local_ids=True, do_linked_ids=False, do_recursive=True

View File

@ -0,0 +1,87 @@
import bpy
from . import util
def get_type_datablocks(datablocks):
"""Filters for items in a list of datablocks that have a 'type'"""
return [datablock for datablock in datablocks if hasattr(datablock, 'type')]
def get_users_of_id(datablock):
"""Returns datablocks that are using/referencing a give datablock"""
return bpy.data.user_map()[datablock]
def recursively_find_parent_objs(datablock):
"""Recursively loop through ID parents and return a parent obj
of a given datablock"""
datablocks = bpy.data.user_map()[datablock]
if datablock not in list(bpy.data.objects):
for datablock in datablocks:
recursively_find_parent_objs(datablock)
else:
return datablocks
def referenced_in_scene(scene: bpy.types.Scene, datablock):
"""Returns datablocks that are being references by data within
the scene"""
users = get_users_of_id(datablock)
for user in users:
if user in list(scene.objects):
return True
# FOR DATABLOCKS THAT ARE NOT OBJ BUT ARE REFERENCES BY OBJS IN SCENE
parent_users = recursively_find_parent_objs(datablock)
if parent_users is None:
return
for parent_user in parent_users:
if parent_user in list(scene.objects):
return True
def remap_get_data_blocks(scene: bpy.types.Scene):
"""Returns list of datablocks that aren't in the scene
but are referenced by data within the scene"""
retun_datablocks = []
datablocks = [db for db in bpy.data.user_map() if hasattr(db, 'type')]
for datablock in datablocks:
if referenced_in_scene(scene, datablock) and datablock not in list(
scene.objects
):
retun_datablocks.append(datablock)
return retun_datablocks
def remap_user(source_datablock: bpy.data, target_datablock: bpy.data):
"""Remap datablock and append name to datablock that has been remapped"""
source_datablock.user_remap(target_datablock)
source_datablock.name += "_Users_Remapped"
def get_opposite_suffix(suffix: str):
# TODO FIX HACK that is used until I have transfer mapping
# TODO Creating a map would be easier that doing this on the fly
if suffix.endswith("EXTERNAL"):
return ".LOCAL"
if suffix.endswith("LOCAL"):
return ".EXTERNAL"
def remap_datablocks_outside_scene(scene: bpy.types.Scene):
"""Remap Datablocks that are used in the scene but will be purged
because they are not references by the items within the scene"""
# TODO STANDARDIZE IF ASSET SHOULD HAVE . IN SUFFIX OR NOT,
# ADD A CORE FUNCTION FOR APPENDING SUFFIX TO SINGLE ITEM
datablocks = remap_get_data_blocks(scene)
for datablock in datablocks:
# FIND TARGET DATA-BLOCK BY SUFFIX
current_suffix = "." + datablock.name.split(".")[-1]
target_suffix = get_opposite_suffix(current_suffix)
target_name = datablock.name.replace(current_suffix, target_suffix)
storage = util.get_storage_of_id(datablock)
target_datablock = storage.get(target_name)
print(f"Will remap {datablock.name} to {target_datablock.name}")
if target_datablock:
remap_user(datablock, target_datablock)

View File

@ -1,70 +0,0 @@
import bpy
from . import util
from bpy.types import bpy_prop_collection
# TODO CHECK OTHER DATA TYPES OUTSIDE OF OBJECTS
### REMAPPING IDS
def get_users(col, ID):
ret = tuple(repr(o) for o in col if o.user_of_id(ID))
return [eval(item) for item in ret] if ret else None
def get_users_of_id(ID):
users_of_id = []
for p in dir(bpy.data):
if isinstance(getattr(bpy.data, p, None), bpy_prop_collection):
users = get_users(getattr(bpy.data, p), ID)
if users:
for user in users:
users_of_id.append(user)
return users_of_id
def get_users_in_scene(context, ID):
users_in_scene = []
users = get_users_of_id(ID)
for user in users:
has_type = hasattr(user, 'type')
if has_type and user in list(context.scene.objects):
users_in_scene.append(user)
return users_in_scene
def remap_get_data_blocks(context):
retun_datablocks = []
for obj in bpy.data.objects:
references_in_scene = get_users_in_scene(context, obj)
if references_in_scene and obj not in list(context.scene.objects):
retun_datablocks.append(obj)
return retun_datablocks
def remap_user(datablock, target_name):
storage = util.get_storage_of_id(datablock)
remap_datablock = storage.get(target_name)
if remap_datablock:
datablock.user_remap(remap_datablock)
datablock.name += "_Users_Remapped"
def get_opposite_suffix(suffix):
# TODO Creating a map would be easier that doing this on the fly
if suffix.endswith("EXTERNAL"):
return ".LOCAL"
if suffix.endswith("LOCAL"):
return ".EXTERNAL"
def remap_external_datablocks(context):
# TODO STANDARDIZE IF ASSET SHOULD HAVE . IN SUFFIX OR NOT,
# ADD A CORE FUNCTION FOR APPENDING SUFFIX TO SINGLE ITEM
datablocks = remap_get_data_blocks(context)
for datablock in datablocks:
current_suffix = "." + datablock.name.split(".")[-1]
target_suffix = get_opposite_suffix(datablock.name)
target_name = datablock.name.replace(current_suffix, target_suffix)
print(f"Will remap {datablock.name} to {target_name}")
remap_user(datablock, target_name)