Commit Graph
4126 Commits
Author SHA1 Message Date
Matej Kozlovský 310c6da745 Cryptomatte eyedropper: hold the probe in the queued-clicks undo test (#473)
clicks_queued_while_reading_are_one_step_each_and_undo_in_order relied on
a blurred 4K plate being slow to read, and failed when the IDs were read
while the clicks were still being pressed. The probe's ID read is now held
(the Held footage from ui_crypto_pick) until the clicks are checked, and
the test asserts that the build reached that read and that nothing was
made while it was held.
2026-11-03 09:36:23 +01:00
Matej Kozlovský f8463fcf7e Cryptomatte eyedropper: Esc that closes a dialog keeps it armed (#473)
The Esc that closed New Solid or Composition Settings also disarmed the
eyedropper. An open dialog now takes Esc like a focused text field or an
open popup, so that Esc only closes the dialog and the next one disarms.
long_sequence asserts both instead of logging a finding.
2026-11-03 08:56:53 +01:00
Matej Kozlovský 0d1c5c08bf Docs: the Cryptomatte Selection is picked in the viewer (#473)
effects-parity.md and gaps.md: the Selection is picked in the viewer. control-protocol.md: the
viewer.cryptoPick element ids. footage.md: a paragraph on the eyedropper.
2026-11-03 07:37:53 +01:00
Matej Kozlovský 7cea1625f6 Cryptomatte eyedropper: arm it from the Selection in Effect Controls (#473)
An eyedropper next to the Cryptomatte effect's Selection arms the viewer pick, and the status
line says how to use it. It stays armed until Esc or the button (Esc in a text field or a menu
only ends that); disarming, New, Open and Revert end it and let go of the session's probe.

The app runs the pick's bookkeeping at the start and end of each pass, the viewer hands the
pointer to the pick while it is armed and opens its context menu for a right-click the pick
forwarded, and a Selection cut off by a narrow Effect Controls panel shows whole on hover.

UI tests: ui_crypto_pick (arming, hover, clicks, modifiers, drags, waiting clicks, status,
highlight) and ui_crypto_pick_undo (one undo step per pick, the probe kept over undo).
2026-11-03 07:37:53 +01:00
Matej Kozlovský 6b0f72e4be Cryptomatte eyedropper: the viewer pick (#473)
panels::crypto_pick is the eyedropper's viewer side; it is wired in by the next commit. Armed,
the hover names the ID under the cursor and highlights its coverage, a click replaces the
Selection with it, Shift adds, Alt or Ctrl (Option or Cmd on a Mac) removes. Each pick is one
undo step, "Pick Cryptomatte".

The probe the hover needs is built off the UI thread, one at a time for the app
(EffectcraftApp::crypto_probe_busy, re-arming included), not while playing and not until a
scrub has settled for 100 ms; meanwhile the chip says so. Session::crypto_probe_ready asks for
readiness without changing anything; a job is asked for only when it starts.

Clicks made meanwhile are queued, own the build and are made in order at the end of the pass,
after its keys and edits. A click is the frame, point, resolution and project revision its
press saw. If any of them changed before it is made (an edit, Ctrl+Z, a nudge, a frame step),
it and every click waiting with it are dropped and the status says "Pick not made". A pick's
own change of the revision doesn't count as an edit for a click still held. Losing the window
focus drops a held press. A click that takes the focus from the Selection field waits for the
field to commit and is made on top of it.

The overlay takes drags too: a click that drifts picks at its press, and one dragged further
than 24 points picks nothing ("Drag cancelled the pick"). Presses and releases are read from
the pass's events in order rather than from egui's end-of-pass click state, since a slow pass
can hold a whole click. Space, the Hand and the Zoom tool keep their clicks, the middle button
pans, and a right-click is passed on under viewer::FORWARDED_SECONDARY for the viewer to open
its context menu (the viewer side is in the next commit). Errors show in the chip in red,
without the command's prefix, wrapped to the viewer's width.

The hovered ID's coverage (Session::crypto_coverage) is drawn as a texture through the layer's
effect-space transform, rebuilt only when the hovered ID, frame or revision changes, and
exposed to the test harness as viewer.cryptoPick.highlight.

Supporting changes:
- EffectcraftApp::say sets the status line and restarts its 5 s; each status message now gets
  its own 5 s, also when the same text is shown again.
- Points snap to the centre of the shown frame's pixel at the exact 1/n scale the viewer
  renders (frames::render_scale; the frame key keeps 0.333 for Third, which named the next
  row's ID). Cache Frames When Idle renders at that exact scale too, so idle-cached frames are
  on the grid the pick reads.
2026-11-03 07:37:53 +01:00
Matej Kozlovský 6b1f91ffb8 Cryptomatte: read an ID's coverage from the kept probe (#473)
Session::crypto_coverage returns the coverage of one Cryptomatte ID over the layer, read from
the probe Session::crypto_probe_job keeps: at most max_side samples on the long side, each at
the centre of its cell, or None until the probe is built. It is what the Cryptomatte
eyedropper's hover highlight will draw.

Tests cover the coverage of an ID from the kept probe and the cost of a highlight with six
ranks.
2026-11-03 07:22:46 +01:00
Brandon ThomasandClaude Opus 5.5 7870b5916a Release 0.21.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.21.0
2026-11-02 19:26:55 -05:00
FredApps a646bdcc2e Merge pull request #1598 from danielmigueltejedor/fix/gnome-window-decorations
Restore GNOME Wayland window controls without bundled fonts
2026-11-02 19:42:57 +01:00
FredApps f2aeff7e17 Merge current main into fix/gnome-window-decorations 2026-11-02 19:10:38 +01:00
f15b619a92 Follow-up to #2823: box each of several objects around its whole matte on correction frames (#2830)
* Follow-up to #2823: box each of several objects around its whole matte on correction frames

With several objects, a correction frame's box came from the model's cut
of that object's strokes on the frame alone. A stroke on part of the
object boxed only that part, and SAM 2 followed only that part from
there on. Each object's matte is now carried to the frame with its own
strokes, from its first prompted frame or its nearest tracked frame, by
the walk Chain::ensure uses (now Chain::carry). These mattes are not
cached, since object keys hold tracked results.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Follow-up to #2823: carry corrections before the base from the base outwards

Prompt frames were visited in ascending order, but before the base the
carry walks towards it, so each correction there re-walked from the
root. Visit each side from the base outwards and sort the prompts back
into frame order for the tracker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Follow-up to #2823: find an object's carry root in one pass over its strokes

The root search scanned every frame's strokes from the prompt frame to
the base, for every prompt. Take the object's foreground stroke on the
way that is nearest the base in one pass instead; the root is the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* M13.35: reproduce an earlier object correction losing tracked matte

* M13.35: carry earlier object corrections from valid tracked mattes

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: FredApps <FredApps@users.noreply.github.com>
2026-11-02 18:01:39 +01:00
ashandClaude Opus 5.5 9d7baea5cc Fix #2823: Propagate boxes SAM 2 around the matte shown on the stroked frame (#2826)
* Fix #2823: Propagate boxes SAM 2 around the matte shown on the stroked frame

The tracker's box prompt came from the classic graph cut of the strokes,
which can leak into the background; SAM 2 then filled the whole box.
Build the box from the model's own matte (segment_with), the one shown
before Propagate. segment_with falls back to the classic cut when the
model can't segment, so non-model paths are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix #2823: box a lone object around the matte shown on correction frames too

A correction frame shows a matte propagated from the frame before, not a
fresh model cut, so the tracker's box came from a different matte than
the one on screen. With one object the box now comes from Chain::ensure,
the matte shown on that frame. Several objects share one shown matte, so
each keeps the model's cut of its own strokes. Cancelling while the shown
matte is computed stops instead of falling back, and the prompt frame is
read only when needed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 14:18:41 +01:00
Brandon Thomas ad7abfa507 Merge PR #2792 (author's repin, same as main) 2026-11-01 22:15:08 -05:00
Brandon ThomasandClaude Opus 5.5 f6b09d7816 test(ui): the fake sound card waits to pull until the starting frame is checked
Under load its thread pulled samples before the test read the clock, so
'from the first frame' saw frame 1 and a_started_preview_follows_its_sound flaked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 22:13:48 -05:00
Brandon ThomasandClaude Opus 5.5 35ce2186a4 Follow-up to #2804: ProRes frame headers carry the colr atom's colour codes
They said BT.709 for every output, so a non-709 render disagreed with its atom.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 21:53:42 -05:00
Brandon ThomasandClaude Opus 5.5 7441ccf187 Follow-up to #2781: Swedish Keys, File, Top and Bottom read as they're used
Keyframes column, a file field, crop/alignment edges.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 21:51:17 -05:00
Brandon ThomasandClaude Opus 5.5 d2fa9c1905 Follow-up to #2792: pin craft-ecproj-format to craft-libs main (ca1b5e2e, #409)
The PR pinned the head of a fork branch, not in craft-libs history; the crate
source is byte-identical at both revs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 21:51:09 -05:00
Brandon Thomas f3cedac8cc Merge PR #2792 2026-11-01 21:50:53 -05:00
Brandon Thomas 1467d94945 Merge PR #2804 2026-11-01 21:50:53 -05:00
Brandon Thomas 4375b689ea Merge PR #2798 2026-11-01 21:50:53 -05:00
Brandon Thomas 6f89617042 Merge PR #2790 2026-11-01 21:50:53 -05:00
Brandon Thomas a658ec736a Merge PR #1266 2026-11-01 21:50:53 -05:00
Brandon Thomas 4515418fd4 Merge PR #2742 2026-11-01 21:50:53 -05:00
Brandon Thomas 546da0a1f5 Merge PR #2679 2026-11-01 21:50:53 -05:00
Brandon Thomas 5068f42601 Merge PR #2781 2026-11-01 21:50:53 -05:00
Brandon Thomas e0cd2914ba Merge PR #2783 2026-11-01 21:50:53 -05:00
Brandon Thomas e80d5c42c2 Merge PR #2771 2026-11-01 21:50:52 -05:00
Brandon Thomas 43d76d38a0 Merge PR #2759 2026-11-01 21:50:52 -05:00
Brandon Thomas 7c151edd40 Merge PR #2758 2026-11-01 21:50:52 -05:00
dotCooCoo d4f4c43a29 Project files: pin craft-ecproj-format to craft-libs main
craft-libs #409 merged as ca1b5e2. The crate's source is the same as
at the earlier pin d74959f.
2026-11-01 17:39:27 -08:00
JonRC e935818f77 Contributors: add JonRC's name 2026-11-01 22:28:24 -03:00
JonRC d0e7e09ecb Export: write a colr atom in ProRes MOVs (#2801)
ProRes renders had no colr atom, so the stream reported no primaries,
transfer or matrix. Write an nclc atom, as FilmCraft does for MOV, with
the codes of what the render path makes: the project's output space when
it has a working space, BT.709 otherwise.

sRGB output stays at transfer 1, which is still open on #340 and #464.
The frames don't change, so the pinned ProRes bytes move by exactly the
atom's 18 bytes.
2026-11-01 22:28:23 -03:00
dotCooCoo 1c08d8cb04 Merge storytold/effectcraft main into feat/ecproj-format-from-craft-libs 2026-11-01 17:20:50 -08:00
Jonas Neubauer bfe7535a5e G2: web Save As asks before replacing a stored project (#2788) 2026-11-02 01:15:08 +01:00
Jonas Neubauer 55a8a7e0d9 G2: web Save As keeps the project extension on dotted names (#2788) 2026-11-02 01:01:54 +01:00
jayzed80 9bdee07281 fix(path): Wiggle Paths no longer overflows on an absurd speed, time or phase 2026-11-01 22:18:36 +00:00
Jonas Neubauer 9a4c160f0e G2: distinct XML copy name and a name prompt for web Save As (#2788) 2026-11-01 21:08:01 +01:00
Jonas Neubauer 4dac9d04fc G2: Save a Copy starts from "<name> copy" (#2788) 2026-11-01 20:44:57 +01:00
dotCooCoo b133c0500f Project files: read savedBy through craft-ecproj-format's Head
The craft-ecproj-format pin moves to storytold/craft-libs#409's new
head, where Head::read is the one reader and saved_by() is removed.
effectcraft-project's saved_by reads savedBy with Head::read, and from
ReadError::TooNew for a project with a newer schema.

saved_by now returns None for text that is not a JSON object with a u32
schema. EffectCraft calls it only on files Project::from_json opened,
so opening and importing projects are unchanged.
2026-11-01 11:02:30 -08:00
Brandon ThomasandClaude Opus 5.5 720c67117e Release 0.20.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.20.0
2026-11-01 13:59:03 -05:00
dotCooCoo 42b04479be Merge storytold/effectcraft main into feat/ecproj-format-from-craft-libs 2026-11-01 09:42:43 -08:00
dotCooCoo b1571abaaa Project files: the file envelope comes from craft-ecproj-format
effectcraft-project writes and checks the envelope of .ecproj files with
craft-ecproj-format from craft-libs: File (savedBy, then the saved view
and the project) with to_json and to_json_compact for Save Compact
Project Files, check_schema and its message, SCHEMA_VERSION and
saved_by, which stay re-exported under their names. Project, SavedView
and the schema 1 conversion stay here.

Saved files are byte-identical. saved_by now reads only a JSON object,
so a project written as a JSON array no longer reports a savedBy.
2026-11-01 09:42:43 -08:00
Jonas Neubauer cccd5cba8f G2: Save As starts from the open project's name (#2788) 2026-11-01 18:37:46 +01:00
Dylan M. Taylor 6372545dab docs: sync Craft App Suite list with ArtCraft Launcher 2026-11-01 12:30:01 -05:00
tylerjenningswandChewybone-sudo 3ab2167e47 Auto-Trace: traced outlines map back into layer space (#2764)
Co-authored-by: Chewybone-sudo <347238078+Chewybone-sudo@users.noreply.github.com>
2026-11-01 09:05:56 -05:00
tylerjenningswandChewybone-sudo 49774ca5f9 Auto-Trace: test that traced outlines map back into layer space (#2764)
Co-authored-by: Chewybone-sudo <347238078+Chewybone-sudo@users.noreply.github.com>
2026-11-01 09:02:42 -05:00
Patrik LermonandClaude Opus 5.5 34b32d60da i18n(sv): translate 85 new strings
Brings the Swedish catalog up to date with upstream main (e71dd629).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 14:36:23 +01:00
becauseno7 25a7d98ebc PDF import: a trailer string in a stream does not trigger the window fallback
A `trailer` marker inside an unreferenced stream followed by `(` and more
than 4 KiB of text made the lexer stop at the window's end, so a later
`/Encrypt` name anywhere in the file refused a plain file. The unbounded
scan read a string there and opened it. The past-the-window fallback now
applies only when no object starts in the window or the first one opens
a dictionary (`<<`, including one split by the window's end).

Regression test with `trailer(` and `trailer[` in a stream and a later
Encrypt name.
2026-11-01 14:44:26 +06:00
becauseno7 98484975c4 PDF import: a name cut by the trailer window is read whole
The pre-scan window could end inside a trailer key, so a decoy like
`/Encrypted` cut right after `/Encrypt` was taken for the Encrypt key
and an unencrypted file was refused. A window that ends mid-token now
ends before that token instead, and the past-the-window fallback reads
the name whole (a real `/Encrypt` cut as `/Encryp|t` is still refused).

Tests for that boundary, for a trailer with a long /ID, and for `#`
without two hex digits staying as written in a name.
2026-11-01 13:31:59 +06:00
Dylan M. Taylor e71dd629c5 ci: grant packages write permission to release workflow 2026-10-31 23:43:04 -04:00
zitann2020andDeepSeek V4.1 Flash e62ccd359c docs(effects): rewrap the reflowed comment line
Co-Authored-By: DeepSeek V4.1 Flash <noreply@deepseek.com>
2026-11-01 12:07:29 +09:00