black format

This commit is contained in:
2026-01-07 16:05:47 +01:00
parent f7c125ae7b
commit 3d65bb6e4d
49 changed files with 2817 additions and 2280 deletions
+9 -8
View File
@@ -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()
+40 -32
View File
@@ -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))
+62 -43
View File
@@ -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
View File
@@ -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
+6 -4
View File
@@ -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
View File
@@ -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)