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))