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}