black format
This commit is contained in:
@@ -1,27 +1,28 @@
|
||||
|
||||
from asset_library.collection import (
|
||||
gui,
|
||||
operators,
|
||||
keymaps,
|
||||
#build_collection_blends,
|
||||
#create_collection_library,
|
||||
)
|
||||
# build_collection_blends,
|
||||
# create_collection_library,
|
||||
)
|
||||
|
||||
if 'bpy' in locals():
|
||||
if "bpy" in locals():
|
||||
import importlib
|
||||
|
||||
importlib.reload(gui)
|
||||
importlib.reload(operators)
|
||||
importlib.reload(keymaps)
|
||||
#importlib.reload(build_collection_blends)
|
||||
#importlib.reload(create_collection_library)
|
||||
# importlib.reload(build_collection_blends)
|
||||
# importlib.reload(create_collection_library)
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
def register():
|
||||
operators.register()
|
||||
keymaps.register()
|
||||
|
||||
|
||||
def unregister():
|
||||
operators.unregister()
|
||||
keymaps.unregister()
|
||||
keymaps.unregister()
|
||||
|
||||
@@ -29,12 +29,13 @@ from asset_library.constants import ASSETLIB_FILENAME
|
||||
]
|
||||
"""
|
||||
|
||||
|
||||
def build_collection_blends(path, categories=None, clean=True):
|
||||
|
||||
t0 = time()
|
||||
scn = bpy.context.scene
|
||||
scn.render.resolution_x = scn.render.resolution_y = 1000
|
||||
|
||||
|
||||
json_path = Path(path) / ASSETLIB_FILENAME
|
||||
if not json_path.exists():
|
||||
return
|
||||
@@ -43,30 +44,33 @@ def build_collection_blends(path, categories=None, clean=True):
|
||||
category_datas = json.loads(json_path.read_text())
|
||||
|
||||
for category_data in category_datas:
|
||||
if categories and category_data['name'] not in categories:
|
||||
if categories and category_data["name"] not in categories:
|
||||
continue
|
||||
|
||||
bpy.ops.wm.read_homefile(use_empty=True)
|
||||
|
||||
# category_data = next(c for c in category_datas if c['name'] == category)
|
||||
# _col_datas = category_data['children']
|
||||
|
||||
#category_data = next(c for c in category_datas if c['name'] == category)
|
||||
#_col_datas = category_data['children']
|
||||
|
||||
cat_name = category_data['name']
|
||||
build_path = Path(path) / cat_name / f'{cat_name}.blend'
|
||||
cat_name = category_data["name"]
|
||||
build_path = Path(path) / cat_name / f"{cat_name}.blend"
|
||||
|
||||
## re-iterate in grouped filepath
|
||||
col_datas = sorted(category_data['children'], key=lambda x: x['filepath'])
|
||||
for filepath, col_data_groups in groupby(col_datas, key=lambda x: x['filepath']):
|
||||
#f = Path(f)
|
||||
col_datas = sorted(category_data["children"], key=lambda x: x["filepath"])
|
||||
for filepath, col_data_groups in groupby(
|
||||
col_datas, key=lambda x: x["filepath"]
|
||||
):
|
||||
# f = Path(f)
|
||||
if not Path(filepath).exists():
|
||||
print(f'Not exists: {filepath}')
|
||||
print(f"Not exists: {filepath}")
|
||||
continue
|
||||
|
||||
col_data_groups = list(col_data_groups)
|
||||
|
||||
col_names = [a['name'] for a in col_data_groups]
|
||||
linked_cols = load_datablocks(filepath, col_names, link=True, type='collections')
|
||||
col_names = [a["name"] for a in col_data_groups]
|
||||
linked_cols = load_datablocks(
|
||||
filepath, col_names, link=True, type="collections"
|
||||
)
|
||||
|
||||
for i, col in enumerate(linked_cols):
|
||||
# iterate in linked collection and associated data
|
||||
@@ -78,14 +82,14 @@ def build_collection_blends(path, categories=None, clean=True):
|
||||
|
||||
## Directly link as collection inside a marked collection with same name
|
||||
marked_col = col_as_asset(col, verbose=True)
|
||||
marked_col.asset_data.description = asset_data.get('description', '')
|
||||
marked_col.asset_data.catalog_id = category_data['id'] # assign catalog
|
||||
marked_col.asset_data.description = asset_data.get("description", "")
|
||||
marked_col.asset_data.catalog_id = category_data["id"] # assign catalog
|
||||
|
||||
for k, v in asset_data.get('metadata', {}).items():
|
||||
for k, v in asset_data.get("metadata", {}).items():
|
||||
marked_col.asset_data[k] = v
|
||||
|
||||
## exclude collections and generate preview
|
||||
bpy.ops.ed.lib_id_generate_preview({"id": marked_col}) # preview gen
|
||||
bpy.ops.ed.lib_id_generate_preview({"id": marked_col}) # preview gen
|
||||
vcol = bpy.context.view_layer.layer_collection.children[marked_col.name]
|
||||
vcol.exclude = True
|
||||
|
||||
@@ -93,32 +97,36 @@ def build_collection_blends(path, categories=None, clean=True):
|
||||
|
||||
## clear all objects (can be very long with a lot of objects...):
|
||||
if clean:
|
||||
print('Removing links...')
|
||||
print("Removing links...")
|
||||
for lib in reversed(bpy.data.libraries):
|
||||
bpy.data.libraries.remove(lib)
|
||||
|
||||
|
||||
|
||||
# Créer les dossiers intermediaires
|
||||
build_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
print('Saving to', build_path)
|
||||
print("Saving to", build_path)
|
||||
bpy.ops.wm.save_as_mainfile(filepath=str(build_path), compress=False)
|
||||
|
||||
print("build time:", f'{time() - t0:.1f}s')
|
||||
|
||||
print("build time:", f"{time() - t0:.1f}s")
|
||||
|
||||
bpy.ops.wm.quit_blender()
|
||||
|
||||
|
||||
if __name__ == '__main__' :
|
||||
parser = argparse.ArgumentParser(description='build_collection_blends',
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="build_collection_blends",
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
)
|
||||
|
||||
parser.add_argument('-path') # Trouve/créer le json assetlib.json en sous-dossier de libdir
|
||||
parser.add_argument('--category') # Lit la category dans le json et a link tout dans le blend
|
||||
parser.add_argument(
|
||||
"-path"
|
||||
) # Trouve/créer le json assetlib.json en sous-dossier de libdir
|
||||
parser.add_argument(
|
||||
"--category"
|
||||
) # Lit la category dans le json et a link tout dans le blend
|
||||
|
||||
if '--' in sys.argv :
|
||||
index = sys.argv.index('--')
|
||||
sys.argv = [sys.argv[index-1], *sys.argv[index+1:]]
|
||||
if "--" in sys.argv:
|
||||
index = sys.argv.index("--")
|
||||
sys.argv = [sys.argv[index - 1], *sys.argv[index + 1 :]]
|
||||
|
||||
args = parser.parse_args()
|
||||
build_collection_blends(**vars(args))
|
||||
build_collection_blends(**vars(args))
|
||||
|
||||
@@ -44,87 +44,93 @@ from asset_library.constants import ASSETLIB_FILENAME
|
||||
]
|
||||
"""
|
||||
|
||||
|
||||
def create_collection_json(path, source_directory):
|
||||
'''Create a Json from every marked collection in blends
|
||||
"""Create a Json from every marked collection in blends
|
||||
contained in folderpath (respect hierachy)
|
||||
'''
|
||||
"""
|
||||
|
||||
json_path = Path(path) / ASSETLIB_FILENAME
|
||||
|
||||
|
||||
# scan all last version of the assets ?
|
||||
# get last version files ?
|
||||
# or open all blends and look only for marked collection ? (if versionned, get still get only last)
|
||||
|
||||
# get all blend in dir and subdirs (only last when versionned _v???)
|
||||
blends = get_last_files(source_directory, pattern=r'(_v\d{3})?\.blend$', only_matching=True)
|
||||
blends = get_last_files(
|
||||
source_directory, pattern=r"(_v\d{3})?\.blend$", only_matching=True
|
||||
)
|
||||
|
||||
root_path = Path(source_directory).as_posix().rstrip('/') + '/'
|
||||
print('root_path: ', root_path)
|
||||
root_path = Path(source_directory).as_posix().rstrip("/") + "/"
|
||||
print("root_path: ", root_path)
|
||||
# open and check data block marked as asset
|
||||
|
||||
category_datas = []
|
||||
for i, blend in enumerate(blends):
|
||||
fp = Path(blend)
|
||||
print(f'{i+1}/{len(blends)}')
|
||||
|
||||
print(f"{i+1}/{len(blends)}")
|
||||
|
||||
## What is considered a grouping category ? top level folders ? parents[1] ?
|
||||
|
||||
## Remove root path and extension
|
||||
## top level folder ('chars'), problem if blends at root
|
||||
category = fp.as_posix().replace(root_path, '').split('/')[0]
|
||||
|
||||
## top level folder ('chars'), problem if blends at root
|
||||
category = fp.as_posix().replace(root_path, "").split("/")[0]
|
||||
|
||||
## full blend path (chars/perso/perso)
|
||||
# category = fp.as_posix().replace(root_path, '').rsplit('.', 1)[0]
|
||||
|
||||
|
||||
print(category)
|
||||
|
||||
with bpy.data.libraries.load(blend, link=True, assets_only=True) as (data_from, data_to):
|
||||
with bpy.data.libraries.load(blend, link=True, assets_only=True) as (
|
||||
data_from,
|
||||
data_to,
|
||||
):
|
||||
## just listing
|
||||
col_name_list = [c for c in data_from.collections]
|
||||
|
||||
if not col_name_list:
|
||||
continue
|
||||
|
||||
col_list = next((c['children'] for c in category_datas if c['name'] == category), None)
|
||||
col_list = next(
|
||||
(c["children"] for c in category_datas if c["name"] == category), None
|
||||
)
|
||||
if col_list is None:
|
||||
col_list = []
|
||||
category_data = {
|
||||
'name': category,
|
||||
'id': str(uuid.uuid4()),
|
||||
'children': col_list,
|
||||
}
|
||||
"name": category,
|
||||
"id": str(uuid.uuid4()),
|
||||
"children": col_list,
|
||||
}
|
||||
category_datas.append(category_data)
|
||||
|
||||
|
||||
blend_source_path = blend.as_posix()
|
||||
if (project_root := os.environ.get('PROJECT_ROOT')):
|
||||
blend_source_path = blend_source_path.replace(project_root, '$PROJECT_ROOT')
|
||||
|
||||
if project_root := os.environ.get("PROJECT_ROOT"):
|
||||
blend_source_path = blend_source_path.replace(project_root, "$PROJECT_ROOT")
|
||||
|
||||
for name in col_name_list:
|
||||
data = {
|
||||
'filepath' : blend,
|
||||
'name' : name,
|
||||
"filepath": blend,
|
||||
"name": name,
|
||||
# 'tags' : [],
|
||||
'metadata' : {'filepath': blend_source_path},
|
||||
"metadata": {"filepath": blend_source_path},
|
||||
}
|
||||
|
||||
col_list.append(data)
|
||||
|
||||
json_path.write_text(json.dumps(category_datas, indent='\t'))
|
||||
json_path.write_text(json.dumps(category_datas, indent="\t"))
|
||||
## create text catalog from json (keep_existing_category ?)
|
||||
create_catalog_file(json_path, keep_existing_category=True)
|
||||
|
||||
|
||||
def create_collection_library(path, source_directory=None):
|
||||
'''
|
||||
"""
|
||||
path: store collection library (json and blends database)
|
||||
source_directory: if a source is set, rebuild json and library
|
||||
'''
|
||||
"""
|
||||
|
||||
if source_directory:
|
||||
if not Path(source_directory).exists():
|
||||
print(f'Source directory not exists: {source_directory}')
|
||||
print(f"Source directory not exists: {source_directory}")
|
||||
return
|
||||
|
||||
## scan source and build json in assetlib dir root
|
||||
@@ -132,32 +138,45 @@ def create_collection_library(path, source_directory=None):
|
||||
|
||||
json_path = Path(path) / ASSETLIB_FILENAME
|
||||
if not json_path.exists():
|
||||
print(f'No json found at: {json_path}')
|
||||
print(f"No json found at: {json_path}")
|
||||
return
|
||||
|
||||
file_datas = json.loads(json_path.read())
|
||||
|
||||
## For each category in json, execute build_assets_blend script
|
||||
script = Path(__file__).parent / 'build_collection_blends.py'
|
||||
#empty_blend = Path(__file__).parent / 'empty_scene.blend'
|
||||
|
||||
script = Path(__file__).parent / "build_collection_blends.py"
|
||||
# empty_blend = Path(__file__).parent / 'empty_scene.blend'
|
||||
|
||||
# for category, asset_datas in file_datas.items():
|
||||
for category_data in file_datas:
|
||||
## add an empty blend as second arg
|
||||
cmd = [bpy.app.binary_path, '--python', str(script), '--', '--path', path, '--category', category_data['name']]
|
||||
print('cmd: ', cmd)
|
||||
cmd = [
|
||||
bpy.app.binary_path,
|
||||
"--python",
|
||||
str(script),
|
||||
"--",
|
||||
"--path",
|
||||
path,
|
||||
"--category",
|
||||
category_data["name"],
|
||||
]
|
||||
print("cmd: ", cmd)
|
||||
subprocess.call(cmd)
|
||||
|
||||
|
||||
if __name__ == '__main__' :
|
||||
parser = argparse.ArgumentParser(description='Create Collection Library',
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Create Collection Library",
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
)
|
||||
|
||||
parser.add_argument('--path') # trouve/créer le json assetlib.json en sous-dossier de libdir
|
||||
parser.add_argument(
|
||||
"--path"
|
||||
) # trouve/créer le json assetlib.json en sous-dossier de libdir
|
||||
|
||||
if '--' in sys.argv :
|
||||
index = sys.argv.index('--')
|
||||
sys.argv = [sys.argv[index-1], *sys.argv[index+1:]]
|
||||
if "--" in sys.argv:
|
||||
index = sys.argv.index("--")
|
||||
sys.argv = [sys.argv[index - 1], *sys.argv[index + 1 :]]
|
||||
|
||||
args = parser.parse_args()
|
||||
create_collection_library(**vars(args))
|
||||
create_collection_library(**vars(args))
|
||||
|
||||
+2
-3
@@ -1,4 +1,3 @@
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
@@ -9,6 +8,6 @@ def draw_context_menu(layout):
|
||||
|
||||
|
||||
def draw_header(layout):
|
||||
'''Draw the header of the Asset Browser Window'''
|
||||
"""Draw the header of the Asset Browser Window"""
|
||||
|
||||
return
|
||||
return
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
|
||||
|
||||
from typing import List, Tuple
|
||||
|
||||
import bpy
|
||||
|
||||
addon_keymaps: List[Tuple[bpy.types.KeyMap, bpy.types.KeyMapItem]] = []
|
||||
|
||||
|
||||
def register():
|
||||
wm = bpy.context.window_manager
|
||||
addon = wm.keyconfigs.addon
|
||||
@@ -13,10 +12,13 @@ def register():
|
||||
return
|
||||
|
||||
km = addon.keymaps.new(name="File Browser Main", space_type="FILE_BROWSER")
|
||||
kmi = km.keymap_items.new("assetlib.load_asset", "LEFTMOUSE", "DOUBLE_CLICK") # , shift=True
|
||||
kmi = km.keymap_items.new(
|
||||
"assetlib.load_asset", "LEFTMOUSE", "DOUBLE_CLICK"
|
||||
) # , shift=True
|
||||
addon_keymaps.append((km, kmi))
|
||||
|
||||
|
||||
def unregister():
|
||||
for km, kmi in addon_keymaps:
|
||||
km.keymap_items.remove(kmi)
|
||||
addon_keymaps.clear()
|
||||
addon_keymaps.clear()
|
||||
|
||||
+27
-30
@@ -14,24 +14,23 @@ from asset_library.common.bl_utils import load_col
|
||||
from asset_library.common.functions import get_active_library
|
||||
|
||||
|
||||
|
||||
class ASSETLIB_OT_load_asset(Operator):
|
||||
bl_idname = "assetlib.load_asset"
|
||||
bl_options = {"REGISTER", "UNDO", "INTERNAL"}
|
||||
bl_label = 'Load Asset'
|
||||
bl_description = 'Link and override asset in current file'
|
||||
bl_label = "Load Asset"
|
||||
bl_description = "Link and override asset in current file"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context: Context) -> bool:
|
||||
if not asset_utils.SpaceAssetInfo.is_asset_browser(context.space_data):
|
||||
cls.poll_message_set("Current editor is not an asset browser")
|
||||
return False
|
||||
|
||||
|
||||
lib = get_active_library()
|
||||
if not lib or lib.data_type != 'COLLECTION':
|
||||
if not lib or lib.data_type != "COLLECTION":
|
||||
return False
|
||||
|
||||
if not context.active_file or 'filepath' not in context.active_file.asset_data:
|
||||
|
||||
if not context.active_file or "filepath" not in context.active_file.asset_data:
|
||||
cls.poll_message_set("Has not filepath property")
|
||||
return False
|
||||
|
||||
@@ -39,51 +38,49 @@ class ASSETLIB_OT_load_asset(Operator):
|
||||
|
||||
def execute(self, context: Context) -> Set[str]:
|
||||
|
||||
print('Load Asset')
|
||||
print("Load Asset")
|
||||
|
||||
lib = get_active_library()
|
||||
|
||||
|
||||
|
||||
asset = context.active_file
|
||||
if not asset:
|
||||
self.report({"ERROR"}, 'No asset selected')
|
||||
return {'CANCELLED'}
|
||||
|
||||
self.report({"ERROR"}, "No asset selected")
|
||||
return {"CANCELLED"}
|
||||
|
||||
active_lib = lib.library_type.get_active_asset_library()
|
||||
asset_path = asset.asset_data['filepath']
|
||||
asset_path = asset.asset_data["filepath"]
|
||||
asset_path = active_lib.library_type.format_path(asset_path)
|
||||
name = asset.name
|
||||
|
||||
## set mode to object
|
||||
if context.mode != 'OBJECT':
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
||||
if context.mode != "OBJECT":
|
||||
bpy.ops.object.mode_set(mode="OBJECT")
|
||||
|
||||
if not Path(asset_path).exists():
|
||||
self.report({'ERROR'}, f'Not exists: {asset_path}')
|
||||
return {'CANCELLED'}
|
||||
self.report({"ERROR"}, f"Not exists: {asset_path}")
|
||||
return {"CANCELLED"}
|
||||
|
||||
print('Load collection', asset_path, name)
|
||||
res = load_col(asset_path, name, link=True, override=True, rig_pattern='*_rig')
|
||||
print("Load collection", asset_path, name)
|
||||
res = load_col(asset_path, name, link=True, override=True, rig_pattern="*_rig")
|
||||
if res:
|
||||
if res.type == 'ARMATURE':
|
||||
self.report({'INFO'}, f'Override rig {res.name}')
|
||||
elif res.type == 'EMPTY':
|
||||
self.report({'INFO'}, f'Instance collection {res.name}')
|
||||
if res.type == "ARMATURE":
|
||||
self.report({"INFO"}, f"Override rig {res.name}")
|
||||
elif res.type == "EMPTY":
|
||||
self.report({"INFO"}, f"Instance collection {res.name}")
|
||||
|
||||
return {'FINISHED'}
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
### --- REGISTER ---
|
||||
|
||||
classes = (
|
||||
ASSETLIB_OT_load_asset,
|
||||
)
|
||||
classes = (ASSETLIB_OT_load_asset,)
|
||||
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
|
||||
|
||||
def unregister():
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
bpy.utils.unregister_class(cls)
|
||||
|
||||
Reference in New Issue
Block a user