"""Generate pinned Blender 5.2 binary and ASCII STL capability fixtures for M12-07D.""" import hashlib import json import struct import sys from pathlib import Path import bpy 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 text(value): return value.decode("utf-8") if isinstance(value, bytes) else value def runtime_identity(): binary = Path(bpy.app.binary_path) return { "blenderVersion": text(bpy.app.version_string), "versionTuple": list(bpy.app.version), "buildDate": text(bpy.app.build_date), "buildTime": text(bpy.app.build_time), "buildHash": text(bpy.app.build_hash), "buildBranch": text(bpy.app.build_branch), "buildPlatform": text(bpy.app.build_platform), "buildType": text(bpy.app.build_type), "binarySha256": sha256_file(binary), } def create_scene(): bpy.ops.wm.read_factory_settings(use_empty=True) mesh = bpy.data.meshes.new("M12 STL Capability Mesh") mesh.from_pydata( [(-1.0, -1.0, 0.0), (1.0, -1.0, 0.0), (1.0, 1.0, 0.0), (-1.0, 1.0, 0.0)], [], [(0, 1, 2), (0, 2, 3)], ) mesh.update() obj = bpy.data.objects.new("M12 STL Capability", mesh) bpy.context.scene.collection.objects.link(obj) obj.select_set(True) bpy.context.view_layer.objects.active = obj return obj def export_stl(path, ascii_format): result = bpy.ops.wm.stl_export( filepath=str(path), ascii_format=ascii_format, export_selected_objects=True, apply_modifiers=False, evaluation_mode="DAG_EVAL_VIEWPORT", global_scale=1.0, forward_axis="NEGATIVE_Z", up_axis="Y", use_scene_unit=False, ) if "FINISHED" not in result: raise RuntimeError("Blender STL export did not finish: %s" % (result,)) def binary_semantics(path): payload = path.read_bytes() if len(payload) < 84: raise RuntimeError("STL binary is shorter than the header") count = struct.unpack_from("