Files
effectcraft/crates/engine/tests/blender_scene_oracle.py
T

62 lines
2.9 KiB
Python

"""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")