183 lines
5.4 KiB
Python
183 lines
5.4 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))
|