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>
This commit is contained in:
Dennis Kobert
2024-09-21 02:06:43 -07:00
committed by GitHub
co-authored by Keavon Chambers
parent 2febbfd698
commit 3eb98c6d6d
165 changed files with 5990 additions and 78 deletions
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="48" height="48" viewBox="0 0 48 48" version="1.1" id="svg1" xmlns="http://www.w3.org/2000/svg">
<path style="fill:#ff0000;stroke:#000000;stroke-width:1.99937;stroke-linecap:round;stroke-linejoin:round" d="M 30.596088000000,33.005245000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 17.842087000000,23.999999000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 5.088085200000,33.005245000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 17.842087000000,42.010491000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 30.596088000000,33.005245000000"/>
</svg>

After

Width:  |  Height:  |  Size: 719 B

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="48" height="48" viewBox="0 0 48 48" version="1.1" id="svg1" xmlns="http://www.w3.org/2000/svg">
<path style="fill:#ff0000;stroke:#000000;stroke-width:1.99937;stroke-linecap:round;stroke-linejoin:round" d="M 30.596088000000,33.005245000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 17.842087000000,23.999999000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 5.088085200000,33.005245000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 17.842087000000,42.010491000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 30.596088000000,33.005245000000"/>
</svg>

After

Width:  |  Height:  |  Size: 719 B

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="48" height="48" viewBox="0 0 48 48" version="1.1" id="svg1" xmlns="http://www.w3.org/2000/svg">
<path style="fill:#ff0000;stroke:#000000;stroke-width:1.99937;stroke-linecap:round;stroke-linejoin:round" d="M 39.958363000000,15.328637000000 A 7.147991200000 10.562863000000 0.000000000000 0 0 32.810371000000,4.765773800000 A 7.147991200000 10.562863000000 0.000000000000 0 0 25.662380000000,15.328637000000 A 7.147991200000 10.562863000000 0.000000000000 0 0 32.810371000000,25.891500000000 A 7.147991200000 10.562863000000 0.000000000000 0 0 39.958363000000,15.328637000000 M 17.842086000000,10.979142000000 A 4.408302800000 4.349494900000 0.000000000000 0 0 13.433784000000,6.629647300000 A 4.408302800000 4.349494900000 0.000000000000 0 0 9.025480700000,10.979142000000 A 4.408302800000 4.349494900000 0.000000000000 0 0 13.433784000000,15.328637000000 A 4.408302800000 4.349494900000 0.000000000000 0 0 17.842086000000,10.979142000000 M 30.596088000000,33.005245000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 17.842087000000,23.999999000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 5.088085200000,33.005245000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 17.842087000000,42.010491000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 30.596088000000,33.005245000000"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="48" height="48" viewBox="0 0 48 48" version="1.1" id="svg1" xmlns="http://www.w3.org/2000/svg">
<path style="fill:#ff0000;stroke:#000000;stroke-width:1.99937;stroke-linecap:round;stroke-linejoin:round" d="M 39.958363000000,15.328637000000 A 7.147991200000 10.562863000000 0.000000000000 0 0 32.810371000000,4.765773800000 A 7.147991200000 10.562863000000 0.000000000000 0 0 25.662380000000,15.328637000000 A 7.147991200000 10.562863000000 0.000000000000 0 0 32.810371000000,25.891500000000 A 7.147991200000 10.562863000000 0.000000000000 0 0 39.958363000000,15.328637000000"/><path style="fill:#ff0000;stroke:#000000;stroke-width:1.99937;stroke-linecap:round;stroke-linejoin:round" d="M 17.842086000000,10.979142000000 A 4.408302800000 4.349494900000 0.000000000000 0 0 13.433784000000,6.629647300000 A 4.408302800000 4.349494900000 0.000000000000 0 0 9.025480700000,10.979142000000 A 4.408302800000 4.349494900000 0.000000000000 0 0 13.433784000000,15.328637000000 A 4.408302800000 4.349494900000 0.000000000000 0 0 17.842086000000,10.979142000000"/><path style="fill:#ff0000;stroke:#000000;stroke-width:1.99937;stroke-linecap:round;stroke-linejoin:round" d="M 30.596088000000,33.005245000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 17.842087000000,23.999999000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 5.088085200000,33.005245000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 17.842087000000,42.010491000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 30.596088000000,33.005245000000"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="48" height="48" viewBox="0 0 48 48" version="1.1" id="svg1" xmlns="http://www.w3.org/2000/svg">
<path style="fill:#ff0000;stroke:#000000;stroke-width:1.99937;stroke-linecap:round;stroke-linejoin:round" d=""/>
</svg>

After

Width:  |  Height:  |  Size: 351 B

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="48"
height="48"
viewBox="0 0 48 48"
version="1.1"
id="svg1"
xmlns="http://www.w3.org/2000/svg"
>
<path id="a"
style="fill:#ff0000;stroke:#000000;stroke-width:1.99937;stroke-linecap:round;stroke-linejoin:round"
d="M 30.596088,33.005245 A 12.754002,9.0052462 0 0 1 17.842087,42.010491 12.754002,9.0052462 0 0 1 5.0880852,33.005245 12.754002,9.0052462 0 0 1 17.842087,23.999999 12.754002,9.0052462 0 0 1 30.596088,33.005245 Z"/>
<path id="b"
style="fill:#ff0000;stroke:#000000;stroke-width:1.99937;stroke-linecap:round;stroke-linejoin:round"
d="m 17.842086,10.979142 a 4.4083028,4.3494949 0 0 1 -4.408302,4.349495 4.4083028,4.3494949 0 0 1 -4.4083033,-4.349495 4.4083028,4.3494949 0 0 1 4.4083033,-4.3494947 4.4083028,4.3494949 0 0 1 4.408302,4.3494947 z m 22.116277,4.349495 A 7.1479912,10.562863 0 0 1 32.810371,25.8915 7.1479912,10.562863 0 0 1 25.66238,15.328637 7.1479912,10.562863 0 0 1 32.810371,4.7657738 7.1479912,10.562863 0 0 1 39.958363,15.328637 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="48" height="48" viewBox="0 0 48 48" version="1.1" id="svg1" xmlns="http://www.w3.org/2000/svg">
<path style="fill:#ff0000;stroke:#000000;stroke-width:1.99937;stroke-linecap:round;stroke-linejoin:round" d="M 39.958363000000,15.328637000000 A 7.147991200000 10.562863000000 0.000000000000 0 0 32.810371000000,4.765773800000 A 7.147991200000 10.562863000000 0.000000000000 0 0 25.662380000000,15.328637000000 A 7.147991200000 10.562863000000 0.000000000000 0 0 32.810371000000,25.891500000000 A 7.147991200000 10.562863000000 0.000000000000 0 0 39.958363000000,15.328637000000 M 17.842086000000,10.979142000000 A 4.408302800000 4.349494900000 0.000000000000 0 0 13.433784000000,6.629647300000 A 4.408302800000 4.349494900000 0.000000000000 0 0 9.025480700000,10.979142000000 A 4.408302800000 4.349494900000 0.000000000000 0 0 13.433784000000,15.328637000000 A 4.408302800000 4.349494900000 0.000000000000 0 0 17.842086000000,10.979142000000 M 30.596088000000,33.005245000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 17.842087000000,23.999999000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 5.088085200000,33.005245000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 17.842087000000,42.010491000000 A 12.754002000000 9.005246200000 0.000000000000 0 0 30.596088000000,33.005245000000"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB