diff --git a/libraries/bezier-rs/src/subpath/transform.rs b/libraries/bezier-rs/src/subpath/transform.rs index af8ac903..d6a2b86e 100644 --- a/libraries/bezier-rs/src/subpath/transform.rs +++ b/libraries/bezier-rs/src/subpath/transform.rs @@ -368,7 +368,12 @@ impl Subpath { return self.clone(); } - let mut subpaths = self.iter().filter(|bezier| !bezier.is_point()).map(|bezier| bezier.offset(distance)).collect::>>(); + let mut subpaths = self + .iter() + .filter(|bezier| !bezier.is_point()) + .map(|bezier| bezier.offset(distance)) + .filter(|subpath| subpath.len() >= 2) // In some cases the reduced and scaled bézier is marked by is_point (so the subpath is empty). + .collect::>>(); let mut drop_common_point = vec![true; self.len()]; // Clip or join consecutive Subpaths @@ -636,6 +641,37 @@ mod tests { assert!(outline.closed()); } + #[test] + /// Even though the bézier here is not marked as a point, the offset and scaled version is. + fn outline_with_point_offset() { + let subpath = Subpath::new( + vec![ + ManipulatorGroup { + anchor: DVec2::new(1122.6253015182049, 610.9441551227939), + out_handle: Some(DVec2::new(1122.6253015182049, 610.9445412168651)), + in_handle: None, + id: EmptyId, + }, + ManipulatorGroup { + anchor: DVec2::new(1122.6258671405062, 610.9453107605276), + out_handle: None, + in_handle: Some(DVec2::new(1122.6254904904154, 610.9449255479497)), + id: EmptyId, + }, + ManipulatorGroup { + anchor: DVec2::new(0., 0.), + out_handle: None, + in_handle: None, + id: EmptyId, + }, + ], + false, + ); + let outline = subpath.outline(4.4, crate::Join::Round, crate::Cap::Round).0; + assert!(outline.manipulator_groups.windows(2).all(|pair| !pair[0].anchor.abs_diff_eq(pair[1].anchor, MAX_ABSOLUTE_DIFFERENCE))); + assert!(outline.closed()); + } + #[test] fn split_an_open_subpath() { let subpath = set_up_open_subpath(); diff --git a/node-graph/wgpu-executor/src/executor.rs b/node-graph/wgpu-executor/src/executor.rs index 970685d4..f0f3b48a 100644 --- a/node-graph/wgpu-executor/src/executor.rs +++ b/node-graph/wgpu-executor/src/executor.rs @@ -164,14 +164,12 @@ async fn execute_shader(device: Arc< // Since contents are got in bytes, this converts these bytes back to u32 let result = bytemuck::cast_slice(&data).to_vec(); - // With the current interface, we have to make sure all mapped views are - // dropped before we unmap the buffer. + // With the current interface, we have to make sure all mapped views are dropped before we unmap the buffer drop(data); - staging_buffer.unmap(); // Unmaps buffer from memory - // If you are familiar with C++ these 2 lines can be thought of similarly to: - // delete myPointer; - // myPointer = NULL; - // It effectively frees the memory + // Unmaps buffer from memory + staging_buffer.unmap(); + // If you are familiar with C++ these 2 lines can be thought of similarly to `delete myPointer; myPointer = NULL;`. + // It effectively frees the memory. // Returns data from buffer Some(result)