diff --git a/Cargo.lock b/Cargo.lock index f9eee72d1a2c..06b333cf8c00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2741,7 +2741,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.7.4", + "libloading 0.8.5", ] [[package]] @@ -3338,6 +3338,9 @@ name = "float-cmp" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] [[package]] name = "fnv" @@ -7390,8 +7393,8 @@ dependencies = [ "slotmap", "smallvec", "static_assertions", + "stl_io", "thiserror 1.0.65", - "tinystl", "tobj", "type-map", "unindent", @@ -9457,6 +9460,16 @@ dependencies = [ "rerun", ] +[[package]] +name = "stl_io" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff2e145168af9fef3b518ac0c6f9849c407b3df8a28582ced9f1fda510aa34c" +dependencies = [ + "byteorder", + "float-cmp", +] + [[package]] name = "strict-num" version = "0.1.1" @@ -9829,15 +9842,6 @@ dependencies = [ "log", ] -[[package]] -name = "tinystl" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbcdda2f86a57b89b5d9ac17cd4c9f3917ec8edcde403badf3d992d2947af2a" -dependencies = [ - "bytemuck", -] - [[package]] name = "tinystr" version = "0.7.6" diff --git a/Cargo.toml b/Cargo.toml index 59683a26eaa3..2ea0282e4f03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -296,6 +296,7 @@ similar-asserts = "1.4.2" slotmap = { version = "1.0.6", features = ["serde"] } smallvec = { version = "1.0", features = ["const_generics", "union"] } static_assertions = "1.1" +stl_io = "0.8.5" strum = { version = "0.26", features = ["derive"] } strum_macros = "0.26" sublime_fuzzy = "0.7" @@ -310,7 +311,6 @@ time = { version = "0.3.36", default-features = false, features = [ "wasm-bindgen", ] } tiny_http = { version = "0.12", default-features = false } -tinystl = { version = "0.0.3", default-features = false } tobj = "4.0" tokio = { version = "1.44.2", default-features = false } tokio-stream = "0.1.16" diff --git a/crates/viewer/re_renderer/Cargo.toml b/crates/viewer/re_renderer/Cargo.toml index f219e0dad143..7a231230ce97 100644 --- a/crates/viewer/re_renderer/Cargo.toml +++ b/crates/viewer/re_renderer/Cargo.toml @@ -45,7 +45,7 @@ import-obj = ["dep:tobj"] import-gltf = ["dep:gltf"] ## Support importing binary & ascii .stl files -import-stl = ["dep:tinystl"] +import-stl = ["dep:stl_io"] ## Enable (de)serialization using serde. serde = ["dep:serde"] @@ -85,7 +85,7 @@ wgpu.workspace = true # optional gltf = { workspace = true, optional = true } -tinystl = { workspace = true, features = ["bytemuck"], optional = true } +stl_io = { workspace = true, optional = true } serde = { workspace = true, features = ["derive"], optional = true } tobj = { workspace = true, optional = true } diff --git a/crates/viewer/re_renderer/src/importer/stl.rs b/crates/viewer/re_renderer/src/importer/stl.rs index 935e4459d60b..cb82c5cb63ef 100644 --- a/crates/viewer/re_renderer/src/importer/stl.rs +++ b/crates/viewer/re_renderer/src/importer/stl.rs @@ -1,13 +1,12 @@ use itertools::Itertools as _; use smallvec::smallvec; -use tinystl::StlData; -use crate::{CpuModel, RenderContext, mesh}; +use crate::{CpuModel, DebugLabel, RenderContext, mesh}; #[derive(thiserror::Error, Debug)] pub enum StlImportError { #[error("Error loading STL mesh: {0}")] - TinyStl(tinystl::Error), + StlIoError(std::io::Error), #[error(transparent)] MeshError(#[from] mesh::MeshError), @@ -20,40 +19,49 @@ pub fn load_stl_from_buffer( ) -> Result { re_tracing::profile_function!(); - let cursor = std::io::Cursor::new(buffer); - let StlData { - name, - triangles, - normals, - .. - } = StlData::read_buffer(std::io::BufReader::new(cursor)).map_err(StlImportError::TinyStl)?; + let mut cursor = std::io::Cursor::new(buffer); + let reader = stl_io::create_stl_reader(&mut cursor).map_err(StlImportError::StlIoError)?; + + // TODO(hmeyer/stl_io#26): use optional name from ascii stl files. + // https://github.com/hmeyer/stl_io/pull/26 + let name = DebugLabel::from(""); + + let (normals, triangles): (Vec<_>, Vec<_>) = reader + .into_iter() + .map(|triangle| triangle.unwrap()) + .map(|triangle| { + ( + [triangle.normal.0, triangle.normal.0, triangle.normal.0], + [ + triangle.vertices[0].0, + triangle.vertices[1].0, + triangle.vertices[2].0, + ], + ) + }) + .unzip(); let num_vertices = triangles.len() * 3; let material = mesh::Material { - label: name.clone().into(), + label: name.clone(), index_range: 0..num_vertices as u32, albedo: ctx.texture_manager_2d.white_texture_unorm_handle().clone(), albedo_factor: crate::Rgba::WHITE, }; let mesh = mesh::CpuMesh { - label: name.into(), + label: name.clone(), triangle_indices: (0..num_vertices as u32) .tuples::<(_, _, _)>() .map(glam::UVec3::from) .collect::>(), - vertex_positions: bytemuck::cast_slice(&triangles).to_vec(), + + vertex_positions: bytemuck::cast_vec(triangles), // Normals on STL are per triangle, not per vertex. // Yes, this makes STL always look faceted. - vertex_normals: normals - .into_iter() - .flat_map(|n| { - let n = glam::Vec3::from_array(n); - [n, n, n] - }) - .collect(), + vertex_normals: bytemuck::cast_vec(normals), // STL has neither colors nor texcoords. vertex_colors: vec![crate::Rgba32Unmul::WHITE; num_vertices],