From 8a1089938ef13ee8905e4b518cadb45794658f5c Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Mon, 23 Sep 2024 12:16:31 +0200 Subject: [PATCH] Path Bool library code cleanup (#2000) * Remove log statements * Add feature gates to functions in path.rs * Fix infinite parsing loop and add new test * License tweaks * Remove trailing zero in whole number floats * Flatten visual-tests directory * Code review * Clean up printlines * Add error handling to path parsing --------- Co-authored-by: Keavon Chambers --- Cargo.toml | 2 +- .../node_graph/node_graph_message_handler.rs | 6 +- .../document/overlays/grid_overlays.rs | 2 +- .../utility_types/network_interface.rs | 4 +- libraries/bezier-rs/src/bezier/lookup.rs | 2 +- libraries/bezier-rs/src/subpath/lookup.rs | 4 +- libraries/bezier-rs/src/subpath/solvers.rs | 2 +- libraries/bezier-rs/src/symmetrical_basis.rs | 4 +- libraries/path-bool/.gitignore | 4 +- libraries/path-bool/Cargo.toml | 18 ++- libraries/path-bool/NOTICE | 15 +- libraries/path-bool/README.md | 7 +- .../visual-tests/establish-ground-truth.sh | 5 - .../visual-tests/generate-ground-truth.sh | 10 -- libraries/path-bool/benches/painted_dreams.rs | 7 +- .../benches/path_segment_intersection.rs | 8 +- libraries/path-bool/flake.nix | 6 +- libraries/path-bool/src/lib.rs | 90 ++++++----- libraries/path-bool/src/parsing/path_data.rs | 12 +- libraries/path-bool/src/path.rs | 4 +- .../src/path/intersection_path_segment.rs | 49 +++--- libraries/path-bool/src/path/line_segment.rs | 4 +- .../path-bool/src/path/line_segment_aabb.rs | 4 +- .../path_cubic_segment_self_intersection.rs | 24 +-- libraries/path-bool/src/path/path_segment.rs | 149 +++++++++--------- libraries/path-bool/src/path_boolean.rs | 144 +++++++---------- libraries/path-bool/src/util/math.rs | 2 +- libraries/path-bool/src/util/quad_tree.rs | 20 +-- libraries/path-bool/src/visual_tests.rs | 26 ++- .../visual-tests/dangling-01/difference.svg | 0 .../visual-tests/dangling-01/division.svg | 0 .../visual-tests/dangling-01/exclusion.svg | 0 .../visual-tests/dangling-01/fracture.svg | 0 .../visual-tests/dangling-01/intersection.svg | 0 .../visual-tests/dangling-01/original.svg | 0 .../visual-tests/dangling-01/union.svg | 0 .../visual-tests/dangling-02/difference.svg | 0 .../visual-tests/dangling-02/division.svg | 0 .../visual-tests/dangling-02/exclusion.svg | 0 .../visual-tests/dangling-02/fracture.svg | 0 .../visual-tests/dangling-02/intersection.svg | 0 .../visual-tests/dangling-02/original.svg | 0 .../visual-tests/dangling-02/union.svg | 0 .../visual-tests/dangling-03/difference.svg | 0 .../visual-tests/dangling-03/division.svg | 0 .../visual-tests/dangling-03/exclusion.svg | 0 .../visual-tests/dangling-03/fracture.svg | 0 .../visual-tests/dangling-03/intersection.svg | 0 .../visual-tests/dangling-03/original.svg | 0 .../visual-tests/dangling-03/union.svg | 0 .../visual-tests/dangling-04/difference.svg | 0 .../visual-tests/dangling-04/division.svg | 0 .../visual-tests/dangling-04/exclusion.svg | 0 .../visual-tests/dangling-04/fracture.svg | 0 .../visual-tests/dangling-04/intersection.svg | 0 .../visual-tests/dangling-04/original.svg | 0 .../visual-tests/dangling-04/union.svg | 0 .../visual-tests/establish-ground-truth.sh | 5 + .../visual-tests/generate-ground-truth.sh | 10 ++ .../visual-tests/nesting-01/difference.svg | 0 .../visual-tests/nesting-01/division.svg | 0 .../visual-tests/nesting-01/exclusion.svg | 0 .../visual-tests/nesting-01/fracture.svg | 0 .../visual-tests/nesting-01/intersection.svg | 0 .../visual-tests/nesting-01/original.svg | 0 .../visual-tests/nesting-01/union.svg | 0 .../visual-tests/nesting-02/difference.svg | 0 .../visual-tests/nesting-02/division.svg | 0 .../visual-tests/nesting-02/exclusion.svg | 0 .../visual-tests/nesting-02/fracture.svg | 0 .../visual-tests/nesting-02/intersection.svg | 0 .../visual-tests/nesting-02/original.svg | 0 .../visual-tests/nesting-02/union.svg | 0 .../visual-tests/nesting-03/difference.svg | 0 .../visual-tests/nesting-03/division.svg | 0 .../visual-tests/nesting-03/exclusion.svg | 0 .../visual-tests/nesting-03/fracture.svg | 0 .../visual-tests/nesting-03/intersection.svg | 0 .../visual-tests/nesting-03/original.svg | 0 .../visual-tests/nesting-03/union.svg | 0 .../visual-tests/nesting-04/difference.svg | 0 .../visual-tests/nesting-04/division.svg | 0 .../visual-tests/nesting-04/exclusion.svg | 0 .../visual-tests/nesting-04/fracture.svg | 0 .../visual-tests/nesting-04/intersection.svg | 0 .../visual-tests/nesting-04/original.svg | 0 .../visual-tests/nesting-04/union.svg | 0 .../visual-tests/real-01/difference.svg | 0 .../visual-tests/real-01/division.svg | 0 .../visual-tests/real-01/exclusion.svg | 0 .../visual-tests/real-01/fracture.svg | 0 .../visual-tests/real-01/intersection.svg | 0 .../visual-tests/real-01/original.svg | 0 .../visual-tests/real-01/union.svg | 0 .../visual-tests/real-02/difference.svg | 0 .../visual-tests/real-02/division.svg | 0 .../visual-tests/real-02/exclusion.svg | 0 .../visual-tests/real-02/fracture.svg | 0 .../visual-tests/real-02/intersection.svg | 0 .../visual-tests/real-02/original.svg | 0 .../visual-tests/real-02/union.svg | 0 .../visual-tests/real-03/difference.svg | 9 ++ .../visual-tests/real-03/division.svg | 9 ++ .../visual-tests/real-03/exclusion.svg | 9 ++ .../visual-tests/real-03/fracture.svg | 9 ++ .../visual-tests/real-03/intersection.svg | 9 ++ .../visual-tests/real-03/original.svg | 23 +++ .../path-bool/visual-tests/real-03/union.svg | 9 ++ .../visual-tests/simple-01/difference.svg | 0 .../visual-tests/simple-01/division.svg | 0 .../visual-tests/simple-01/exclusion.svg | 0 .../visual-tests/simple-01/fracture.svg | 0 .../visual-tests/simple-01/intersection.svg | 0 .../visual-tests/simple-01/original.svg | 0 .../visual-tests/simple-01/union.svg | 0 .../visual-tests/simple-02/difference.svg | 0 .../visual-tests/simple-02/division.svg | 0 .../visual-tests/simple-02/exclusion.svg | 0 .../visual-tests/simple-02/fracture.svg | 0 .../visual-tests/simple-02/intersection.svg | 0 .../visual-tests/simple-02/original.svg | 0 .../visual-tests/simple-02/union.svg | 0 .../visual-tests/simple-03/difference.svg | 0 .../visual-tests/simple-03/division.svg | 0 .../visual-tests/simple-03/exclusion.svg | 0 .../visual-tests/simple-03/fracture.svg | 0 .../visual-tests/simple-03/intersection.svg | 0 .../visual-tests/simple-03/original.svg | 0 .../visual-tests/simple-03/union.svg | 0 .../visual-tests/simple-04/difference.svg | 0 .../visual-tests/simple-04/division.svg | 0 .../visual-tests/simple-04/exclusion.svg | 0 .../visual-tests/simple-04/fracture.svg | 0 .../visual-tests/simple-04/intersection.svg | 0 .../visual-tests/simple-04/original.svg | 0 .../visual-tests/simple-04/union.svg | 0 .../visual-tests/simple-05/difference.svg | 0 .../visual-tests/simple-05/division.svg | 0 .../visual-tests/simple-05/exclusion.svg | 0 .../visual-tests/simple-05/fracture.svg | 0 .../visual-tests/simple-05/intersection.svg | 0 .../visual-tests/simple-05/original.svg | 0 .../visual-tests/simple-05/union.svg | 0 .../visual-tests/simple-06/difference.svg | 0 .../visual-tests/simple-06/division.svg | 0 .../visual-tests/simple-06/exclusion.svg | 0 .../visual-tests/simple-06/fracture.svg | 0 .../visual-tests/simple-06/intersection.svg | 0 .../visual-tests/simple-06/original.svg | 0 .../visual-tests/simple-06/union.svg | 0 .../visual-tests/simple-07/difference.svg | 0 .../visual-tests/simple-07/division.svg | 0 .../visual-tests/simple-07/exclusion.svg | 0 .../visual-tests/simple-07/fracture.svg | 0 .../visual-tests/simple-07/intersection.svg | 0 .../visual-tests/simple-07/original.svg | 0 .../visual-tests/simple-07/union.svg | 0 .../visual-tests/simple-08/difference.svg | 0 .../visual-tests/simple-08/division.svg | 0 .../visual-tests/simple-08/exclusion.svg | 0 .../visual-tests/simple-08/fracture.svg | 0 .../visual-tests/simple-08/intersection.svg | 0 .../visual-tests/simple-08/original.svg | 0 .../visual-tests/simple-08/union.svg | 0 .../visual-tests/template.svg | 0 node-graph/compilation-client/src/main.rs | 2 +- node-graph/gcore/src/raster/color.rs | 2 +- node-graph/gcore/src/raster/discrete_srgb.rs | 14 +- node-graph/gstd/src/brush.rs | 4 +- node-graph/gstd/src/gpu_nodes.rs | 2 +- node-graph/gstd/src/image_color_palette.rs | 16 +- node-graph/gstd/src/imaginate.rs | 4 +- node-graph/gstd/src/raster.rs | 8 +- node-graph/gstd/src/wasm_application_io.rs | 2 +- node-graph/wgpu-executor/src/lib.rs | 8 +- 175 files changed, 442 insertions(+), 346 deletions(-) delete mode 100755 libraries/path-bool/__fixtures__/visual-tests/establish-ground-truth.sh delete mode 100755 libraries/path-bool/__fixtures__/visual-tests/generate-ground-truth.sh rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-01/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-01/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-01/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-01/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-01/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-01/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-01/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-02/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-02/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-02/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-02/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-02/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-02/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-02/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-03/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-03/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-03/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-03/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-03/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-03/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-03/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-04/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-04/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-04/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-04/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-04/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-04/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/dangling-04/union.svg (100%) create mode 100644 libraries/path-bool/visual-tests/establish-ground-truth.sh create mode 100644 libraries/path-bool/visual-tests/generate-ground-truth.sh rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-01/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-01/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-01/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-01/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-01/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-01/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-01/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-02/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-02/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-02/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-02/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-02/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-02/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-02/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-03/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-03/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-03/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-03/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-03/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-03/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-03/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-04/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-04/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-04/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-04/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-04/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-04/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/nesting-04/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-01/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-01/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-01/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-01/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-01/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-01/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-01/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-02/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-02/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-02/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-02/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-02/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-02/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/real-02/union.svg (100%) create mode 100644 libraries/path-bool/visual-tests/real-03/difference.svg create mode 100644 libraries/path-bool/visual-tests/real-03/division.svg create mode 100644 libraries/path-bool/visual-tests/real-03/exclusion.svg create mode 100644 libraries/path-bool/visual-tests/real-03/fracture.svg create mode 100644 libraries/path-bool/visual-tests/real-03/intersection.svg create mode 100644 libraries/path-bool/visual-tests/real-03/original.svg create mode 100644 libraries/path-bool/visual-tests/real-03/union.svg rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-01/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-01/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-01/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-01/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-01/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-01/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-01/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-02/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-02/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-02/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-02/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-02/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-02/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-02/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-03/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-03/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-03/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-03/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-03/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-03/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-03/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-04/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-04/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-04/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-04/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-04/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-04/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-04/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-05/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-05/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-05/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-05/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-05/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-05/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-05/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-06/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-06/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-06/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-06/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-06/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-06/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-06/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-07/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-07/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-07/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-07/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-07/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-07/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-07/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-08/difference.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-08/division.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-08/exclusion.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-08/fracture.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-08/intersection.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-08/original.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/simple-08/union.svg (100%) rename libraries/path-bool/{__fixtures__ => }/visual-tests/template.svg (100%) diff --git a/Cargo.toml b/Cargo.toml index 1ca3a9bcf..33dc19397 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +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"] } +path-bool = { path = "libraries/path-bool", default-features = false } node-macro = { path = "node-graph/node-macro" } # Workspace dependencies diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs index d8073a5c8..6eb0e23d2 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler.rs @@ -1926,10 +1926,10 @@ impl NodeGraphMessageHandler { // } let curve_length = 24.; - let curve_falloff_rate = curve_length * std::f64::consts::PI * 2.0; + let curve_falloff_rate = curve_length * std::f64::consts::PI * 2.; - let horizontal_curve_amount = -(2.0f64.powf((-10. * horizontal_gap) / curve_falloff_rate)) + 1.; - let vertical_curve_amount = -(2.0f64.powf((-10. * vertical_gap) / curve_falloff_rate)) + 1.; + let horizontal_curve_amount = -(2_f64.powf((-10. * horizontal_gap) / curve_falloff_rate)) + 1.; + let vertical_curve_amount = -(2_f64.powf((-10. * vertical_gap) / curve_falloff_rate)) + 1.; let horizontal_curve = horizontal_curve_amount * curve_length; let vertical_curve = vertical_curve_amount * curve_length; diff --git a/editor/src/messages/portfolio/document/overlays/grid_overlays.rs b/editor/src/messages/portfolio/document/overlays/grid_overlays.rs index f89e4808e..dbed875dc 100644 --- a/editor/src/messages/portfolio/document/overlays/grid_overlays.rs +++ b/editor/src/messages/portfolio/document/overlays/grid_overlays.rs @@ -160,7 +160,7 @@ fn grid_overlay_isometric_dot(document: &DocumentMessageHandler, overlay_context let max_x = bounds.0.iter().map(|&corner| corner.x).max_by(cmp).unwrap_or_default(); let spacing_x = isometric_spacing.x; let tan = tan_a; - let multiply = -1.0; + let multiply = -1.; let project = |corner: &DVec2| corner.y + multiply * tan * (corner.x - origin.x); let inverse_project = |corner: &DVec2| corner.y - tan * multiply * (corner.x - origin.x); let min_y = bounds.0.into_iter().min_by(|a, b| inverse_project(a).partial_cmp(&inverse_project(b)).unwrap()).unwrap_or_default(); diff --git a/editor/src/messages/portfolio/document/utility_types/network_interface.rs b/editor/src/messages/portfolio/document/utility_types/network_interface.rs index 64a81acec..e6a201354 100644 --- a/editor/src/messages/portfolio/document/utility_types/network_interface.rs +++ b/editor/src/messages/portfolio/document/utility_types/network_interface.rs @@ -2285,7 +2285,7 @@ impl NodeNetworkInterface { let chain_width_grid_spaces = self.chain_width(node_id, network_path); let node_bottom_right = node_top_left + DVec2::new(width as f64, height as f64); - let chain_top_left = node_top_left - DVec2::new((chain_width_grid_spaces * crate::consts::GRID_SIZE) as f64, 0.0); + let chain_top_left = node_top_left - DVec2::new((chain_width_grid_spaces * crate::consts::GRID_SIZE) as f64, 0.); let radius = 10.; let subpath = bezier_rs::Subpath::new_rounded_rect(chain_top_left, node_bottom_right, [radius; 4]); let node_click_target = ClickTarget::new(subpath, 0.); @@ -5083,7 +5083,7 @@ impl Ports { fn insert_layer_output(&mut self, node_top_left: DVec2) { // The center of the click target is always 24 px down from the top left corner of the node - let center = node_top_left + DVec2::new(2. * 24., -8.0); + let center = node_top_left + DVec2::new(2. * 24., -8.); self.insert_output_port_at_center(0, center); } diff --git a/libraries/bezier-rs/src/bezier/lookup.rs b/libraries/bezier-rs/src/bezier/lookup.rs index b74f42707..c86cef65e 100644 --- a/libraries/bezier-rs/src/bezier/lookup.rs +++ b/libraries/bezier-rs/src/bezier/lookup.rs @@ -357,7 +357,7 @@ mod tests { let bezier2 = Bezier::from_quadratic_coordinates(0., 0., 0., 100., 100., 100.); assert_eq!(bezier2.project(DVec2::new(100., 0.)), 0.); - let bezier3 = Bezier::from_cubic_coordinates(-50.0, -50.0, -50.0, -50.0, 50.0, -50.0, 50.0, -50.0); + let bezier3 = Bezier::from_cubic_coordinates(-50., -50., -50., -50., 50., -50., 50., -50.); assert_eq!(DVec2::new(0., -50.), bezier3.evaluate(TValue::Parametric(bezier3.project(DVec2::new(0., -50.))))); } } diff --git a/libraries/bezier-rs/src/subpath/lookup.rs b/libraries/bezier-rs/src/subpath/lookup.rs index 6a48d4870..a63b7a179 100644 --- a/libraries/bezier-rs/src/subpath/lookup.rs +++ b/libraries/bezier-rs/src/subpath/lookup.rs @@ -513,7 +513,7 @@ mod tests { let subpath: Subpath = Subpath::from_bezier(&Bezier::from_quadratic_dvec2(start, handle, end)); - assert_eq!(subpath.evaluate(SubpathTValue::GlobalEuclidean(0.0)), start); - assert_eq!(subpath.evaluate(SubpathTValue::GlobalEuclidean(1.0)), end); + assert_eq!(subpath.evaluate(SubpathTValue::GlobalEuclidean(0.)), start); + assert_eq!(subpath.evaluate(SubpathTValue::GlobalEuclidean(1.)), end); } } diff --git a/libraries/bezier-rs/src/subpath/solvers.rs b/libraries/bezier-rs/src/subpath/solvers.rs index d9bcd99be..321f3858a 100644 --- a/libraries/bezier-rs/src/subpath/solvers.rs +++ b/libraries/bezier-rs/src/subpath/solvers.rs @@ -607,7 +607,7 @@ mod tests { ) .all()); - let t4 = 1.0; + let t4 = 1.; assert!(utils::dvec2_compare( subpath.evaluate(SubpathTValue::GlobalParametric(t4)), quadratic_bezier.evaluate(TValue::Parametric(1.)), diff --git a/libraries/bezier-rs/src/symmetrical_basis.rs b/libraries/bezier-rs/src/symmetrical_basis.rs index 59443cb27..2e4abb44e 100644 --- a/libraries/bezier-rs/src/symmetrical_basis.rs +++ b/libraries/bezier-rs/src/symmetrical_basis.rs @@ -357,7 +357,7 @@ impl Bezier1d { fn value_at(&self, t: f64) -> f64 { let bz = self; let order = bz.len() - 1; - let u = 1.0 - t; + let u = 1. - t; let mut bc = 1.; let mut tn = 1.; let mut tmp = bz[0] * u; @@ -611,7 +611,7 @@ mod tests { #[test] fn find_bernstein_roots() { - let bz = Bezier1d(vec![50.0, -100.0, 170.0]); + let bz = Bezier1d(vec![50., -100., 170.]); let mut solutions = Vec::new(); bz.find_bernstein_roots(&mut solutions, 0, 0., 1.); diff --git a/libraries/path-bool/.gitignore b/libraries/path-bool/.gitignore index 3d626b230..73bdcbf49 100644 --- a/libraries/path-bool/.gitignore +++ b/libraries/path-bool/.gitignore @@ -1,2 +1,2 @@ -/target -test-results +/target/ +test-results/ diff --git a/libraries/path-bool/Cargo.toml b/libraries/path-bool/Cargo.toml index 6686b33ad..3ccb176f4 100644 --- a/libraries/path-bool/Cargo.toml +++ b/libraries/path-bool/Cargo.toml @@ -2,13 +2,22 @@ name = "path-bool" version = "0.1.0" rust-version = "1.81" -authors = ["Graphite Authors "] +authors = ["Graphite Authors ", "Adam Platkevič"] edition = "2021" -keywords = ["bezier", "boolean", "path", "ops", "operations", "2d"] +keywords = [ + "bezier", + "curve", + "boolean", + "path", + "geometry", + "computational geometry", + "vector graphics", + "2d", + "graphics", +] categories = ["graphics", "mathematics"] license = "MIT OR Apache-2.0" - [features] logging = ["parsing"] parsing = [] @@ -26,13 +35,12 @@ resvg = "0.42" image = "0.24" # Required dependencies -criterion = { version = "0.5", features = ["html_reports"]} +criterion = { version = "0.5", features = ["html_reports"] } # Benchmarks [[bench]] name = "painted_dreams" harness = false - [[bench]] name = "path_segment_intersection" harness = false diff --git a/libraries/path-bool/NOTICE b/libraries/path-bool/NOTICE index 80cfbdae4..80e631b18 100644 --- a/libraries/path-bool/NOTICE +++ b/libraries/path-bool/NOTICE @@ -1,6 +1,15 @@ NOTICE -This project includes software originally developed by Adam Platkevič. -The original project is licensed under the MIT License. - Rust port and modifications are (c) 2024 Graphite Authors. + +This library is derived from software originally developed by Adam Platkevič which is licensed under the MIT License reproduced below: + +MIT License + +Copyright (c) 2024 Adam Platkevič + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/libraries/path-bool/README.md b/libraries/path-bool/README.md index 379b975d6..0293bb1bc 100644 --- a/libraries/path-bool/README.md +++ b/libraries/path-bool/README.md @@ -28,8 +28,8 @@ 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 path_a = path_from_path_data("M 10 10 L 50 10 L 30 40 Z").unwrap(); + let path_b = path_from_path_data("M 20 30 L 60 30 L 60 50 L 20 50 Z").unwrap(); let result = path_boolean( &path_a, @@ -50,13 +50,14 @@ The boolean operations are implemented using a graph-based approach. After the p ## 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. +This project is a port of PathBool.js which 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 +- Support for path builder tool features ## License and acknowledgements diff --git a/libraries/path-bool/__fixtures__/visual-tests/establish-ground-truth.sh b/libraries/path-bool/__fixtures__/visual-tests/establish-ground-truth.sh deleted file mode 100755 index 6bdb1ae54..000000000 --- a/libraries/path-bool/__fixtures__/visual-tests/establish-ground-truth.sh +++ /dev/null @@ -1,5 +0,0 @@ -for dir in */; do - for fn in difference division exclusion fracture intersection union; do - cp "${dir}test-results/$fn-ours.svg" "$dir$fn.svg" - done -done diff --git a/libraries/path-bool/__fixtures__/visual-tests/generate-ground-truth.sh b/libraries/path-bool/__fixtures__/visual-tests/generate-ground-truth.sh deleted file mode 100755 index 104b43cf1..000000000 --- a/libraries/path-bool/__fixtures__/visual-tests/generate-ground-truth.sh +++ /dev/null @@ -1,10 +0,0 @@ -INKSCAPE_CMD=inkscape -OPS=(union difference intersection exclusion division fracture) - -for dir in */; do - for op in "${OPS[@]}"; do - if [ ! -e "$dir/$op.svg" ]; then - $INKSCAPE_CMD --actions="select-all; path-$op; export-filename:$dir/$op.svg; export-plain-svg; export-do; file-close" "$dir/original.svg" - fi - done -done diff --git a/libraries/path-bool/benches/painted_dreams.rs b/libraries/path-bool/benches/painted_dreams.rs index 3fe66bc07..c619143ff 100644 --- a/libraries/path-bool/benches/painted_dreams.rs +++ b/libraries/path-bool/benches/painted_dreams.rs @@ -2,10 +2,11 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use path_bool::*; pub fn criterion_benchmark(c: &mut Criterion) { - let path_a = path_from_path_data("M0,340C161.737914,383.575765 107.564182,490.730587 273,476 C419,463 481.741198,514.692273 481.333333,768 C481.333333,768 -0,768 -0,768 C-0,768 0,340 0,340 Z "); + let path_a = + path_from_path_data("M0,340C161.737914,383.575765 107.564182,490.730587 273,476 C419,463 481.741198,514.692273 481.333333,768 C481.333333,768 -0,768 -0,768 C-0,768 0,340 0,340 Z").unwrap(); let path_b = path_from_path_data( - "M458.370270,572.165771C428.525848,486.720093 368.618805,467.485992 273,476 C107.564178,490.730591 161.737915,383.575775 0,340 C0,340 0,689 0,689 C56,700 106.513901,779.342590 188,694.666687 C306.607422,571.416260 372.033966,552.205139 458.370270,572.165771 Z", - ); + "M458.370270,572.165771C428.525848,486.720093 368.618805,467.485992 273,476 C107.564178,490.730591 161.737915,383.575775 0,340 C0,340 0,689 0,689 C56,700 106.513901,779.342590 188,694.666687 C306.607422,571.416260 372.033966,552.205139 458.370270,572.165771 Z", + ).unwrap(); c.bench_function("painted_dreams_diff", |b| { b.iter(|| path_boolean(black_box(&path_a), FillRule::NonZero, black_box(&path_b), FillRule::NonZero, PathBooleanOperation::Difference)) }); diff --git a/libraries/path-bool/benches/path_segment_intersection.rs b/libraries/path-bool/benches/path_segment_intersection.rs index 33fc9aece..27519cf8e 100644 --- a/libraries/path-bool/benches/path_segment_intersection.rs +++ b/libraries/path-bool/benches/path_segment_intersection.rs @@ -15,15 +15,15 @@ fn a() -> PathSegment { DVec2::new(458.37027, 572.165771), DVec2::new(428.525848, 486.720093), DVec2::new(368.618805, 467.485992), - DVec2::new(273.0, 476.0), + DVec2::new(273., 476.), ) } fn b() -> PathSegment { - PathSegment::Cubic(DVec2::new(273.0, 476.0), DVec2::new(419.0, 463.0), DVec2::new(481.741198, 514.692273), DVec2::new(481.333333, 768.0)) + PathSegment::Cubic(DVec2::new(273., 476.), DVec2::new(419., 463.), DVec2::new(481.741198, 514.692273), DVec2::new(481.333333, 768.)) } fn c() -> PathSegment { - PathSegment::Cubic(DVec2::new(273.0, 476.0), DVec2::new(107.564178, 490.730591), DVec2::new(161.737915, 383.575775), DVec2::new(0.0, 340.0)) + PathSegment::Cubic(DVec2::new(273., 476.), DVec2::new(107.564178, 490.730591), DVec2::new(161.737915, 383.575775), DVec2::new(0., 340.)) } fn d() -> PathSegment { - PathSegment::Cubic(DVec2::new(0.0, 340.0), DVec2::new(161.737914, 383.575765), DVec2::new(107.564182, 490.730587), DVec2::new(273.0, 476.0)) + PathSegment::Cubic(DVec2::new(0., 340.), DVec2::new(161.737914, 383.575765), DVec2::new(107.564182, 490.730587), DVec2::new(273., 476.)) } diff --git a/libraries/path-bool/flake.nix b/libraries/path-bool/flake.nix index 88be72b76..a9056e3ec 100644 --- a/libraries/path-bool/flake.nix +++ b/libraries/path-bool/flake.nix @@ -23,7 +23,7 @@ }; buildInputs = with pkgs; [ llvm - ]; + ]; in { devShells.default = pkgs.mkShell { stdenv = pkgs.clangStdenv; @@ -38,8 +38,8 @@ toolchain llvm cargo - ]; - inherit buildInputs; + ]; + inherit buildInputs; LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs; }; diff --git a/libraries/path-bool/src/lib.rs b/libraries/path-bool/src/lib.rs index 6dd027199..0703a1f03 100644 --- a/libraries/path-bool/src/lib.rs +++ b/libraries/path-bool/src/lib.rs @@ -1,12 +1,11 @@ #![expect(clippy::needless_doctest_main)] #![doc = include_str!("../README.md")] mod path_boolean; -#[cfg(feature = "parsing")] +// #[cfg(feature = "parsing")] mod parsing { pub(crate) mod path_command; pub(crate) mod path_data; } - mod util { pub(crate) mod aabb; pub(crate) mod epsilons; @@ -30,16 +29,14 @@ pub use path_segment::PathSegment; #[cfg(test)] mod test { - use crate::{ - path_boolean::{self, FillRule, PathBooleanOperation}, - path_data::{path_from_path_data, path_to_path_data}, - }; + use crate::path_boolean::{self, FillRule, PathBooleanOperation}; + use crate::path_data::{path_from_path_data, path_to_path_data}; use path_boolean::path_boolean; #[test] fn square() { - let a = path_from_path_data("M 10 10 L 50 10 L 30 40 Z"); - let b = path_from_path_data("M 20 30 L 60 30 L 60 50 L 20 50 Z"); + let a = path_from_path_data("M 10 10 L 50 10 L 30 40 Z").unwrap(); + let b = path_from_path_data("M 20 30 L 60 30 L 60 50 L 20 50 Z").unwrap(); let union = path_boolean( &a, path_boolean::FillRule::NonZero, @@ -50,23 +47,23 @@ mod test { .unwrap(); dbg!(path_to_path_data(&union[0], 0.001)); assert!(!union[0].is_empty()); - // panic!(); } #[test] fn nesting_01() { - let a = path_from_path_data("M 47,24 A 23,23 0 0 1 24,47 23,23 0 0 1 1,24 23,23 0 0 1 24,1 23,23 0 0 1 47,24 Z"); + let a = path_from_path_data("M 47,24 A 23,23 0 0 1 24,47 23,23 0 0 1 1,24 23,23 0 0 1 24,1 23,23 0 0 1 47,24 Z").unwrap(); let b = path_from_path_data( "M 37.909023,24 A 13.909023,13.909023 0 0 1 24,37.909023 13.909023,13.909023 0 0 1 10.090978,24 13.909023,13.909023 0 0 1 24,10.090978 13.909023,13.909023 0 0 1 37.909023,24 Z", - ); + ) + .unwrap(); let union = path_boolean(&a, path_boolean::FillRule::NonZero, &b, path_boolean::FillRule::NonZero, path_boolean::PathBooleanOperation::Union).unwrap(); dbg!(path_to_path_data(&union[0], 0.001)); assert!(!union[0].is_empty()); } #[test] fn nesting_02() { - let a = path_from_path_data("M 0.99999994,31.334457 C 122.61195,71.81859 -79.025816,-5.5803326 47,32.253367 V 46.999996 H 0.99999994 Z"); - let b = path_from_path_data("m 25.797222,29.08718 c 0,1.292706 -1.047946,2.340652 -2.340652,2.340652 -1.292707,0 -2.340652,-1.047946 -2.340652,-2.340652 0,-1.292707 1.047945,-2.340652 2.340652,-2.340652 1.292706,0 2.340652,1.047945 2.340652,2.340652 z M 7.5851073,28.332212 c 1e-7,1.292706 -1.0479456,2.340652 -2.3406521,2.340652 -1.2927063,-1e-6 -2.3406518,-1.047946 -2.3406517,-2.340652 -10e-8,-1.292707 1.0479454,-2.340652 2.3406517,-2.340652 1.2927065,-1e-6 2.3406522,1.047945 2.3406521,2.340652 z"); + let a = path_from_path_data("M 0.99999994,31.334457 C 122.61195,71.81859 -79.025816,-5.5803326 47,32.253367 V 46.999996 H 0.99999994 Z").unwrap(); + let b = path_from_path_data("m 25.797222,29.08718 c 0,1.292706 -1.047946,2.340652 -2.340652,2.340652 -1.292707,0 -2.340652,-1.047946 -2.340652,-2.340652 0,-1.292707 1.047945,-2.340652 2.340652,-2.340652 1.292706,0 2.340652,1.047945 2.340652,2.340652 z M 7.5851073,28.332212 c 1e-7,1.292706 -1.0479456,2.340652 -2.3406521,2.340652 -1.2927063,-1e-6 -2.3406518,-1.047946 -2.3406517,-2.340652 -10e-8,-1.292707 1.0479454,-2.340652 2.3406517,-2.340652 1.2927065,-1e-6 2.3406522,1.047945 2.3406521,2.340652 z").unwrap(); let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Union).unwrap(); @@ -77,8 +74,8 @@ mod test { } #[test] fn nesting_03() { - let a = path_from_path_data("m 21.829117,3.5444345 h 4.341766 V 16.502158 H 21.829117 Z M 47,24 A 23,23 0 0 1 24,47 23,23 0 0 1 1,24 23,23 0 0 1 24,1 23,23 0 0 1 47,24 Z"); - let b = path_from_path_data("M 24 6.4960938 A 17.504802 17.504802 0 0 0 6.4960938 24 A 17.504802 17.504802 0 0 0 24 41.503906 A 17.504802 17.504802 0 0 0 41.503906 24 A 17.504802 17.504802 0 0 0 24 6.4960938 z M 24 12.193359 A 11.805881 11.805881 0 0 1 35.806641 24 A 11.805881 11.805881 0 0 1 24 35.806641 A 11.805881 11.805881 0 0 1 12.193359 24 A 11.805881 11.805881 0 0 1 24 12.193359 z "); + let a = path_from_path_data("m 21.829117,3.5444345 h 4.341766 V 16.502158 H 21.829117 Z M 47,24 A 23,23 0 0 1 24,47 23,23 0 0 1 1,24 23,23 0 0 1 24,1 23,23 0 0 1 47,24 Z").unwrap(); + let b = path_from_path_data("M 24 6.4960938 A 17.504802 17.504802 0 0 0 6.4960938 24 A 17.504802 17.504802 0 0 0 24 41.503906 A 17.504802 17.504802 0 0 0 41.503906 24 A 17.504802 17.504802 0 0 0 24 6.4960938 z M 24 12.193359 A 11.805881 11.805881 0 0 1 35.806641 24 A 11.805881 11.805881 0 0 1 24 35.806641 A 11.805881 11.805881 0 0 1 12.193359 24 A 11.805881 11.805881 0 0 1 24 12.193359 z ").unwrap(); let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Union).unwrap(); @@ -92,8 +89,8 @@ mod test { #[test] fn simple_07() { let a = path_from_path_data("M 37.671452,24 C 52.46888,31.142429 42.887716,37.358779 24,37.671452 16.4505,37.796429 10.328548,31.550534 10.328548,24 c 0,-7.550534 6.120918,-13.671452 13.671452,-13.671452 7.550534,0 6.871598,10.389295 13.671452,13.671452 z", - ); - let b = path_from_path_data("M 37.671452,24 C 33.698699,53.634887 29.50935,49.018306 24,37.671452 20.7021,30.879219 10.328548,31.550534 10.328548,24 c 0,-7.550534 6.120918,-13.671452 13.671452,-13.671452 7.550534,0 14.674677,6.187863 13.671452,13.671452 z"); + ).unwrap(); + let b = path_from_path_data("M 37.671452,24 C 33.698699,53.634887 29.50935,49.018306 24,37.671452 20.7021,30.879219 10.328548,31.550534 10.328548,24 c 0,-7.550534 6.120918,-13.671452 13.671452,-13.671452 7.550534,0 14.674677,6.187863 13.671452,13.671452 z").unwrap(); let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Union).unwrap(); @@ -105,8 +102,8 @@ mod test { } #[test] fn rect_ellipse() { - let a = path_from_path_data("M0,0C0,0 100,0 100,0 C100,0 100,100 100,100 C100,100 0,100 0,100 C0,100 0,0 0,0 Z"); - let b = path_from_path_data("M50,0C77.589239,0 100,22.410761 100,50 C100,77.589239 77.589239,100 50,100 C22.410761,100 0,77.589239 0,50 C0,22.410761 22.410761,0 50,0 Z"); + let a = path_from_path_data("M0,0C0,0 100,0 100,0 C100,0 100,100 100,100 C100,100 0,100 0,100 C0,100 0,0 0,0 Z").unwrap(); + let b = path_from_path_data("M50,0C77.589239,0 100,22.410761 100,50 C100,77.589239 77.589239,100 50,100 C22.410761,100 0,77.589239 0,50 C0,22.410761 22.410761,0 50,0 Z").unwrap(); let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Union).unwrap(); @@ -118,10 +115,10 @@ mod test { } #[test] fn red_dress_loop() { - let a = path_from_path_data("M969.000000,0.000000C969.000000,0.000000 1110.066898,76.934393 1085.000000,181.000000 C1052.000000,318.000000 1199.180581,334.301571 1277.000000,319.000000 C1455.000000,284.000000 1586.999985,81.000000 1418.000000,0.000000 C1418.000000,0.000000 969.000000,0.000000 969.000000,0.000000"); + let a = path_from_path_data("M969.000000,0.000000C969.000000,0.000000 1110.066898,76.934393 1085.000000,181.000000 C1052.000000,318.000000 1199.180581,334.301571 1277.000000,319.000000 C1455.000000,284.000000 1586.999985,81.000000 1418.000000,0.000000 C1418.000000,0.000000 969.000000,0.000000 969.000000,0.000000").unwrap(); let b = path_from_path_data( "M1211.000000,0.000000C1211.000000,0.000000 1255.000000,78.000000 1536.000000,95.000000 C1536.000000,95.000000 1536.000000,0.000000 1536.000000,0.000000 C1536.000000,0.000000 1211.000000,0.000000 1211.000000,0.000000 Z", - ); + ).unwrap(); let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Intersection).unwrap(); @@ -133,10 +130,10 @@ mod test { } #[test] fn painted_dreams_1() { - let a = path_from_path_data("M969.000000,0.000000C969.000000,0.000000 1110.066898,76.934393 1085.000000,181.000000 C1052.000000,318.000000 1199.180581,334.301571 1277.000000,319.000000 C1455.000000,284.000000 1586.999985,81.000000 1418.000000,0.000000 C1418.000000,0.000000 969.000000,0.000000 969.000000,0.000000 Z"); + let a = path_from_path_data("M969.000000,0.000000C969.000000,0.000000 1110.066898,76.934393 1085.000000,181.000000 C1052.000000,318.000000 1199.180581,334.301571 1277.000000,319.000000 C1455.000000,284.000000 1586.999985,81.000000 1418.000000,0.000000 C1418.000000,0.000000 969.000000,0.000000 969.000000,0.000000 Z").unwrap(); let b = path_from_path_data( "M763.000000,0.000000C763.000000,0.000000 1536.000000,0.000000 1536.000000,0.000000 C1536.000000,0.000000 1536.000000,254.000000 1536.000000,254.000000 C1536.000000,254.000000 1462.000000,93.000000 1271.000000,199.000000 C1149.163056,266.616314 976.413656,188.510842 908.000000,134.000000 C839.586344,79.489158 763.000000,0.000000 763.000000,0.000000 Z", - ); + ).unwrap(); let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Intersection).unwrap(); @@ -148,10 +145,11 @@ mod test { } #[test] fn painted_dreams_2() { - let a = path_from_path_data("M0,340C161.737914,383.575765 107.564182,490.730587 273,476 C419,463 481.741198,514.692273 481.333333,768 C481.333333,768 -0,768 -0,768 C-0,768 0,340 0,340 Z "); + let a = path_from_path_data("M0,340C161.737914,383.575765 107.564182,490.730587 273,476 C419,463 481.741198,514.692273 481.333333,768 C481.333333,768 -0,768 -0,768 C-0,768 0,340 0,340 Z ") + .unwrap(); let b = path_from_path_data( "M458.370270,572.165771C428.525848,486.720093 368.618805,467.485992 273,476 C107.564178,490.730591 161.737915,383.575775 0,340 C0,340 0,689 0,689 C56,700 106.513901,779.342590 188,694.666687 C306.607422,571.416260 372.033966,552.205139 458.370270,572.165771 Z", - ); + ).unwrap(); let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Union).unwrap(); @@ -163,10 +161,10 @@ mod test { } #[test] fn painted_dreams_3() { - let a = path_from_path_data("M889,0C889,0 889,21 898,46 C909.595887,78.210796 872.365858,104.085306 869,147 C865,198 915,237 933,273 C951,309 951.703704,335.407407 923,349 C898.996281,360.366922 881,367 902,394 C923,421 928.592593,431.407407 898,468 C912.888889,472.888889 929.333333,513.333333 896,523 C896,523 876,533.333333 886,572 C896.458810,612.440732 873.333333,657.777778 802.666667,656.444444 C738.670245,655.236965 689,643 655,636 C621,629 604,623 585,666 C566,709 564,768 564,768 C564,768 0,768 0,768 C0,768 0,0 0,0 C0,0 889,0 889,0 Z "); + let a = path_from_path_data("M889,0C889,0 889,21 898,46 C909.595887,78.210796 872.365858,104.085306 869,147 C865,198 915,237 933,273 C951,309 951.703704,335.407407 923,349 C898.996281,360.366922 881,367 902,394 C923,421 928.592593,431.407407 898,468 C912.888889,472.888889 929.333333,513.333333 896,523 C896,523 876,533.333333 886,572 C896.458810,612.440732 873.333333,657.777778 802.666667,656.444444 C738.670245,655.236965 689,643 655,636 C621,629 604,623 585,666 C566,709 564,768 564,768 C564,768 0,768 0,768 C0,768 0,0 0,0 C0,0 889,0 889,0 Z ").unwrap(); let b = path_from_path_data( "M552,768C552,768 993,768 993,768 C993,768 1068.918039,682.462471 1093,600 C1126,487 1007.352460,357.386071 957,324 C906.647540,290.613929 842,253 740,298 C638,343 491.342038,421.999263 491.342038,506.753005 C491.342038,641.999411 552,768 552,768 Z ", - ); + ).unwrap(); let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Difference).unwrap(); @@ -178,10 +176,10 @@ mod test { } #[test] fn painted_dreams_4() { - let a = path_from_path_data("M458.370270,572.165771C372.033966,552.205139 306.607422,571.416260 188.000000,694.666687 C106.513901,779.342590 56.000000,700.000000 0.000000,689.000000 C0.000000,689.000000 0.000000,768.000000 0.000000,768.000000 C0.000000,768.000000 481.333344,768.000000 481.333344,768.000000 C481.474091,680.589417 474.095154,617.186768 458.370270,572.165771 Z "); + let a = path_from_path_data("M458.370270,572.165771C372.033966,552.205139 306.607422,571.416260 188.000000,694.666687 C106.513901,779.342590 56.000000,700.000000 0.000000,689.000000 C0.000000,689.000000 0.000000,768.000000 0.000000,768.000000 C0.000000,768.000000 481.333344,768.000000 481.333344,768.000000 C481.474091,680.589417 474.095154,617.186768 458.370270,572.165771 Z ").unwrap(); let b = path_from_path_data( "M364.000000,768.000000C272.000000,686.000000 294.333333,468.666667 173.333333,506.666667 C110.156241,526.507407 0.000000,608.000000 0.000000,608.000000 L -0.000000,768.000000 L 364.000000,768.000000 Z", - ); + ).unwrap(); let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Difference).unwrap(); @@ -194,10 +192,10 @@ mod test { #[test] fn painted_dreams_5() { let a = path_from_path_data("M889.000000,0.000000C889.000000,0.000000 889.000000,21.000000 898.000000,46.000000 C909.595887,78.210796 872.365858,104.085306 869.000000,147.000000 C865.000000,198.000000 915.000000,237.000000 933.000000,273.000000 C951.000000,309.000000 951.703704,335.407407 923.000000,349.000000 C898.996281,360.366922 881.000000,367.000000 902.000000,394.000000 C923.000000,421.000000 928.592593,431.407407 898.000000,468.000000 C912.888889,472.888889 929.333333,513.333333 896.000000,523.000000 C896.000000,523.000000 876.000000,533.333333 886.000000,572.000000 C896.458810,612.440732 873.333333,657.777778 802.666667,656.444444 C738.670245,655.236965 689.000000,643.000000 655.000000,636.000000 C621.000000,629.000000 604.000000,623.000000 585.000000,666.000000 C566.000000,709.000000 564.000000,768.000000 564.000000,768.000000 C564.000000,768.000000 0.000000,768.000000 0.000000,768.000000 C0.000000,768.000000 0.000000,0.000000 0.000000,0.000000 C0.000000,0.000000 889.000000,0.000000 889.000000,0.000000 Z" - ); + ).unwrap(); let b = path_from_path_data( "M891.555556,569.382716C891.555556,569.382716 883.555556,577.777778 879.111111,595.851852 C874.666667,613.925926 857.185185,631.407407 830.814815,633.777778 C804.444444,636.148148 765.629630,637.925926 708.148148,616.296296 C650.666667,594.666667 560.666667,568.000000 468.000000,487.333333 C375.333333,406.666667 283.333333,354.666667 283.333333,354.666667 C332.000000,330.666667 373.407788,298.323579 468.479950,219.785706 C495.739209,197.267187 505.084065,165.580817 514.452332,146.721008 C525.711584,124.054345 577.519713,94.951389 589.958848,64.658436 C601.152263,37.399177 601.175694,0.000010 601.175694,0.000000 C601.175694,0.000000 0.000000,0.000000 0.000000,0.000000 C0.000000,0.000000 0.000000,768.000000 0.000000,768.000000 C0.000000,768.000000 891.555556,768.000000 891.555556,768.000000 C891.555556,768.000000 891.555556,569.382716 891.555556,569.382716 Z", - ); + ).unwrap(); let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Intersection).unwrap(); @@ -211,10 +209,10 @@ mod test { fn painted_dreams_6() { let a = path_from_path_data( "M 969.000000000000,0.000000000000 C 969.000000000000,0.000000000000 1110.066900000000,76.934400000000 1085.000000000000,181.000000000000 C 1052.000000000000,318.000000000000 1199.180600000000,334.301600000000 1277.000000000000,319.000000000000 C 1455.000000000000,284.000000000000 1587.000000000000,81.000000000000 1418.000000000000,0.000000000000 C 1418.000000000000,0.000000000000 969.000000000000,0.000000000000 969.000000000000,0.000000000000 L 969.000000000000,0.000000000000" - ); + ).unwrap(); let b = path_from_path_data( "M 763.000000000000,0.000000000000 C 763.000000000000,0.000000000000 1536.000000000000,0.000000000000 1536.000000000000,0.000000000000 C 1536.000000000000,0.000000000000 1536.000000000000,254.000000000000 1536.000000000000,254.000000000000 C 1536.000000000000,254.000000000000 1462.000000000000,93.000000000000 1271.000000000000,199.000000000000 C 1149.163100000000,266.616300000000 976.413700000000,188.510800000000 908.000000000000,134.000000000000 C 839.586300000000,79.489200000000 763.000000000000,0.000000000000 763.000000000000,0.000000000000 L 763.000000000000,0.000000000000", - ); + ).unwrap(); let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Intersection).unwrap(); @@ -228,10 +226,10 @@ mod test { fn painted_dreams_7() { let a = path_from_path_data( "M 989.666700000000,768.000000000000 C 989.666700000000,768.000000000000 1011.111100000000,786.399400000000 1011.111100000000,786.399400000000 C 1011.111100000000,786.399400000000 1299.306500000000,786.399400000000 1299.306500000000,786.399400000000 C 1299.306500000000,786.399400000000 1318.000000000000,768.000000000000 1318.000000000000,768.000000000000 C 1293.666700000000,681.000000000000 1173.363200000000,625.103600000000 1094.162400000000,594.296600000000 C 1094.162400000000,594.296600000000 1058.747200000000,687.805800000000 989.666700000000,768.000000000000" - ); + ).unwrap(); let b = path_from_path_data( "M 983.155000000000,775.589300000000 L 1004.599400000000,793.988700000000 L 1007.409000000000,796.399400000000 L 1011.111100000000,796.399400000000 L 1299.306500000000,796.399400000000 L 1303.402200000000,796.399400000000 L 1306.321200000000,793.526300000000 L 1325.014800000000,775.126900000000 L 1329.236900000000,770.971200000000 L 1327.630400000000,765.306400000000 C 1302.280700000000,675.920800000000 1179.503900000000,617.211200000000 1097.787500000000,584.976800000000 L 1088.418100000000,581.280900000000 L 1084.806400000000,590.765700000000 C 1084.117400000000,592.575300000000 1049.449700000000,683.516200000000 982.090100000000,761.473400000000 L 975.539200000000,769.055000000000 L 983.155000000000,775.589300000000 M 1003.696800000000,766.861600000000 C 1068.901100000000,687.878900000000 1102.806400000000,599.696700000000 1103.497000000000,597.883400000000 L 1090.537200000000,603.616300000000 C 1165.521500000000,632.344400000000 1279.846400000000,683.736400000000 1306.585700000000,765.203400000000 L 1295.210700000000,776.399400000000 L 1014.813100000000,776.399400000000 L 1003.696800000000,766.861600000000", - ); + ).unwrap(); let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Difference).unwrap(); @@ -247,8 +245,26 @@ mod test { "m658.03348 118.4966c7.85928 4.83645 114.84582 7.8304 127.89652 6.52531 20.97932-2.09799 43.06722-24.79623 43.06722-24.79623 0 0-96.43723-26.02101-108.97311-28.54836-20.22849-4.07832-78.95651 36.37872-61.99063 46.81928z m658.03348 115.88649c40.45718-30.01653 82.213-45.24662 103.10032-31.32163 7.83037 5.2203-3.58567 22.51547 13.05064 39.152 3.91519 3.9152-129.49099 2.06705-116.15096-7.83037z m680.87214 56.0165c2.20775-9.60391 62.6449-29.65403 101.79518-30.01652 17.61846-0.16312 119.39605 40.30737 130.50668 54.8128 5.8045 7.57806-76.88558 29.08762-91.35464 31.32162-15.28899 2.36056-144.20983-41.92525-140.94722-56.1179z" - ); - let b = path_from_path_data(""); + ).unwrap(); + let b = path_from_path_data("").unwrap(); + + let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Union).unwrap(); + + // Add assertions here based on expected results + assert_eq!(result.len(), 1, "Expected 1 resulting path for Union operation"); + dbg!(path_to_path_data(&result[0], 0.001)); + // Add more specific assertions about the resulting path if needed + assert!(!result[0].is_empty()); + } + #[test] + fn shared_line() { + let a = path_from_path_data( + "m 658.03348,118.4966 c 7.85928,4.83645 114.84582,7.8304 127.89652,6.52531 20.97932,-2.09799 43.06722,-24.79623 43.06722,-24.79623 0,0 -96.43723,-26.02101 -108.97311,-28.54836 -20.22849,-4.07832 -78.95651,36.37872 -61.99063,46.81928 Z" + ).unwrap(); + let b = path_from_path_data( + "m 658.03348,115.88649 c 40.45718,-30.01653 82.213,-45.24662 103.10032,-31.32163 7.83037,5.2203 -3.58567,22.51547 13.05064,39.152 3.91519,3.9152 -129.49099,2.06705 -116.15096,-7.83037 z", + ) + .unwrap(); let result = path_boolean(&a, FillRule::NonZero, &b, FillRule::NonZero, PathBooleanOperation::Union).unwrap(); diff --git a/libraries/path-bool/src/parsing/path_data.rs b/libraries/path-bool/src/parsing/path_data.rs index aa0b66f20..afc2f5e4a 100644 --- a/libraries/path-bool/src/parsing/path_data.rs +++ b/libraries/path-bool/src/parsing/path_data.rs @@ -1,9 +1,10 @@ use crate::path::{path_from_commands, path_to_commands, Path}; use crate::path_command::{AbsolutePathCommand, PathCommand, RelativePathCommand}; +use crate::BooleanError; use glam::DVec2; use regex::Regex; -pub fn commands_from_path_data(d: &str) -> Vec { +pub fn commands_from_path_data(d: &str) -> Result, BooleanError> { let re_float = Regex::new(r"^\s*,?\s*(-?\d*(?:\d\.|\.\d|\d)\d*(?:[eE][+\-]?\d+)?)").unwrap(); let re_cmd = Regex::new(r"^\s*([MLCSQTAZHVmlhvcsqtaz])").unwrap(); let re_bool = Regex::new(r"^\s*,?\s*([01])").unwrap(); @@ -24,6 +25,7 @@ pub fn commands_from_path_data(d: &str) -> Vec { match last_cmd { 'M' => Some('L'), 'm' => Some('l'), + 'z' | 'Z' => None, _ => Some(last_cmd), } } @@ -111,15 +113,15 @@ pub fn commands_from_path_data(d: &str) -> Vec { get_float(&mut i), get_float(&mut i), ))), - _ => panic!("Invalid command: {}", cmd), + _ => return Err(BooleanError::InvalidPathCommand(cmd)), } } - commands + Ok(commands) } -pub fn path_from_path_data(d: &str) -> Path { - path_from_commands(commands_from_path_data(d)).collect() +pub fn path_from_path_data(d: &str) -> Result { + Ok(path_from_commands(commands_from_path_data(d)?).collect()) } pub fn path_to_path_data(path: &Path, eps: f64) -> String { diff --git a/libraries/path-bool/src/path.rs b/libraries/path-bool/src/path.rs index 7c71bb82c..0654506df 100644 --- a/libraries/path-bool/src/path.rs +++ b/libraries/path-bool/src/path.rs @@ -13,9 +13,10 @@ use crate::path_segment::PathSegment; pub type Path = Vec; fn reflect_control_point(point: DVec2, control_point: DVec2) -> DVec2 { - point * 2.0 - control_point + point * 2. - control_point } +#[cfg(feature = "parsing")] pub fn path_from_commands(commands: I) -> impl Iterator where I: IntoIterator, @@ -93,6 +94,7 @@ where }) } +#[cfg(feature = "parsing")] pub fn path_to_commands<'a, I>(segments: I, eps: f64) -> impl Iterator + 'a where I: IntoIterator + 'a, diff --git a/libraries/path-bool/src/path/intersection_path_segment.rs b/libraries/path-bool/src/path/intersection_path_segment.rs index b5a6deaeb..4a4b53bf7 100644 --- a/libraries/path-bool/src/path/intersection_path_segment.rs +++ b/libraries/path-bool/src/path/intersection_path_segment.rs @@ -1,5 +1,3 @@ -use glam::DVec2; - use crate::aabb::{bounding_box_max_extent, bounding_boxes_overlap, Aabb}; use crate::epsilons::Epsilons; use crate::line_segment::{line_segment_intersection, line_segments_intersect}; @@ -7,6 +5,8 @@ use crate::line_segment_aabb::line_segment_aabb_intersect; use crate::math::lerp; use crate::path_segment::PathSegment; +use glam::DVec2; + #[derive(Clone)] struct IntersectionSegment { seg: PathSegment, @@ -18,7 +18,7 @@ struct IntersectionSegment { #[inline(never)] fn subdivide_intersection_segment(int_seg: &IntersectionSegment) -> [IntersectionSegment; 2] { let (seg0, seg1) = int_seg.seg.split_at(0.5); - let mid_param = (int_seg.start_param + int_seg.end_param) / 2.0; + let mid_param = (int_seg.start_param + int_seg.end_param) / 2.; [ IntersectionSegment { seg: seg0, @@ -88,10 +88,9 @@ pub fn segments_equal(seg0: &PathSegment, seg1: &PathSegment, point_epsilon: f64 } pub fn path_segment_intersection(seg0: &PathSegment, seg1: &PathSegment, endpoints: bool, eps: &Epsilons) -> Vec<[f64; 2]> { - // dbg!(&seg0, &seg1, endpoints); if let (PathSegment::Line(start0, end0), PathSegment::Line(start1, end1)) = (seg0, seg1) { if let Some(st) = line_segment_intersection([*start0, *end0], [*start1, *end1], eps.param) { - if !endpoints && (st.0 < eps.param || st.0 > 1.0 - eps.param) && (st.1 < eps.param || st.1 > 1.0 - eps.param) { + if !endpoints && (st.0 < eps.param || st.0 > 1. - eps.param) && (st.1 < eps.param || st.1 > 1. - eps.param) { return vec![]; } return vec![st.into()]; @@ -103,14 +102,14 @@ pub fn path_segment_intersection(seg0: &PathSegment, seg1: &PathSegment, endpoin let mut pairs = vec![( IntersectionSegment { seg: *seg0, - start_param: 0.0, - end_param: 1.0, + start_param: 0., + end_param: 1., bounding_box: seg0.bounding_box(), }, IntersectionSegment { seg: *seg1, - start_param: 0.0, - end_param: 1.0, + start_param: 0., + end_param: 1., bounding_box: seg1.bounding_box(), }, )]; @@ -120,13 +119,12 @@ pub fn path_segment_intersection(seg0: &PathSegment, seg1: &PathSegment, endpoin let mut subdivided0 = Vec::new(); let mut subdivided1 = Vec::new(); - // check if start and end points are on the other bezier curves. If so, add as intersection. + // Check if start and end points are on the other bezier curves. If so, add an intersection. while !pairs.is_empty() { next_pairs.clear(); if pairs.len() > 1000 { - // TODO: check for intersections of the start/end points. If the two lines overlap, return split points for the start/end points. Use a binary search to check where the points are on the line. return calculate_overlap_intersections(seg0, seg1, eps); } @@ -143,7 +141,6 @@ pub fn path_segment_intersection(seg0: &PathSegment, seg1: &PathSegment, endpoin let line_segment0 = path_segment_to_line_segment(&seg0.seg); let line_segment1 = path_segment_to_line_segment(&seg1.seg); if let Some(st) = line_segment_intersection(line_segment0, line_segment1, eps.param) { - // dbg!("pushing param"); params.push([lerp(seg0.start_param, seg0.end_param, st.0), lerp(seg1.start_param, seg1.end_param, st.1)]); } } else { @@ -174,7 +171,7 @@ pub fn path_segment_intersection(seg0: &PathSegment, seg1: &PathSegment, endpoin } if !endpoints { - params.retain(|[s, t]| (s > &eps.param && s < &(1.0 - eps.param)) || (t > &eps.param && t < &(1.0 - eps.param))); + params.retain(|[s, t]| (s > &eps.param && s < &(1. - eps.param)) || (t > &eps.param && t < &(1. - eps.param))); } params @@ -190,22 +187,22 @@ fn calculate_overlap_intersections(seg0: &PathSegment, seg1: &PathSegment, eps: // Check start0 against seg1 if let Some(t1) = find_point_on_segment(seg1, start0, eps) { - intersections.push([0.0, t1]); + intersections.push([0., t1]); } // Check end0 against seg1 if let Some(t1) = find_point_on_segment(seg1, end0, eps) { - intersections.push([1.0, t1]); + intersections.push([1., t1]); } // Check start1 against seg0 if let Some(t0) = find_point_on_segment(seg0, start1, eps) { - intersections.push([t0, 0.0]); + intersections.push([t0, 0.]); } // Check end1 against seg0 if let Some(t0) = find_point_on_segment(seg0, end1, eps) { - intersections.push([t0, 1.0]); + intersections.push([t0, 1.]); } // Remove duplicates and sort intersections @@ -216,7 +213,7 @@ fn calculate_overlap_intersections(seg0: &PathSegment, seg1: &PathSegment, eps: if intersections.is_empty() { // Check if segments are identical if (start0.abs_diff_eq(start1, eps.point)) && end0.abs_diff_eq(end1, eps.point) { - return vec![[0.0, 0.0], [1.0, 1.0]]; + return vec![[0., 0.], [1., 1.]]; } } else if intersections.len() > 2 { // Keep only the first and last intersection points @@ -227,8 +224,8 @@ fn calculate_overlap_intersections(seg0: &PathSegment, seg1: &PathSegment, eps: } fn find_point_on_segment(seg: &PathSegment, point: DVec2, eps: &Epsilons) -> Option { - let start = 0.0; - let end = 1.0; + let start = 0.; + let end = 1.; let mut t = 0.5; for _ in 0..32 { @@ -251,9 +248,9 @@ fn find_point_on_segment(seg: &PathSegment, point: DVec2, eps: &Epsilons) -> Opt } if dist_start < dist_end { - t = (start + t) / 2.0; + t = (start + t) / 2.; } else { - t = (t + end) / 2.0; + t = (t + end) / 2.; } if (end - start) < eps.param { @@ -283,16 +280,16 @@ mod test { DVec2::new(458.37027, 572.165771), DVec2::new(428.525848, 486.720093), DVec2::new(368.618805, 467.485992), - DVec2::new(273.0, 476.0), + DVec2::new(273., 476.), ) } fn b() -> PathSegment { - PathSegment::Cubic(DVec2::new(273.0, 476.0), DVec2::new(419.0, 463.0), DVec2::new(481.741198, 514.692273), DVec2::new(481.333333, 768.0)) + PathSegment::Cubic(DVec2::new(273., 476.), DVec2::new(419., 463.), DVec2::new(481.741198, 514.692273), DVec2::new(481.333333, 768.)) } fn c() -> PathSegment { - PathSegment::Cubic(DVec2::new(273.0, 476.0), DVec2::new(107.564178, 490.730591), DVec2::new(161.737915, 383.575775), DVec2::new(0.0, 340.0)) + PathSegment::Cubic(DVec2::new(273., 476.), DVec2::new(107.564178, 490.730591), DVec2::new(161.737915, 383.575775), DVec2::new(0., 340.)) } fn d() -> PathSegment { - PathSegment::Cubic(DVec2::new(0.0, 340.0), DVec2::new(161.737914, 383.575765), DVec2::new(107.564182, 490.730587), DVec2::new(273.0, 476.0)) + PathSegment::Cubic(DVec2::new(0., 340.), DVec2::new(161.737914, 383.575765), DVec2::new(107.564182, 490.730587), DVec2::new(273., 476.)) } } diff --git a/libraries/path-bool/src/path/line_segment.rs b/libraries/path-bool/src/path/line_segment.rs index 71e0a28c4..ecabd1ebf 100644 --- a/libraries/path-bool/src/path/line_segment.rs +++ b/libraries/path-bool/src/path/line_segment.rs @@ -2,7 +2,7 @@ use glam::DVec2; pub type LineSegment = [DVec2; 2]; -const COLLINEAR_EPS: f64 = f64::EPSILON * 64.0; +const COLLINEAR_EPS: f64 = f64::EPSILON * 64.; #[inline(never)] pub fn line_segment_intersection([p1, p2]: LineSegment, [p3, p4]: LineSegment, eps: f64) -> Option<(f64, f64)> { @@ -21,7 +21,7 @@ pub fn line_segment_intersection([p1, p2]: LineSegment, [p3, p4]: LineSegment, e let s = (c.x * b.y - c.y * b.x) / denom; let t = (a.x * c.y - a.y * c.x) / denom; - if (-eps..=1.0 + eps).contains(&s) && (-eps..=1.0 + eps).contains(&t) { + if (-eps..=1. + eps).contains(&s) && (-eps..=1. + eps).contains(&t) { Some((s, t)) } else { None diff --git a/libraries/path-bool/src/path/line_segment_aabb.rs b/libraries/path-bool/src/path/line_segment_aabb.rs index 58be8316b..86b7fa157 100644 --- a/libraries/path-bool/src/path/line_segment_aabb.rs +++ b/libraries/path-bool/src/path/line_segment_aabb.rs @@ -42,8 +42,8 @@ pub(crate) fn line_segment_aabb_intersect(seg: LineSegment, bounding_box: &Aabb) } else { // failed both tests, so calculate the line segment to clip // from an outside point to an intersection with clip edge - let mut x = 0.0; - let mut y = 0.0; + let mut x = 0.; + let mut y = 0.; // At least one endpoint is outside the clip rectangle; pick it. let outcode_out = if outcode1 > outcode0 { outcode1 } else { outcode0 }; diff --git a/libraries/path-bool/src/path/path_cubic_segment_self_intersection.rs b/libraries/path-bool/src/path/path_cubic_segment_self_intersection.rs index bb766ae36..fba671f9c 100644 --- a/libraries/path-bool/src/path/path_cubic_segment_self_intersection.rs +++ b/libraries/path-bool/src/path/path_cubic_segment_self_intersection.rs @@ -6,27 +6,27 @@ pub fn path_cubic_segment_self_intersection(seg: &PathSegment) -> Option<[f64; 2 // https://math.stackexchange.com/questions/3931865/self-intersection-of-a-cubic-bezier-interpretation-of-the-solution if let PathSegment::Cubic(p1, p2, p3, p4) = seg { - let ax = -p1.x + 3.0 * p2.x - 3.0 * p3.x + p4.x; - let ay = -p1.y + 3.0 * p2.y - 3.0 * p3.y + p4.y; - let bx = 3.0 * p1.x - 6.0 * p2.x + 3.0 * p3.x; - let by = 3.0 * p1.y - 6.0 * p2.y + 3.0 * p3.y; - let cx = -3.0 * p1.x + 3.0 * p2.x; - let cy = -3.0 * p1.y + 3.0 * p2.y; + let ax = -p1.x + 3. * p2.x - 3. * p3.x + p4.x; + let ay = -p1.y + 3. * p2.y - 3. * p3.y + p4.y; + let bx = 3. * p1.x - 6. * p2.x + 3. * p3.x; + let by = 3. * p1.y - 6. * p2.y + 3. * p3.y; + let cx = -3. * p1.x + 3. * p2.x; + let cy = -3. * p1.y + 3. * p2.y; let m = ay * bx - ax * by; let n = ax * cy - ay * cx; - let k = (-3.0 * ax * ax * cy * cy + 6.0 * ax * ay * cx * cy + 4.0 * ax * bx * by * cy - 4.0 * ax * by * by * cx - 3.0 * ay * ay * cx * cx - 4.0 * ay * bx * bx * cy + 4.0 * ay * bx * by * cx) - / (ax * ax * by * by - 2.0 * ax * ay * bx * by + ay * ay * bx * bx); + let k = (-3. * ax * ax * cy * cy + 6. * ax * ay * cx * cy + 4. * ax * bx * by * cy - 4. * ax * by * by * cx - 3. * ay * ay * cx * cx - 4. * ay * bx * bx * cy + 4. * ay * bx * by * cx) + / (ax * ax * by * by - 2. * ax * ay * bx * by + ay * ay * bx * bx); - if k < 0.0 { + if k < 0. { return None; } - let t1 = (n / m + k.sqrt()) / 2.0; - let t2 = (n / m - k.sqrt()) / 2.0; + let t1 = (n / m + k.sqrt()) / 2.; + let t2 = (n / m - k.sqrt()) / 2.; - if (EPS..=1.0 - EPS).contains(&t1) && (EPS..=1.0 - EPS).contains(&t2) { + if (EPS..=1. - EPS).contains(&t1) && (EPS..=1. - EPS).contains(&t2) { let mut result = [t1, t2]; result.sort_by(|a, b| a.partial_cmp(b).unwrap()); Some(result) diff --git a/libraries/path-bool/src/path/path_segment.rs b/libraries/path-bool/src/path/path_segment.rs index 7d14a0dbe..532e1c078 100644 --- a/libraries/path-bool/src/path/path_segment.rs +++ b/libraries/path-bool/src/path/path_segment.rs @@ -34,7 +34,7 @@ use crate::EPS; /// use path_bool::PathSegment; /// use glam::DVec2; /// -/// let line = PathSegment::Line(DVec2::new(0.0, 0.0), DVec2::new(1.0, 1.0)); +/// let line = PathSegment::Line(DVec2::new(0., 0.), DVec2::new(1., 1.)); /// ``` /// /// Creating a cubic Bézier curve: @@ -43,10 +43,10 @@ use crate::EPS; /// use glam::DVec2; /// /// let cubic = PathSegment::Cubic( -/// DVec2::new(0.0, 0.0), -/// DVec2::new(1.0, 0.0), -/// DVec2::new(1.0, 1.0), -/// DVec2::new(2.0, 1.0) +/// DVec2::new(0., 0.), +/// DVec2::new(1., 0.), +/// DVec2::new(1., 1.), +/// DVec2::new(2., 1.) /// ); /// ``` #[derive(Clone, Copy, Debug, PartialEq)] @@ -95,7 +95,7 @@ impl PathSegment { /// use glam::DVec2; /// use std::f64::consts::{TAU, FRAC_PI_4}; /// - /// let line = PathSegment::Line(DVec2::new(0.0, 0.0), DVec2::new(1.0, 1.0)); + /// let line = PathSegment::Line(DVec2::new(0., 0.), DVec2::new(1., 1.)); /// assert_eq!(line.start_angle(), TAU - (FRAC_PI_4)); /// ``` pub fn start_angle(&self) -> f64 { @@ -104,7 +104,7 @@ impl PathSegment { PathSegment::Cubic(start, control1, control2, _) => { let diff = control1 - start; if diff.abs_diff_eq(DVec2::ZERO, EPS.point) { - // if this diff were empty too, the segments would have been convertet to a line + // if this diff were empty too, the segments would have been converted to a line (control2 - start).angle_to(DVec2::X) } else { diff.angle_to(DVec2::X) @@ -134,43 +134,42 @@ impl PathSegment { /// use path_bool::PathSegment; /// use glam::DVec2; /// - /// let line = PathSegment::Line(DVec2::new(0.0, 0.0), DVec2::new(1.0, 1.0)); - /// assert_eq!(line.start_curvature(), 0.0); + /// let line = PathSegment::Line(DVec2::new(0., 0.), DVec2::new(1., 1.)); + /// assert_eq!(line.start_curvature(), 0.); /// /// let curve = PathSegment::Cubic( - /// DVec2::new(0.0, 0.0), - /// DVec2::new(0.0, 1.0), - /// DVec2::new(1.0, 1.0), - /// DVec2::new(1.0, 0.0) + /// DVec2::new(0., 0.), + /// DVec2::new(0., 1.), + /// DVec2::new(1., 1.), + /// DVec2::new(1., 0.) /// ); - /// assert!(curve.start_curvature() < 0.0); + /// assert!(curve.start_curvature() < 0.); /// ``` pub fn start_curvature(&self) -> f64 { match *self { - PathSegment::Line(_, _) => 0.0, + PathSegment::Line(_, _) => 0., PathSegment::Cubic(start, control1, control2, _) => { let a = control1 - start; let a = 3. * a; - let b = start - 2.0 * control1 + control2; + let b = start - 2. * control1 + control2; let b = 6. * b; let numerator = a.x * b.y - a.y * b.x; let denominator = a.length_squared() * a.length(); - // dbg!(a, b, numerator, denominator); - if denominator == 0.0 { - 0.0 + if denominator == 0. { + 0. } else { numerator / denominator } } PathSegment::Quadratic(start, control, end) => { - // first derivatiave + // First derivative let a = 2. * (control - start); - // second derivatiave - let b = 2. * (start - 2.0 * control + end); + // Second derivative + let b = 2. * (start - 2. * control + end); let numerator = a.x * b.y - a.y * b.x; let denominator = a.length_squared() * a.length(); - if denominator == 0.0 { - 0.0 + if denominator == 0. { + 0. } else { numerator / denominator } @@ -196,10 +195,10 @@ impl PathSegment { /// use path_bool::PathSegment; /// use glam::DVec2; /// - /// let line = PathSegment::Line(DVec2::new(0.0, 0.0), DVec2::new(1.0, 1.0)); + /// let line = PathSegment::Line(DVec2::new(0., 0.), DVec2::new(1., 1.)); /// let cubic = line.to_cubic(); - /// assert_eq!(cubic[0], DVec2::new(0.0, 0.0)); - /// assert_eq!(cubic[3], DVec2::new(1.0, 1.0)); + /// assert_eq!(cubic[0], DVec2::new(0., 0.)); + /// assert_eq!(cubic[3], DVec2::new(1., 1.)); /// ``` /// /// # Panics @@ -257,10 +256,10 @@ impl PathSegment { /// use path_bool::PathSegment; /// use glam::DVec2; /// - /// let line = PathSegment::Line(DVec2::new(0.0, 0.0), DVec2::new(1.0, 1.0)); + /// let line = PathSegment::Line(DVec2::new(0., 0.), DVec2::new(1., 1.)); /// let reversed = line.reverse(); - /// assert_eq!(reversed.start(), DVec2::new(1.0, 1.0)); - /// assert_eq!(reversed.end(), DVec2::new(0.0, 0.0)); + /// assert_eq!(reversed.start(), DVec2::new(1., 1.)); + /// assert_eq!(reversed.end(), DVec2::new(0., 0.)); /// ``` pub fn reverse(&self) -> PathSegment { match *self { @@ -283,7 +282,7 @@ impl PathSegment { /// is an `Arc`, or `None` otherwise. pub fn arc_segment_to_center(&self) -> Option { if let PathSegment::Arc(xy1, rx, ry, phi, fa, fs, xy2) = *self { - if rx == 0.0 || ry == 0.0 { + if rx == 0. || ry == 0. { return None; } @@ -298,7 +297,7 @@ impl PathSegment { let mut rx = rx.abs(); let mut ry = ry.abs(); let lambda = x1_prime2 / rx2 + y1_prime2 / ry2 + 1e-12; - if lambda > 1.0 { + if lambda > 1. { let lambda_sqrt = lambda.sqrt(); rx *= lambda_sqrt; ry *= lambda_sqrt; @@ -307,7 +306,7 @@ impl PathSegment { ry2 *= lambda_abs; } - let sign = if fa == fs { -1.0 } else { 1.0 }; + let sign = if fa == fs { -1. } else { 1. }; let multiplier = ((rx2 * ry2 - rx2 * y1_prime2 - ry2 * x1_prime2) / (rx2 * y1_prime2 + ry2 * x1_prime2)).sqrt(); let cx_prime = sign * multiplier * ((rx * xy1_prime.y) / ry); let cy_prime = sign * multiplier * ((-ry * xy1_prime.x) / rx); @@ -315,12 +314,12 @@ impl PathSegment { let cxy = rotation_matrix.transpose() * DVec2::new(cx_prime, cy_prime) + (xy1 + xy2) * 0.5; let vec1 = DVec2::new((xy1_prime.x - cx_prime) / rx, (xy1_prime.y - cy_prime) / ry); - let theta1 = vector_angle(DVec2::new(1.0, 0.0), vec1); + let theta1 = vector_angle(DVec2::new(1., 0.), vec1); let mut delta_theta = vector_angle(vec1, DVec2::new((-xy1_prime.x - cx_prime) / rx, (-xy1_prime.y - cy_prime) / ry)); - if !fs && delta_theta > 0.0 { + if !fs && delta_theta > 0. { delta_theta -= TAU; - } else if fs && delta_theta < 0.0 { + } else if fs && delta_theta < 0. { delta_theta += TAU; } @@ -342,7 +341,7 @@ impl PathSegment { /// /// # Arguments /// - /// * `t` - A value between 0.0 and 1.0 representing the position along the segment. + /// * `t` - A value between 0. and 1. representing the position along the segment. /// /// # Examples /// @@ -350,8 +349,8 @@ impl PathSegment { /// use path_bool::PathSegment; /// use glam::DVec2; /// - /// let line = PathSegment::Line(DVec2::new(0.0, 0.0), DVec2::new(2.0, 2.0)); - /// assert_eq!(line.sample_at(0.5), DVec2::new(1.0, 1.0)); + /// let line = PathSegment::Line(DVec2::new(0., 0.), DVec2::new(2., 2.)); + /// assert_eq!(line.sample_at(0.5), DVec2::new(1., 1.)); /// ``` pub fn sample_at(&self, t: f64) -> DVec2 { match *self { @@ -405,22 +404,22 @@ impl PathSegment { let from_unit = DMat3::from_translation(center_param.center) * DMat3::from_angle(phi.to_radians()) * DMat3::from_scale(DVec2::new(rx, ry)); let theta = center_param.delta_theta / count as f64; - let k = (4.0 / 3.0) * (theta / 4.0).tan(); + let k = (4. / 3.) * (theta / 4.).tan(); let sin_theta = theta.sin(); let cos_theta = theta.cos(); (0..count) .map(|i| { - let start = DVec2::new(1.0, 0.0); - let control1 = DVec2::new(1.0, k); + let start = DVec2::new(1., 0.); + let control1 = DVec2::new(1., k); let control2 = DVec2::new(cos_theta + k * sin_theta, sin_theta - k * cos_theta); let end = DVec2::new(cos_theta, sin_theta); let matrix = DMat3::from_angle(center_param.theta1 + i as f64 * theta) * from_unit; - let start = (matrix * start.extend(1.0)).truncate(); - let control1 = (matrix * control1.extend(1.0)).truncate(); - let control2 = (matrix * control2.extend(1.0)).truncate(); - let end = (matrix * end.extend(1.0)).truncate(); + let start = (matrix * start.extend(1.)).truncate(); + let control1 = (matrix * control1.extend(1.)).truncate(); + let control2 = (matrix * control2.extend(1.)).truncate(); + let end = (matrix * end.extend(1.)).truncate(); PathSegment::Cubic(start, control1, control2, end) }) @@ -466,7 +465,7 @@ impl PathArcSegmentCenterParametrization { let mut xy2 = rotation_matrix * DVec2::new(self.rx * (self.theta1 + self.delta_theta).cos(), self.ry * (self.theta1 + self.delta_theta).sin()) + self.center; let fa = self.delta_theta.abs() > PI; - let fs = self.delta_theta > 0.0; + let fs = self.delta_theta > 0.; xy1 = start.unwrap_or(xy1); xy2 = end.unwrap_or(xy2); @@ -509,27 +508,27 @@ fn cubic_bounding_interval(p0: f64, p1: f64, p2: f64, p3: f64) -> (f64, f64) { let mut min = p0.min(p3); let mut max = p0.max(p3); - let a = 3.0 * (-p0 + 3.0 * p1 - 3.0 * p2 + p3); - let b = 6.0 * (p0 - 2.0 * p1 + p2); - let c = 3.0 * (p1 - p0); - let d = b * b - 4.0 * a * c; + let a = 3. * (-p0 + 3. * p1 - 3. * p2 + p3); + let b = 6. * (p0 - 2. * p1 + p2); + let c = 3. * (p1 - p0); + let d = b * b - 4. * a * c; - if d < 0.0 || a == 0.0 { + if d < 0. || a == 0. { // TODO: if a=0, solve linear return (min, max); } let sqrt_d = d.sqrt(); - let t0 = (-b - sqrt_d) / (2.0 * a); - if 0.0 < t0 && t0 < 1.0 { + let t0 = (-b - sqrt_d) / (2. * a); + if 0. < t0 && t0 < 1. { let x0 = eval_cubic_1d(p0, p1, p2, p3, t0); min = min.min(x0); max = max.max(x0); } - let t1 = (-b + sqrt_d) / (2.0 * a); - if 0.0 < t1 && t1 < 1.0 { + let t1 = (-b + sqrt_d) / (2. * a); + if 0. < t1 && t1 < 1. { let x1 = eval_cubic_1d(p0, p1, p2, p3, t1); min = min.min(x1); max = max.max(x1); @@ -570,14 +569,14 @@ fn quadratic_bounding_interval(p0: f64, p1: f64, p2: f64) -> (f64, f64) { let mut min = p0.min(p2); let mut max = p0.max(p2); - let denominator = p0 - 2.0 * p1 + p2; + let denominator = p0 - 2. * p1 + p2; - if denominator == 0.0 { + if denominator == 0. { return (min, max); } let t = (p0 - p1) / denominator; - if (0.0..=1.0).contains(&t) { + if (0.0..=1.).contains(&t) { let x = eval_quadratic_1d(p0, p1, p2, t); min = min.min(x); max = max.max(x); @@ -595,7 +594,7 @@ impl PathSegment { /// /// # Returns /// - /// An `AaBb` representing the axis-aligned bounding box of the segment. + /// An [`Aabb`] representing the axis-aligned bounding box of the segment. pub(crate) fn bounding_box(&self) -> Aabb { match *self { PathSegment::Line(start, end) => Aabb { @@ -617,34 +616,34 @@ impl PathSegment { PathSegment::Arc(start, rx, ry, phi, _, _, end) => { if let Some(center_param) = self.arc_segment_to_center() { let theta2 = center_param.theta1 + center_param.delta_theta; - let mut bounding_box = extend_bounding_box(Some(bounding_box_around_point(start, 0.0)), end); + let mut bounding_box = extend_bounding_box(Some(bounding_box_around_point(start, 0.)), end); - if phi == 0.0 || rx == ry { - // FIXME: the following gives false positives, resulting in larger boxes + if phi == 0. || rx == ry { + // TODO: Fix the fact that the following gives false positives, resulting in larger boxes if in_interval(-PI, center_param.theta1, theta2) || in_interval(PI, center_param.theta1, theta2) { bounding_box = extend_bounding_box(Some(bounding_box), DVec2::new(center_param.center.x - rx, center_param.center.y)); } - if in_interval(-PI / 2.0, center_param.theta1, theta2) || in_interval(3.0 * PI / 2.0, center_param.theta1, theta2) { + if in_interval(-PI / 2., center_param.theta1, theta2) || in_interval(3. * PI / 2., center_param.theta1, theta2) { bounding_box = extend_bounding_box(Some(bounding_box), DVec2::new(center_param.center.x, center_param.center.y - ry)); } - if in_interval(0.0, center_param.theta1, theta2) || in_interval(2.0 * PI, center_param.theta1, theta2) { + if in_interval(0., center_param.theta1, theta2) || in_interval(2. * PI, center_param.theta1, theta2) { bounding_box = extend_bounding_box(Some(bounding_box), DVec2::new(center_param.center.x + rx, center_param.center.y)); } - if in_interval(PI / 2.0, center_param.theta1, theta2) || in_interval(5.0 * PI / 2.0, center_param.theta1, theta2) { + if in_interval(PI / 2., center_param.theta1, theta2) || in_interval(5. * PI / 2., center_param.theta1, theta2) { bounding_box = extend_bounding_box(Some(bounding_box), DVec2::new(center_param.center.x, center_param.center.y + ry)); } - expand_bounding_box(&bounding_box, 1e-11) // TODO: get rid of expansion + expand_bounding_box(&bounding_box, 1e-11) // TODO: Get rid of expansion } else { - // TODO: don't convert to cubics - let cubics = self.arc_segment_to_cubics(PI / 16.0); + // TODO: Don't convert to cubics + let cubics = self.arc_segment_to_cubics(PI / 16.); let mut bounding_box = None; for cubic_seg in cubics { bounding_box = Some(merge_bounding_boxes(bounding_box, &cubic_seg.bounding_box())); } - bounding_box.unwrap_or_else(|| bounding_box_around_point(start, 0.0)) + bounding_box.unwrap_or_else(|| bounding_box_around_point(start, 0.)) } } else { - extend_bounding_box(Some(bounding_box_around_point(start, 0.0)), end) + extend_bounding_box(Some(bounding_box_around_point(start, 0.)), end) } } } @@ -654,7 +653,7 @@ impl PathSegment { /// /// # Arguments /// - /// * `t` - A value between 0.0 and 1.0 representing the split point along the segment. + /// * `t` - A value between 0. and 1. representing the split point along the segment. /// /// # Returns /// @@ -666,10 +665,10 @@ impl PathSegment { /// use path_bool::PathSegment; /// use glam::DVec2; /// - /// let line = PathSegment::Line(DVec2::new(0.0, 0.0), DVec2::new(2.0, 2.0)); + /// let line = PathSegment::Line(DVec2::new(0., 0.), DVec2::new(2., 2.)); /// let (first_half, second_half) = line.split_at(0.5); - /// assert_eq!(first_half.end(), DVec2::new(1.0, 1.0)); - /// assert_eq!(second_half.start(), DVec2::new(1.0, 1.0)); + /// assert_eq!(first_half.end(), DVec2::new(1., 1.)); + /// assert_eq!(second_half.start(), DVec2::new(1., 1.)); /// ``` pub fn split_at(&self, t: f64) -> (PathSegment, PathSegment) { match *self { diff --git a/libraries/path-bool/src/path_boolean.rs b/libraries/path-bool/src/path_boolean.rs index 138bf0b6d..2f513b993 100644 --- a/libraries/path-bool/src/path_boolean.rs +++ b/libraries/path-bool/src/path_boolean.rs @@ -51,8 +51,6 @@ //! This approach allows for efficient and accurate boolean operations, even on //! complex paths with many intersections or self-intersections. -use slotmap::{new_key_type, SlotMap}; - new_key_type! { pub struct MajorVertexKey; pub struct MajorEdgeKey; @@ -74,9 +72,12 @@ use crate::path_segment::PathSegment; #[cfg(feature = "logging")] use crate::path_to_path_data; use crate::quad_tree::QuadTree; + use glam::DVec2; +use slotmap::{new_key_type, SlotMap}; use std::cmp::Ordering; use std::collections::{HashMap, HashSet, VecDeque}; +use std::fmt::Display; /// Represents the types of boolean operations that can be performed on paths. #[derive(Debug, Clone, Copy)] @@ -183,6 +184,7 @@ impl MinorGraphEdge { } } } + // Compares Segments based on their derivative at the start. If the derivative // is equal, check the curvature instead. This should correctly sort most instances. fn compare_segments(a: &PathSegment, b: &PathSegment) -> Ordering { @@ -368,7 +370,7 @@ fn split_at_self_intersections(edges: &mut Vec) { new_edges.push((seg2, *parent)); } else { let (seg1, tmp_seg) = seg.split_at(t1); - let (seg2, seg3) = &tmp_seg.split_at((t2 - t1) / (1.0 - t1)); + let (seg2, seg3) = &tmp_seg.split_at((t2 - t1) / (1. - t1)); *seg = seg1; new_edges.push((*seg2, *parent)); new_edges.push((*seg3, *parent)); @@ -447,17 +449,17 @@ fn split_at_intersections(edges: &[MajorGraphEdgeStage1]) -> (Vec 1.0 - EPS.param { + if t > 1. - EPS.param { break; } - let tt = (t - prev_t) / (1.0 - prev_t); + let tt = (t - prev_t) / (1. - prev_t); prev_t = t; if tt < EPS.param { continue; } - if tt > 1.0 - EPS.param { + if tt > 1. - EPS.param { continue; } let (seg1, seg2) = tmp_seg.split_at(tt); @@ -651,7 +653,7 @@ fn compute_minor(major_graph: &MajorGraph) -> MinorGraph { segments.push(edge.seg); visited.insert(edge.incident_vertices[1]); let next_vertex = &major_graph.vertices[edge.incident_vertices[1]]; - // choose the edge which is not our twin so we can make progress + // Choose the edge which is not our twin so we can make progress edge_key = *next_vertex.outgoing_edges.iter().find(|&&e| Some(e) != edge.twin).unwrap(); edge = &major_graph.edges[edge_key]; } @@ -718,7 +720,7 @@ fn compute_minor(major_graph: &MajorGraph) -> MinorGraph { } fn remove_dangling_edges(graph: &mut MinorGraph) { - // Basically DFS for each parent with bfs number + // Basically DFS for each parent with BFS number fn walk(parent: u8, graph: &MinorGraph) -> HashSet { let mut kept_vertices = HashSet::new(); let mut vertex_to_level = HashMap::new(); @@ -780,36 +782,10 @@ fn remove_dangling_edges(graph: &mut MinorGraph) { }); } -fn get_incidence_angle(edge: &MinorGraphEdge) -> f64 { - let seg = &edge.segments[0]; // TODO: explain in comment why this is always the incident one in both fwd and bwd - - // eprintln!("{edge:?}"); //, edge.direction_flag.forward()); - let (p0, p1) = if edge.direction_flag.forward() { - (seg.sample_at(0.0), seg.sample_at(EPS.param)) - } else { - (seg.sample_at(1.0), seg.sample_at(1.0 - EPS.param)) - }; - - // eprintln!("{p0:?} {p1:?}"); - let angle = (p1.y - p0.y).atan2(p1.x - p0.x); - // eprintln!("angle: {}", angle); - (angle * 10000.).round() / 1000. -} - fn sort_outgoing_edges_by_angle(graph: &mut MinorGraph) { for (vertex_key, vertex) in graph.vertices.iter_mut() { if vertex.outgoing_edges.len() > 2 { - vertex.outgoing_edges.sort_by(|&a, &b| { - // TODO(@TrueDoctor): Make more robust. The js version seems to sort the data slightly differently when the angles are reallly close. In that case put the edge wich was discovered later first. - let new = graph.edges[a].partial_cmp(&graph.edges[b]).unwrap(); - let old = (get_incidence_angle(&graph.edges[a]) - (a.0.as_ffi() & 0xFFFFFF) as f64 / 1000000.) - .partial_cmp(&(get_incidence_angle(&graph.edges[b]) - (b.0.as_ffi() & 0xFFFFFF) as f64 / 1000000.)) - .unwrap_or(b.cmp(&a)); - if new != old { - // dbg!(new, old, a, b); - } - new - }); + vertex.outgoing_edges.sort_by(|&a, &b| graph.edges[a].partial_cmp(&graph.edges[b]).unwrap()); if cfg!(feature = "logging") { eprintln!("Outgoing edges for {:?}:", vertex_key); for &edge_key in &vertex.outgoing_edges { @@ -824,18 +800,15 @@ fn sort_outgoing_edges_by_angle(graph: &mut MinorGraph) { fn face_to_polygon(face: &DualGraphVertex, edges: &SlotMap) -> Vec { const CNT: usize = 3; - // #[cfg(feature = "logging")] - // eprintln!("incident node counts {}", face.incident_edges.len()); face.incident_edges .iter() .flat_map(|&edge_key| { let edge = &edges[edge_key]; - // eprintln!("{}", path_to_path_data(&edge.segments, 0.001)); edge.segments.iter().flat_map(move |seg| { (0..CNT).map(move |i| { let t0 = i as f64 / CNT as f64; - let t = if edge.direction_flag.forward() { t0 } else { 1.0 - t0 }; + let t = if edge.direction_flag.forward() { t0 } else { 1. - t0 }; seg.sample_at(t) }) }) @@ -908,18 +881,11 @@ fn compute_signed_area(face: &DualGraphVertex, edges: &SlotMap Result { let mut visited_edges = HashSet::new(); if cfg!(feature = "logging") { - // eeprintln!("minor_to_dual: {:#?}", minor_to_dual_edge); eprintln!("faces: {}, dual-edges: {}, cycles: {}", new_vertices.len(), dual_edges.len(), minor_graph.cycles.len()) } // This can be very useful for debugging: - // Copy the face outlines to a file called faces_combined.csv and then use this - // gnuplot command: - // `plot 'faces_combined.csv' i 0:99 w l, 'faces_combined.csv' index 0 w l lc 'red'` - // the first part of the command plots all faces to the graph and the second comand - // plots one surface, specifed by the index, in red. This allows you to check if all surfaces are closed paths and can be used in conjunction with the flag debugging to identify issues later down the line as well + // Copy the face outlines to a file called faces_combined.csv and then use this gnuplot command: + // ``` + // plot 'faces_combined.csv' i 0:99 w l, 'faces_combined.csv' index 0 w l lc 'red' + // ``` + // The first part of the command plots all faces to the graph and the second comand plots one surface, + // specified by the index, in red. This allows you to check if all surfaces are closed paths and can + // be used in conjunction with the flag debugging to identify issues later down the line as well. #[cfg(feature = "logging")] for (vertex_key, vertex) in &dual_vertices { eprintln!("\n\n#{:?}", vertex_key.0); @@ -1118,7 +1085,6 @@ fn compute_dual(minor_graph: &MinorGraph) -> Result { reverse_winding = true; } let outer_face_key = if count != 1 { - // return Err(BooleanError::MultipleOuterFaces); #[cfg(feature = "logging")] eprintln!("Found multiple outer faces: {areas:?}, falling back to area calculation"); let (key, _) = *areas.iter().max_by_key(|(_, area)| ((area.abs() * 1000.) as u64)).unwrap(); @@ -1335,7 +1301,6 @@ fn flag_faces( } visited_faces.insert(face_key); - // dbg!(face_key, a_count, b_count); let a_flag = get_flag(a_count, a_fill_rule); let b_flag = get_flag(b_count, b_fill_rule); *flags.entry(face_key).or_default() = a_flag | (b_flag << 1); @@ -1458,7 +1423,7 @@ fn dump_faces( } } - // poke holes in the face + // Poke holes in the face if let Some(subtrees) = tree.outgoing_edges.get(&face_key) { for subtree in subtrees { let outer_face_key = subtree.component.outer_face.unwrap(); @@ -1499,7 +1464,6 @@ const OPERATION_PREDICATES: [fn(u8) -> bool; 6] = [ |flag: u8| flag > 0, // Fracture ]; -// TODO: Impl error trait /// Represents errors that can occur during boolean operations on paths. #[derive(Debug)] pub enum BooleanError { @@ -1507,6 +1471,17 @@ pub enum BooleanError { MultipleOuterFaces, /// Indicates that no valid ear was found in a polygon during triangulation. NoEarInPolygon, + InvalidPathCommand(char), +} + +impl Display for BooleanError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::MultipleOuterFaces => f.write_str("Found multiple candidates for the outer face in a connected component of the dual graph."), + Self::NoEarInPolygon => f.write_str("Failed to compute winding order for one of the faces, this usually happens when the polygon is malformed."), + Self::InvalidPathCommand(cmd) => f.write_fmt(format_args!("Encountered a '{cmd}' while parsing the svg data which was not recogniezed")), + } + } } /// Performs boolean operations on two paths. @@ -1519,8 +1494,8 @@ pub enum BooleanError { /// ``` /// use path_bool::{path_boolean, FillRule, PathBooleanOperation, path_from_path_data, path_to_path_data}; /// -/// 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 path_a = path_from_path_data("M 10 10 L 50 10 L 30 40 Z").unwrap(); +/// let path_b = path_from_path_data("M 20 30 L 60 30 L 60 50 L 20 50 Z").unwrap(); /// /// let result = path_boolean( /// &path_a, @@ -1573,13 +1548,12 @@ pub fn path_boolean(a: &Path, a_fill_rule: FillRule, b: &Path, b_fill_rule: Fill #[cfg(feature = "logging")] for (edge, _, _) in split_edges.iter() { - // eprintln!("{}", edge.format_path()); eprintln!("{}", path_to_path_data(&vec![*edge], 0.001)); } let total_bounding_box = match total_bounding_box { Some(bb) => bb, - None => return Ok(Vec::new()), // input geometry is empty + None => return Ok(Vec::new()), // Input geometry is empty }; let major_graph = find_vertices(&split_edges, total_bounding_box); @@ -1604,7 +1578,6 @@ pub fn path_boolean(a: &Path, a_fill_rule: FillRule, b: &Path, b_fill_rule: Fill #[cfg(feature = "logging")] for (key, edge) in minor_graph.edges.iter() { - // eprintln!("{}", edge.format_path()); eprintln!("{key:?}:\n{}", path_to_path_data(&edge.segments, 0.001)); } #[cfg(feature = "logging")] @@ -1662,10 +1635,9 @@ pub fn path_boolean(a: &Path, a_fill_rule: FillRule, b: &Path, b_fill_rule: Fill #[cfg(test)] mod tests { - use std::f64::consts::TAU; - use super::*; - use glam::DVec2; // Assuming DVec2 is defined in your crate + use glam::DVec2; + use std::f64::consts::TAU; // Assuming DVec2 is defined in your crate #[test] fn test_split_at_intersections() { @@ -1690,14 +1662,14 @@ mod tests { fn unsplit_edges() -> Vec<(PathSegment, u8)> { let unsplit_edges = vec![ - (PathSegment::Arc(DVec2::new(39.0, 20.0), 19.0, 19.0, 0.0, false, true, DVec2::new(20.0, 39.0)), 1), - (PathSegment::Arc(DVec2::new(20.0, 39.0), 19.0, 19.0, 0.0, false, true, DVec2::new(1.0, 20.0)), 1), - (PathSegment::Arc(DVec2::new(1.0, 20.0), 19.0, 19.0, 0.0, false, true, DVec2::new(20.0, 1.0)), 1), - (PathSegment::Arc(DVec2::new(20.0, 1.0), 19.0, 19.0, 0.0, false, true, DVec2::new(39.0, 20.0)), 1), - (PathSegment::Arc(DVec2::new(47.0, 28.0), 19.0, 19.0, 0.0, false, true, DVec2::new(28.0, 47.0)), 2), - (PathSegment::Arc(DVec2::new(28.0, 47.0), 19.0, 19.0, 0.0, false, true, DVec2::new(9.0, 28.0)), 2), - (PathSegment::Arc(DVec2::new(9.0, 28.0), 19.0, 19.0, 0.0, false, true, DVec2::new(28.0, 9.0)), 2), - (PathSegment::Arc(DVec2::new(28.0, 9.0), 19.0, 19.0, 0.0, false, true, DVec2::new(47.0, 28.0)), 2), + (PathSegment::Arc(DVec2::new(39., 20.), 19., 19., 0., false, true, DVec2::new(20., 39.)), 1), + (PathSegment::Arc(DVec2::new(20., 39.), 19., 19., 0., false, true, DVec2::new(1., 20.)), 1), + (PathSegment::Arc(DVec2::new(1., 20.), 19., 19., 0., false, true, DVec2::new(20., 1.)), 1), + (PathSegment::Arc(DVec2::new(20., 1.), 19., 19., 0., false, true, DVec2::new(39., 20.)), 1), + (PathSegment::Arc(DVec2::new(47., 28.), 19., 19., 0., false, true, DVec2::new(28., 47.)), 2), + (PathSegment::Arc(DVec2::new(28., 47.), 19., 19., 0., false, true, DVec2::new(9., 28.)), 2), + (PathSegment::Arc(DVec2::new(9., 28.), 19., 19., 0., false, true, DVec2::new(28., 9.)), 2), + (PathSegment::Arc(DVec2::new(28., 9.), 19., 19., 0., false, true, DVec2::new(47., 28.)), 2), ]; unsplit_edges } @@ -1713,7 +1685,7 @@ mod tests { let minor_graph = compute_minor(&major_graph); // Print minor graph state - // eprintln!("Minor Graph:"); + eprintln!("Minor Graph:"); print_minor_graph_state(&minor_graph); // Assertions @@ -1817,18 +1789,18 @@ mod tests { fn get_incidence_angle(edge: &MinorGraphEdge) -> f64 { let seg = &edge.segments[0]; // First segment is always the incident one in both fwd and bwd let (p0, p1) = if edge.direction_flag.forward() { - (seg.sample_at(0.0), seg.sample_at(0.1)) + (seg.sample_at(0.), seg.sample_at(0.1)) } else { - (seg.sample_at(1.0), seg.sample_at(1.0 - 0.1)) + (seg.sample_at(1.), seg.sample_at(1. - 0.1)) }; ((p1.y - p0.y).atan2(p1.x - p0.x) + TAU) % TAU } #[test] fn test_path_segment_horizontal_ray_intersection_count() { - let orig_seg = PathSegment::Arc(DVec2::new(24.0, 10.090978), 13.909023, 13.909023, 0.0, false, true, DVec2::new(47., 24.0)); + let orig_seg = PathSegment::Arc(DVec2::new(24., 10.090978), 13.909023, 13.909023, 0., false, true, DVec2::new(47., 24.)); - let point = DVec2::new(37.99, 24.0); + let point = DVec2::new(37.99, 24.); eprintln!("Starting test with segment: {:?}", orig_seg); eprintln!("Test point: {:?}", point); @@ -1844,15 +1816,15 @@ mod tests { #[test] fn test_bounding_box_intersects_horizontal_ray() { let bbox = Aabb { - top: 10.0, - right: 40.0, - bottom: 30.0, - left: 20.0, + top: 10., + right: 40., + bottom: 30., + left: 20., }; - assert!(bounding_box_intersects_horizontal_ray(&bbox, DVec2::new(0.0, 30.0))); - assert!(bounding_box_intersects_horizontal_ray(&bbox, DVec2::new(20.0, 30.0))); - assert!(bounding_box_intersects_horizontal_ray(&bbox, DVec2::new(10.0, 20.0))); - assert!(!bounding_box_intersects_horizontal_ray(&bbox, DVec2::new(30.0, 40.0))); + assert!(bounding_box_intersects_horizontal_ray(&bbox, DVec2::new(0., 30.))); + assert!(bounding_box_intersects_horizontal_ray(&bbox, DVec2::new(20., 30.))); + assert!(bounding_box_intersects_horizontal_ray(&bbox, DVec2::new(10., 20.))); + assert!(!bounding_box_intersects_horizontal_ray(&bbox, DVec2::new(30., 40.))); } } diff --git a/libraries/path-bool/src/util/math.rs b/libraries/path-bool/src/util/math.rs index 6367d048d..6d099a276 100644 --- a/libraries/path-bool/src/util/math.rs +++ b/libraries/path-bool/src/util/math.rs @@ -15,7 +15,7 @@ pub fn vector_angle(u: DVec2, v: DVec2) -> f64 { let sign = u.x * v.y - u.y * v.x; if sign.abs() < EPS && (u + v).length_squared() < EPS * EPS { - // TODO: u can be scaled + // TODO: `u` can be scaled return PI; } diff --git a/libraries/path-bool/src/util/quad_tree.rs b/libraries/path-bool/src/util/quad_tree.rs index 75fece1dd..9468ad611 100644 --- a/libraries/path-bool/src/util/quad_tree.rs +++ b/libraries/path-bool/src/util/quad_tree.rs @@ -72,15 +72,15 @@ impl QuadTree { return; } - let midx = (self.bounding_box.left + self.bounding_box.right) / 2.0; - let midy = (self.bounding_box.top + self.bounding_box.bottom) / 2.0; + let mid_x = (self.bounding_box.left + self.bounding_box.right) / 2.; + let mid_y = (self.bounding_box.top + self.bounding_box.bottom) / 2.; self.subtrees = Some(Box::new([ QuadTree::new( Aabb { top: self.bounding_box.top, - right: midx, - bottom: midy, + right: mid_x, + bottom: mid_y, left: self.bounding_box.left, }, self.depth - 1, @@ -90,16 +90,16 @@ impl QuadTree { Aabb { top: self.bounding_box.top, right: self.bounding_box.right, - bottom: midy, - left: midx, + bottom: mid_y, + left: mid_x, }, self.depth - 1, self.inner_node_capacity, ), QuadTree::new( Aabb { - top: midy, - right: midx, + top: mid_y, + right: mid_x, bottom: self.bounding_box.bottom, left: self.bounding_box.left, }, @@ -108,10 +108,10 @@ impl QuadTree { ), QuadTree::new( Aabb { - top: midy, + top: mid_y, right: self.bounding_box.right, bottom: self.bounding_box.bottom, - left: midx, + left: mid_x, }, self.depth - 1, self.inner_node_capacity, diff --git a/libraries/path-bool/src/visual_tests.rs b/libraries/path-bool/src/visual_tests.rs index 3bebb92a8..2c9aa9f40 100644 --- a/libraries/path-bool/src/visual_tests.rs +++ b/libraries/path-bool/src/visual_tests.rs @@ -1,3 +1,6 @@ +use crate::path_boolean::{self, FillRule, PathBooleanOperation}; +use crate::path_data::{path_from_path_data, path_to_path_data}; + use core::panic; use glob::glob; use image::{DynamicImage, GenericImageView, RgbaImage}; @@ -8,9 +11,6 @@ use std::fs; use std::path::PathBuf; use svg::parser::Event; -use crate::path_boolean::{self, FillRule, PathBooleanOperation}; -use crate::path_data::{path_from_path_data, path_to_path_data}; - const TOLERANCE: u8 = 84; fn get_fill_rule(fill_rule: &str) -> FillRule { @@ -31,7 +31,7 @@ fn visual_tests() { ("fracture", PathBooleanOperation::Fracture), ]; - let folders: Vec<(String, PathBuf, &str, PathBooleanOperation)> = glob("__fixtures__/visual-tests/*/") + let folders: Vec<(String, PathBuf, &str, PathBooleanOperation)> = glob("visual-tests/*/") .expect("Failed to read glob pattern") .flat_map(|entry| { let dir = entry.expect("Failed to get directory entry"); @@ -58,6 +58,7 @@ fn visual_tests() { let mut width = String::new(); let mut height = String::new(); let mut view_box = String::new(); + let mut transform = String::new(); for event in svg_tree { match event { Event::Tag("svg", svg::node::element::tag::Type::Start, attributes) => { @@ -65,6 +66,11 @@ fn visual_tests() { height = attributes.get("height").map(|s| s.to_string()).unwrap_or_default(); view_box = attributes.get("viewBox").map(|s| s.to_string()).unwrap_or_default(); } + Event::Tag("g", svg::node::element::tag::Type::Start, attributes) => { + if let Some(transform_attr) = attributes.get("transform") { + transform = transform_attr.to_string(); + } + } Event::Tag("path", svg::node::element::tag::Type::Empty, attributes) => { let data = attributes.get("d").map(|s| s.to_string()).expect("Path data not found"); let fill_rule = attributes.get("fill-rule").map(|v| v.to_string()).unwrap_or_else(|| "nonzero".to_string()); @@ -98,19 +104,25 @@ fn visual_tests() { let a_node = paths[0].clone(); let b_node = paths[1].clone(); - let a = path_from_path_data(&a_node.0); - let b = path_from_path_data(&b_node.0); + let a = path_from_path_data(&a_node.0).unwrap(); + let b = path_from_path_data(&b_node.0).unwrap(); let a_fill_rule = get_fill_rule(&a_node.1); let b_fill_rule = get_fill_rule(&b_node.1); let result = path_boolean::path_boolean(&a, a_fill_rule, &b, b_fill_rule, op).unwrap(); - // Create the result SVG with correct dimensions + // Create the result SVG with correct dimensions and transform let mut result_svg = format!("", width, height, view_box); + if !transform.is_empty() { + result_svg.push_str(&format!("", transform)); + } for path in &result { result_svg.push_str(&format!("", path_to_path_data(path, 1e-4), first_path_attributes)); } + if !transform.is_empty() { + result_svg.push_str(""); + } result_svg.push_str(""); // Save the result SVG diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-01/difference.svg b/libraries/path-bool/visual-tests/dangling-01/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-01/difference.svg rename to libraries/path-bool/visual-tests/dangling-01/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-01/division.svg b/libraries/path-bool/visual-tests/dangling-01/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-01/division.svg rename to libraries/path-bool/visual-tests/dangling-01/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-01/exclusion.svg b/libraries/path-bool/visual-tests/dangling-01/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-01/exclusion.svg rename to libraries/path-bool/visual-tests/dangling-01/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-01/fracture.svg b/libraries/path-bool/visual-tests/dangling-01/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-01/fracture.svg rename to libraries/path-bool/visual-tests/dangling-01/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-01/intersection.svg b/libraries/path-bool/visual-tests/dangling-01/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-01/intersection.svg rename to libraries/path-bool/visual-tests/dangling-01/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-01/original.svg b/libraries/path-bool/visual-tests/dangling-01/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-01/original.svg rename to libraries/path-bool/visual-tests/dangling-01/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-01/union.svg b/libraries/path-bool/visual-tests/dangling-01/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-01/union.svg rename to libraries/path-bool/visual-tests/dangling-01/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-02/difference.svg b/libraries/path-bool/visual-tests/dangling-02/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-02/difference.svg rename to libraries/path-bool/visual-tests/dangling-02/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-02/division.svg b/libraries/path-bool/visual-tests/dangling-02/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-02/division.svg rename to libraries/path-bool/visual-tests/dangling-02/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-02/exclusion.svg b/libraries/path-bool/visual-tests/dangling-02/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-02/exclusion.svg rename to libraries/path-bool/visual-tests/dangling-02/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-02/fracture.svg b/libraries/path-bool/visual-tests/dangling-02/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-02/fracture.svg rename to libraries/path-bool/visual-tests/dangling-02/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-02/intersection.svg b/libraries/path-bool/visual-tests/dangling-02/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-02/intersection.svg rename to libraries/path-bool/visual-tests/dangling-02/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-02/original.svg b/libraries/path-bool/visual-tests/dangling-02/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-02/original.svg rename to libraries/path-bool/visual-tests/dangling-02/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-02/union.svg b/libraries/path-bool/visual-tests/dangling-02/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-02/union.svg rename to libraries/path-bool/visual-tests/dangling-02/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-03/difference.svg b/libraries/path-bool/visual-tests/dangling-03/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-03/difference.svg rename to libraries/path-bool/visual-tests/dangling-03/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-03/division.svg b/libraries/path-bool/visual-tests/dangling-03/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-03/division.svg rename to libraries/path-bool/visual-tests/dangling-03/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-03/exclusion.svg b/libraries/path-bool/visual-tests/dangling-03/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-03/exclusion.svg rename to libraries/path-bool/visual-tests/dangling-03/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-03/fracture.svg b/libraries/path-bool/visual-tests/dangling-03/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-03/fracture.svg rename to libraries/path-bool/visual-tests/dangling-03/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-03/intersection.svg b/libraries/path-bool/visual-tests/dangling-03/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-03/intersection.svg rename to libraries/path-bool/visual-tests/dangling-03/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-03/original.svg b/libraries/path-bool/visual-tests/dangling-03/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-03/original.svg rename to libraries/path-bool/visual-tests/dangling-03/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-03/union.svg b/libraries/path-bool/visual-tests/dangling-03/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-03/union.svg rename to libraries/path-bool/visual-tests/dangling-03/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-04/difference.svg b/libraries/path-bool/visual-tests/dangling-04/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-04/difference.svg rename to libraries/path-bool/visual-tests/dangling-04/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-04/division.svg b/libraries/path-bool/visual-tests/dangling-04/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-04/division.svg rename to libraries/path-bool/visual-tests/dangling-04/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-04/exclusion.svg b/libraries/path-bool/visual-tests/dangling-04/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-04/exclusion.svg rename to libraries/path-bool/visual-tests/dangling-04/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-04/fracture.svg b/libraries/path-bool/visual-tests/dangling-04/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-04/fracture.svg rename to libraries/path-bool/visual-tests/dangling-04/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-04/intersection.svg b/libraries/path-bool/visual-tests/dangling-04/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-04/intersection.svg rename to libraries/path-bool/visual-tests/dangling-04/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-04/original.svg b/libraries/path-bool/visual-tests/dangling-04/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-04/original.svg rename to libraries/path-bool/visual-tests/dangling-04/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/dangling-04/union.svg b/libraries/path-bool/visual-tests/dangling-04/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/dangling-04/union.svg rename to libraries/path-bool/visual-tests/dangling-04/union.svg diff --git a/libraries/path-bool/visual-tests/establish-ground-truth.sh b/libraries/path-bool/visual-tests/establish-ground-truth.sh new file mode 100644 index 000000000..557a2b645 --- /dev/null +++ b/libraries/path-bool/visual-tests/establish-ground-truth.sh @@ -0,0 +1,5 @@ +for dir in */; do + for fn in difference division exclusion fracture intersection union; do + cp "${dir}test-results/$fn-ours.svg" "$dir$fn.svg" + done +done diff --git a/libraries/path-bool/visual-tests/generate-ground-truth.sh b/libraries/path-bool/visual-tests/generate-ground-truth.sh new file mode 100644 index 000000000..5471a1e10 --- /dev/null +++ b/libraries/path-bool/visual-tests/generate-ground-truth.sh @@ -0,0 +1,10 @@ +INKSCAPE_CMD=inkscape +OPS=(union difference intersection exclusion division fracture) + +for dir in */; do + for op in "${OPS[@]}"; do + if [ ! -e "$dir/$op.svg" ]; then + $INKSCAPE_CMD --actions="select-all; path-$op; export-filename:$dir/$op.svg; export-plain-svg; export-do; file-close" "$dir/original.svg" + fi + done +done diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-01/difference.svg b/libraries/path-bool/visual-tests/nesting-01/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-01/difference.svg rename to libraries/path-bool/visual-tests/nesting-01/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-01/division.svg b/libraries/path-bool/visual-tests/nesting-01/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-01/division.svg rename to libraries/path-bool/visual-tests/nesting-01/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-01/exclusion.svg b/libraries/path-bool/visual-tests/nesting-01/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-01/exclusion.svg rename to libraries/path-bool/visual-tests/nesting-01/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-01/fracture.svg b/libraries/path-bool/visual-tests/nesting-01/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-01/fracture.svg rename to libraries/path-bool/visual-tests/nesting-01/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-01/intersection.svg b/libraries/path-bool/visual-tests/nesting-01/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-01/intersection.svg rename to libraries/path-bool/visual-tests/nesting-01/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-01/original.svg b/libraries/path-bool/visual-tests/nesting-01/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-01/original.svg rename to libraries/path-bool/visual-tests/nesting-01/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-01/union.svg b/libraries/path-bool/visual-tests/nesting-01/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-01/union.svg rename to libraries/path-bool/visual-tests/nesting-01/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-02/difference.svg b/libraries/path-bool/visual-tests/nesting-02/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-02/difference.svg rename to libraries/path-bool/visual-tests/nesting-02/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-02/division.svg b/libraries/path-bool/visual-tests/nesting-02/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-02/division.svg rename to libraries/path-bool/visual-tests/nesting-02/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-02/exclusion.svg b/libraries/path-bool/visual-tests/nesting-02/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-02/exclusion.svg rename to libraries/path-bool/visual-tests/nesting-02/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-02/fracture.svg b/libraries/path-bool/visual-tests/nesting-02/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-02/fracture.svg rename to libraries/path-bool/visual-tests/nesting-02/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-02/intersection.svg b/libraries/path-bool/visual-tests/nesting-02/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-02/intersection.svg rename to libraries/path-bool/visual-tests/nesting-02/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-02/original.svg b/libraries/path-bool/visual-tests/nesting-02/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-02/original.svg rename to libraries/path-bool/visual-tests/nesting-02/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-02/union.svg b/libraries/path-bool/visual-tests/nesting-02/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-02/union.svg rename to libraries/path-bool/visual-tests/nesting-02/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-03/difference.svg b/libraries/path-bool/visual-tests/nesting-03/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-03/difference.svg rename to libraries/path-bool/visual-tests/nesting-03/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-03/division.svg b/libraries/path-bool/visual-tests/nesting-03/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-03/division.svg rename to libraries/path-bool/visual-tests/nesting-03/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-03/exclusion.svg b/libraries/path-bool/visual-tests/nesting-03/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-03/exclusion.svg rename to libraries/path-bool/visual-tests/nesting-03/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-03/fracture.svg b/libraries/path-bool/visual-tests/nesting-03/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-03/fracture.svg rename to libraries/path-bool/visual-tests/nesting-03/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-03/intersection.svg b/libraries/path-bool/visual-tests/nesting-03/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-03/intersection.svg rename to libraries/path-bool/visual-tests/nesting-03/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-03/original.svg b/libraries/path-bool/visual-tests/nesting-03/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-03/original.svg rename to libraries/path-bool/visual-tests/nesting-03/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-03/union.svg b/libraries/path-bool/visual-tests/nesting-03/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-03/union.svg rename to libraries/path-bool/visual-tests/nesting-03/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-04/difference.svg b/libraries/path-bool/visual-tests/nesting-04/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-04/difference.svg rename to libraries/path-bool/visual-tests/nesting-04/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-04/division.svg b/libraries/path-bool/visual-tests/nesting-04/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-04/division.svg rename to libraries/path-bool/visual-tests/nesting-04/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-04/exclusion.svg b/libraries/path-bool/visual-tests/nesting-04/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-04/exclusion.svg rename to libraries/path-bool/visual-tests/nesting-04/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-04/fracture.svg b/libraries/path-bool/visual-tests/nesting-04/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-04/fracture.svg rename to libraries/path-bool/visual-tests/nesting-04/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-04/intersection.svg b/libraries/path-bool/visual-tests/nesting-04/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-04/intersection.svg rename to libraries/path-bool/visual-tests/nesting-04/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-04/original.svg b/libraries/path-bool/visual-tests/nesting-04/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-04/original.svg rename to libraries/path-bool/visual-tests/nesting-04/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/nesting-04/union.svg b/libraries/path-bool/visual-tests/nesting-04/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/nesting-04/union.svg rename to libraries/path-bool/visual-tests/nesting-04/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-01/difference.svg b/libraries/path-bool/visual-tests/real-01/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-01/difference.svg rename to libraries/path-bool/visual-tests/real-01/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-01/division.svg b/libraries/path-bool/visual-tests/real-01/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-01/division.svg rename to libraries/path-bool/visual-tests/real-01/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-01/exclusion.svg b/libraries/path-bool/visual-tests/real-01/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-01/exclusion.svg rename to libraries/path-bool/visual-tests/real-01/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-01/fracture.svg b/libraries/path-bool/visual-tests/real-01/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-01/fracture.svg rename to libraries/path-bool/visual-tests/real-01/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-01/intersection.svg b/libraries/path-bool/visual-tests/real-01/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-01/intersection.svg rename to libraries/path-bool/visual-tests/real-01/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-01/original.svg b/libraries/path-bool/visual-tests/real-01/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-01/original.svg rename to libraries/path-bool/visual-tests/real-01/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-01/union.svg b/libraries/path-bool/visual-tests/real-01/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-01/union.svg rename to libraries/path-bool/visual-tests/real-01/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-02/difference.svg b/libraries/path-bool/visual-tests/real-02/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-02/difference.svg rename to libraries/path-bool/visual-tests/real-02/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-02/division.svg b/libraries/path-bool/visual-tests/real-02/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-02/division.svg rename to libraries/path-bool/visual-tests/real-02/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-02/exclusion.svg b/libraries/path-bool/visual-tests/real-02/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-02/exclusion.svg rename to libraries/path-bool/visual-tests/real-02/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-02/fracture.svg b/libraries/path-bool/visual-tests/real-02/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-02/fracture.svg rename to libraries/path-bool/visual-tests/real-02/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-02/intersection.svg b/libraries/path-bool/visual-tests/real-02/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-02/intersection.svg rename to libraries/path-bool/visual-tests/real-02/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-02/original.svg b/libraries/path-bool/visual-tests/real-02/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-02/original.svg rename to libraries/path-bool/visual-tests/real-02/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/real-02/union.svg b/libraries/path-bool/visual-tests/real-02/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/real-02/union.svg rename to libraries/path-bool/visual-tests/real-02/union.svg diff --git a/libraries/path-bool/visual-tests/real-03/difference.svg b/libraries/path-bool/visual-tests/real-03/difference.svg new file mode 100644 index 000000000..17b8a2eb6 --- /dev/null +++ b/libraries/path-bool/visual-tests/real-03/difference.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/libraries/path-bool/visual-tests/real-03/division.svg b/libraries/path-bool/visual-tests/real-03/division.svg new file mode 100644 index 000000000..29c94779b --- /dev/null +++ b/libraries/path-bool/visual-tests/real-03/division.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/libraries/path-bool/visual-tests/real-03/exclusion.svg b/libraries/path-bool/visual-tests/real-03/exclusion.svg new file mode 100644 index 000000000..2e7c2febd --- /dev/null +++ b/libraries/path-bool/visual-tests/real-03/exclusion.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/libraries/path-bool/visual-tests/real-03/fracture.svg b/libraries/path-bool/visual-tests/real-03/fracture.svg new file mode 100644 index 000000000..b0fe6ba41 --- /dev/null +++ b/libraries/path-bool/visual-tests/real-03/fracture.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/libraries/path-bool/visual-tests/real-03/intersection.svg b/libraries/path-bool/visual-tests/real-03/intersection.svg new file mode 100644 index 000000000..e1df517ce --- /dev/null +++ b/libraries/path-bool/visual-tests/real-03/intersection.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/libraries/path-bool/visual-tests/real-03/original.svg b/libraries/path-bool/visual-tests/real-03/original.svg new file mode 100644 index 000000000..eb0bf96a7 --- /dev/null +++ b/libraries/path-bool/visual-tests/real-03/original.svg @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/libraries/path-bool/visual-tests/real-03/union.svg b/libraries/path-bool/visual-tests/real-03/union.svg new file mode 100644 index 000000000..cd81bc792 --- /dev/null +++ b/libraries/path-bool/visual-tests/real-03/union.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-01/difference.svg b/libraries/path-bool/visual-tests/simple-01/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-01/difference.svg rename to libraries/path-bool/visual-tests/simple-01/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-01/division.svg b/libraries/path-bool/visual-tests/simple-01/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-01/division.svg rename to libraries/path-bool/visual-tests/simple-01/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-01/exclusion.svg b/libraries/path-bool/visual-tests/simple-01/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-01/exclusion.svg rename to libraries/path-bool/visual-tests/simple-01/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-01/fracture.svg b/libraries/path-bool/visual-tests/simple-01/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-01/fracture.svg rename to libraries/path-bool/visual-tests/simple-01/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-01/intersection.svg b/libraries/path-bool/visual-tests/simple-01/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-01/intersection.svg rename to libraries/path-bool/visual-tests/simple-01/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-01/original.svg b/libraries/path-bool/visual-tests/simple-01/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-01/original.svg rename to libraries/path-bool/visual-tests/simple-01/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-01/union.svg b/libraries/path-bool/visual-tests/simple-01/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-01/union.svg rename to libraries/path-bool/visual-tests/simple-01/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-02/difference.svg b/libraries/path-bool/visual-tests/simple-02/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-02/difference.svg rename to libraries/path-bool/visual-tests/simple-02/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-02/division.svg b/libraries/path-bool/visual-tests/simple-02/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-02/division.svg rename to libraries/path-bool/visual-tests/simple-02/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-02/exclusion.svg b/libraries/path-bool/visual-tests/simple-02/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-02/exclusion.svg rename to libraries/path-bool/visual-tests/simple-02/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-02/fracture.svg b/libraries/path-bool/visual-tests/simple-02/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-02/fracture.svg rename to libraries/path-bool/visual-tests/simple-02/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-02/intersection.svg b/libraries/path-bool/visual-tests/simple-02/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-02/intersection.svg rename to libraries/path-bool/visual-tests/simple-02/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-02/original.svg b/libraries/path-bool/visual-tests/simple-02/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-02/original.svg rename to libraries/path-bool/visual-tests/simple-02/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-02/union.svg b/libraries/path-bool/visual-tests/simple-02/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-02/union.svg rename to libraries/path-bool/visual-tests/simple-02/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-03/difference.svg b/libraries/path-bool/visual-tests/simple-03/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-03/difference.svg rename to libraries/path-bool/visual-tests/simple-03/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-03/division.svg b/libraries/path-bool/visual-tests/simple-03/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-03/division.svg rename to libraries/path-bool/visual-tests/simple-03/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-03/exclusion.svg b/libraries/path-bool/visual-tests/simple-03/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-03/exclusion.svg rename to libraries/path-bool/visual-tests/simple-03/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-03/fracture.svg b/libraries/path-bool/visual-tests/simple-03/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-03/fracture.svg rename to libraries/path-bool/visual-tests/simple-03/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-03/intersection.svg b/libraries/path-bool/visual-tests/simple-03/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-03/intersection.svg rename to libraries/path-bool/visual-tests/simple-03/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-03/original.svg b/libraries/path-bool/visual-tests/simple-03/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-03/original.svg rename to libraries/path-bool/visual-tests/simple-03/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-03/union.svg b/libraries/path-bool/visual-tests/simple-03/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-03/union.svg rename to libraries/path-bool/visual-tests/simple-03/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-04/difference.svg b/libraries/path-bool/visual-tests/simple-04/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-04/difference.svg rename to libraries/path-bool/visual-tests/simple-04/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-04/division.svg b/libraries/path-bool/visual-tests/simple-04/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-04/division.svg rename to libraries/path-bool/visual-tests/simple-04/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-04/exclusion.svg b/libraries/path-bool/visual-tests/simple-04/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-04/exclusion.svg rename to libraries/path-bool/visual-tests/simple-04/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-04/fracture.svg b/libraries/path-bool/visual-tests/simple-04/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-04/fracture.svg rename to libraries/path-bool/visual-tests/simple-04/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-04/intersection.svg b/libraries/path-bool/visual-tests/simple-04/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-04/intersection.svg rename to libraries/path-bool/visual-tests/simple-04/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-04/original.svg b/libraries/path-bool/visual-tests/simple-04/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-04/original.svg rename to libraries/path-bool/visual-tests/simple-04/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-04/union.svg b/libraries/path-bool/visual-tests/simple-04/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-04/union.svg rename to libraries/path-bool/visual-tests/simple-04/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-05/difference.svg b/libraries/path-bool/visual-tests/simple-05/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-05/difference.svg rename to libraries/path-bool/visual-tests/simple-05/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-05/division.svg b/libraries/path-bool/visual-tests/simple-05/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-05/division.svg rename to libraries/path-bool/visual-tests/simple-05/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-05/exclusion.svg b/libraries/path-bool/visual-tests/simple-05/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-05/exclusion.svg rename to libraries/path-bool/visual-tests/simple-05/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-05/fracture.svg b/libraries/path-bool/visual-tests/simple-05/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-05/fracture.svg rename to libraries/path-bool/visual-tests/simple-05/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-05/intersection.svg b/libraries/path-bool/visual-tests/simple-05/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-05/intersection.svg rename to libraries/path-bool/visual-tests/simple-05/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-05/original.svg b/libraries/path-bool/visual-tests/simple-05/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-05/original.svg rename to libraries/path-bool/visual-tests/simple-05/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-05/union.svg b/libraries/path-bool/visual-tests/simple-05/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-05/union.svg rename to libraries/path-bool/visual-tests/simple-05/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-06/difference.svg b/libraries/path-bool/visual-tests/simple-06/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-06/difference.svg rename to libraries/path-bool/visual-tests/simple-06/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-06/division.svg b/libraries/path-bool/visual-tests/simple-06/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-06/division.svg rename to libraries/path-bool/visual-tests/simple-06/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-06/exclusion.svg b/libraries/path-bool/visual-tests/simple-06/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-06/exclusion.svg rename to libraries/path-bool/visual-tests/simple-06/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-06/fracture.svg b/libraries/path-bool/visual-tests/simple-06/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-06/fracture.svg rename to libraries/path-bool/visual-tests/simple-06/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-06/intersection.svg b/libraries/path-bool/visual-tests/simple-06/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-06/intersection.svg rename to libraries/path-bool/visual-tests/simple-06/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-06/original.svg b/libraries/path-bool/visual-tests/simple-06/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-06/original.svg rename to libraries/path-bool/visual-tests/simple-06/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-06/union.svg b/libraries/path-bool/visual-tests/simple-06/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-06/union.svg rename to libraries/path-bool/visual-tests/simple-06/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-07/difference.svg b/libraries/path-bool/visual-tests/simple-07/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-07/difference.svg rename to libraries/path-bool/visual-tests/simple-07/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-07/division.svg b/libraries/path-bool/visual-tests/simple-07/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-07/division.svg rename to libraries/path-bool/visual-tests/simple-07/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-07/exclusion.svg b/libraries/path-bool/visual-tests/simple-07/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-07/exclusion.svg rename to libraries/path-bool/visual-tests/simple-07/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-07/fracture.svg b/libraries/path-bool/visual-tests/simple-07/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-07/fracture.svg rename to libraries/path-bool/visual-tests/simple-07/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-07/intersection.svg b/libraries/path-bool/visual-tests/simple-07/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-07/intersection.svg rename to libraries/path-bool/visual-tests/simple-07/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-07/original.svg b/libraries/path-bool/visual-tests/simple-07/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-07/original.svg rename to libraries/path-bool/visual-tests/simple-07/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-07/union.svg b/libraries/path-bool/visual-tests/simple-07/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-07/union.svg rename to libraries/path-bool/visual-tests/simple-07/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-08/difference.svg b/libraries/path-bool/visual-tests/simple-08/difference.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-08/difference.svg rename to libraries/path-bool/visual-tests/simple-08/difference.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-08/division.svg b/libraries/path-bool/visual-tests/simple-08/division.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-08/division.svg rename to libraries/path-bool/visual-tests/simple-08/division.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-08/exclusion.svg b/libraries/path-bool/visual-tests/simple-08/exclusion.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-08/exclusion.svg rename to libraries/path-bool/visual-tests/simple-08/exclusion.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-08/fracture.svg b/libraries/path-bool/visual-tests/simple-08/fracture.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-08/fracture.svg rename to libraries/path-bool/visual-tests/simple-08/fracture.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-08/intersection.svg b/libraries/path-bool/visual-tests/simple-08/intersection.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-08/intersection.svg rename to libraries/path-bool/visual-tests/simple-08/intersection.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-08/original.svg b/libraries/path-bool/visual-tests/simple-08/original.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-08/original.svg rename to libraries/path-bool/visual-tests/simple-08/original.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/simple-08/union.svg b/libraries/path-bool/visual-tests/simple-08/union.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/simple-08/union.svg rename to libraries/path-bool/visual-tests/simple-08/union.svg diff --git a/libraries/path-bool/__fixtures__/visual-tests/template.svg b/libraries/path-bool/visual-tests/template.svg similarity index 100% rename from libraries/path-bool/__fixtures__/visual-tests/template.svg rename to libraries/path-bool/visual-tests/template.svg diff --git a/node-graph/compilation-client/src/main.rs b/node-graph/compilation-client/src/main.rs index 36121e15d..7d1dc662a 100644 --- a/node-graph/compilation-client/src/main.rs +++ b/node-graph/compilation-client/src/main.rs @@ -49,7 +49,7 @@ fn add_network() -> NodeNetwork { if _global_index.x < i2[2] {{ i0[_global_index.x as usize] }} else {{ - Color::from_rgbaf32_unchecked(0.0, 0.0, 0.0, 0.0) + Color::from_rgbaf32_unchecked(0., 0., 0., 0.) }}, ))"#, TaggedValue::BlendMode(BlendMode::Normal).to_primitive_string(), diff --git a/node-graph/gcore/src/raster/color.rs b/node-graph/gcore/src/raster/color.rs index 66943edb8..336ce114d 100644 --- a/node-graph/gcore/src/raster/color.rs +++ b/node-graph/gcore/src/raster/color.rs @@ -355,7 +355,7 @@ impl Color { /// let color = Color::from_rgbaf32(0.3, 0.14, 0.15, 0.92).unwrap(); /// assert!(color.components() == (0.3, 0.14, 0.15, 0.92)); /// - /// let color = Color::from_rgbaf32(1.0, 1.0, 1.0, f32::NAN); + /// let color = Color::from_rgbaf32(1., 1., 1., f32::NAN); /// assert!(color == None); /// ``` #[inline(always)] diff --git a/node-graph/gcore/src/raster/discrete_srgb.rs b/node-graph/gcore/src/raster/discrete_srgb.rs index f7ee28b2c..108608a4b 100644 --- a/node-graph/gcore/src/raster/discrete_srgb.rs +++ b/node-graph/gcore/src/raster/discrete_srgb.rs @@ -56,16 +56,16 @@ const FLOAT_SRGB_LERP: [u32; 27] = [ #[inline] pub fn float_to_srgb_u8(mut f: f32) -> u8 { // Clamp f to [0, 1], with a negated condition to handle NaNs as 0. - if !(f >= 0.0) { - f = 0.0; - } else if f > 1.0 { - f = 1.0; + if !(f >= 0.) { + f = 0.; + } else if f > 1. { + f = 1.; } // Shift away slightly from 0.0 to reduce exponent range. const C: f32 = 0.009842521f32; let u = (f + C).to_bits() - C.to_bits(); - if u > (1.0 + C).to_bits() - C.to_bits() { + if u > (1. + C).to_bits() - C.to_bits() { // We clamped f to [0, 1], and the integer representations // of the positive finite non-NaN floats are monotonic. // This makes the later LUT lookup panicless. @@ -144,7 +144,7 @@ mod tests { } else if f <= 0.0031308f32 { 12.92_f32 * f } else if f < 1_f32 { - 1.055f32 * f.powf(1.0_f32 / 2.4_f32) - 0.055f32 + 1.055f32 * f.powf(1_f32 / 2.4_f32) - 0.055f32 } else { 1_f32 } @@ -164,7 +164,7 @@ mod tests { } fn srgb_u8_to_float_ref(c: u8) -> f32 { - srgb_to_float_ref(c as f32 * (1_f32 / 255.0_f32)) + srgb_to_float_ref(c as f32 * (1_f32 / 255_f32)) } #[test] diff --git a/node-graph/gstd/src/brush.rs b/node-graph/gstd/src/brush.rs index 7af640348..2c31183fb 100644 --- a/node-graph/gstd/src/brush.rs +++ b/node-graph/gstd/src/brush.rs @@ -239,7 +239,7 @@ fn brush(_footprint: Footprint, image: ImageFrame, bounds: ImageFrame, bounds: ImageFrame, background: Image let fg_point = (*i4) * bg_point + (*i5); if !((fg_point.cmpge(Vec2::ZERO) & bg_point.cmpge(Vec2::ZERO)) == BVec2::new(true, true)) {{ - Color::from_rgbaf32_unchecked(0.0, 0.0, 0.0, 0.0) + Color::from_rgbaf32_unchecked(0., 0., 0., 0.) }} else {{ i2[((fg_point.y as u32) * i3 + (fg_point.x as u32)) as usize] }} diff --git a/node-graph/gstd/src/image_color_palette.rs b/node-graph/gstd/src/image_color_palette.rs index da78668e6..851b6efcd 100644 --- a/node-graph/gstd/src/image_color_palette.rs +++ b/node-graph/gstd/src/image_color_palette.rs @@ -22,8 +22,8 @@ async fn image_color_palette( let bins = GRID * GRID * GRID; - let mut histogram: Vec = vec![0; (bins + 1.0) as usize]; - let mut colors: Vec> = vec![vec![]; (bins + 1.0) as usize]; + let mut histogram: Vec = vec![0; (bins + 1.) as usize]; + let mut colors: Vec> = vec![vec![]; (bins + 1.) as usize]; let image = image.eval(footprint).await; for pixel in image.image.data.iter() { @@ -44,10 +44,10 @@ async fn image_color_palette( for i in shorted.iter().take(max_size as usize) { let list = colors[*i].clone(); - let mut r = 0.0; - let mut g = 0.0; - let mut b = 0.0; - let mut a = 0.0; + let mut r = 0.; + let mut g = 0.; + let mut b = 0.; + let mut a = 0.; for color in list.iter() { r += color.r(); @@ -86,7 +86,7 @@ mod test { image: Image { width: 100, height: 100, - data: vec![Color::from_rgbaf32(0.0, 0.0, 0.0, 1.0).unwrap(); 10000], + data: vec![Color::from_rgbaf32(0., 0., 0., 1.).unwrap(); 10000], base64_string: None, }, ..Default::default() @@ -94,6 +94,6 @@ mod test { }) }), }; - assert_eq!(futures::executor::block_on(node.eval(())), [Color::from_rgbaf32(0.0, 0.0, 0.0, 1.0).unwrap()]); + assert_eq!(futures::executor::block_on(node.eval(())), [Color::from_rgbaf32(0., 0., 0., 1.).unwrap()]); } } diff --git a/node-graph/gstd/src/imaginate.rs b/node-graph/gstd/src/imaginate.rs index e4dafb1b9..ec649552f 100644 --- a/node-graph/gstd/src/imaginate.rs +++ b/node-graph/gstd/src/imaginate.rs @@ -517,10 +517,10 @@ pub fn pick_safe_imaginate_resolution((width, height): (f64, f64)) -> (u64, u64) let scale = (MAX_RESOLUTION as f64 / resolution as f64).sqrt(); let size = size.as_dvec2() * scale; - if size.x < 64.0 { + if size.x < 64. { // The image is extremely wide (64, MAX_DIMENSION) - } else if size.y < 64.0 { + } else if size.y < 64. { // The image is extremely high (MAX_DIMENSION, 64) } else { diff --git a/node-graph/gstd/src/raster.rs b/node-graph/gstd/src/raster.rs index 5787dd666..3eb78a222 100644 --- a/node-graph/gstd/src/raster.rs +++ b/node-graph/gstd/src/raster.rs @@ -309,7 +309,7 @@ fn extend_image_to_bounds(image: ImageFrame, bounds: DAffine2) -> ImageFr // Compute new transform. // let layer_to_new_texture_space = (DAffine2::from_scale(1. / new_scale) * DAffine2::from_translation(new_start) * layer_to_image_space).inverse(); - let new_texture_to_layer_space = image.transform * DAffine2::from_scale(1.0 / orig_image_scale) * DAffine2::from_translation(new_start) * DAffine2::from_scale(new_scale); + let new_texture_to_layer_space = image.transform * DAffine2::from_scale(1. / orig_image_scale) * DAffine2::from_translation(new_start) * DAffine2::from_scale(new_scale); ImageFrame { image: new_img, transform: new_texture_to_layer_space, @@ -641,10 +641,10 @@ fn mandelbrot(footprint: Footprint) -> ImageFrame { #[inline(always)] fn mandelbrot_impl(c: Vec2, max_iter: usize) -> usize { - let mut z = Vec2::new(0.0, 0.0); + let mut z = Vec2::new(0., 0.); for i in 0..max_iter { - z = Vec2::new(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c; - if z.length_squared() > 4.0 { + z = Vec2::new(z.x * z.x - z.y * z.y, 2. * z.x * z.y) + c; + if z.length_squared() > 4. { return i; } } diff --git a/node-graph/gstd/src/wasm_application_io.rs b/node-graph/gstd/src/wasm_application_io.rs index caebb8b82..20ea989fe 100644 --- a/node-graph/gstd/src/wasm_application_io.rs +++ b/node-graph/gstd/src/wasm_application_io.rs @@ -45,7 +45,7 @@ async fn draw_image_frame(_: (), image: ImageFrame().unwrap(); let image_data = web_sys::ImageData::new_with_u8_clamped_array_and_sh(array, image.image.width, image.image.height).expect("Failed to construct ImageData"); - context.put_image_data(&image_data, 0.0, 0.0).unwrap(); + context.put_image_data(&image_data, 0., 0.).unwrap(); } graphene_core::application_io::SurfaceHandleFrame { surface_handle, diff --git a/node-graph/wgpu-executor/src/lib.rs b/node-graph/wgpu-executor/src/lib.rs index dcb9f2edb..bef0535b2 100644 --- a/node-graph/wgpu-executor/src/lib.rs +++ b/node-graph/wgpu-executor/src/lib.rs @@ -86,19 +86,19 @@ impl Vertex { const VERTICES: &[Vertex] = &[ Vertex { - position: [-1., 1., 0.0], + position: [-1., 1., 0.], tex_coords: [0., 0.], }, // A Vertex { - position: [-1., -1., 0.0], + position: [-1., -1., 0.], tex_coords: [0., 1.], }, // B Vertex { - position: [1., 1., 0.0], + position: [1., 1., 0.], tex_coords: [1., 0.], }, // C Vertex { - position: [1., -1., 0.0], + position: [1., -1., 0.], tex_coords: [1., 1.], }, // D ];