Files
workinf_Blender_Wasm/tools/web/generate-blender-family-inventory.py
mes123456 10640aeb3c
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled
Govern task context and advance execution pointer
2026-08-20 06:02:43 -04:00

130 lines
4.7 KiB
Python

#!/usr/bin/env python3
"""Generate deterministic Blender 5.2 modifier, constraint, and node inventories."""
import hashlib
import json
import pathlib
import sys
import bpy
def text(value):
return value.decode("utf-8", errors="replace") if isinstance(value, bytes) else str(value)
def sha256_file(path):
digest = hashlib.sha256()
with open(path, "rb") as handle:
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def property_info(prop):
result = {
"identifier": prop.identifier,
"type": prop.type,
"readOnly": bool(prop.is_readonly),
}
if hasattr(prop, "array_length"):
result["arrayLength"] = prop.array_length
return result
def enum_item_info(item):
return {
"identifier": item.identifier,
"name": text(item.name),
"description": text(item.description),
"value": item.value,
}
def enum_inventory(rna_type, property_name):
enum = rna_type.bl_rna.properties[property_name].enum_items
entries = [enum_item_info(item) for item in enum]
entries.sort(key=lambda item: item["identifier"])
return entries
def node_properties(rna):
properties = [property_info(prop) for prop in rna.properties if prop.identifier != "rna_type"]
properties.sort(key=lambda prop: prop["identifier"])
return properties
def node_inventory():
entries = []
for class_name in sorted(name for name in dir(bpy.types) if not name.startswith("_")):
cls = getattr(bpy.types, class_name)
try:
if not isinstance(cls, type) or not issubclass(cls, bpy.types.Node) or cls is bpy.types.Node:
continue
is_registered = getattr(cls, "is_registered_node_type", None)
if is_registered is None or not is_registered():
continue
rna = getattr(cls, "bl_rna", None)
identifier = text(getattr(rna, "identifier", "")) if rna else ""
family = next((prefix[:-4] for prefix in ("ShaderNode", "GeometryNode", "CompositorNode") if identifier.startswith(prefix)), None)
if not family:
continue
entries.append({
"family": family,
"className": class_name,
"rnaIdentifier": identifier,
"properties": node_properties(rna),
})
except (AttributeError, RuntimeError, TypeError):
continue
entries.sort(key=lambda entry: (entry["family"], entry["rnaIdentifier"], entry["className"]))
return entries
def main():
if "--" not in sys.argv or len(sys.argv[sys.argv.index("--") + 1:]) != 1:
raise SystemExit("usage: blender --background --factory-startup --python generate-blender-family-inventory.py -- OUTPUT.json")
output = pathlib.Path(sys.argv[sys.argv.index("--") + 1]).resolve()
version = tuple(int(value) for value in bpy.app.version)
if version != (5, 2, 0):
raise RuntimeError(f"expected Blender 5.2.0, got {version}")
modifiers = enum_inventory(bpy.types.Modifier, "type")
constraints = enum_inventory(bpy.types.Constraint, "type")
nodes = node_inventory()
family_counts = {family: sum(1 for node in nodes if node["family"] == family) for family in ("Shader", "Geometry", "Compositor")}
binary_path = pathlib.Path(bpy.app.binary_path).resolve()
inventory = {
"schemaVersion": 1,
"task": "M15-01C",
"operation": "BLENDER_FAMILY_INVENTORY",
"sourceAnchor": "blender-5.2.0/source/blender/makesrna",
"runtime": {
"blenderVersion": text(bpy.app.version_string),
"versionTuple": list(version),
"buildHash": text(bpy.app.build_hash),
"buildBranch": text(bpy.app.build_branch),
"buildPlatform": text(bpy.app.build_platform),
"buildType": text(bpy.app.build_type),
"buildDate": text(bpy.app.build_date),
"buildTime": text(bpy.app.build_time),
"binarySha256": sha256_file(binary_path),
},
"summary": {
"modifierCount": len(modifiers),
"constraintCount": len(constraints),
"nodeCount": len(nodes),
"nodesByFamily": family_counts,
},
"modifiers": modifiers,
"constraints": constraints,
"nodes": nodes,
"nextTask": "M15-01D",
}
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(json.dumps(inventory, indent=2, sort_keys=True) + "\n", encoding="utf-8")
print(f"blender-family-inventory-generated modifiers={len(modifiers)} constraints={len(constraints)} nodes={len(nodes)} output={output}")
if __name__ == "__main__":
main()