mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-30 04:57:54 -06:00
62 lines
2.9 KiB
Python
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")
|