Commit Graph
101 Commits
Author SHA1 Message Date
bflatastic 334bf0f785 Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	crates/engine/Cargo.toml
2026-10-30 17:22:12 +07:00
BFlat 3d285116d8 Merge pull request #1539 from nanox333/feat/sam2-roto-tracker
Roto Brush: follow the object with SAM 2.1 (Tiny, Small, Base+, Large; optional models)
2026-10-30 17:02:45 +07:00
bflatastic 2a72f03872 Merge remote-tracking branch 'origin/main' into HEAD
# Conflicts:
#	apps/effectcraft-cli/tests/it/cli.rs
#	crates/engine/src/output_guard.rs
#	docs/agents.md
2026-10-30 16:38:01 +07:00
Kristian Myram a4f5c516ed #1539: validate benchmark inputs and preserve shared refinement strokes 2026-10-30 10:00:33 +01:00
Kristian Myram 41148e9b72 #1743: validate background and bridged exports in their owning session 2026-10-30 09:41:38 +01:00
Kristian Myram 76f82d7d55 #1539: clarify fallback visibility and benchmark correction rounds 2026-10-30 08:53:17 +01:00
Kristian Myram baa1ca31b3 #1539: preserve stroke corrections and current main APIs 2026-10-30 08:49:47 +01:00
Kristian Myram 365abf0f2d Roto Brush: discard failed tracks and bound SAM2 caches (#1539) 2026-10-30 08:43:33 +01:00
Claude 66d8e5e948 SAM 2 roto tracker: review fixes (direction-limited tracking, non-blocking model reload, per-object start passes, loader dispatch, CLI errors, hints)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RDvxCS8xcR28VArjzn1x7U
2026-10-30 08:43:32 +01:00
Kristian MyramandClaude Sonnet 5.5 ac8765bf67 S2.65: help and bench follow all four SAM 2 sizes; tests for the size configs and detection
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-30 08:43:31 +01:00
Kristian MyramandClaude Sonnet 5.5 65c5eda39a S2.53: bench --roto takes the user's own clips and reports peak memory
--clip FRAMES_DIR --truth MASKS_DIR runs the trackers on image sequences with true
mattes (strokes made from the truth; nothing is bundled or copied), tested end to end.
Trackers report the most memory their banks held (peakMB column).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-30 08:43:31 +01:00
Kristian MyramandClaude Sonnet 5.5 a39cee8104 S2.51: bench --roto --fixes counts the corrections each tracker needs
Simulated user paints a foreground stroke through the true object and a background
stroke on the biggest false positive on the first frame under IoU 0.9, up to 6
rounds. SAM 2 needs none on every clip; classical and MobileSAM need more than 6 on
occlusion and re-entry. All trackers now take strokes on any frame.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-30 08:43:31 +01:00
Kristian MyramandClaude Sonnet 5.5 b72637bb55 S2.50: bench --roto compares classical, MobileSAM and SAM 2
--mobilesam FILE; results recorded in docs/roto-brush-sam2.md (re-entry clip:
0.632 classical, 0.499 MobileSAM, 0.975 SAM 2).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-30 08:43:30 +01:00
Kristian MyramandClaude Sonnet 5.5 4655425d01 S2.50: bench --roto adds the SAM 2 tracker column
run_tracker follows the object with the model's video tracker on the same
synthetic clips (--sam2 FILE or the installed weights). 12 frames, dev build:
re-entry clip mean IoU 0.632 classical vs 0.975 SAM 2 (0.000 vs 0.967 after
the object returns); the other clips 0.98 vs 0.99.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-30 08:43:30 +01:00
Kristian MyramandClaude Sonnet 5.5 71e44deb84 S2.50: effectcraft-cli bench --roto on synthetic clips
Synthetic Roto Brush clips with known mattes (movement, lighting change,
occlusion, leaving and re-entering) and a runner that compares the classical
engine with MobileSAM when installed. Needs no weights; SAM 2 plugs in later.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-30 08:43:29 +01:00
Kristian MyramandClaude Sonnet 5.5 d2930b2554 Fix #1743 (follow-up): commands that write to a given path never replace footage, a proxy or the project file
Session::write_output (and refuse_export) is the one place that checks; Save Frame As
(PNG/PSD/EXR), Export Lottie, Save a Copy (+XML), Collect Files, Export Timeline (and its
pre-rendered movies), Export Template, Save Animation Preset, Export Guides and Export
Shortcuts write through it. The control channel's render.frame/ui.screenshot, MCP
render_frame and CLI render-frame --out check first (new query file.checkOutput for the
bridged cases). Save/Save As/auto-save are untouched.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-30 08:06:48 +01:00
Kristian MyramandClaude Sonnet 5.5 615c4cdffb Render Queue: two outputs of one job never write the same file, and default names avoid the queue's other outputs
Two queue items that resolve to one output (the same comp added twice, a duplicated item) replaced
each other's file inside one job. Nothing is on disk when the job starts, so no check said anything.

- A default output name (renderQueue.add, render.preRender, comp.saveFrameAs {queue},
  file.createProxy) that another item of the queue writes, in any output module or segment, is
  numbered like a footage collision: Main.mp4, Main_1.mp4, Main_2.mp4. Sequences are compared by
  the frames they write, so two stills of one comp at different times keep their names. Names a
  caller gave and names already stored in items are never changed.
- Outputs of one job that still name the same file (explicit names, renderQueue.duplicate, output
  modules, segments) refuse the whole render before anything is written, naming both items.
  Sequences clash only on frames both write; a later item with Skip Existing Files leaves the
  earlier item's frames alone; items refused for footage take no part.

Refusing the whole render, not just the later item: which of two items should keep the file is the
user's to say, and failing only the later one would leave a half-rendered queue found after they
left. renderQueue.duplicate stays a verbatim copy so the clash is reported, not hidden.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RDvxCS8xcR28VArjzn1x7U
2026-10-30 08:04:32 +01:00
bflatastic b9a86f5139 Merge main into #1758; no conflicts 2026-10-30 09:17:08 +07:00
bflatastic 0039081952 Merge main into #2567; keep both test modules, and convert four layer stacks main's new render tests assign as Vec<Layer> with .into() 2026-10-30 06:01:06 +07:00
BFlat b669e4a951 Merge pull request #2476 from ashokram-si/feat/targa-sequence-output
Export: Targa (.tga) sequence output, 24-bit RGB or 32-bit RGB + Alpha
2026-10-30 01:19:27 +07:00
BFlat e6e0c98c20 Merge pull request #2311 from marcoarnulfo/feat/run-commands
CLI: run --commands reads {"command", "params"} steps from a JSON or JSON Lines file, or standard input (#2251)
2026-10-30 01:17:37 +07:00
BFlat 5be5ad1167 Merge pull request #1651 from MatejKozlovsky/cli-warn-logging
CLI: log warnings to stderr by default
2026-10-30 00:09:39 +07:00
Claude 7583fb914a Merge main into fix/1743-render-overwrite-confirm
output_guard joins the split engine lib.rs; the overwrite tests move to tests/render_overwrite.rs
(#2491) and the regression workflow's test filter follows.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RDvxCS8xcR28VArjzn1x7U
2026-10-29 10:31:40 +00:00
Eduardo EspinosaandClaude Opus 5.5 e1d66a3c5c perf: share unchanged layers between undo states
Every undoable edit keeps the previous project for undo, so the comp it touches
is shared and Arc::make_mut deep-copies it: every layer and every keyframe. An
edit therefore costs time in proportion to the comp's size, and a script that
sets many keyframes in a big comp goes quadratic (a 1,600-layer build with
~100k sampled keys took ~45 minutes).

Comp::layers is now a Layers collection backed by Vec<Arc<Layer>>: copying the
stack copies pointers, and only the layer an edit changes is copied. The API
mirrors Vec<Layer>; serialized form is unchanged (a list of layers).
Comp::layer_mut and the iter_mut().filter/find call sites use find_mut /
iter_mut_where so they copy only the layers they actually change.

- prop.addKey in a 400-layer comp: 1.36 ms -> 0.16 ms per key (flat in comp size)
- the 1,600-layer script build: ~45 min -> 47 s, frames pixel-identical
- regression tests: an edit leaves the other layers shared with undo; layers
  round-trip as a plain list

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VkpGcKfWyCudfSsQNiWAaG
2026-10-28 22:20:23 -04:00
Dylan M. Taylor 5fa72d83de Refactor the effectcraft apps for strict Clippy checks 2026-10-28 06:09:21 +00:00
Matej Kozlovský 3ad8ba9581 CLI: log warnings to stderr by default
The CLI installed no logger, so GPU warnings (a declined frame, out of
memory, fallback to the CPU) were dropped and an export silently rendered
on the CPU. Install the engine logger with a `warn` default (RUST_LOG
still overrides). Split out of #1415.
2026-10-27 18:52:16 +01:00
ashokram-si de27e1ea0a Merge main into feat/targa-sequence-output 2026-10-27 10:46:47 +05:30
skylar taylor-barrick af354e49e8 M0.37: resolve relocated test binaries and expose GPU failures 2026-10-26 16:22:51 +01:00
ashokram-si c51a08ceb4 Export: Targa (.tga) sequence output, 24-bit RGB or 32-bit RGB + Alpha
After Effects lists Targa among its still-image output formats; EffectCraft
imported Targa (#745) but could not render to it.

- OutputFormat::TargaSequence ("Targa Sequence", `.tga`, numbered like the
  other sequences; `tga` / `targa` as a format name or output extension).
- Written by the `image` crate's Targa encoder (its `tga` feature, already
  enabled in effectcraft-media; no new crates, Cargo.lock unchanged), with
  run-length compression off: an 18-byte header, top-left origin, 24-bit BGR
  for RGB, 32-bit BGRA with 8 alpha bits in the image descriptor for
  RGB + Alpha (straight or premultiplied), 8-bit grey for Alpha.
- The render queue's size estimate counts the uncompressed bytes.
- CLI usage, the renderQueue command specs, README, architecture.md and
  file-format-parity.md name the new format.

Tests: each Targa frame holds exactly the pixels of the PNG sequence of the
same job, with the expected header, numbering and size; the frames read back
through the Targa importer as the same picture (straight, and premultiplied
when interpreted so); the image-sequence round trip, the format parser and
the renderQueue commands cover it too.
2026-10-26 15:34:12 +05:30
Kristian Myram 39137fbd78 #1743: report refused queue items to CLI callers 2026-10-24 23:28:42 +00:00
Marco Arnulfo 2c683a1ae1 CLI: run --commands reads {"command", "params"} steps from a JSON or JSON Lines file, or standard input (#2251) 2026-10-24 20:09:43 +02:00
aiongg aa65e498ce Merge #1948: CLI: preserve template composition names when rendering (@tylerjenningsw) 2026-10-24 02:09:49 +00:00
aiongg 86623ee062 Merge #1906: xtask bench: run on Windows (scenario commands from an args file, os error 206) (@ded-achtung) 2026-10-23 23:32:52 +00:00
aiongg 0173abde8c CI: dev-profile gate, one test binary per crate, nextest, line tables only (#2235)
* Dev profile: line tables only for workspace crates, no debug info for dependencies

* xtask ci: dev-profile gate, nextest, tests without examples, wasm --keep-going

* One integration-test binary per crate

* xtask ci: run effectcraft-gpu's shared-device tests in one cargo test process

* xtask ci: run every stage and report all failures

* xtask ci: name the stage type (clippy type_complexity)

* xtask ci: run every test pass and report all failures

* cargo fmt
2026-10-23 12:59:51 -04:00
tylerjenningsw 5fb5666d78 Tests: template render outputs keep the template composition's name (#1937) 2026-10-20 09:56:25 -04:00
tylerjenningsw b24438f9bb CLI: template renders keep the template composition's name (#1937) 2026-10-20 09:40:59 -04:00
dedandClaude Opus 5.5 35691f8d19 G5: bench builds scenarios from an args file on Windows
xtask bench passed the whole layers scenario on one command line, longer
than Windows' 32 767-character limit (os error 206), so no scenario past
demo ran. effectcraft-cli run takes --args-file F (one argument per line)
and bench writes its commands there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 21:29:59 +03:00
FredApps b0acbbe121 CLI: regression tests for render --progress (#1778) and template media values (#1787)
- render --progress with a piped stderr writes well-formed
  `progress <done> <total> <elapsed> <left|->` lines, one per change, and
  the same render without the flag writes none.
- A template's Media Replacement control takes {"path"|"file"|"media": …},
  is found by name ignoring case, and a path that cannot be imported fails
  with an error naming the control and the path.
2026-10-18 16:46:06 +02:00
Brandon Thomas 043eb5a157 Merge pull request #1787 2026-10-18 09:35:35 -04:00
Brandon Thomas 692feb7925 Merge pull request #1778 2026-10-18 09:35:35 -04:00
MarekSpodBiedry c74e67ca32 Let render --template --values fill a media replacement control with a file path (#1780) 2026-10-18 13:53:15 +02:00
ArchersIntelandClaude Sonnet 5.5 c6b700fe83 feat(cli): render --progress reports frames on stderr when it is not a terminal
A terminal already gets a live `[1/1] frame 16/180 ... ~14.2s left` line while
`effectcraft-cli render` runs. A program that starts the CLI (FilmCraft runs it to
render a composition for a clip) reads stderr through a pipe, so it saw nothing
until the render ended.

`--progress` prints one line per update instead, at most four a second:

    progress <frames done> <frames total> <seconds elapsed> <seconds left, or - when unknown>

It has no effect on a terminal, which keeps its live line. Without the flag
nothing changes.

Documented in the usage text, the module header and docs/agents.md.

Tests: cargo fmt --check and cargo clippy --all-targets -D warnings pass; the
effectcraft-cli tests pass except render_out_is_relative_to_the_working_directory,
which already fails on Windows (it compares a canonicalize()d `\?\` path with the
path the CLI prints) and is unrelated to this change.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-18 02:17:33 -05:00
Matej Kozlovský f8bd967861 gpu: honour wgpu env overrides in headless/CLI (with_env, WGPU_ADAPTER_NAME, WGPU_POWER_PREF)
GpuContext::request() now applies InstanceDescriptor::with_env() (WGPU_BACKEND,
WGPU_DX12_COMPILER, WGPU_VALIDATION, WGPU_DEBUG, ...), the same variables the
desktop app honours via egui-wgpu, and requests PowerPreference::from_env(),
defaulting to HighPerformance (an unknown WGPU_POWER_PREF logs a warning).

WGPU_ADAPTER_NAME (CLI/headless only; the desktop ignores it) picks the first
adapter whose name contains the trimmed value, case-insensitively. Empty or
blank counts as unset. Only the name is matched (backend via WGPU_BACKEND). A non-matching name is an
error that says so and lists each distinct adapter once as 'name (backend)', instead of wgpu::util::initialize_adapter_from_env's panic;
no adapters at all gets its own message.
2026-10-16 20:12:35 +02:00
BFlat 16c6180d91 Merge pull request #1391 from sanyamsingh001/fix/cli-render-empty-r49
Honor --empty when rendering from the CLI
2026-10-16 19:03:09 +07:00
BFlat 67f3a0513c Merge pull request #1313 from sanyamsingh001/fix/cli-input-preservation-r48
Preserve CLI template inputs when output is a hard link
2026-10-16 19:02:58 +07:00
BFlat c3cb658be1 Merge pull request #1432 from marcoarnulfo/fix/render-queue-failed-exit
CLI: a failed render under run/exec exits 1, like render --queue
2026-10-16 18:59:52 +07:00
bflatasticandClaude Opus 5.5 3725c321a6 CLI: drop a debug print from the --empty render test
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 18:39:06 +07:00
bflatasticandClaude Opus 5.5 ced1857637 Templates: the hard-link check covers every Unix, not only Linux
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 18:39:03 +07:00
BFlat a2c2a1078a Merge pull request #1357 from iannitram/upstream-pr/cli-args-os
CLI: an argument that is not Unicode is a usage error, not a panic
2026-10-16 18:09:16 +07:00
Marco Arnulfo e26dd21af7 CLI: a failed render under run/exec exits 1, like render --queue (part of #1426) 2026-10-14 13:47:08 +02:00