Skip to content

Commit 4d767de

Browse files
committed
Try to remove more path_bool
1 parent 9c456d3 commit 4d767de

4 files changed

Lines changed: 22 additions & 47 deletions

File tree

Cargo.lock

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

editor/src/messages/portfolio/document/document_message_handler.rs

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,17 @@ use glam::{DAffine2, DVec2, IVec2};
3131
use graph_craft::document::value::TaggedValue;
3232
use graph_craft::document::{NodeId, NodeInput, NodeNetwork, OldNodeNetwork};
3333
use graphene_std::math::quad::Quad;
34-
use graphene_std::path_bool::{boolean_intersect, path_bool_lib};
34+
use graphene_std::path_bool::boolean_intersect;
3535
use graphene_std::raster::BlendMode;
3636
use graphene_std::raster_types::Raster;
3737
use graphene_std::subpath::Subpath;
3838
use graphene_std::table::Table;
3939
use graphene_std::text::Font;
4040
use graphene_std::vector::PointId;
4141
use graphene_std::vector::click_target::{ClickTarget, ClickTargetType};
42-
use graphene_std::vector::misc::{dvec2_to_point, point_to_dvec2};
42+
use graphene_std::vector::misc::dvec2_to_point;
4343
use graphene_std::vector::style::RenderMode;
44-
use kurbo::{Affine, CubicBez, Line, ParamCurve, PathSeg, QuadBez};
44+
use kurbo::{Affine, BezPath, Line, PathSeg};
4545
use std::path::PathBuf;
4646
use std::time::Duration;
4747

@@ -3015,7 +3015,7 @@ fn default_document_network_interface() -> NodeNetworkInterface {
30153015
enum XRayTarget {
30163016
Point(DVec2),
30173017
Quad(Quad),
3018-
Path(Vec<path_bool_lib::PathSegment>),
3018+
Path(BezPath),
30193019
Polygon(Subpath<PointId>),
30203020
}
30213021

@@ -3033,17 +3033,12 @@ pub struct ClickXRayIter<'a> {
30333033
parent_targets: Vec<(LayerNodeIdentifier, XRayTarget)>,
30343034
}
30353035

3036-
fn quad_to_path_lib_segments(quad: Quad) -> Vec<path_bool_lib::PathSegment> {
3037-
quad.all_edges().into_iter().map(|[start, end]| path_bool_lib::PathSegment::Line(start, end)).collect()
3036+
fn quad_to_kurbo(quad: Quad) -> BezPath {
3037+
BezPath::from_path_segments(quad.all_edges().into_iter().map(|[start, end]| PathSeg::Line(Line::new(dvec2_to_point(start), dvec2_to_point(end)))))
30383038
}
30393039

3040-
fn click_targets_to_path_lib_segments<'a>(click_targets: impl Iterator<Item = &'a ClickTarget>, transform: DAffine2) -> Vec<path_bool_lib::PathSegment> {
3041-
let segment = |bezier: PathSeg| match bezier {
3042-
PathSeg::Line(line) => path_bool_lib::PathSegment::Line(point_to_dvec2(line.p0), point_to_dvec2(line.p1)),
3043-
PathSeg::Quad(quad_bez) => path_bool_lib::PathSegment::Quadratic(point_to_dvec2(quad_bez.p0), point_to_dvec2(quad_bez.p1), point_to_dvec2(quad_bez.p2)),
3044-
PathSeg::Cubic(cubic_bez) => path_bool_lib::PathSegment::Cubic(point_to_dvec2(cubic_bez.p0), point_to_dvec2(cubic_bez.p1), point_to_dvec2(cubic_bez.p2), point_to_dvec2(cubic_bez.p3)),
3045-
};
3046-
click_targets
3040+
fn click_targets_to_kurbo<'a>(click_targets: impl Iterator<Item = &'a ClickTarget>, transform: DAffine2) -> BezPath {
3041+
let segments = click_targets
30473042
.filter_map(|target| {
30483043
if let ClickTargetType::Subpath(subpath) = target.target_type() {
30493044
Some(subpath.iter())
@@ -3052,8 +3047,8 @@ fn click_targets_to_path_lib_segments<'a>(click_targets: impl Iterator<Item = &'
30523047
}
30533048
})
30543049
.flatten()
3055-
.map(|bezier| segment(Affine::new(transform.to_cols_array()) * bezier))
3056-
.collect()
3050+
.map(|bezier| Affine::new(transform.to_cols_array()) * bezier);
3051+
BezPath::from_path_segments(segments)
30573052
}
30583053

30593054
impl<'a> ClickXRayIter<'a> {
@@ -3074,15 +3069,8 @@ impl<'a> ClickXRayIter<'a> {
30743069
}
30753070

30763071
/// Handles the checking of the layer where the target is a rect or path
3077-
fn check_layer_area_target(&mut self, click_targets: Option<&Vec<ClickTarget>>, clip: bool, layer: LayerNodeIdentifier, path: Vec<path_bool_lib::PathSegment>, transform: DAffine2) -> XRayResult {
3078-
// Convert back to Kurbo types for intersections
3079-
let segment = |bezier: &path_bool_lib::PathSegment| match *bezier {
3080-
path_bool_lib::PathSegment::Line(start, end) => PathSeg::Line(Line::new(dvec2_to_point(start), dvec2_to_point(end))),
3081-
path_bool_lib::PathSegment::Cubic(start, h1, h2, end) => PathSeg::Cubic(CubicBez::new(dvec2_to_point(start), dvec2_to_point(h1), dvec2_to_point(h2), dvec2_to_point(end))),
3082-
path_bool_lib::PathSegment::Quadratic(start, h1, end) => PathSeg::Quad(QuadBez::new(dvec2_to_point(start), dvec2_to_point(h1), dvec2_to_point(end))),
3083-
path_bool_lib::PathSegment::Arc(_, _, _, _, _, _, _) => unimplemented!(),
3084-
};
3085-
let get_clip = || path.iter().map(segment);
3072+
fn check_layer_area_target(&mut self, click_targets: Option<&Vec<ClickTarget>>, clip: bool, layer: LayerNodeIdentifier, path: BezPath, transform: DAffine2) -> XRayResult {
3073+
let get_clip = || path.segments();
30863074

30873075
let intersects = click_targets.is_some_and(|targets| targets.iter().any(|target| target.intersect_path(get_clip, transform)));
30883076
let clicked = intersects;
@@ -3091,8 +3079,9 @@ impl<'a> ClickXRayIter<'a> {
30913079
// In the case of a clip path where the area partially intersects, it is necessary to do a boolean operation.
30923080
// We do this on this using the target area to reduce computation (as the target area is usually very simple).
30933081
if clip && intersects {
3094-
let clip_path = click_targets_to_path_lib_segments(click_targets.iter().flat_map(|x| x.iter()), transform);
3095-
let subtracted = boolean_intersect(path, clip_path).into_iter().flatten().collect::<Vec<_>>();
3082+
let clip_path = click_targets_to_kurbo(click_targets.iter().flat_map(|x| x.iter()), transform);
3083+
let intersection = boolean_intersect(&path, &clip_path);
3084+
let subtracted = BezPath::from_path_segments(intersection.iter().flat_map(|p| p.segments()));
30963085
if subtracted.is_empty() {
30973086
use_children = false;
30983087
} else {
@@ -3125,13 +3114,10 @@ impl<'a> ClickXRayIter<'a> {
31253114
use_children: !clip || intersects,
31263115
}
31273116
}
3128-
XRayTarget::Quad(quad) => self.check_layer_area_target(click_targets, clip, layer, quad_to_path_lib_segments(*quad), transform),
3117+
XRayTarget::Quad(quad) => self.check_layer_area_target(click_targets, clip, layer, quad_to_kurbo(*quad), transform),
31293118
XRayTarget::Path(path) => self.check_layer_area_target(click_targets, clip, layer, path.clone(), transform),
31303119
XRayTarget::Polygon(polygon) => {
3131-
let polygon = polygon
3132-
.iter_closed()
3133-
.map(|line| path_bool_lib::PathSegment::Line(point_to_dvec2(line.start()), point_to_dvec2(line.end())))
3134-
.collect();
3120+
let polygon = BezPath::from_path_segments(polygon.iter_closed());
31353121
self.check_layer_area_target(click_targets, clip, layer, polygon, transform)
31363122
}
31373123
}

node-graph/nodes/path-bool/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ glam = { workspace = true }
1616
specta = { workspace = true }
1717
linesweeper = { workspace = true }
1818
log = { workspace = true }
19-
path-bool = { workspace = true }
2019
serde = { workspace = true }
2120
smallvec = { workspace = true }
2221
vector-types = { workspace = true }

node-graph/nodes/path-bool/src/lib.rs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ use graphic_types::vector_types::vector::algorithms::merge_by_distance::MergeByD
88
use graphic_types::vector_types::vector::style::Fill;
99
use graphic_types::{Graphic, Vector};
1010
use linesweeper::topology::Topology;
11-
pub use path_bool as path_bool_lib;
12-
use path_bool::{FillRule, PathBooleanOperation};
11+
use linesweeper::{BinaryOp, FillRule, binary_op};
1312
use smallvec::SmallVec;
1413
use vector_types::kurbo::{Affine, BezPath, CubicBez, ParamCurve, Point};
1514

@@ -334,20 +333,12 @@ fn from_bez_paths<'a>(paths: impl Iterator<Item = &'a BezPath>) -> Vec<Subpath<P
334333
all_subpaths
335334
}
336335

337-
type Path = Vec<path_bool::PathSegment>;
338-
339-
fn path_bool(a: Path, b: Path, op: PathBooleanOperation) -> Vec<Path> {
340-
match path_bool::path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, op) {
341-
Ok(results) => results,
336+
pub fn boolean_intersect(a: &BezPath, b: &BezPath) -> Vec<BezPath> {
337+
match binary_op(a, b, FillRule::NonZero, BinaryOp::Intersection) {
338+
Ok(contours) => contours.contours().map(|c| c.path.clone()).collect(),
342339
Err(e) => {
343-
let a_path = path_bool::path_to_path_data(&a, 0.001);
344-
let b_path = path_bool::path_to_path_data(&b, 0.001);
345-
log::error!("Boolean error {e:?} encountered while processing {a_path}\n {op:?}\n {b_path}");
340+
log::error!("boolean op failed: {e}");
346341
Vec::new()
347342
}
348343
}
349344
}
350-
351-
pub fn boolean_intersect(a: Path, b: Path) -> Vec<Path> {
352-
path_bool(a, b, PathBooleanOperation::Intersection)
353-
}

0 commit comments

Comments
 (0)