Adding MeshViewer XYZ format support
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
pub mod bincode;
|
pub mod bincode;
|
||||||
pub mod json;
|
pub mod json;
|
||||||
pub mod model;
|
pub mod model;
|
||||||
|
pub mod xyz;
|
||||||
|
|||||||
117
src/storage/xyz.rs
Normal file
117
src/storage/xyz.rs
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::io::Error;
|
||||||
|
use std::io::ErrorKind;
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
use super::bincode::store;
|
||||||
|
use super::model::v1::Shape;
|
||||||
|
use super::model::v1::SpatialObject;
|
||||||
|
use super::model::Properties;
|
||||||
|
|
||||||
|
fn convert(string: &str) -> Result<Vec<SpatialObject>, Error> {
|
||||||
|
// Read manually the XYZ file, as this is a simple format.
|
||||||
|
// Read line by line, skip all line we don't know how to parse, for the
|
||||||
|
// remaining ones do:
|
||||||
|
// * lines starting with '#A' we update the current point ID
|
||||||
|
// * lines we can parse as triplet fo f64, add a position to the list,
|
||||||
|
// under the oid key.
|
||||||
|
let mut oids = HashMap::new();
|
||||||
|
let mut oid = None;
|
||||||
|
let mut origin = vec![];
|
||||||
|
for line in string.lines() {
|
||||||
|
let values = line.split_whitespace().collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if values.is_empty() {
|
||||||
|
// Skip empty lines
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
match values[0] {
|
||||||
|
"RGBA" => (),
|
||||||
|
"RGB" => (),
|
||||||
|
"SCALE" => (),
|
||||||
|
_ if values[0].starts_with("#A") => {
|
||||||
|
// Update the oid value.
|
||||||
|
oid = Some(format!("{}", values[0].trim_start_matches("#")));
|
||||||
|
trace!("FOUND OID {:?}", oid);
|
||||||
|
}
|
||||||
|
_ if line.contains("WHS") => {
|
||||||
|
// Store the voxel offset value
|
||||||
|
let t: Vec<_> = values[0]
|
||||||
|
.split(',')
|
||||||
|
.filter_map(|s| match s.parse::<f64>() {
|
||||||
|
Err(_) => None,
|
||||||
|
Ok(v) => Some(v),
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if t.len() == 3 && origin.is_empty() {
|
||||||
|
origin = t;
|
||||||
|
} else {
|
||||||
|
return Err(Error::new(
|
||||||
|
ErrorKind::InvalidData,
|
||||||
|
format!("Invalid WHS origin new {:?}, current {:?}", t, origin),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
trace!("ORIGIN FOUND: {:?}", origin);
|
||||||
|
}
|
||||||
|
_ if values.len() == 3 => {
|
||||||
|
// Check we have an oid to register the position under first.
|
||||||
|
|
||||||
|
let x = values[0].parse::<f64>();
|
||||||
|
let y = values[1].parse::<f64>();
|
||||||
|
let z = values[2].parse::<f64>();
|
||||||
|
|
||||||
|
if let (Some(oid), Ok(x), Ok(y), Ok(z)) = (oid.clone(), x, y, z) {
|
||||||
|
trace!("after (oid, x, y, z) = {:?}", (&oid, &x, &y, &z));
|
||||||
|
// We need to convert these voxel values into mm-s
|
||||||
|
let (x, y, z) = (x - origin[0], y - origin[1], z - origin[2]);
|
||||||
|
let (x, y, z) = (x * 0.039_062_5, y * 0.039_062_5, z * 0.039_062_5);
|
||||||
|
|
||||||
|
oids.entry(oid)
|
||||||
|
.or_insert_with(|| vec![])
|
||||||
|
.push(vec![x, y, z]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => trace!("line {:?}, values: {:?}", line, values),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform the points into SpatialObjects
|
||||||
|
Ok(oids
|
||||||
|
.drain()
|
||||||
|
.map(|(k, v)| {
|
||||||
|
let properties = Properties {
|
||||||
|
type_name: "Feature".to_string(),
|
||||||
|
id: k,
|
||||||
|
};
|
||||||
|
|
||||||
|
let shapes = v
|
||||||
|
.into_iter()
|
||||||
|
.map(|position| Shape {
|
||||||
|
type_name: "Point".to_string(),
|
||||||
|
reference_space: "WHS-Rat-um".to_string(),
|
||||||
|
vertices: vec![position],
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
SpatialObject { properties, shapes }
|
||||||
|
})
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from(name: &str) -> Result<(), Error> {
|
||||||
|
// Convert Reference Space definitions
|
||||||
|
let fn_in = format!("{}.xyz", name);
|
||||||
|
let fn_out = format!("{}.bin", name);
|
||||||
|
|
||||||
|
let mut file_in = BufReader::new(File::open(&fn_in)?);
|
||||||
|
let mut string = String::new();
|
||||||
|
file_in.read_to_string(&mut string)?;
|
||||||
|
|
||||||
|
let v = convert(&string)?;
|
||||||
|
|
||||||
|
store(v, &fn_out)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user