106 lines
3.7 KiB
Python
106 lines
3.7 KiB
Python
import json
|
|
import pathlib
|
|
import sys
|
|
|
|
import bpy
|
|
|
|
|
|
NIL_UUID = "00000000-0000-0000-0000-000000000000"
|
|
|
|
|
|
def catalog_records(path):
|
|
version = None
|
|
records = []
|
|
for line_number, raw_line in enumerate(path.read_text(encoding="utf-8").splitlines(), 1):
|
|
line = raw_line.strip()
|
|
if not line or line.startswith("#"):
|
|
continue
|
|
if version is None:
|
|
if not line.startswith("VERSION "):
|
|
raise RuntimeError(f"catalog definition line {line_number} has no version marker")
|
|
version = int(line.removeprefix("VERSION "))
|
|
continue
|
|
catalog_id, catalog_path, simple_name = line.split(":", 2)
|
|
records.append({
|
|
"catalogId": catalog_id,
|
|
"path": catalog_path,
|
|
"simpleName": simple_name.strip(),
|
|
"parentPath": catalog_path.rpartition("/")[0] or None,
|
|
})
|
|
return version, records
|
|
|
|
|
|
def custom_property_value(value):
|
|
if isinstance(value, (bool, int, float, str)):
|
|
return value
|
|
if hasattr(value, "to_list"):
|
|
return value.to_list()
|
|
if isinstance(value, (list, tuple)):
|
|
return list(value)
|
|
raise RuntimeError(f"unsupported asset custom property type {type(value).__name__}")
|
|
|
|
|
|
def asset_record(id_type, asset):
|
|
metadata = asset.asset_data
|
|
custom_properties = [
|
|
{
|
|
"name": name,
|
|
"type": type(metadata[name]).__name__.upper(),
|
|
"value": custom_property_value(metadata[name]),
|
|
}
|
|
for name in sorted(metadata.keys())
|
|
]
|
|
return {
|
|
"idType": id_type,
|
|
"name": asset.name,
|
|
"catalogId": metadata.catalog_id or NIL_UUID,
|
|
"catalogSimpleName": metadata.catalog_simple_name,
|
|
"author": metadata.author,
|
|
"description": metadata.description,
|
|
"copyright": metadata.copyright,
|
|
"license": metadata.license,
|
|
"tags": [tag.name for tag in metadata.tags],
|
|
"activeTag": metadata.active_tag,
|
|
"usePreferredImportMethod": metadata.use_preferred_import_method,
|
|
"preferredImportMethod": metadata.preferred_import_method,
|
|
"customProperties": custom_properties,
|
|
}
|
|
|
|
|
|
def main(catalog_file, output_file):
|
|
catalog_path = pathlib.Path(catalog_file).resolve()
|
|
output_path = pathlib.Path(output_file).resolve()
|
|
version, catalogs = catalog_records(catalog_path)
|
|
assets = []
|
|
for id_type, collection in (
|
|
("MATERIAL", bpy.data.materials),
|
|
("OBJECT", bpy.data.objects),
|
|
("WORLD", bpy.data.worlds),
|
|
):
|
|
assets.extend(asset_record(id_type, asset) for asset in collection if asset.asset_data is not None)
|
|
assets.sort(key=lambda item: (item["idType"], item["name"]))
|
|
report = {
|
|
"schemaVersion": 1,
|
|
"task": "M12-01B",
|
|
"enablingTask": True,
|
|
"parityStateChange": False,
|
|
"blenderVersion": ".".join(str(value) for value in bpy.app.version),
|
|
"catalogDefinition": {
|
|
"fileName": catalog_path.name,
|
|
"version": version,
|
|
"records": catalogs,
|
|
},
|
|
"assets": assets,
|
|
"nextTask": "M12-01C",
|
|
}
|
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
output_path.write_text(json.dumps(report, indent=2, ensure_ascii=True) + "\n", encoding="utf-8", newline="\n")
|
|
print(f"m12-asset-catalog-v1-canonical catalogs={len(catalogs)} assets={len(assets)} output={output_path}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
|
|
if len(arguments) != 2:
|
|
raise SystemExit("usage: blender --background FIXTURE --python export-asset-catalog-v1.py -- CATALOG_FILE OUTPUT_JSON")
|
|
main(*arguments)
|