Commit Graph
8 Commits
Author SHA1 Message Date
arhammusheerandClaude Opus 5.5 4c5809302d #1172: Pathfinder Trim, Merge and Crop 9-12x faster, same output
Trim, Merge and Crop walk the arrangement once per input shape, and every walk tested each edge
side with a coverage mask built from a winding vector with one slot per input. On 300 paths,
against main:

- Trim: 362 → 31 ms
- Merge: 366 → 31 ms
- Crop: 303 → 28 ms
- Unite, Intersect, Exclude, Minus Front and Minus Back: unchanged or a little faster

- Multi, the arrangement's winding, keeps only the non-zero windings as sorted (input, winding)
  pairs, added in place. A face is covered by a few inputs, so a test reads a few entries
  instead of one per input. The winding arithmetic is unchanged.
- Arrangement::covered lists the inputs that cover a face (the true entries of its coverage
  mask). Trim, Merge, Crop, Minus Front, Minus Back, Intersect and Exclude test that list; each
  test's old mask form is in a comment beside it. mask() still builds the same mask for the rest.

pathfinder_pinned hashes the output of all ten operations on 2, 5, 12 and 30 overlapping
ellipses, rectangles and stars (even-odd and non-zero, shared keys for Merge). The 40 hashes were
computed with main's dense windings, and the new code gives every one of them. A wrong Crop test
fails it. The pathops suite (103 tests) passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VmMmc1J8XeNLxhRihWv9cc
2026-10-11 23:26:53 +07:00
bflatasticandClaude Opus 5.5 f5bf327447 Review: rustfmt; ROADMAP progress log (#1028)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 05:30:41 +07:00
lloydandClaude Opus 5.5 1622a70f85 #1028: Offset Path finishes where the sweep looped forever
The sweep under Offset Path (linesweeper 0.4) never finished on some
miter offsets: on the reported glyph and on a synthetic outline it kept
allocating until the app ran out of memory. linesweeper 0.5 fixes that
infinite loop ("Fixed an infinite loop", 0.5.0 changelog), and builds
without changes.

0.5 can hand back a curve piece that doesn't follow the input curve it
was cut from. In the Shape Builder rosette test, a contour runs out along
one petal and back by such a piece, which became a 59 x 4 pt hole in the
merged shape. Tidy::repair rebuilds a piece that strays from the one input
curve through both its ends as that curve's exact sub-curve (input curves
are indexed by their bounds' left edge, so it stays cheap). The there-and-
back then encloses nothing and is dropped as a sliver. Pieces on their
curve, and pieces whose ends two input curves pass through (a real lens),
are left alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 05:30:41 +07:00
bflatasticandClaude Opus 5.5 700b6786c4 Fix #206: Live Paint treats every path as an edge, open lines included
The Live Paint Bucket now fills areas enclosed by any paths. Crossing
lines enclose faces it can fill, a line across a shape splits that shape's
face in two, and an area enclosed by paths becomes a face even when nothing
fills it (it starts unfilled). Edges are the paths cut wherever another path
meets them, keeping their stroke, so Shift-click paints each piece. Closed
shapes give the same faces as before.

Root cause: Live Paint built its faces from the Pathfinder regions, which
divide the filled areas of closed shapes. An open path counted only as the
area it would fill if closed, which for a straight line is nothing, so lines
divided nothing and the bucket found no face to fill. A new planar map in
vectorcraft-pathops (live_paint) sweeps every path as an edge: an open path
goes in traced there and back, with crossing counts that never cancel; faces
are walked on the resulting graph (holes included), and their fills and the
edges' sources are found geometrically. The sweep runs in an exactly sheared
frame, because it mishandles a horizontal line traced there and back.
Make, Merge, the bucket and Live Paint Selection all use it;
interior_point moves to vectorcraft-pathops with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 02:08:39 +07:00
bflatasticandClaude Opus 5.5 be7006ccf5 M6.10: Boolean operations hold their area identities on almost-horizontal edges
The sweep compares a curve with another segment over a y-span shorter than
its tolerance by bounding boxes only, so an edge rising by less than that
tolerance (e.g. a rectangle edge cut through a circle's cap, whose computed
intersection end sits ~1e-12 off the horizontal) was mis-ordered and the
result lost a corner: xor/difference/area disagreed by up to 10%. Every
sweep input now snaps on-curve y values within the tolerance to one level
(handles follow and are levelled with their anchor), so such edges become
exact horizontals, which the sweep handles exactly.

- tests/regressions.rs: the six minimal failures found by the properties,
  the root cause in isolation, and the self-crossing "star" polygon.
- The star-polygon strategy rejected no angular step of half a turn or
  more, so it sometimes drew self-crossing polygons (the shoelace failure).
- Property suites run from a fixed seed (PROPTEST_CASES / PROPTEST_RNG_SEED
  still override), so CI cannot fail at random.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 03:36:30 +07:00
Brandon ThomasandClaude Opus 5.5 5a36fa1a9b M6.1: a panic inside the curve sweep (rare near-degenerate input) becomes PathOpsError::Degenerate instead of crashing (found by the randomized export test)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 08:16:35 -04:00
Brandon ThomasandClaude Opus 5.5 4878f1c5dd Rename DrawCraft → VectorCraft: crates (vectorcraft-*), apps, binaries, types, env vars, docs, examples (.vectorcraft); old .drawcraft files and preferences still load. Fix: text bounds exact after opening a file; selection no longer marks a document modified (dirty = content differs from the saved document). Screenshots and renders regenerated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:30:09 -04:00
Brandon ThomasandClaude Opus 5.5 bfee80a22c M0: workspace skeleton — geom, color, doc, render, text, pathops, svg, tools, engine
Engine-first Cargo workspace for DrawCraft (clean-room Illustrator):
- geom: anchor-based path model, shapes, hit testing, snapping
- color: colours, paints, gradients, swatches, blend modes, harmonies
- doc: persistent Arc document tree, appearance stacks, text model, selection
- render: vello_cpu renderer (appearance, gradients, clip groups, blend modes)
- text: font DB, harfrust shaping, point/area/path layout
- pathops: curve booleans (linesweeper), Pathfinder, offset, simplify
- svg: import (usvg) and export
- tools: selection/direct/pen/shape tools emitting commands
- engine: Session, history with interactions, ~110 commands

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 05:53:29 -04:00