Graphite/libraries/path-bool
Dennis Kobert 3eb98c6d6d
Add path-bool library (#1952)
* Add path-bool library

* Cleanup code

* Cargo format

* Integrate boolean ops into graphite

* Add test for editor crash

* Fix edge sort floating point instability

* Add unit test for red-dress failure

* Backport tests and aux functions

* Use curvature based sorting

* Convert linear cubic splines to line segments

* Deduplicate reversed path segments

* Fix epsilon for empty segments

* Remove parameter based intersection pruning

* Add support for reversed paths

* Add benchmark infrastructure

* Add intersection benchmark

* Add recursion bound

* Implement support for overlapping path segments

* Remove rouge prinln

* Fix sorting for bezier segments with one control point at the start of the segment

* Cleanup log statements

* Directly translate graphite paths to Path segments

* Round data before passing it to path_bool

* Fix flag_faces traversal order

* Add test for white dots in bottom right of painted dreams

* Make rounding configurable

* Update demo artwork to remove manual path modifications

* Convert from path segments to manipulator groups directly

* Remove dead code

* Fix clippy lints

* Replace functions in path segment with methods and add documentation

* Add more documentation

* Close subpaths

* Reorganize files and add README.md

* Add license information

* Code review

* Fix license info

* Adopt new node macro and fix demo artwork

* Close subpaths with Z

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
2024-09-21 02:06:43 -07:00
..
__fixtures__/visual-tests Add path-bool library (#1952) 2024-09-21 02:06:43 -07:00
benches Add path-bool library (#1952) 2024-09-21 02:06:43 -07:00
src Add path-bool library (#1952) 2024-09-21 02:06:43 -07:00
.gitignore Add path-bool library (#1952) 2024-09-21 02:06:43 -07:00
Cargo.toml Add path-bool library (#1952) 2024-09-21 02:06:43 -07:00
LICENSE-APACHE Add path-bool library (#1952) 2024-09-21 02:06:43 -07:00
LICENSE-MIT Add path-bool library (#1952) 2024-09-21 02:06:43 -07:00
NOTICE Add path-bool library (#1952) 2024-09-21 02:06:43 -07:00
README.md Add path-bool library (#1952) 2024-09-21 02:06:43 -07:00
flake.nix Add path-bool library (#1952) 2024-09-21 02:06:43 -07:00
shell.nix Add path-bool library (#1952) 2024-09-21 02:06:43 -07:00

README.md

Path Bool

A Rust library for performing boolean operations on SVG paths.

Path Bool is a port of PathBool.js, providing low-level functionality for boolean operations on complex 2D paths. It handles paths with multiple subpaths, self-intersections, and different fill rules.

Features

  • Supports multiple boolean operations: Union, Intersection, Difference, Exclusion, Division, and Fracture.
  • Handles both NonZero and EvenOdd fill rules.
  • Works with paths containing lines, cubic Bézier curves, quadratic Bézier curves, and elliptical arcs.
  • Provides utilities for parsing and generating SVG path data.

Installation

Add this to your Cargo.toml:

[dependencies]
path-bool = "0.1.0"

Usage

Here's a basic example of performing an intersection operation on two paths:

use path_bool::{path_boolean, FillRule, PathBooleanOperation, path_from_path_data, path_to_path_data};

fn main() {
    let path_a = path_from_path_data("M 10 10 L 50 10 L 30 40 Z");
    let path_b = path_from_path_data("M 20 30 L 60 30 L 60 50 L 20 50 Z");

    let result = path_boolean(
        &path_a,
        FillRule::NonZero,
        &path_b,
        FillRule::NonZero,
        PathBooleanOperation::Intersection
    ).unwrap();

    let result_data = path_to_path_data(&result[0], 0.001);
    println!("Result: {}", result_data);
}

Algorithm

The boolean operations are implemented using a graph-based approach. After the parsing the input, self-intersecting cubic beziers curves are simplified. Then the intersection points between all edges are calculated. These are then turned into a graph representation where every intersection becomes a new vertex. We then apply edge contractions to remove vertices with a degree of 2 to compute the graph minor. At this stage, identical edges are deduplicated. Because we are ultimately interested in the faces of the graph to decide if they should be included in the final output, we then compute the dual graph in which the faces become vertices and vertices become the new faces. That dual structure is then used to determine which faces (dual vertices) should be included in the final output.

Development status

This project is a port of PathBool.js and is still in early stages of development. Contributions, bug reports, and feedback are welcome.

Future work includes:

  • Comprehensive test suite
  • Performance optimizations
  • Additional examples and documentation

License and acknowledgements

This library is a Rust port of PathBool.js by Adam Platkevič.

It is dual-licensed under the MIT License or Apache-2.0 License. You may opt to comply with either license.

Copyright © 2024 Adam Platkevič Copyright © 2024 Graphite Authors