import json import pathlib import sys import bpy def main(blend_path: str, output_path: str) -> None: bpy.ops.wm.open_mainfile(filepath=str(pathlib.Path(blend_path).resolve()), load_ui=False) obj = bpy.data.objects.get("RiggedShapeObject") if obj is None: raise RuntimeError("RiggedShapeObject is missing") # This golden isolates Blender's shape-key plus armature deformation. The saved fixture still # keeps Decimate enabled so modifier undo/redo tests exercise its normal default state. if obj.modifiers.get("Preview Decimate") is not None: obj.modifiers["Preview Decimate"].show_viewport = False scene = bpy.context.scene scene.frame_set(scene.frame_current) depsgraph = bpy.context.evaluated_depsgraph_get() evaluated = obj.evaluated_get(depsgraph) mesh = evaluated.to_mesh(preserve_all_data_layers=True, depsgraph=depsgraph) try: positions = [coordinate for vertex in mesh.vertices for coordinate in vertex.co] result = { "schemaVersion": 1, "fixture": "rigged_shape_scene.blend", "evaluator": "Blender Depsgraph", "blenderVersion": bpy.app.version_string, "frame": scene.frame_current, "object": obj.name, "mesh": obj.data.name, "vertexCount": len(mesh.vertices), "polygonCount": len(mesh.polygons), "positions": positions, "tolerance": {"maxPositionError": 1e-5, "rmsPositionError": 1e-6}, "modifierStack": [{"name": modifier.name, "type": modifier.type, "showViewport": modifier.show_viewport} for modifier in obj.modifiers], } finally: evaluated.to_mesh_clear() pathlib.Path(output_path).write_text(json.dumps(result, indent=2) + "\n", encoding="utf-8") if __name__ == "__main__": if "--" not in sys.argv or len(sys.argv) <= sys.argv.index("--") + 2: raise SystemExit("usage: blender -b --python generate-blender-deformation-golden.py -- input.blend output.json") arguments = sys.argv[sys.argv.index("--") + 1:] main(arguments[0], arguments[1])