use crate::*;
use super::types::*;
use std::io::Write;
pub fn save_ply_ascii<M, P, W>(write: &mut W, mesh: &M) -> PlyResult<()>
where
M: IsMesh<P, Face3>,
P: IsBuildable3D,
W: Write,
{
let header = "ply\n".to_string()
+ "format ascii 1.0\n"
+ "comment Created by rust-3d\n"
+ "element vertex "
+ &mesh.num_vertices().to_string()
+ "\n"
+ "property float x\n"
+ "property float y\n"
+ "property float z\n"
+ "element face "
+ &mesh.num_faces().to_string()
+ "\n"
+ "property list uchar uint vertex_indices\n"
+ "end_header\n";
write.write_all(header.as_bytes())?;
for i in 0..mesh.num_vertices() {
let vertex = mesh.vertex(VId { val: i }).unwrap(); write.write_all((vertex.to_str() + "\n").as_bytes())?;
}
for i in 0..mesh.num_faces() {
let face = mesh.face_vertex_ids(FId { val: i }).unwrap(); write.write_all(
("3 ".to_string()
+ &face.a.to_string()
+ " "
+ &face.b.to_string()
+ " "
+ &face.c.to_string()
+ "\n")
.as_bytes(),
)?;
}
Ok(())
}
pub fn save_ply_ascii_colored<M, P, W>(write: &mut W, mesh: &M, colors: &Vec<Rgb>) -> PlyResult<()>
where
M: IsMesh<P, Face3>,
P: IsBuildable3D,
W: Write,
{
let n_vertices = mesh.num_vertices();
let n_faces = mesh.num_faces();
if n_vertices != colors.len() {
return Err(PlyError::ColorArrayIncorrectLength);
}
let header = "ply\n".to_string()
+ "format ascii 1.0\n"
+ "comment Created by rust-3d\n"
+ "element vertex "
+ &n_vertices.to_string()
+ "\n"
+ "property float x\n"
+ "property float y\n"
+ "property float z\n"
+ "property uchar red\n"
+ "property uchar green\n"
+ "property uchar blue\n"
+ "element face "
+ &n_faces.to_string()
+ "\n"
+ "property list uchar uint vertex_indices\n"
+ "end_header\n";
write.write_all(header.as_bytes())?;
for i in 0..n_vertices {
let vertex = mesh.vertex(VId { val: i }).unwrap(); let color = &colors[i];
write.write_all(
format!(
"{} {} {} {} {} {}\n",
vertex.x(),
vertex.y(),
vertex.z(),
color.r,
color.g,
color.b
)
.as_bytes(),
)?;
}
for i in 0..n_faces {
let face = mesh.face_vertex_ids(FId { val: i }).unwrap(); write.write_all(
("3 ".to_string()
+ &face.a.to_string()
+ " "
+ &face.b.to_string()
+ " "
+ &face.c.to_string()
+ "\n")
.as_bytes(),
)?;
}
Ok(())
}
pub fn save_ply_binary<M, P, W>(write: &mut W, mesh: &M, precision: &Precision) -> PlyResult<()>
where
M: IsMesh<P, Face3>,
P: IsBuildable3D,
W: Write,
{
let header = match precision {
Precision::P32 => {
"ply\n".to_string()
+ "format binary_big_endian 1.0\n"
+ "comment Created by rust-3d\n"
+ "element vertex "
+ &mesh.num_vertices().to_string()
+ "\n"
+ "property float x\n"
+ "property float y\n"
+ "property float z\n"
+ "element face "
+ &mesh.num_faces().to_string()
+ "\n"
+ "property list uint8 uint32 vertex_indices\n"
+ "end_header\n"
}
Precision::P64 => {
"ply\n".to_string()
+ "format binary_big_endian 1.0\n"
+ "comment Created by rust-3d\n"
+ "element vertex "
+ &mesh.num_vertices().to_string()
+ "\n"
+ "property double x\n"
+ "property double y\n"
+ "property double z\n"
+ "element face "
+ &mesh.num_faces().to_string()
+ "\n"
+ "property list uint8 uint32 vertex_indices\n"
+ "end_header\n"
}
};
write.write_all(header.as_bytes())?;
match precision {
Precision::P32 => {
for i in 0..mesh.num_vertices() {
let vertex = mesh.vertex(VId { val: i }).unwrap(); write.write(&(vertex.x() as f32).to_be_bytes())?;
write.write(&(vertex.y() as f32).to_be_bytes())?;
write.write(&(vertex.z() as f32).to_be_bytes())?;
}
}
Precision::P64 => {
for i in 0..mesh.num_vertices() {
let vertex = mesh.vertex(VId { val: i }).unwrap(); write.write(&(vertex.x()).to_be_bytes())?;
write.write(&(vertex.y()).to_be_bytes())?;
write.write(&(vertex.z()).to_be_bytes())?;
}
}
}
for i in 0..mesh.num_faces() {
let face = mesh.face_vertex_ids(FId { val: i }).unwrap(); write.write(&3u8.to_be_bytes())?;
write.write(&(face.a.val as u32).to_be_bytes())?;
write.write(&(face.b.val as u32).to_be_bytes())?;
write.write(&(face.c.val as u32).to_be_bytes())?;
}
Ok(())
}
pub fn save_ply_binary_colored<M, P, W>(
write: &mut W,
mesh: &M,
precision: &Precision,
colors: &Vec<Rgb>,
) -> PlyResult<()>
where
M: IsMesh<P, Face3>,
P: IsBuildable3D,
W: Write,
{
let n_vertices = mesh.num_vertices();
let n_faces = mesh.num_faces();
if n_vertices != colors.len() {
return Err(PlyError::ColorArrayIncorrectLength);
}
let header = match precision {
Precision::P32 => {
"ply\n".to_string()
+ "format binary_big_endian 1.0\n"
+ "comment Created by rust-3d\n"
+ "element vertex "
+ &n_vertices.to_string()
+ "\n"
+ "property float x\n"
+ "property float y\n"
+ "property float z\n"
+ "property uchar red\n"
+ "property uchar green\n"
+ "property uchar blue\n"
+ "element face "
+ &n_faces.to_string()
+ "\n"
+ "property list uint8 uint32 vertex_indices\n"
+ "end_header\n"
}
Precision::P64 => {
"ply\n".to_string()
+ "format binary_big_endian 1.0\n"
+ "comment Created by rust-3d\n"
+ "element vertex "
+ &n_vertices.to_string()
+ "\n"
+ "property double x\n"
+ "property double y\n"
+ "property double z\n"
+ "property uchar red\n"
+ "property uchar green\n"
+ "property uchar blue\n"
+ "element face "
+ &n_faces.to_string()
+ "\n"
+ "property list uint8 uint32 vertex_indices\n"
+ "end_header\n"
}
};
write.write_all(header.as_bytes())?;
match precision {
Precision::P32 => {
for i in 0..n_vertices {
let vertex = mesh.vertex(VId { val: i }).unwrap(); let color = &colors[i];
write.write(&(vertex.x() as f32).to_be_bytes())?;
write.write(&(vertex.y() as f32).to_be_bytes())?;
write.write(&(vertex.z() as f32).to_be_bytes())?;
write.write(&color.r.to_be_bytes())?;
write.write(&color.g.to_be_bytes())?;
write.write(&color.b.to_be_bytes())?;
}
}
Precision::P64 => {
for i in 0..n_vertices {
let vertex = mesh.vertex(VId { val: i }).unwrap(); let color = &colors[i];
write.write(&(vertex.x()).to_be_bytes())?;
write.write(&(vertex.y()).to_be_bytes())?;
write.write(&(vertex.z()).to_be_bytes())?;
write.write(&color.r.to_be_bytes())?;
write.write(&color.g.to_be_bytes())?;
write.write(&color.b.to_be_bytes())?;
}
}
}
for i in 0..n_faces {
let face = mesh.face_vertex_ids(FId { val: i }).unwrap(); write.write(&3u8.to_be_bytes())?;
write.write(&(face.a.val as u32).to_be_bytes())?;
write.write(&(face.b.val as u32).to_be_bytes())?;
write.write(&(face.c.val as u32).to_be_bytes())?;
}
Ok(())
}