Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,15 @@ then write your current edits. Changes made by another program are preserved and
conflict. Recovery never marks newer edits saved without writing them to both files.

This workflow currently covers audited media-free and local-image experiments, plus selected-member
updates to existing image archives. The first linked-movie writer supports mass and mark edits in
updates to existing image archives. The linked-movie writer supports mass, mark and clip-range edits in
audited constant-rate imports after timestamp indexing; its edited-file Tracker save/reopen acceptance
has passed for the pinned four-frame AVI case. Later revisions still require their own CI and review.
Movie timing/calibration/track-identity edits, movie packaging, filters and broader settings remain unfinished. An unsupported export is refused; save a MoTrack copy to retain work.
Image experiments can retain Clip Settings changes to the starting frame, ending frame and frame
interval in linked `.trk` files, existing image archives and portable image exports. All source images
and marks remain available, including those outside the selected clip; image timing stays unchanged.
The new range-edit cases still require actual Tracker application acceptance before merge.
Audited linked movies also retain Clip Settings range and interval edits after indexing. The complete
movie and all measurements stay available; source frame numbers and numeric timing are unchanged.
The [format guide](docs/native-format.md) records the exact supported edits and compatibility evidence.

### Export a portable image experiment
Expand Down
4 changes: 2 additions & 2 deletions docs/migration-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ and platform evidence before it can be marked complete.
| --- | --- | --- | --- |
| R01 | Reproducible native builds, CI, review, numerical tests, at least 90% combined C++ line coverage | Implemented foundation; continue applying gates to every new component. The reference helper executes repeated loader completion callbacks once, fixing the empty-resave race in #105; bounded failure diagnostics remain and no retry or acceptance bypass is added. The #137 infrastructure correction partitions journal/session cases with complementary filters and unchanged 60-second limits; full case-inventory and CI validation remain required. | 0, every phase |
| R02 | Open `.trk`/`.trz`; preserve all supported and unknown content, references, metadata, and archive tabs | Partial: supported point masses/vectors/calibration import; one archive tab selected. Native documents retain that tab's original XML, editable-track IDs and source-object associations for new imports. Version 5 embeds the exact original archive, including all tabs/media/unknown files. A partial read-only reference index maps original track names, panel/nested-view selections, table/plot owners (including dataset rows), ordered plot guests, mechanical-tool attachment slots/step targets center-of-mass/vector-sum members, model boosters and dynamic-system members to source nodes and known IDs; unknown subclass relationships remain explicit. Dataset rows have source-structure evidence only; media-backed application acceptance remains. Older native sources retain an explicit unknown-association state. | 1–3 |
| R03 | Save edited standard files plus optional `.motrack`; reopen in both applications without data loss | Partial: native source/archive preservation and audited standard writers are merged. Depending on the source schema, verified edits include mass/marks, independent vectors, clip ranges, media-free constant timing, fixed/partly fixed/varying calibration, unit labels, audited renames, independent track creation and supported removal/selection/plot/table cleanup. The [format guide](native-format.md) defines those per-schema limits. Linked images, selected image-archive members and indexed constant-rate linked movies have native reopen/relocation and actual Tracker acceptance. Per-output checkpoints, explicit recovery, desktop paired Save and portable image export are merged through #133. Image clip ranges/strides are merged in #134 with all four linked/archive/package application cases, including complete post-resave image inventory checks. Untouched archive experiments are checked independently. Remaining work includes broader schemas and dependencies, dataset-owner removal, movie archives/packaging, broader media timing and full export authoring. Known Tracker table-format losses (#64) and vector-sum losses (#63) retain strict guards and independent failing expectations. | 2–3, every feature |
| R03 | Save edited standard files plus optional `.motrack`; reopen in both applications without data loss | Partial: native source/archive preservation and audited standard writers are merged. Depending on the source schema, verified edits include mass/marks, independent vectors, clip ranges, media-free constant timing, fixed/partly fixed/varying calibration, unit labels, audited renames, independent track creation and supported removal/selection/plot/table cleanup. The [format guide](native-format.md) defines those per-schema limits. Linked images, selected image-archive members and indexed constant-rate linked movies have native reopen/relocation and actual Tracker acceptance. Per-output checkpoints, explicit recovery, desktop paired Save and portable image export are merged through #133. Image clip ranges/strides are merged in #134 with all four linked/archive/package application cases, including complete post-resave image inventory checks. The next movie clip-range slice has local native/desktop/export checks and a complete post-resave movie-hash oracle; its actual Tracker acceptance and current-head CI/review remain pending. Untouched archive experiments are checked independently. Remaining work includes broader schemas and dependencies, dataset-owner removal, movie archives/packaging, broader media timing and full export authoring. Known Tracker table-format losses (#64) and vector-sum losses (#63) retain strict guards and independent failing expectations. | 2–3, every feature |
| R04 | Multiple experiment tabs, independent undo/dirty state, tab/project Save As, cross-tab import and reusable views | Partial foundation: document sessions own independent data/history/save checkpoints, and native storage preserves unopened archive tabs. The desktop still has one active experiment; multi-tab controllers/UI, cross-tab import and reusable views remain. | 2–4 |
| R05 | Movies, stills, image sequences and zipped sequences; accurate clip/time/frame controls and media properties | Partial: local movies/images, trim/stride, indexing, orientation, bounded caching and playback exist. Media-free duration/time-origin edits have history and export oracles. Four-image and four-frame constant-rate AVI fixtures independently check pixels, order, timestamps, clip time and calibrated marks. The movie baseline (#132) passes actual Tracker load/save/fresh reopen; existing mass/mark export (#133) also passes native reimport; movie edits require unchanged timing/calibration/identity and a matching completed native index. Image clip edits (#134) pass all four linked/archive/package cases while preserving source frame numbers, measurements and every image, including excluded frames. See the merged CI table above. Variable-rate timing, movie archives, broader formats/properties/controls, numeric media timing edits and media export remain. The synthetic AVI does not reproduce or resolve the historical MOV/Open Recent report in #65. | 1, 3–4, 6 |
| R05 | Movies, stills, image sequences and zipped sequences; accurate clip/time/frame controls and media properties | Partial: local movies/images, trim/stride, indexing, orientation, bounded caching and playback exist. Media-free duration/time-origin edits have history and export oracles. Four-image and four-frame constant-rate AVI fixtures independently check pixels, order, timestamps, clip time and calibrated marks. The movie baseline (#132) passes actual Tracker load/save/fresh reopen; existing mass/mark export (#133) also passes native reimport; movie edits require unchanged timing/calibration/identity and a matching completed native index. Image clip edits (#134) pass all four linked/archive/package cases while preserving source frame numbers, measurements and every image, including excluded frames. See the merged CI table above. Strided/single-frame movie range saving now has local native/desktop tests and two new reference modes pending actual Tracker acceptance. Variable-rate timing, movie archives, broader formats/properties/controls, numeric media timing edits and media export remain. The synthetic AVI does not reproduce or resolve the historical MOV/Open Recent report in #65. | 1, 3–4, 6 |
| R06 | Complete point-mass editing and appearance: selection, dragging/nudging, numeric positions, multiselect, locks, labels, trails, paths, and vector overlays | Partial: manual marking/replacement, repeat, rename/delete, mass, and undo exist. Finish manipulation, appearance, path length, and selection behavior. | 4–5 |
| R07 | Independent vectors, linked vectors, sums, their data, editing, and persistence | Partial: independent vectors import/display/edit/undo/native-save. Internal sample export, new-vector creation and unreferenced removal have independent empty/sparse/zero-vector reference cases; native selection-cleanup regressions cover empty and replacement vectors; creation retains the snapping/precision guards and requires an audited independent-vector/axes source. A Java-authored vector-sum case retains independent expected results but reproduces a Tracker 6.3.5 defect: members never resolve and resave loses their names. This is explicitly not accepted round-trip evidence; the internal writer rejects edited projects containing vector sums, including empty member tracks. Native read-only indexing now records original member links with explicit ambiguity/unclassified targets. Native links/sum evaluation, analysis and desktop standard saving remain. | 3–5 |
| R08 | Center-of-mass tracks, constituents, dependent updates, and moving reference frames | Native evaluation/editing missing. A Java-authored center-of-mass reference checks named constituents, total mass and independent weighted positions; native member-link indexing and constituent-name export preserve original targets. The rename case requires unchanged 5 kg total mass and weighted positions through actual Tracker resave; native dependency evaluation, constituent editing and moving reference frames remain. | 2, 5 |
Expand Down
45 changes: 41 additions & 4 deletions docs/native-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -650,9 +650,9 @@ Windows/macOS and actual Tracker package acceptance, with 95.72% combined C++ li
### Linked constant-rate movie edits

The document writer accepts the explicitly audited `XuggleVideo`/`VideoClipControl` schema only through
its movie adapter. Existing point-mass values and image-coordinate marks, plus the linked media path,
may change. Original names, membership, calibration, unit labels, clip timing/range and other parsed
fields must remain unchanged. Filters, vectors, other track types except axes, display-orientation
its movie adapter. Existing point-mass values and image-coordinate marks, clip start/step/count and the
linked media path may change. Original names, membership, calibration, unit labels, numeric clip timing
and other parsed fields must remain unchanged. Filters, vectors, other track types except axes, display-orientation
transforms and archived movies remain refused. The archive entry point rejects movie documents before
clearing archive metadata for its internal snapshot; this also applies after indexing and native reopen.
This opt-in schema does not enable movie renames or
Expand All @@ -667,7 +667,9 @@ index limit. Clip endpoints and marks must fit that index. The native runtime fr
the complete index or the clip endpoint inferred on import; it is removed from the export snapshot,
not written as a standard-file edit. Existing saved `video_framecount`, when present, must match the
index. Decoded timestamps stay in seconds; preserved XML clip time origin and interval use milliseconds.
Native movie analysis remains aligned to the imported clip's time origin.
Native movie analysis remains aligned to the imported clip's time origin. Range edits retain every
original-frame mark and the full movie index; no frames are renumbered or movie bytes rewritten. The
shared clip writer retains its 500000 last-frame bound and checks Tracker's temporary Java-int count.

Movie links use the same physical-directory, retained-location and atomic-write checks as images.
Preflight verifies current readability and identity, not general codec compatibility or protection
Expand All @@ -686,3 +688,38 @@ and review at d9a24c6 in [PR #133](https://github.com/mgradwohl/MoTrack/pull/133
[run 42549945960](https://github.com/mgradwohl/MoTrack/actions/runs/42549945960), including the edited
Tracker movie case and 95.71% combined coverage. This scoped acceptance does not establish full
movie interchange or resolve #65.


The movie-range extension adds strided and single-frame native export/reopen cases, desktop Clip
Settings/undo/redo/paired-save checks and two actual-Tracker acceptance modes. Independent whole-XML
expectations permit only the requested range, mass, mark and path; every mark outside the clip remains.
After Tracker saves and freshly reopens, the saved movie reference must resolve locally to the complete
pinned byte count/SHA-256, including excluded frames. Initial Windows validation passes all nine CTest
groups (124.80 seconds), 86 Python tests, both native export/oracle/reimport cases, formatting and
static analysis for all four changed C++ source files, with 95.64% line coverage (8838/9241). Three
existing LLVM function-profile mismatch warnings remain visible. Current-head three-platform CI,
actual Tracker movie-range acceptance and review remain required before merging this extension.


A standard movie import initially infers a provisional source-frame bound from its saved clip endpoint.
When the linked movie's full index completes and contains the saved clip, the desktop extends that
bound to the decoded source count without reducing a previously known bound. Otherwise a reopened
single-frame clip could not expand to retained frames beyond its endpoint.
A desktop regression reproduced that failure, then verified single-frame export, standard-file reopen,
index completion, expansion to all four frames, paired resave and display of the retained final frame.
Index completion does not mark the document modified or remove measurements.

If a replacement movie is shorter than the recorded clip, indexing retains the original bound rather
than producing an invalid native document. A regression records a five-frame clip and a mark on frame
4 with an available four-frame movie: native save/reopen retains the range, mark and available index.
An already trimmed native copy also retains its larger known bound, so indexing cannot invalidate an
earlier range that can be restored through undo.
Standard export still rejects this incomplete media/index match and preserves the existing destination.

After the reopen-bound correction, Linux static analysis required a checked image-sequence reference
outside the test's frame loop. With that guard, retained movie bounds and the merged journal-group split,
all ten Windows CTest groups pass in 129.56 seconds with 95.64% production line coverage (8844/9247).
Desktop regressions reproduced both the shortened expansion bound and an unreadable native save
after indexing shorter media, then passed with the corrections. All four related desktop cases, both affected source-file static
analyses and formatting pass. Three existing LLVM profile-mismatch warnings remain visible. Actual
Tracker and three-platform acceptance still require the final published revision's CI.
8 changes: 8 additions & 0 deletions src/main_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,14 @@ void MainWindow::scheduleMovieIndex(const QString& path, bool standalone)
if (!index.frameTimes.empty())
{
m_Session.document.movieFrameTimes = std::move(index.frameTimes);
auto& clip = m_Session.document.project.clip;
const auto steps = clip.stepCount.value_or(0);
const auto last =
static_cast<std::int64_t>(clip.firstFrame) + static_cast<std::int64_t>(steps - 1) * clip.stepSize;
// Extend the provisional bound only if the movie contains the saved
// clip. Retain known bounds for earlier ranges and their undo history.
if (steps == 0 || last < index.frameCount)
clip.sourceFrameCount = std::max(clip.sourceFrameCount.value_or(0), index.frameCount);
}
refreshPlot();
return;
Expand Down
Loading
Loading