rapier3d_stl/lib.rs
1//! **This crate is deprecated. Use [`rapier3d-meshloader`](https://crates.io/crates/rapier3d-meshloader) instead which
2//! supports STL as well as other formats.**
3
4#![warn(missing_docs)]
5
6use rapier3d::geometry::{MeshConverter, MeshConverterError, SharedShape};
7use rapier3d::math::{Isometry, Point, Real, Vector};
8use std::fs::File;
9use std::io::{BufReader, Read, Seek};
10use std::path::Path;
11use stl_io::IndexedMesh;
12
13/// Error while loading an STL file.
14#[derive(thiserror::Error, Debug)]
15pub enum StlLoaderError {
16 /// An error triggered by rapier’s [`MeshConverter`].
17 #[error(transparent)]
18 MeshConverter(#[from] MeshConverterError),
19 /// A generic IO error.
20 #[error(transparent)]
21 Io(#[from] std::io::Error),
22}
23
24/// The result of loading a shape from an stl mesh.
25pub struct StlShape {
26 /// The shape loaded from the file and converted by the [`MeshConverter`].
27 pub shape: SharedShape,
28 /// The shape’s pose.
29 pub pose: Isometry<Real>,
30 /// The raw mesh read from the stl file without any modification.
31 pub raw_mesh: IndexedMesh,
32}
33
34/// Loads an STL file as a shape from a file.
35///
36/// # Parameters
37/// - `file_path`: the STL file’s path.
38/// - `converter`: controls how the shape is computed from the STL content. In particular, it lets
39/// you specify if the computed [`StlShape::shape`] is a triangle mesh, its convex hull,
40/// bounding box, etc.
41/// - `scale`: the scaling factor applied to the geometry input to the `converter`. This scale will
42/// affect at the geometric level the [`StlShape::shape`]. Note that raw mesh value stored
43/// in [`StlShape::raw_mesh`] remains unscaled.
44pub fn load_from_path(
45 file_path: impl AsRef<Path>,
46 converter: MeshConverter,
47 scale: Vector<Real>,
48) -> Result<StlShape, StlLoaderError> {
49 let mut reader = BufReader::new(File::open(file_path)?);
50 load_from_reader(&mut reader, converter, scale)
51}
52
53/// Loads an STL file as a shape from an arbitrary reader.
54///
55/// # Parameters
56/// - `reader`: the reader.
57/// - `converter`: controls how the shape is computed from the STL content. In particular, it lets
58/// you specify if the computed [`StlShape::shape`] is a triangle mesh, its convex hull,
59/// bounding box, etc.
60/// - `scale`: the scaling factor applied to the geometry input to the `converter`. This scale will
61/// affect at the geometric level the [`StlShape::shape`]. Note that raw mesh value stored
62/// in [`StlShape::raw_mesh`] remains unscaled.
63pub fn load_from_reader<R: Read + Seek>(
64 read: &mut R,
65 converter: MeshConverter,
66 scale: Vector<Real>,
67) -> Result<StlShape, StlLoaderError> {
68 let stl_mesh = stl_io::read_stl(read)?;
69 Ok(load_from_raw_mesh(stl_mesh, converter, scale)?)
70}
71
72/// Loads an STL file as a shape from a preloaded raw stl mesh.
73///
74/// # Parameters
75/// - `raw_mesh`: the raw stl mesh.
76/// - `converter`: controls how the shape is computed from the STL content. In particular, it lets
77/// you specify if the computed [`StlShape::shape`] is a triangle mesh, its convex hull,
78/// bounding box, etc.
79/// - `scale`: the scaling factor applied to the geometry input to the `converter`. This scale will
80/// affect at the geometric level the [`StlShape::shape`]. Note that raw mesh value stored
81/// in [`StlShape::raw_mesh`] remains unscaled.
82pub fn load_from_raw_mesh(
83 raw_mesh: IndexedMesh,
84 converter: MeshConverter,
85 scale: Vector<Real>,
86) -> Result<StlShape, MeshConverterError> {
87 let mut vertices: Vec<_> = raw_mesh
88 .vertices
89 .iter()
90 .map(|xyz| Point::new(xyz[0], xyz[1], xyz[2]))
91 .collect();
92 vertices
93 .iter_mut()
94 .for_each(|pt| pt.coords.component_mul_assign(&scale));
95 let indices: Vec<_> = raw_mesh
96 .faces
97 .iter()
98 .map(|f| f.vertices.map(|i| i as u32))
99 .collect();
100 let (shape, pose) = converter.convert(vertices, indices)?;
101
102 Ok(StlShape {
103 shape,
104 pose,
105 raw_mesh,
106 })
107}