From bce8a7331bb737234461f498e538c6081b4a2656 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Sat, 28 Dec 2019 16:15:54 +0100 Subject: [PATCH] Fix a bug in the wgpu_svg example and a flattening issue with tiny curves. --- examples/wgpu_svg/src/main.rs | 39 ++++++++++++++++++------- tessellation/src/event_queue.rs | 52 +++++++++++++++++---------------- 2 files changed, 56 insertions(+), 35 deletions(-) diff --git a/examples/wgpu_svg/src/main.rs b/examples/wgpu_svg/src/main.rs index 71b85093..0dbf49a6 100644 --- a/examples/wgpu_svg/src/main.rs +++ b/examples/wgpu_svg/src/main.rs @@ -48,6 +48,13 @@ fn main() { .value_name("INPUT") .takes_value(true) .required(true)) + .arg(Arg::with_name("TESS_ONLY") + .help("Perform the tessellation and exit without rendering") + .value_name("TESS_ONLY") + .long("tessellate-only") + .short("t") + .takes_value(false) + .required(false)) .get_matches(); let msaa_samples = if let Some(msaa) = app.value_of("MSAA") { @@ -62,15 +69,13 @@ fn main() { 1 }; - - // Parse and tessellate the geometry let filename = app.value_of("INPUT").unwrap(); let mut fill_tess = FillTessellator::new(); let mut stroke_tess = StrokeTessellator::new(); - let mut mesh: VertexBuffers<_, u16> = VertexBuffers::new(); + let mut mesh: VertexBuffers<_, u32> = VertexBuffers::new(); let opt = usvg::Options::default(); @@ -140,14 +145,17 @@ fn main() { } } + if app.is_present("TESS_ONLY") { + return; + } + println!( "Finished tesselation: {} vertices, {} indices", mesh.vertices.len(), mesh.indices.len() ); - println!("Use arrow keys to pan, pageup and pagedown to zoom."); - + println!("Use arrow keys to pan, pageup and pagedown to zoom."); // Initialize wgpu and send some data to the GPU. @@ -328,7 +336,7 @@ fn main() { write_mask: wgpu::ColorWrite::ALL, }], depth_stencil_state: None, - index_format: wgpu::IndexFormat::Uint16, + index_format: wgpu::IndexFormat::Uint32, vertex_buffers: &[ wgpu::VertexBufferDescriptor { stride: std::mem::size_of::() as u64, @@ -642,18 +650,20 @@ impl<'l> Iterator for PathConvIter<'l> { return self.deferred.take() } - match self.iter.next() { + let next = self.iter.next(); + match next { Some(usvg::PathSegment::MoveTo { x, y }) => { if self.needs_end { let last = self.prev; let first = self.first; self.needs_end = false; - self.deferred = Some(PathEvent::Begin { at: self.prev }); self.prev = point(x, y); + self.deferred = Some(PathEvent::Begin { at: self.prev }); self.first = self.prev; Some(PathEvent::End { last, first, close: false }) } else { - Some(PathEvent::Begin { at: self.prev }) + self.first = point(x, y); + Some(PathEvent::Begin { at: self.first }) } } Some(usvg::PathSegment::LineTo { x, y }) => { @@ -682,7 +692,16 @@ impl<'l> Iterator for PathConvIter<'l> { close: true, }) } - None => None, + None => { + if self.needs_end { + self.needs_end = false; + let last = self.prev; + let first = self.first; + Some(PathEvent::End { last, first, close: false }) + } else { + None + } + } } } } diff --git a/tessellation/src/event_queue.rs b/tessellation/src/event_queue.rs index 68ab1f0a..bcb1c2a7 100644 --- a/tessellation/src/event_queue.rs +++ b/tessellation/src/event_queue.rs @@ -617,6 +617,7 @@ impl EventQueueBuilder { fn end(&mut self, first: Point, first_endpoint_id: EndpointId) { if self.nth == 0 { + self.prev_evt_is_edge = false; return; } @@ -635,7 +636,6 @@ impl EventQueueBuilder { self.prev_evt_is_edge = false; self.prev_endpoint_id = first_endpoint_id; - self.nth = 0; } @@ -785,20 +785,21 @@ impl EventQueueBuilder { from = to; }); - let first = first.unwrap(); - let (second, previous) = if needs_swap { (prev, first) } else { (first, prev) }; + if let Some(first) = first { + let (second, previous) = if needs_swap { (prev, first) } else { (first, prev) }; - if is_first_edge { - self.second = second; - } else if is_after(original.from, self.prev) && is_after(original.from, second) { - // Handle the first vertex we took out of the loop above. - // The missing vertex is always the origin of the edge (before the flip). - self.vertex_event(original.from, self.prev_endpoint_id); - } + if is_first_edge { + self.second = second; + } else if is_after(original.from, self.prev) && is_after(original.from, second) { + // Handle the first vertex we took out of the loop above. + // The missing vertex is always the origin of the edge (before the flip). + self.vertex_event(original.from, self.prev_endpoint_id); + } - self.prev = previous; - self.current = original.to; - self.prev_endpoint_id = to_id; + self.prev = previous; + self.current = original.to; + self.prev_endpoint_id = to_id; + } } fn cubic_bezier_segment( @@ -870,20 +871,21 @@ impl EventQueueBuilder { from = to; }); - let first = first.unwrap(); - let (second, previous) = if needs_swap { (prev, first) } else { (first, prev) }; + if let Some(first) = first { + let (second, previous) = if needs_swap { (prev, first) } else { (first, prev) }; - if is_first_edge { - self.second = second; - } else if is_after(original.from, self.prev) && is_after(original.from, second) { - // Handle the first vertex we took out of the loop above. - // The missing vertex is always the origin of the edge (before the flip). - self.vertex_event(original.from, self.prev_endpoint_id); - } + if is_first_edge { + self.second = second; + } else if is_after(original.from, self.prev) && is_after(original.from, second) { + // Handle the first vertex we took out of the loop above. + // The missing vertex is always the origin of the edge (before the flip). + self.vertex_event(original.from, self.prev_endpoint_id); + } - self.prev = previous; - self.current = original.to; - self.prev_endpoint_id = to_id; + self.prev = previous; + self.current = original.to; + self.prev_endpoint_id = to_id; + } } }