Commit Graph
10 Commits
Author SHA1 Message Date
dotCooCoo 500f74b700 Tests: the index read count includes entries read from more than one cell
RectIndex::at notes its reads before it sorts and removes repeats, so an
entry filed under several of the cells a lookup spans counts once per cell.
2026-11-08 11:42:47 +07:00
dotCooCoo 4cf4ea3a39 Tests: the shape builder and large edit guards count work instead of timing it
The Shape Builder, Live Paint and run_around tests in planar/tests.rs
measured elapsed time against a 5 s limit, and the large edit tests
(large_edits.rs, with the Lock and Hide All Artwork Above and perspective
Alt-drag tests that share `soon`) against 20 s. On a loaded machine they
failed without any change in the code.

- pathops: a test-only counter adds up the items `RectIndex::at` reads
  and the segments `nearest_u` searches. The four planar tests assert a
  bound on that count.
- doc: `tree_walks` counts, per thread, the walks of a document's tree
  that lookups by id make. `soon` fails when a command walks the tree
  more than 64 times, and keeps a 300 s wait for a hang. The tests that
  named a 20 s limit are renamed.

Looking objects up one at a time in Delete or Offset Path, or scanning
the whole index or ring in the planar code, makes these tests fail.
2026-11-08 11:42:46 +07:00
dotCooCoo 19d9843971 Shape Builder: a merge or erase takes the stretch of every coincident line
Where two open paths lie along the same stretch, the planar map gave
that stretch to one of them only, so a merge or an erase across it left
the other path in place there. Every other open path along an edge now
has its own piece in `lines_under`, under a closed path's outline or
along a line in front. `lines`, `edges` and Live Paint's edges stay one
per stretch, and an Alt-click there still takes the piece in front.
2026-11-05 14:12:18 +07:00
bflatastic b814fcf689 Pathfinder: holes that touch at a point stay holes of their region
The Live Paint faces were right; the Pathfinder regions over-counted.
Two small circles inside a big one, touching each other at one point,
gave the big circle's region only one of its two holes, and the other
hole came out as a region of its own.

linesweeper walks the boundary of the two touching holes as one loop
and, when the walk comes back to the shared point, cuts the second
hole off as a child of the first and flags it outer, as if it were an
island inside it. face_groups trusted that flag, so the hole started a
face. The same cut goes wrong the other way when an outer contour
touches its own hole: the outer contour comes out as an island inside
the hole.

Such a loop winds the same way as the contour it was cut from, against
its flag. face_groups now checks every contour's flag against its
winding; a pass where any disagrees is grouped by geometry instead
(each hole goes with the smallest outer contour of its mask around it).
Passes where they all agree keep the sweep's tree as before, at the
cost of one area per contour.

Adds deterministic tests for both shapes of the bug and checks in the
proptest regression seed.
2026-11-05 03:02:03 +07:00
dotCooCoo f7bebdeaf0 Live Paint: preserve face colors at shared curved boundaries
Capture sweep-piece source attribution before endpoint pinning can move its
midpoint off the original outlines. Keep the existing lookup after pinning
when the original piece has no source.

Add planar coverage and native compound Make/Expand/undo regressions, and
document the existing front-most source-fill rule.
2026-11-04 14:08:23 +07:00
dotCooCoo 79c5218f8a Fix #5161: Shape Builder merges across a line under a merged shape's edge
Where a line lies under the outline of a closed path in front of it (such as
a shape an earlier merge made, which takes the place of the art in front of
the lines), the planar map gave that stretch only to the closed path, so the
line had no piece there. A merge or an erase across it left the line whole,
and the next map split the new shape along it into two regions.

- pathops: each planar edge records every input it lies on, and
  BuilderArrangement::lines_under holds the lines' pieces under a closed
  outline in front of them. lines, edges and Live Paint are unchanged.
- tools: BuilderMap adds those pieces to its lines, so a merge or an erase
  removes the stretch between the regions it takes, as it does elsewhere.
  An Alt-click where a line lies under an edge hits the one in front.
2026-11-02 14:32:57 +07:00
Dylan M. Taylor 542a5ae58c refactor(pathops): extract planar sweep graph builder 2026-10-27 17:47:12 +00:00
aiongg 91e9555921 refactor(pathops): move planar.rs items to planar/{graph,index,live_paint,map,shape_builder}.rs 2026-10-26 21:17:08 +00:00
aiongg f1d427762b style: cargo fmt on files moved without formatting 2026-10-26 19:32:10 +00:00
aiongg 327cb2656c refactor(pathops): move planar.rs tests to planar/tests.rs 2026-10-26 18:18:17 +00:00