mirror of
https://github.com/visioncortex/vtracer.git
synced 2026-09-12 07:06:03 -07:00
ba2b80455e
Face assembly bucketed contours by region label, so a region appearing as several disjoint patches contributed all of their contours to one face — and compose emitted them as subpaths of a single <path>. Isolated islands were therefore not separately addressable downstream. Faces are now keyed by (region, island). `islands` flood-fills the label map into connected components in one pass, and `island_of` attributes a contour via the region-side pixel flanking its first directed edge: every contour is walked with its region on the left, so that pixel is interior to the patch the contour bounds, and an outer ring agrees with the holes inside it. graph gains `left_pixel_coord` (the coordinate half of `left_pixel_at`, which now delegates to it) and `dir_from_delta`, needed because a ring has no start node or first_dir. A BTreeMap keeps face order deterministic: region ascending, then island in raster-scan order. Connectivity is 8-way to match the successor rule, which pinches a checkerboard corner into a single contour: lobes meeting only at a diagonal are walked as one contour and must stay in one face. Splitting them could separate a hole contour from the ring enclosing it, and a lone hole ring fills solid under nonzero. Gum tree in cutout goes 492 -> 517 paths and the tank sprite 1022 -> 1023, with renders byte-identical in both cases: the change is structural only. Costs one O(W*H) pass over a pipeline that is already O(W*H).