Asset Pipeline v2 #145
@ -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
|
||||||
|
87
scripts-blender/addons/asset_pipeline_2/datablocks.py
Normal file
87
scripts-blender/addons/asset_pipeline_2/datablocks.py
Normal 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)
|
@ -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)
|
|
Loading…
Reference in New Issue
Block a user