mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 18:56:55 -06:00
The Shape Builder only used the filled areas of the selected paths, so a stroke-only line or open path across a shape did nothing. Like the reference app's Shape Builder, open paths now act as cutting edges: - pathops::shape_builder: with an open path in the selection, the regions are the Live Paint planar map's faces (every path an edge), so a line across a shape splits it and lines can enclose a region of their own; it also returns each open path cut where other paths meet it. Closed shapes alone, more than SHAPE_BUILDER_MAX_SEGMENTS segments, or a map that can't be built fall back to the filled-area arrangement. - Filled open paths count as closed (an invisible closing edge) where that encloses an area; unfilled open paths and straight lines stay edges. - shapeBuilder.merge: merging or deleting regions on both sides of a line piece removes that piece (the line is split, its other pieces kept); an area only lines enclose takes the current fill and the front-most object's look. Alt (erase) within `tolerance` of a line piece deletes it. Returns `lines` (pieces deleted). - shapeBuilder.regions also lists the line pieces. - The tool shares BuilderMap/Touched with the command, highlights the line piece under the pointer while Alt is held and passes its tolerance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
35 lines
1.4 KiB
Rust
35 lines
1.4 KiB
Rust
//! VectorCraft path operations: booleans (Pathfinder), shape builder regions, offset, outline stroke,
|
|
//! simplify and the other Object → Path commands.
|
|
//!
|
|
//! Booleans are curve-preserving: `linesweeper`'s robust sweep-line works directly on cubic
|
|
//! Béziers, and the pieces it splits curves into are refitted afterwards so results carry few
|
|
//! anchors. See the crate README for the API overview.
|
|
#![forbid(unsafe_code)]
|
|
|
|
mod boolean;
|
|
mod edit;
|
|
mod fit;
|
|
mod offset;
|
|
mod pathfinder;
|
|
mod planar;
|
|
|
|
pub use boolean::{BoolOp, DEFAULT_PRECISION, area, boolean, boolean_n, normalize, try_boolean, try_normalize, unite_all};
|
|
pub use edit::{
|
|
AverageAxis, SimplifyOptions, add_anchor_points, average, join, remove_anchor, remove_redundant_points, simplify, simplify_with, smooth,
|
|
split_into_grid,
|
|
};
|
|
pub use offset::{Cap, Join, offset_path, outline_stroke, stroke_region};
|
|
pub use pathfinder::{PathfinderOp, Region, Shape, merge_regions, pathfinder, region_at, regions};
|
|
pub use planar::{SHAPE_BUILDER_MAX_SEGMENTS, interior_point, live_paint, shape_builder};
|
|
|
|
/// Errors from fallible operations.
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
|
|
pub enum PathOpsError {
|
|
#[error("input contains NaN or infinite coordinates")]
|
|
NonFinite,
|
|
#[error("input path could not be closed")]
|
|
OpenPath,
|
|
#[error("the shapes are too degenerate to combine")]
|
|
Degenerate,
|
|
}
|