-
-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support STL #594
Support STL #594
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,16 +14,35 @@ | |
|
||
#![deny(missing_docs)] | ||
|
||
use std::path::Path; | ||
use std::{fs::File, path::Path}; | ||
|
||
use anyhow::{anyhow, Result}; | ||
|
||
use fj_interop::mesh::Mesh; | ||
use fj_math::Point; | ||
use fj_math::{Point, Triangle, Vector}; | ||
|
||
/// Export the provided mesh to the file at the given path | ||
/// Export the provided mesh to the file at the given path. | ||
/// | ||
/// This function will create a file if it does not exist, and will truncate it if it does. | ||
/// | ||
/// Currently only 3MF is supported as an export format. The file extension of | ||
/// the provided path is ignored. | ||
pub fn export(mesh: &Mesh<Point<3>>, path: &Path) -> Result<(), Error> { | ||
/// Currently 3MF & STL file types are supported. The case insensitive file extension of | ||
/// the provided path is used to switch between supported types. | ||
pub fn export(mesh: &Mesh<Point<3>>, path: &Path) -> Result<()> { | ||
match path.extension() { | ||
Some(extension) if extension.to_ascii_uppercase() == "3MF" => { | ||
export_3mf(mesh, path) | ||
} | ||
Some(extension) if extension.to_ascii_uppercase() == "STL" => { | ||
export_stl(mesh, path) | ||
} | ||
Some(extension) => { | ||
Err(anyhow!("Extension not recognised, got {:?}", extension)) | ||
} | ||
None => Err(anyhow!("No extension specified")), | ||
} | ||
} | ||
|
||
fn export_3mf(mesh: &Mesh<Point<3>>, path: &Path) -> Result<()> { | ||
let vertices = mesh.vertices().map(|vertex| vertex.into()).collect(); | ||
|
||
let indices: Vec<_> = mesh.indices().collect(); | ||
|
@@ -48,4 +67,46 @@ pub fn export(mesh: &Mesh<Point<3>>, path: &Path) -> Result<(), Error> { | |
Ok(()) | ||
} | ||
|
||
pub use threemf::Error; | ||
fn export_stl(mesh: &Mesh<Point<3>>, path: &Path) -> Result<()> { | ||
let points = mesh | ||
.triangles() | ||
.map(|triangle| triangle.points) | ||
.collect::<Vec<_>>(); | ||
|
||
let vertices = points.iter().map(|points| { | ||
points.map(|point| { | ||
stl_io::Vertex::new([ | ||
point.x.into_f32(), | ||
point.y.into_f32(), | ||
point.z.into_f32(), | ||
]) | ||
}) | ||
}); | ||
|
||
let normals = mesh | ||
.triangles() | ||
.map(|triangle| triangle.points.into()) | ||
.map(|triangle: Triangle<3>| triangle.to_parry().normal()) | ||
.collect::<Option<Vec<_>>>() | ||
.ok_or_else(|| anyhow!("Unable to compute normal"))?; | ||
Comment on lines
+85
to
+87
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since Neither of those need to happen in this pull request though. |
||
|
||
let normals = normals.iter().map(|vector| vector.into_inner().into()).map( | ||
|vector: Vector<3>| { | ||
stl_io::Normal::new([ | ||
vector.x.into_f32(), | ||
vector.y.into_f32(), | ||
vector.z.into_f32(), | ||
]) | ||
}, | ||
); | ||
|
||
let mesh = vertices | ||
.zip(normals) | ||
.map(|(vertices, normal)| stl_io::Triangle { normal, vertices }); | ||
|
||
let mut file = File::create(path)?; | ||
|
||
stl_io::write_stl(&mut file, mesh).unwrap(); | ||
|
||
Ok(()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since
fj-export
is a library,thiserror
would be a more appropriate choice here for error handling. Doesn't really matter though. Good enough for now!