Skip to content

Commit a7c37af

Browse files
jneemKeavon
authored andcommitted
Do it again
1 parent 4c75ddf commit a7c37af

3 files changed

Lines changed: 54 additions & 10 deletions

File tree

Cargo.lock

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node-graph/gpath-bool/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@ specta = { workspace = true }
1717
log = { workspace = true }
1818
path-bool = { workspace = true }
1919
serde = { workspace = true }
20+
linesweeper = { git = "https://github.com/jneem/linesweeper", features = ["slow-asserts"] }
21+
kurbo.workspace = true

node-graph/gpath-bool/src/lib.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use graphene_core::vector::style::Fill;
77
use graphene_core::vector::{PointId, VectorData, VectorDataTable};
88
use graphene_core::{Color, Ctx, GraphicElement, GraphicGroupTable};
99
pub use path_bool as path_bool_lib;
10-
use path_bool::{FillRule, PathBooleanOperation};
10+
use path_bool::PathBooleanOperation;
1111
use std::ops::Mul;
1212

1313
// TODO: Fix boolean ops to work by removing .transform() and .one_instnace_*() calls,
@@ -374,20 +374,48 @@ fn from_path(path_data: &[Path]) -> VectorData {
374374

375375
type Path = Vec<path_bool::PathSegment>;
376376

377+
fn path_to_bezpath(path: Path) -> kurbo::BezPath {
378+
let p = |p: DVec2| -> kurbo::Point { kurbo::Point::new(p.x, p.y) };
379+
kurbo::BezPath::from_path_segments(path.into_iter().map(|s| match s {
380+
path_bool::PathSegment::Line(p0, p1) => kurbo::Line::new(p(p0), p(p1)).into(),
381+
path_bool::PathSegment::Cubic(p0, p1, p2, p3) => kurbo::CubicBez::new(p(p0), p(p1), p(p2), p(p3)).into(),
382+
path_bool::PathSegment::Quadratic(p0, p1, p2) => kurbo::QuadBez::new(p(p0), p(p1), p(p2)).into(),
383+
path_bool::PathSegment::Arc(..) => unimplemented!(),
384+
}))
385+
}
386+
377387
fn boolean_union(a: Path, b: Path) -> Vec<Path> {
378388
path_bool(a, b, PathBooleanOperation::Union)
379389
}
380390

381391
fn path_bool(a: Path, b: Path, op: PathBooleanOperation) -> Vec<Path> {
382-
match path_bool::path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, op) {
383-
Ok(results) => results,
384-
Err(e) => {
385-
let a_path = path_bool::path_to_path_data(&a, 0.001);
386-
let b_path = path_bool::path_to_path_data(&b, 0.001);
387-
log::error!("Boolean error {e:?} encountered while processing {a_path}\n {op:?}\n {b_path}");
388-
Vec::new()
389-
}
390-
}
392+
let op = match op {
393+
PathBooleanOperation::Union => linesweeper::BinaryOp::Union,
394+
PathBooleanOperation::Difference => linesweeper::BinaryOp::Difference,
395+
PathBooleanOperation::Intersection => linesweeper::BinaryOp::Intersection,
396+
PathBooleanOperation::Exclusion => linesweeper::BinaryOp::Xor,
397+
PathBooleanOperation::Division => unimplemented!(),
398+
PathBooleanOperation::Fracture => unimplemented!(),
399+
};
400+
let a = path_to_bezpath(a);
401+
let b = path_to_bezpath(b);
402+
log::warn!("first path: {:?}", a.to_svg());
403+
log::warn!("second path: {:?}", b.to_svg());
404+
let p = |q: kurbo::Point| -> DVec2 { DVec2::new(q.x, q.y) };
405+
linesweeper::binary_op(&a, &b, linesweeper::FillRule::NonZero, op)
406+
.unwrap()
407+
.contours()
408+
.map(|c| {
409+
c.path
410+
.segments()
411+
.map(|s| match s {
412+
kurbo::PathSeg::Line(ln) => path_bool::PathSegment::Line(p(ln.p0), p(ln.p1)),
413+
kurbo::PathSeg::Quad(q) => path_bool::PathSegment::Quadratic(p(q.p0), p(q.p1), p(q.p2)),
414+
kurbo::PathSeg::Cubic(c) => path_bool::PathSegment::Cubic(p(c.p0), p(c.p1), p(c.p2), p(c.p3)),
415+
})
416+
.collect()
417+
})
418+
.collect()
391419
}
392420

393421
fn boolean_subtract(a: Path, b: Path) -> Vec<Path> {

0 commit comments

Comments
 (0)