import argparse import sys import os import json import uuid import subprocess import bpy from pathlib import Path from asset_library.common.functions import create_catalog_file from asset_library.common.file_utils import get_last_files from asset_library.constants import ASSETLIB_FILENAME """ ### Create asset collection ## create_collection_library: generate all category blend from json ## if source_directory is set, call create_collection_json ## # create_collection_json: ## # scan marked blend, create json and call create_catalog_file ## # create_catalog_file ## # create catalog file from json file ### Json Structure [ { 'name': 'chars/main', 'id': '013562-56315-4563156-123', 'children': [ { 'filepath' : '/z/...', 'name' : 'collection name', 'tags' : ['variation', 'machin', 'chose'], 'metadata' : {'filepath': '$PROJECT/...', 'version' : 'mushable'} }, { 'filepath' : '/z/...', }, ], }, ] """ def create_collection_json(path, source_directory): """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 ) 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)}") ## 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] ## 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, ): ## 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 ) if col_list is None: col_list = [] category_data = { "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") for name in col_name_list: data = { "filepath": blend, "name": name, # 'tags' : [], "metadata": {"filepath": blend_source_path}, } col_list.append(data) 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}") return ## scan source and build json in assetlib dir root create_collection_json(path, source_directory) json_path = Path(path) / ASSETLIB_FILENAME if not json_path.exists(): 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' # 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) subprocess.call(cmd) 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 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))