pub struct StlImporter;Expand description
Imports STL files (binary or ASCII) into 3MF Model structures.
The importer supports both binary and ASCII STL formats:
read(): Auto-detects the format using the file size formula, then dispatches to the appropriate parser. RequiresRead + Seek.read_binary(): Explicit binary-format parser. Requires onlyRead.read_ascii(): Explicit ASCII-format parser. Requires onlyRead.
Vertices are deduplicated using bitwise float comparison during import.
Implementations§
Source§impl StlImporter
impl StlImporter
Sourcepub fn read<R: Read + Seek>(reader: R) -> Result<Model>
pub fn read<R: Read + Seek>(reader: R) -> Result<Model>
Reads an STL file, auto-detecting binary vs ASCII format.
Uses the file size formula to distinguish binary files (even those whose headers begin with “solid”) from ASCII files.
§Arguments
§Returns
A Model containing the parsed geometry. Binary STL produces a single object;
ASCII STL produces one object per solid.
§Errors
Returns Lib3mfError::Io if reading or seeking fails.
Returns [Lib3mfError::Validation] or [Lib3mfError::InvalidStructure] if parsing fails.
Sourcepub fn read_binary<R: Read>(reader: R) -> Result<Model>
pub fn read_binary<R: Read>(reader: R) -> Result<Model>
Reads a binary STL file and converts it to a 3MF Model.
§Arguments
reader- Any type implementingReadcontaining binary STL data
§Returns
A Model containing:
- Single mesh object with ResourceId(1) named “STL Import”
- All triangles from the STL file
- Deduplicated vertices (using bitwise float comparison)
- Single build item referencing the mesh object
§Errors
Returns Lib3mfError::Io if:
- Cannot read 80-byte header
- Cannot read triangle count
- Cannot read triangle data (normals, vertices, attribute bytes)
Returns Lib3mfError::Validation if triangle count field cannot be parsed.
§Format Details
- Vertex deduplication: Uses HashMap with bitwise float comparison
[x.to_bits(), y.to_bits(), z.to_bits()]as key. Only exactly identical vertices (bitwise) are merged. - Normal vectors: Read from STL but ignored (not stored in Model).
- Attribute bytes: Read but ignored (2-byte field after each triangle).
§Examples
use lib3mf_converters::stl::StlImporter;
use std::fs::File;
let file = File::open("cube.stl")?;
let model = StlImporter::read_binary(file)?;
// Access the imported mesh
let obj = model.resources.get_object(lib3mf_core::model::resources::ResourceId(1))
.expect("STL import creates object with ID 1");
if let lib3mf_core::model::Geometry::Mesh(mesh) = &obj.geometry {
println!("Imported {} vertices, {} triangles",
mesh.vertices.len(), mesh.triangles.len());
}Sourcepub fn read_ascii<R: Read>(reader: R) -> Result<Model>
pub fn read_ascii<R: Read>(reader: R) -> Result<Model>
Reads an ASCII STL file and converts it to a 3MF Model.
Parses one or more solid ... endsolid blocks. Each solid becomes a separate
Object with its own ResourceId and BuildItem.
§Arguments
reader- Any type implementingReadcontaining ASCII STL text
§Returns
A Model containing:
- One mesh object per solid, with ResourceIds starting at 1
- Object names taken from the solid name (if any)
- Deduplicated vertices per solid (using bitwise float comparison)
- One build item per solid with identity transform
§Errors
Returns [Lib3mfError::Io] if reading fails.
Returns [Lib3mfError::InvalidStructure] if vertex coordinates cannot be parsed.
§Behavior
- Keywords are matched case-insensitively (
SOLID,Facet,VERTEX, etc.) - Solid names with spaces are supported (
solid My Cool Part) endsolidname is not validated (may differ fromsolidname or be absent)- Files that end without
endsolidare handled leniently - Normal vectors from
facet normallines are read and discarded
Trait Implementations§
Auto Trait Implementations§
impl Freeze for StlImporter
impl RefUnwindSafe for StlImporter
impl Send for StlImporter
impl Sync for StlImporter
impl Unpin for StlImporter
impl UnwindSafe for StlImporter
Blanket Implementations§
§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more