Handle tesselation error and switch to u32 index format

This commit is contained in:
Maximilian Ammann 2022-03-15 21:07:02 +01:00
parent 62e818f9ab
commit 1b4eada46c
5 changed files with 54 additions and 38 deletions

View File

@ -1,7 +1,16 @@
//! Errors which can happen in various parts of the library.
use lyon::tessellation::TessellationError;
#[derive(Debug)]
pub enum Error {
Network(String),
File(String),
Tesselation(TessellationError),
}
impl From<TessellationError> for Error {
fn from(e: TessellationError) -> Self {
Error::Tesselation(e)
}
}

View File

@ -1,6 +1,6 @@
use std::collections::{HashMap, HashSet};
use log::info;
use log::{error, info};
use std::sync::mpsc::{channel, Receiver, SendError, Sender};
use std::sync::{Arc, Mutex};
@ -110,22 +110,30 @@ impl ThreadLocalTessellatorState {
.iter()
.find(|layer| to_load.as_str() == layer.name())
{
if let Some((buffer, feature_indices)) = layer.tessellate() {
self.layer_result_sender.send(TileTessellateResult::Layer(
LayerResult::TessellatedLayer {
coords,
buffer: buffer.into(),
feature_indices,
layer_data: layer.clone(),
},
))?;
} else {
self.layer_result_sender.send(TileTessellateResult::Layer(
LayerResult::UnavailableLayer {
coords,
layer_name: to_load.to_string(),
},
))?;
match layer.tessellate() {
Ok((buffer, feature_indices)) => {
self.layer_result_sender.send(TileTessellateResult::Layer(
LayerResult::TessellatedLayer {
coords,
buffer: buffer.into(),
feature_indices,
layer_data: layer.clone(),
},
))?;
}
Err(e) => {
self.layer_result_sender.send(TileTessellateResult::Layer(
LayerResult::UnavailableLayer {
coords,
layer_name: to_load.to_string(),
},
))?;
error!(
"tesselation for layer {} failed: {} {:?}",
to_load, &coords, e
);
}
}
info!("layer {} ready: {}", to_load, &coords);

View File

@ -2,7 +2,7 @@ use wgpu::BufferAddress;
pub const DEBUG_WIREFRAME: bool = false;
pub const DEBUG_STENCIL_PATTERN: bool = false;
pub const INDEX_FORMAT: wgpu::IndexFormat = wgpu::IndexFormat::Uint16; // Must match IndexDataType
pub const INDEX_FORMAT: wgpu::IndexFormat = wgpu::IndexFormat::Uint32; // Must match IndexDataType
pub const VERTEX_BUFFER_SIZE: BufferAddress = 1024 * 1024 * 32;
pub const FEATURE_METADATA_BUFFER_SIZE: BufferAddress = 1024 * 1024 * 32;

View File

@ -11,6 +11,7 @@ use lyon::tessellation::{
use lyon_path::traits::SvgPathBuilder;
use lyon_path::{FillRule, Path};
use crate::error::Error;
use vector_tile::geometry::{Command, Geometry};
use vector_tile::tile::Layer;
@ -18,7 +19,7 @@ use crate::render::ShaderVertex;
use crate::tessellation::{Tessellated, VertexConstructor, DEFAULT_TOLERANCE};
impl<I: Add + From<lyon::lyon_tessellation::VertexId> + MaxIndex + Pod> Tessellated<I> for Layer {
fn tessellate(&self) -> Option<(VertexBuffers<ShaderVertex, I>, Vec<u32>)> {
fn tessellate(&self) -> Result<(VertexBuffers<ShaderVertex, I>, Vec<u32>), Error> {
let mut buffer: VertexBuffers<ShaderVertex, I> = VertexBuffers::new();
let mut feature_indices: Vec<u32> = Vec::new();
let mut current_index = 0;
@ -47,14 +48,12 @@ impl<I: Add + From<lyon::lyon_tessellation::VertexId> + MaxIndex + Pod> Tessella
}
let mut fill_tessellator = FillTessellator::new();
fill_tessellator
.tessellate_path(
&polygon_builder.build(),
&FillOptions::tolerance(DEFAULT_TOLERANCE)
.with_fill_rule(FillRule::NonZero),
&mut BuffersBuilder::new(&mut buffer, VertexConstructor {}),
)
.ok()?;
fill_tessellator.tessellate_path(
&polygon_builder.build(),
&FillOptions::tolerance(DEFAULT_TOLERANCE)
.with_fill_rule(FillRule::NonZero),
&mut BuffersBuilder::new(&mut buffer, VertexConstructor {}),
)?;
}
Geometry::GeometryLineString(line_string) => {
let mut line_string_builder = Path::builder();
@ -89,13 +88,11 @@ impl<I: Add + From<lyon::lyon_tessellation::VertexId> + MaxIndex + Pod> Tessella
let mut stroke_tessellator = StrokeTessellator::new();
stroke_tessellator
.tessellate_path(
&line_string_builder.build(),
&StrokeOptions::tolerance(DEFAULT_TOLERANCE),
&mut BuffersBuilder::new(&mut buffer, VertexConstructor {}),
)
.ok()?;
stroke_tessellator.tessellate_path(
&line_string_builder.build(),
&StrokeOptions::tolerance(DEFAULT_TOLERANCE),
&mut BuffersBuilder::new(&mut buffer, VertexConstructor {}),
)?;
}
_ => {}
};
@ -106,6 +103,6 @@ impl<I: Add + From<lyon::lyon_tessellation::VertexId> + MaxIndex + Pod> Tessella
current_index = next_index;
}
Some((buffer, feature_indices))
Ok((buffer, feature_indices))
}
}

View File

@ -5,22 +5,24 @@ use std::ops::Add;
use crate::render::ShaderVertex;
use lyon::tessellation::{
FillVertex, FillVertexConstructor, StrokeVertex, StrokeVertexConstructor, VertexBuffers,
FillVertex, FillVertexConstructor, StrokeVertex, StrokeVertexConstructor, TessellationError,
VertexBuffers,
};
use crate::error::Error;
use wgpu::BufferAddress;
mod layer;
const DEFAULT_TOLERANCE: f32 = 0.02;
pub type IndexDataType = u16; // Must match INDEX_FORMAT
pub type IndexDataType = u32; // Must match INDEX_FORMAT
pub trait Tessellated<I: Add> {
/// Returns a vertex buffer which represents some object like a layer. Each object can contain
/// multiple features. For each feature also the amount of indices is returned.
///
fn tessellate(&self) -> Option<(VertexBuffers<ShaderVertex, I>, Vec<u32>)>;
fn tessellate(&self) -> Result<(VertexBuffers<ShaderVertex, I>, Vec<u32>), Error>;
}
pub struct VertexConstructor {}