Extracting Data
dwerner95 opened this issue · 2 comments
Hey All,
is there any way to extract data from a vtk data easily ?
I couldn't find any evidence of a extraction method for the datasets into arrays.
I tried to write a function myself, but now i am stuck making it generic for the different datatypes of IOBuffer
and, to be honest, i have no idea what I am doing here, but it returns a array in the end.
use vtkio::model::*;
fn main() {
let file = "test.vtk";
let mut vtk_file = match Vtk::import(&file)
.expect(&format!("Failed to load file: {:?}", file))
.data
{
DataSet::PolyData { pieces, .. } => pieces,
_ => panic!("OhOh"),
};
let data = &**match &vtk_file[0] {
Piece::Inline(x) => x,
_ => panic!("OhOh2"),
};
let x = &data.data.point[0];
let y = match &x {
Attribute::Field { name, data_array } => data_array,
_ => panic!("OhOh3"),
};
let mut data: Option<&Vec<i32>> = None;
for elem in y {
if elem.name == "id" {
data = Some(match &elem.data {
IOBuffer::I32(vec) => vec,
_ => panic!("OhOh4"),
});
break;
}
}
let data = if let Some(data) = data {
data
} else {
panic!("OhOh5")
};
println!("{:?}", data);
}
}
Is there any better way to do this?
Thank you for the question!
I think you have the gist of it. Sadly there aren't too many utilities in vtkio
yet to make it convenient to extract specific data from a vtk file, though I'm not exactly sure what this API would look like. I expect it heavily depends on the use case since VTK spans many different ones.
Having said this, for IOBuffer
specifically you can use the cast_into
method to get your data into the format you like. or if you are sure about the type, you can use the into_vec
method.
I think also with a few rust tricks, you may get a slightly simpler version, but not by much:
fn get_id_field() -> Vec<i32> {
let file = "test.vtk";
let mut vtk_file = match Vtk::import(&file)
.expect(&format!("Failed to load file: {:?}", file));
let pieces = if let DataSet::UnstructuredGrid { pieces, .. } = vtk_file.data {
pieces
} else {
panic!("Wrong vtk data type");
};
// If piece is already inline, this just returns a piece data clone.
let piece = pieces[0].load_piece_data(None).expect("Failed to load piece data");
let attribute = &piece.data.point[0];
if let Attribute::Field { data_array, .. } = attribute {
data_array
.iter()
.find(|&DataArrayBase { name, .. }| name == "id")
.expect("Failed to find id field")
.data
.clone()
.cast_into::<i32>()
.expect("Failed cast")
} else {
panic!("No field attribute found");
}
}
I hope this helps and thanks again for this question, I also realized that the clone before cast_into
shouldn't be necessary, so I will simplify it in a next release!