178 lines
5.7 KiB
Python
178 lines
5.7 KiB
Python
import argparse
|
|
import sys
|
|
import json
|
|
from pathlib import Path
|
|
import bpy
|
|
import re
|
|
import uuid
|
|
from itertools import groupby
|
|
|
|
from asset_library.constants import ASSETLIB_FILENAME, MODULE_DIR
|
|
from asset_library.common.bl_utils import thumbnail_blend_file
|
|
from asset_library.common.functions import command
|
|
|
|
|
|
@command
|
|
def bundle_library(
|
|
source_directory,
|
|
bundle_directory,
|
|
template_info,
|
|
thumbnail_template,
|
|
template=None,
|
|
data_file=None,
|
|
):
|
|
|
|
field_pattern = r"{(\w+)}"
|
|
asset_data_path = Path(bundle_directory) / ASSETLIB_FILENAME
|
|
|
|
glob_pattern = re.sub(field_pattern, "*", template)
|
|
re_pattern = re.sub(field_pattern, r"([\\w -_.]+)", template)
|
|
re_pattern = re_pattern.replace("?", ".")
|
|
|
|
field_names = re.findall(field_pattern, template)
|
|
|
|
asset_file_datas = []
|
|
for f in sorted(Path(source_directory).glob(glob_pattern)):
|
|
rel_path = f.relative_to(source_directory).as_posix()
|
|
|
|
field_values = re.findall(re_pattern, rel_path)[0]
|
|
field_data = {k: v for k, v in zip(field_names, field_values)}
|
|
|
|
name = field_data.get("name", f.stem)
|
|
thumbnail = (f / thumbnail_template.format(name=name)).resolve()
|
|
asset_data = (f / template_info.format(name=name)).resolve()
|
|
|
|
catalogs = sorted(
|
|
[v for k, v in sorted(field_data.items()) if re.findall("cat[0-9]+", k)]
|
|
)
|
|
catalogs = [c.replace("_", " ").title() for c in catalogs]
|
|
|
|
if not thumbnail.exists():
|
|
thumbnail_blend_file(f, thumbnail)
|
|
|
|
asset_data = {
|
|
"catalog": "/".join(catalogs),
|
|
"preview": thumbnail.as_posix(), #'./' + bpy.path.relpath(str(thumbnail), start=str(f))[2:],
|
|
"filepath": f.as_posix(), #'./' + bpy.path.relpath(str(f), start=str(asset_data_path))[2:],
|
|
"name": name,
|
|
"tags": [],
|
|
"metadata": {"filepath": f.as_posix()},
|
|
}
|
|
|
|
asset_file_datas.append(asset_data)
|
|
|
|
# Write json data file to store all asset found
|
|
print(f"Writing asset data file to, {asset_data_path}")
|
|
asset_data_path.write_text(json.dumps(asset_file_datas, indent=4))
|
|
|
|
# script = MODULE_DIR / 'common' / 'bundle_blend.py'
|
|
# cmd = [bpy.app.binary_path, '--python', str(script), '--', '--filepath', str(filepath)]
|
|
# print(cmd)
|
|
# subprocess.call(cmd)
|
|
|
|
|
|
@command
|
|
def bundle_blend(filepath, depth=0):
|
|
# print('Bundle Blend...')
|
|
filepath = Path(filepath)
|
|
|
|
# asset_data_path = get_asset_datas_file(filepath)
|
|
|
|
asset_data_path = filepath / ASSETLIB_FILENAME
|
|
blend_name = filepath.name.replace(" ", "_").lower()
|
|
blend_path = (filepath / blend_name).with_suffix(".blend")
|
|
|
|
if not asset_data_path.exists():
|
|
raise Exception(f"The file {asset_data_path} not exist")
|
|
|
|
catalog_path = get_catalog_path(filepath)
|
|
catalog_data = read_catalog(catalog_path)
|
|
|
|
asset_file_data = json.loads(asset_data_path.read_text())
|
|
# asset_file_data = {i['catalog']:i for i in asset_file_data}
|
|
|
|
if depth == 0:
|
|
groups = [asset_file_data]
|
|
else:
|
|
asset_file_data.sort(key=lambda x: x["catalog"].split("/")[:depth])
|
|
groups = groupby(asset_file_data, key=lambda x: x["catalog"].split("/")[:depth])
|
|
|
|
# progress = 0
|
|
total_assets = len(asset_file_data)
|
|
|
|
i = 0
|
|
for sub_path, asset_datas in groups:
|
|
bpy.ops.wm.read_homefile(use_empty=True)
|
|
|
|
for asset_data in asset_datas:
|
|
blend_name = sub_path[-1].replace(" ", "_").lower()
|
|
blend_path = Path(filepath, *sub_path, blend_name).with_suffix(".blend")
|
|
|
|
if i % int(total_assets / 100) == 0:
|
|
print(f"Progress: {int(i / total_assets * 100)}")
|
|
|
|
col = bpy.data.collections.new(name=asset_data["name"])
|
|
|
|
# Seems slow
|
|
# bpy.context.scene.collection.children.link(col)
|
|
col.asset_mark()
|
|
|
|
with bpy.context.temp_override(id=col):
|
|
bpy.ops.ed.lib_id_load_custom_preview(filepath=asset_data["preview"])
|
|
|
|
col.asset_data.description = asset_data.get("description", "")
|
|
|
|
catalog_name = asset_data["catalog"]
|
|
catalog = catalog_data.get(catalog_name)
|
|
if not catalog:
|
|
catalog = {"id": str(uuid.uuid4()), "name": catalog_name}
|
|
catalog_data[catalog_name] = catalog
|
|
|
|
col.asset_data.catalog_id = catalog["id"]
|
|
|
|
for k, v in asset_data.get("metadata", {}).items():
|
|
col.asset_data[k] = v
|
|
|
|
i += 1
|
|
|
|
print(f"Saving Blend to {blend_path}")
|
|
|
|
blend_path.mkdir(exist_ok=True, parents=True)
|
|
bpy.ops.wm.save_as_mainfile(filepath=str(blend_path), compress=True)
|
|
|
|
write_catalog(catalog_path, catalog_data)
|
|
|
|
bpy.ops.wm.quit_blender()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(
|
|
description="bundle_blend",
|
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
)
|
|
|
|
parser.add_argument("--source-path")
|
|
parser.add_argument("--bundle-path")
|
|
parser.add_argument("--asset-data-template")
|
|
parser.add_argument("--thumbnail-template")
|
|
parser.add_argument("--template", default=None)
|
|
parser.add_argument("--data-file", default=None)
|
|
parser.add_argument("--depth", default=0, type=int)
|
|
|
|
if "--" in sys.argv:
|
|
index = sys.argv.index("--")
|
|
sys.argv = [sys.argv[index - 1], *sys.argv[index + 1 :]]
|
|
|
|
args = parser.parse_args()
|
|
|
|
bundle_library(
|
|
source_directory=args.source_directory,
|
|
bundle_directory=args.bundle_directory,
|
|
template_info=args.template_info,
|
|
thumbnail_template=args.thumbnail_template,
|
|
template=args.template,
|
|
data_file=args.data_file,
|
|
)
|
|
|
|
bundle_blend(filepath=args.bundle_directory, depth=args.depth)
|