Commit Graph
813 Commits
Author SHA1 Message Date
tylerjenningsw 9ee6c5ef62 Clipboard: keyframe text for Time Remap and separated X / Y / Z Position (#1908) 2026-10-20 09:45:51 -04:00
tylerjenningsw 30dc57f790 Clipboard: keyframe text in current After Effects' layout, with a tab after each column (#1908) 2026-10-20 09:42:08 -04:00
dedandClaude Opus 5.5 49ec37ec3f Disk cache: an edit that leaves the footage alone keeps its salt (#1926)
Session::bump took the disk cache's footage salt at every edit, which reads the size and time of
every footage file, each frame of an image sequence included. With three 5000-frame sequences a
caret move or a typed character in a text field took ~0.6 s on the UI thread (9 ms with the disk
cache off). The salt is now taken again only when the footage items changed, or when a project
is opened, footage is reloaded or the disk cache attached.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 16:40:24 +03:00
tylerjenningsw 8ace9aac7f Clipboard: keyframe text starts the layer with a Layer line (#1908) 2026-10-20 09:10:29 -04:00
tylerjenningsw 47093d997a Clipboard: keyframe text has the source's pixel aspect (#1908) 2026-10-20 08:52:55 -04:00
tylerjenningsw 22ddf7bb99 Clipboard: keyframe text for a 2D layer writes the Z it shows (#1908) 2026-10-20 08:51:09 -04:00
tylerjenningsw 6b77e6a1a7 Clipboard: keyframe text leaves out Transform properties the layer doesn't use (#1908) 2026-10-20 08:49:33 -04:00
tylerjenningsw 9313784304 Clipboard: Orientation and Rotation headers as After Effects writes them (#1908) 2026-10-20 08:47:51 -04:00
Camille Moine c7eb48dc3a Layer: reveal layer sources in the Project panel (#1809) 2026-10-20 13:59:01 +02:00
Camille Moine 8d887fd6da Layer: replace a layer's source with Alt-drag and Ctrl+Alt+/ (#991, #813)
Alt/Option-drag a Project item onto a Timeline layer, or press Ctrl+Alt+/ (Cmd+Opt+/) with layers and an item selected, to swap the layer's source. The layer keeps its name, timing, transforms, keyframes, expressions, effects, masks, switches, parenting and track matte; a source with audio adds Audio properties when missing. Precompositions can't be nested inside themselves.

AVLayer.replaceSource now runs the same engine command and closes the replaceSource part of #813.
2026-10-20 12:18:46 +02:00
tylerjenningsw 598f0d51c1 Clipboard: copied keyframes as After Effects keyframe text (#1908)
Copying keys or unanimated properties of one layer records them as After Effects keyframe text: its Transform properties, one row per key with the frame in comp time (start offset and stretch applied) or a frameless row for a static value. EffectCraft's own keyframe clipboard is unchanged.
2026-10-19 22:49:41 -04:00
vangel76andClaude Sonnet 5.5 67ccf44fba Review: behavior preset test also covers redo
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 01:38:45 +02:00
vangel76andClaude Opus 5.5 d57b73d4cb Shape rectangles start at the top-right, as After Effects, so Trim Paths cut the same segment
After Effects draws a Rectangle Path clockwise from its top-right corner, or
with round corners from the end of the top-right arc on the right edge;
Trim Paths measures from there (AE 2026, case 930: 400 x 300 rectangles,
Trim 0-25 % and 70 / 30). EffectCraft built the path with kurbo, starting at
the top-left corner, so trimmed rectangles drew another segment: case 930
was 86 of 5184 grid points off (max 255), now 5 at stroke edges. Start > End
was already drawn swapped, as in AE. Convert to Bezier now gives AE's vertex
order (top-right first); the engine test follows. Lottie rectangles share
the path and now start where lottie players start them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:33:44 +02:00
Camille Moine f72e17a2bb Engine: Video's Alt-click and Hide Other Video take cameras and lights along
The Timeline draws the Video switch (the eye) on every layer's row, nulls,
cameras and lights included, but set_switch_others and hide_other_video
skipped cameras and lights: Alt-clicking the eye of a selected layer neither
set them apart with the selection nor hid them with the rest.

Both now use the rule the eye cell shows: every layer but track mattes.
2026-10-19 10:25:17 +02:00
Matej Kozlovský d74cb70938 Cryptomatte pick: snap to the effect's input buffer grid, not the preview scale
At preview scales from 0.75 to 1 footage keeps native pixels, a proxy sets
its own buffer scale at any render scale, a Preserve Resolution precomp is
drawn at full size, and earlier effects can pad or offset the buffer, so
snapping to the preview grid could pick a different ID than the rendered
matte. Use the scale and offset of the buffer the Cryptomatte effect
receives (layer_input, rendered once and then cached).

The pixel centre goes to an aux point through effectcraft_effects::aux_point,
which index_map_at now calls too, so the two round identically (a division
vs the reciprocal picked the other ID on a 104 px proxy of 1920 px footage).

An unknown effect uid errors "no such effect" and a layer without pixels
"this layer has no pixels", as effect.pickColor does.
2026-10-19 08:40:16 +02:00
Matej Kozlovský 76098665b0 Cryptomatte: effect.pickCryptomatte picks the ID under a point into the Selection (#473)
Engine part of viewer picking: replace / add / remove the top-coverage ID at a
layer-space point in one undo step, at the time the Selection was read. The
aux channels come from the render's own path (Renderer::layer_aux, shared with
the effect host; footage at its source time, 3D precomps) through a renderer
set up like Session::render (expressions, render prefs, layer cache). An
optional scale snaps the point to the pixel a preview at that resolution
samples. New effects::crypto_select quotes names and falls back to <hex> for
unnamed, wildcard-looking or ambiguous names. effect.cryptomatteAt is the
read-only hover query.
2026-10-19 06:10:27 +02:00
Vikram Bhaskaran d3fd2c58d7 Key browser preview caches on a file generation, and hash bytes only when that key misses.
Replacing a virtual file bumps a counter the UI lookup reads. The content hash runs on that miss, from a callback, so the frame path does not stat every footage item or hash on every store write.
2026-10-19 13:04:16 +11:00
vangel76andClaude Sonnet 5.5 24612b0eaf Merge upstream/main into gap-behaviors-presets
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 02:02:16 +02:00
Davit MatchakhelidzeandClaude Opus 5.5 5a069af3fd Merge i18n-improvements (main merged)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YMTAbGNRxnMEzRvYnQGphF
2026-10-19 02:58:18 +04:00
iannitramandClaude Opus 5.5 c1d411b249 Tests: serialise disk-cache-opening tests with the roto tests
The Roto/Object Matte segment store is one per process (roto::set_seg_store),
and every Session::configure_disk_cache that opens a cache takes it over. The
roto and disk-cache tests already serialise on hold_roto_cache_test_lock(), but
many other engine tests build a Session with a settings store, which opens the
disk cache at the platform folder and takes the store; once that session drops,
the weak store is dead and object_matte_mattes_persist_in_the_disk_cache sees
no disk writes. It failed 3 of 3 in the full parallel suite here.

configure_disk_cache now takes that lock under cfg(test) before opening a
cache, so every such test runs apart from the roto tests. Re-entry on the same
thread is a no-op. Product code is unchanged: only the app's one session ever
opens a disk cache, so users cannot hit the race.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:51:47 -06:00
tylerjenningsw dd50e42486 Merge remote-tracking branch 'origin/main' into enhance/pickwhip-index-refs
# Conflicts:
#	crates/ui-egui/tests/ui_inline_edit.rs
2026-10-18 12:38:44 -04:00
Charles BaumerandClaude Opus 5.5 4fa31b5e5b Engine tests: clippy passes on Windows (Stills is Unix-only)
`Stills` is only used by the `#[cfg(unix)]` part of
`footage_on_other_computers_is_never_looked_at`. On Windows it was dead
code, so `cargo xtask ci` stopped at clippy (`-D warnings`).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:12:55 +00:00
Brandon Thomas 7804cfd223 Format merged community PRs 2026-10-18 09:37:06 -04:00
Brandon Thomas 10cf6690c4 Merge pull request #1730
# Conflicts:
#	crates/engine/src/commands/prop_groups.rs
2026-10-18 09:36:40 -04:00
Brandon Thomas a594abf4f7 Merge pull request #1652
# Conflicts:
#	docs/gaps.md
2026-10-18 09:35:51 -04:00
Brandon Thomas dfff3f9010 Merge pull request #1785 2026-10-18 09:35:35 -04:00
Brandon Thomas 1dac4c0e6b Merge pull request #1759 2026-10-18 09:35:35 -04:00
Brandon Thomas d9e3c56404 Merge pull request #1721 2026-10-18 09:35:35 -04:00
Brandon Thomas 415e353dc0 Merge pull request #1711 2026-10-18 09:35:35 -04:00
Brandon Thomas fcc9e853de Merge pull request #1709 2026-10-18 09:35:35 -04:00
Brandon Thomas 072a7f7af9 Merge pull request #1695 2026-10-18 09:35:34 -04:00
Brandon Thomas 972a2d21d2 Merge pull request #1659 2026-10-18 09:35:34 -04:00
Brandon Thomas 65d955c32a Merge pull request #1572 2026-10-18 09:35:34 -04:00
Brandon Thomas 226fbf5810 Merge pull request #1485 2026-10-18 09:35:33 -04:00
Brandon Thomas 736c0ec4b4 Merge pull request #1430 2026-10-18 09:35:33 -04:00
Brandon Thomas bb8dd41af1 Merge pull request #1087 2026-10-18 09:35:32 -04:00
Kristian Myram cffa1f25d0 fix(shapes): update inner controls when Polystar type changes (#1685) 2026-10-18 10:05:57 +00:00
MarekSpodBiedry 0e7f525a81 Keep the target's paint when pasting Merge Paths (#1681) 2026-10-18 10:57:23 +02:00
MarekSpodBiedry 4f49017329 Merge remote-tracking branch 'origin/main' into review-1730 2026-10-18 10:56:01 +02:00
MarekSpodBiedry 651ee5a78e Resolve effects/<match name> property paths in anim.applyPreset (#1746) 2026-10-18 01:10:30 +02:00
skylar taylor-barrick 2d805d1b69 Merge pull request #1748 from skylartaylor/import-and-open
Import templates and open originals within their own folders
2026-10-17 12:13:54 -06:00
Moein Saharkhiz 8e59ccdb3a Fix #1231: keep autosave completion tied to its originating project (#1330) 2026-10-17 08:58:56 -06:00
MarekSpodBiedry b8d52cd8c4 Paste path operators below the shapes they act on (#1681)
Pasting Trim Paths, Wiggle Paths or a paint into a shape layer with nothing
selected put it on top of Contents, where it acts on no shapes. It now goes
to the bottom, as Add places it. Also fixes #1629.
2026-10-17 14:37:42 +02:00
arnav-hiwarkarandClaude Opus 5.5 c28daa479b #1714: test several comps, negative and malformed saved times
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 15:35:12 +05:30
arnav-hiwarkarandClaude Opus 5.5 ea67c46880 #1714: doc comments name the saved current times
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 14:40:44 +05:30
arnav-hiwarkarandClaude Opus 5.5 b9172fec2f #1714: reopen each comp at its saved current time
Layer times were already saved and read back as exact ticks; the values in
the issue are 34f, 315f and 3033f at 59.94 fps. The viewer was black because
the playhead wasn't saved: a reopened comp started at 0, before its layers.
The project file's view (`activeComp`, `openComps`) now also records each
comp's current time (`compTimes`), restored on open within the comp's frames.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 14:32:14 +05:30
MarekSpodBiedry 7146006c15 Duplicate the selected text animator or selector instead of the whole text layer (#1665) 2026-10-17 07:50:03 +02:00
MarekSpodBiedry 8f74c3790e Replace non-ASCII characters in EXR layer names so ProEXR export no longer panics (#1702) 2026-10-17 07:46:32 +02:00
Ayberk A. 107cedb84c fix(effects): starred effects survive a restart (#1692)
Effects & Presets kept its favourites in `UiState::effects_favorites`,
which nothing writes out (only the workspace layout is saved), so the
stars were gone the next time the app opened. They now live in the
settings (`Prefs::effects_favorites`, saved when a star is clicked) like
the recent fonts and presets, survive Reset All like them, and a
hand-edited list loses empty and repeated ids on load.
2026-10-17 00:40:04 +03:00
aiongg 816ca95800 Footage: follow stored footage paths only on this computer or the project's share
Footage paths stored in a project are resolved through craft-docpath against
the project file when it is opened or imported: relative paths are taken from
the project's folder, and an item whose path is on another computer, names a
device or is a non-file URL is marked missing without being looked at. The
footage check, the changed-on-disk scan, Reload Footage, Relink, Edit Original
and Reveal in Finder resolve the path again before touching the file, and the
Project panel, Metadata panel and waveforms read no file details of missing
footage.

Lottie image assets are resolved against the Lottie file; one on another
computer is skipped with a warning. Files a 3D model names are read only when
local or on the model's own share.

Reveal in Finder refuses a folder that would open as an app or other bundle.

Files imported or relinked in this session are opened as given.
2026-10-16 17:43:58 +00:00