"""Public-API oracle for scripts generated by src/tests/blender.rs; no Blender source dependency.""" import json import math import runpy import sys import bpy from bpy_extras.object_utils import world_to_camera_view from mathutils import Quaternion, Vector path = sys.argv[sys.argv.index("--") + 1] before = set(bpy.data.scenes) exported = runpy.run_path(path, run_name="__main__") scene = exported["EFFECTCRAFT_SCENE"] data = exported["DATA"] assert before.issubset(set(bpy.data.scenes)), "existing scenes were removed" assert scene not in before assert scene.frame_start == 101 and scene.frame_end == 103 assert abs(scene.render.fps / scene.render.fps_base - 30000 / 1001) < 1e-4 assert (scene.render.resolution_x, scene.render.resolution_y) == (640, 360) camera = scene.camera assert camera.animation_data.action is not None assert camera.data.animation_data.action is not None assert camera.data.sensor_fit == 'HORIZONTAL' metadata = json.loads(bpy.data.texts[scene["effectcraft_metadata_text"]].as_string()) assert metadata["solve"]["averageError"] == 0.12 cloud = scene.objects["Solved Track Points"] assert len(cloud.data.vertices) == 2 assert cloud.hide_render assert cloud.data.attributes["track_id"].data[0].value == 7 assert any(obj.name.startswith("Solved Ground Plane") for obj in scene.objects) for i, sample in enumerate(data["frames"]): scene.frame_set(sample["frame"]) bpy.context.view_layer.update() assert abs(camera.data.lens - sample["lens"]) < 1e-5 assert abs(camera.data.dof.focus_distance - sample["focus"]) < 1e-5 assert abs(camera.data.dof.aperture_fstop - sample["fstop"]) < 1e-5 assert camera.data.dof.use_dof assert (camera.location - Vector(sample["location"])).length < 1e-5 raw = data["solve"]["frames"][i] rot = Vector(raw["rot"]) rotation = Quaternion(rot.normalized(), rot.length).to_matrix() if rot.length else Quaternion().to_matrix() for vertex, point in zip(cloud.data.vertices, data["solve"]["points"]): relative = rotation @ (Vector(point["pos"]) - Vector(raw["center"])) expected = (raw["focal"] * relative.x / relative.z + 320, raw["focal"] * relative.y / relative.z + 180) projected = world_to_camera_view(scene, camera, vertex.co) actual = (projected.x * 640, (1.0 - projected.y) * 360) assert math.dist(actual, expected) < 0.002, (sample["frame"], actual, expected) if "Video not found" not in " ".join(data["warnings"]): background = camera.data.background_images[0] assert background.image.source == 'MOVIE' assert tuple(background.image.size) == (640, 360) user = background.image_user actual_source = sample["frame"] - user.frame_start + user.frame_offset assert actual_source == sample["sourceFrame"], (actual_source, sample["sourceFrame"]) assert user.use_auto_refresh print("EFFECTCRAFT_BLENDER_ORACLE_OK")