Skip to content

Add path-bool library #1952

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 39 commits into from
Sep 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
883b0bb
Add path-bool library
TrueDoctor Sep 2, 2024
5abda28
Cleanup code
TrueDoctor Sep 2, 2024
b38c323
Cargo format
TrueDoctor Sep 2, 2024
a407572
Integrate boolean ops into graphite
TrueDoctor Sep 2, 2024
94f72d1
Add test for editor crash
TrueDoctor Sep 2, 2024
3c2c1fe
Fix edge sort floating point instability
TrueDoctor Sep 4, 2024
6c2c2cd
Add unit test for red-dress failure
TrueDoctor Sep 5, 2024
fe40a70
Backport tests and aux functions
TrueDoctor Sep 13, 2024
cd6f45e
Use curvature based sorting
TrueDoctor Sep 13, 2024
eb6868c
Convert linear cubic splines to line segments
TrueDoctor Sep 13, 2024
7d40e4e
Deduplicate reversed path segments
TrueDoctor Sep 13, 2024
71ba9d4
Fix epsilon for empty segments
TrueDoctor Sep 14, 2024
5b7b848
Remove parameter based intersection pruning
TrueDoctor Sep 14, 2024
24eecdf
Add support for reversed paths
TrueDoctor Sep 14, 2024
5fccfd9
Add benchmark infrastructure
TrueDoctor Sep 14, 2024
676c22f
Add intersection benchmark
TrueDoctor Sep 14, 2024
3f0a282
Add recursion bound
TrueDoctor Sep 14, 2024
5f18b42
Implement support for overlapping path segments
TrueDoctor Sep 16, 2024
61f760c
Remove rouge prinln
TrueDoctor Sep 16, 2024
27de2e0
Fix sorting for bezier segments with one control point at the start o…
TrueDoctor Sep 16, 2024
4100a6f
Cleanup log statements
TrueDoctor Sep 16, 2024
4ac1f2d
Directly translate graphite paths to Path segments
TrueDoctor Sep 16, 2024
a4c33d4
Round data before passing it to path_bool
TrueDoctor Sep 17, 2024
88c72ae
Fix flag_faces traversal order
TrueDoctor Sep 17, 2024
3acce4e
Add test for white dots in bottom right of painted dreams
TrueDoctor Sep 17, 2024
2047c59
Make rounding configurable
TrueDoctor Sep 17, 2024
50e2db0
Update demo artwork to remove manual path modifications
TrueDoctor Sep 17, 2024
96fe907
Convert from path segments to manipulator groups directly
TrueDoctor Sep 17, 2024
dcf8655
Remove dead code
TrueDoctor Sep 17, 2024
0a5ddc2
Fix clippy lints
TrueDoctor Sep 17, 2024
b15f30f
Replace functions in path segment with methods and add documentation
TrueDoctor Sep 17, 2024
bc95d81
Add more documentation
TrueDoctor Sep 17, 2024
4a300f4
Close subpaths
TrueDoctor Sep 17, 2024
db7a199
Reorganize files and add README.md
TrueDoctor Sep 20, 2024
53e9da2
Add license information
TrueDoctor Sep 20, 2024
544b149
Code review
TrueDoctor Sep 20, 2024
99de883
Fix license info
Keavon Sep 20, 2024
176be29
Adopt new node macro and fix demo artwork
Keavon Sep 20, 2024
dd20465
Close subpaths with Z
Keavon Sep 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ members = [
"node-graph/gpu-executor",
"node-graph/gpu-compiler/gpu-compiler-bin-wrapper",
"libraries/dyn-any",
"libraries/path-bool",
"libraries/bezier-rs",
"libraries/raw-rs",
"libraries/raw-rs/tag-derive",
Expand All @@ -32,6 +33,7 @@ graphene-core = { path = "node-graph/gcore" }
graph-craft = { path = "node-graph/graph-craft", features = ["serde"] }
wgpu-executor = { path = "node-graph/wgpu-executor" }
bezier-rs = { path = "libraries/bezier-rs", features = ["dyn-any"] }
path-bool = { path = "libraries/path-bool", features = ["parsing"] }
node-macro = { path = "node-graph/node-macro" }

# Workspace dependencies
Expand Down
2 changes: 1 addition & 1 deletion demo-artwork/painted-dreams.graphite

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,15 @@ impl<'a> ModifyInputsContext<'a> {
}

pub fn insert_vector_data(&mut self, subpaths: Vec<Subpath<PointId>>, layer: LayerNodeIdentifier) {
let shape = resolve_document_node_type("Shape")
.expect("Shape node does not exist")
let path = resolve_document_node_type("Path")
.expect("Path node does not exist")
.node_template_input_override([Some(NodeInput::value(TaggedValue::Subpaths(subpaths), false))]);
let transform = resolve_document_node_type("Transform").expect("Transform node does not exist").default_node_template();
let fill = resolve_document_node_type("Fill").expect("Fill node does not exist").default_node_template();
let stroke = resolve_document_node_type("Stroke").expect("Stroke node does not exist").default_node_template();

let shape_id = NodeId(generate_uuid());
self.network_interface.insert_node(shape_id, shape, &[]);
self.network_interface.insert_node(shape_id, path, &[]);
self.network_interface.move_node_to_chain_start(&shape_id, layer, &[]);

let transform_id = NodeId(generate_uuid());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2159,12 +2159,13 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
DocumentNode {
inputs: vec![NodeInput::network(concrete!(VectorData), 0), NodeInput::network(concrete!(vector::style::Fill), 1)],
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_std::vector::BooleanOperationNode")),
manual_composition: Some(generic!(T)),
..Default::default()
},
DocumentNode {
inputs: vec![NodeInput::node(NodeId(0), 0)],
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::memo::ImpureMemoNode")),
manual_composition: Some(concrete!(Footprint)),
manual_composition: Some(generic!(T)),
..Default::default()
},
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2268,17 +2268,10 @@ pub(crate) fn generate_node_properties(document_node: &DocumentNode, node_id: No
}

pub(crate) fn boolean_operation_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let group_of_paths_index = 0;
let operation_index = 1;

let mut widgets = start_widgets(document_node, node_id, group_of_paths_index, "Group of Paths", FrontendGraphDataType::Graphic, true);

widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
widgets.push(TextLabel::new("The output of a layer stack, which contains all elements to operate on").widget_holder());

let operation = boolean_operation_radio_buttons(document_node, node_id, operation_index, "Operation", true);

vec![LayoutGroup::Row { widgets }, operation]
vec![operation]
}

pub(crate) fn copy_to_points_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
Expand Down
13 changes: 3 additions & 10 deletions libraries/bezier-rs/src/bezier/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,9 @@ impl Bezier {

/// Return the string argument used to create a curve in an SVG `path`, excluding the start point.
pub fn svg_curve_argument(&self) -> String {
let handle_args = match self.handles {
BezierHandles::Linear => SVG_ARG_LINEAR.to_string(),
BezierHandles::Quadratic { handle } => {
format!("{SVG_ARG_QUADRATIC}{} {}", handle.x, handle.y)
}
BezierHandles::Cubic { handle_start, handle_end } => {
format!("{SVG_ARG_CUBIC}{} {} {} {}", handle_start.x, handle_start.y, handle_end.x, handle_end.y)
}
};
format!("{handle_args} {} {}", self.end.x, self.end.y)
let mut out = String::new();
self.write_curve_argument(&mut out).unwrap();
out
}

/// Write the curve argument to the string
Expand Down
2 changes: 2 additions & 0 deletions libraries/path-bool/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
test-results
38 changes: 38 additions & 0 deletions libraries/path-bool/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[package]
name = "path-bool"
version = "0.1.0"
rust-version = "1.81"
authors = ["Graphite Authors <[email protected]>"]
edition = "2021"
keywords = ["bezier", "boolean", "path", "ops", "operations", "2d"]
categories = ["graphics", "mathematics"]
license = "MIT OR Apache-2.0"


[features]
logging = ["parsing"]
parsing = []
default = ["parsing"]

[dependencies]
glam = "0.28.0"
regex = "1.10.6"
slotmap = "1.0.7"

[dev-dependencies]
glob = "0.3"
svg = "0.13"
resvg = "0.42"
image = "0.24"

# Required dependencies
criterion = { version = "0.5", features = ["html_reports"]}

# Benchmarks
[[bench]]
name = "painted_dreams"
harness = false

[[bench]]
name = "path_segment_intersection"
harness = false
Loading
Loading