163 lines
5.2 KiB
Python
163 lines
5.2 KiB
Python
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)) |