Conversation
Tested by tests/unit/CurveEditionTest.cpp, which drives Curve::ToolPalette on a real presenter and view and runs each crash in a forked child. - View: the value tooltip belongs to each view instead of a static that dangled once its view was destroyed mid-drag. - CurveEditor::paste: splice in one pass, no more indexing past the end. - MovePointCommandObject: rewritten on a vector (no pointers into a dense hash map across erase), with explicit move / suppress / cross cases and no validity checks halfway through an update; lock between points holds at neighbours sharing the point's x. - Model::fromCurveData validates before clearing and orders segments by their chains; UpdateCurve validates in update() too; loading relinks a curve with broken links instead of asserting. - IdContainer::at always looks the id up: the cached pointer could name a replaced, not yet deleted object. - Tool events record ids when posted rather than an item pointer. - A lost mouse release ends the gesture (UngrabMouse, and on the next press) instead of dragging the old point. - PointArraySegment serializes its points; conversions need two points. - JSON SegmentData reads its id; removeSegment no longer erases while iterating; power / easing segments interpolate both ends and survive a zero width; non-finite cursor positions are dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ering Edition: - UpdateCurve stores the changed segments (before / after) instead of the whole curve; Model::applyChanges updates segments in place, splices the x order and reuses the point objects. An ongoing drag reverts to the original state on each update. - The command objects work on a reused vector; overlap suppression, pen, paste and removal are single passes with batched erasure. Segment ids are stable across a gesture. - CommandBackupFile keeps the serialized commands instead of re-serializing the stack on every command; ScenarioValidity does not walk curves; the model leaves its segments to QObject on destruction. - Non-finite values go through ossia::safe_isfinite; ossia containers (hash_map / hash_set / flat_map / pod_vector) replace the std ones. Execution: - Automations and mappings read the model's sorted segments by reference, build scaled executor functions, and swap the automation behavior so the old curve dies on the GUI thread (needs libossia's swap_behavior). Sampled segments: - PointArraySegment is a real segment: shared copy-on-write samples, interpolated valueAt, cropping with setSegmentExtent, serialization. - Curve::curveFromSamples turns more than 10k values into one sampled segment; "Convert samples to editable points" simplifies them with Douglas-Peucker. Recording builds sampled segments the same way. Rendering: - A min/max pyramid gives the extremes of any sample range in O(log N). Where there are more samples than pixels, a segment is drawn as a waveform, one cosmetic line per device pixel column; otherwise as the envelope polyline. Direct-draw curves use the same code. Tests: test_unit_curve_edition covers the above; test_unit_curve_bench (hidden, NO_CTEST) measures edition, paint and execution at N points. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RskGW91A5EsEeuHyC91XHV
This was referenced Sep 23, 2026
CurveModel.cpp also has an anonymous-namespace ChangeScratch; in a unity build both land in the same translation unit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RskGW91A5EsEeuHyC91XHV
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two commits, meant to be reviewed separately.
Depends on ossia/libossia#949 (the submodule points at it). ossia/score-addon-hdf5 has a companion PR that makes CSV/HDF5 drops use the new sampled segments.
1. curve: fix the crashes and corruptions of curve edition
Reproduced from the GUI through
Curve::ToolPaletteon a real Presenter/View, each case in a forked child:CurveEditor::pasteindexed past the end when pasting at the start of a curve.MovePointCommandObjectis rewritten on a vector.UpdateCurve::update()did not validate.Model::fromCurveDatanow validates before clearing the model.IdContainer::at()returned a cached pointer to a replaced segment across back-to-back undo/redo.QEvent::UngrabMouseis now handled).PowerSegmentmisbehaved with 0 steps or zero width; recording a single value crashed;SegmentDatalost its id through JSON.2. curve: scale edition to 100k+ points, sampled segments, waveform rendering
UpdateCurvestores only the changed segments.Model::applyChangesupdates them in place, splices the order and reuses point objects.CommandBackupFilestops re-serializing the whole stack on every command.ScenarioValidityskips curves. Model destruction avoids Qt's O(N²) child removal.PointArraySegmentis a real segment: shared copy-on-write samples, interpolated evaluation, cropping, serialization.Curve::curveFromSamplesturns more than 10k values into one sampled segment. "Convert samples to editable points" simplifies them with Douglas–Peucker.swap_behavior).ossia::safe_isfiniteand the ossia containers.Release timings, 100k-segment automation, master → this branch:
Tests
test_unit_curve_edition: 42 cases covering crashes, invariants, undo/redo, backup-file equality, the executor swap, sampled segments and rendering.test_unit_curve_bench: hidden benchmark (NO_CTEST), run withCURVE_BENCH_N=10000,100000 tests/unit/test_unit_curve_bench "[.curve_bench]".🤖 Generated with Claude Code
https://claude.ai/code/session_01RskGW91A5EsEeuHyC91XHV