mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-06 10:31:05 +00:00
Merge PR #2824
This commit is contained in:
commit
e175a272c7
3 files changed
+27
-3
No files matched your search
@@ -246,13 +246,18 @@ fn status(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
out["deleted"] = json!(settings.deleted.len());
|
||||
out["lensDistortionSolved"] = json!(settings.lens_distortion);
|
||||
let solve = ct::solve(¶ms);
|
||||
out["solved"] = json!(solve.is_some());
|
||||
// The solver interpolates the frames it could not solve: only a solve of every frame is
|
||||
// `solved` (what `camera.exportBlender` needs); one with gaps is `partial`.
|
||||
let solved_frames = solve.as_ref().map_or(0, |sv| sv.frames.iter().filter(|c| c.solved).count());
|
||||
let complete = solve.as_ref().is_some_and(|sv| solved_frames == sv.frames.len());
|
||||
out["solved"] = json!(complete);
|
||||
out["partial"] = json!(solve.is_some() && !complete);
|
||||
if let Some(sv) = &solve {
|
||||
let f = sv.focal();
|
||||
out["methodUsed"] = json!(sv.method_used.label());
|
||||
out["averageError"] = json!(sv.average_error);
|
||||
out["points"] = json!(sv.points.len());
|
||||
out["solvedFrames"] = json!(sv.frames.iter().filter(|c| c.solved).count());
|
||||
out["solvedFrames"] = json!(solved_frames);
|
||||
out["focalLength"] = json!(f);
|
||||
out["horizontalAngleOfView"] = json!(sv.hfov(f));
|
||||
out["groundPlane"] = json!(sv.ground.is_some());
|
||||
|
||||
@@ -238,6 +238,23 @@ fn blender_export_rejects_malformed_solves_without_panicking() {
|
||||
}
|
||||
}
|
||||
|
||||
/// A solve with unsolved (interpolated) frames is partial, not solved, so the status agrees with
|
||||
/// the export, which refuses it.
|
||||
#[test]
|
||||
fn solve_status_reports_unsolved_frames_as_partial() {
|
||||
let (mut s, lid, uid) = fixture(false);
|
||||
let st = s.execute("camera.solveStatus", json!({"layer": lid.0})).unwrap();
|
||||
assert_eq!((&st["solved"], &st["partial"], &st["solvedFrames"]), (&json!(true), &json!(false), &json!(3)), "{st}");
|
||||
let mut solve =
|
||||
ct::solve(&crate::camera_track::static_params(s.active_comp().unwrap().layer(lid).unwrap().props.find_group(uid).unwrap())).unwrap().as_ref().clone();
|
||||
solve.frames[1].solved = false;
|
||||
s.execute("prop.set", json!({"layer": lid.0, "path": "effects/#1/solve", "value": solve.to_json()})).unwrap();
|
||||
s.camera_pending.clear();
|
||||
let st = s.execute("camera.solveStatus", json!({"layer": lid.0})).unwrap();
|
||||
assert_eq!((&st["solved"], &st["partial"], &st["solvedFrames"]), (&json!(false), &json!(true), &json!(2)), "{st}");
|
||||
assert!(s.execute_checked("camera.exportBlender", json!({"layer": lid.0, "path": path("partial.py")})).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blender_export_respects_script_write_permission() {
|
||||
let (mut s, lid, _) = fixture(false);
|
||||
|
||||
+3
-1
@@ -476,7 +476,9 @@ undistort?, wait?}`) apply
|
||||
Effect ▸ Perspective ▸ 3D Camera Tracker (or reuse the layer's) and analyse it in the background:
|
||||
"Analyzing in background (step 1 of 2)" tracks features, "Solving camera" solves.
|
||||
`camera.analyze {layer?, effect?, wait?}` re-runs it, `camera.cancel` stops it without writing
|
||||
anything. `camera.solveStatus` reports `progress`/`banner`, `analyzed`, `solved`, `methodUsed`,
|
||||
anything. `camera.solveStatus` reports `progress`/`banner`, `analyzed`, `solved` (every frame
|
||||
solved), `partial` with `solvedFrames` of `frames` (the camera is interpolated on the other frames,
|
||||
and `camera.exportBlender` refuses such a solve), `methodUsed`,
|
||||
`averageError` (pixels), `focalLength`, `horizontalAngleOfView`, the current frame's `camera`
|
||||
(position, orientation, zoom), `groundPlane` and the solved `lensDistortion` (`k1`, `k2`, normalised by
|
||||
half the frame diagonal) when Solve Lens Distortion (`effects/#1/advanced/lensDistortion`, also on
|
||||
|
||||
Reference in new issue
Block a user