Files
workinf_Blender_Wasm/tools/web/generate-nonmesh-desktop-golden.py
2026-08-12 04:47:48 -04:00

83 lines
3.0 KiB
Python

import json
import os
import sys
import bpy
TYPE_NAMES = {
"CURVE": "CURVE",
"SURFACE": "SURFACE",
"FONT": "FONT",
"META": "METABALL",
}
def rounded(value):
return round(float(value), 7)
def geometry_record(obj, depsgraph):
evaluated = obj.evaluated_get(depsgraph)
mesh = evaluated.to_mesh()
try:
mesh.calc_loop_triangles()
positions = [component for vertex in mesh.vertices for component in vertex.co]
edge_indices = [index for edge in mesh.edges for index in edge.vertices]
indices = [index for triangle in mesh.loop_triangles for index in triangle.vertices]
point_count = len(mesh.vertices)
bounds_min = [min((vertex.co[axis] for vertex in mesh.vertices), default=0.0) for axis in range(3)]
bounds_max = [max((vertex.co[axis] for vertex in mesh.vertices), default=0.0) for axis in range(3)]
centroid = [
sum((vertex.co[axis] for vertex in mesh.vertices), 0.0) / point_count
if point_count else 0.0
for axis in range(3)
]
return {
"object": obj.name,
"sourceType": TYPE_NAMES[obj.type],
"vertexCount": point_count,
"edgeCount": len(mesh.edges),
"triangleCount": len(mesh.loop_triangles),
"boundsMin": [rounded(value) for value in bounds_min],
"boundsMax": [rounded(value) for value in bounds_max],
"centroid": [rounded(value) for value in centroid],
"surfaceArea": rounded(sum((triangle.area for triangle in mesh.loop_triangles), 0.0)),
"positionMoment": rounded(sum((index + 1) * value for index, value in enumerate(positions))),
"edgeIndexMoment": sum((index + 1) * (value + 1) for index, value in enumerate(edge_indices)),
"indexMoment": sum((index + 1) * (value + 1) for index, value in enumerate(indices)),
}
finally:
evaluated.to_mesh_clear()
def main(output_path):
depsgraph = bpy.context.evaluated_depsgraph_get()
records = [
geometry_record(obj, depsgraph)
for obj in bpy.context.scene.objects
if obj.type in TYPE_NAMES
]
records.sort(key=lambda record: record["object"])
payload = {
"schemaVersion": 1,
"blenderVersion": bpy.app.version_string,
"fixture": os.path.basename(bpy.data.filepath),
"tolerance": {
"coordinate": 0.00001,
"surfaceArea": 0.0001,
"positionMoment": 0.001,
},
"geometries": records,
}
with open(output_path, "w", encoding="ascii") as output:
json.dump(payload, output, indent=2, sort_keys=True)
output.write("\n")
print(f"nonmesh-desktop-golden-generated output={os.path.abspath(output_path)} geometries={len(records)}")
if __name__ == "__main__":
if "--" not in sys.argv or len(sys.argv) <= sys.argv.index("--") + 1:
raise SystemExit("usage: blender -b fixture.blend --python generate-nonmesh-desktop-golden.py -- output.json")
main(sys.argv[sys.argv.index("--") + 1])