Skip to content

Commit ad4b20e

Browse files
committed
Support for f64 and f32 scalar attributes
1 parent b1c22d5 commit ad4b20e

1 file changed

Lines changed: 61 additions & 38 deletions

File tree

splashsurf_lib/src/io/vtk_format.rs

Lines changed: 61 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -97,56 +97,25 @@ impl DataPiece {
9797
) -> Result<Vec<MeshAttribute<R>>, anyhow::Error> {
9898
let mut mesh_attributes = Vec::new();
9999

100-
// Converts an IOBuffer to the corresponding supported AttributeData
101-
let io_buffer_to_attribute_data = |num_comp: usize,
102-
io_buffer: &vtkio::model::IOBuffer|
103-
-> Result<AttributeData<R>, anyhow::Error> {
104-
match num_comp {
105-
1 => {
106-
if let IOBuffer::U32(vec) = &io_buffer {
107-
Ok(AttributeData::ScalarReal(
108-
vec.iter()
109-
.copied()
110-
.map(|val| R::from_u32(val).unwrap())
111-
.collect(),
112-
))
113-
} else {
114-
Err(anyhow!("Unsupported IOBuffer scalar type"))
115-
}
116-
}
117-
3 => match &io_buffer {
118-
IOBuffer::F32(coords) => {
119-
particles_from_coords(coords).map(|p| AttributeData::Vector3Real(p))
120-
}
121-
IOBuffer::F64(coords) => {
122-
particles_from_coords(coords).map(|p| AttributeData::Vector3Real(p))
123-
}
124-
_ => Err(anyhow!("Unsupported IOBuffer vector type")),
125-
},
126-
_ => Err(anyhow!(
127-
"Unsupported number of components ({}) in VTK DataArray",
128-
num_comp
129-
)),
130-
}
131-
};
132-
133100
'fields: for field_name in names {
134101
for attribute in self.point_attributes() {
135102
match attribute {
136103
Attribute::DataArray(data_array) if data_array.name == *field_name => {
137-
let attribute_data =
138-
io_buffer_to_attribute_data(data_array.num_comp(), &data_array.data)
139-
.with_context(|| anyhow!("Attribute \"{}\"", field_name))?;
104+
let attribute_data = try_convert_io_buffer_to_attribute(
105+
&data_array.data,
106+
data_array.num_comp(),
107+
)
108+
.with_context(|| anyhow!("Attribute \"{}\"", field_name))?;
140109
let mesh_attribute = MeshAttribute::new(field_name, attribute_data);
141110
mesh_attributes.push(mesh_attribute);
142111
continue 'fields;
143112
}
144113
Attribute::Field { data_array, .. } => {
145114
for field_array in data_array {
146115
if field_array.name == *field_name {
147-
let attribute_data = io_buffer_to_attribute_data(
148-
field_array.num_comp(),
116+
let attribute_data = try_convert_io_buffer_to_attribute(
149117
&field_array.data,
118+
field_array.num_comp(),
150119
)
151120
.with_context(|| anyhow!("Attribute \"{}\"", field_name))?;
152121
let mesh_attribute = MeshAttribute::new(field_name, attribute_data);
@@ -333,6 +302,60 @@ fn surface_mesh_from_unstructured_grid<R: Real>(
333302
}))
334303
}
335304

305+
/// Converts a VTK IOBuffer to the corresponding supported AttributeData
306+
fn try_convert_io_buffer_to_attribute<R: Real>(
307+
io_buffer: &vtkio::model::IOBuffer,
308+
num_comp: usize,
309+
) -> Result<AttributeData<R>, anyhow::Error> {
310+
match num_comp {
311+
1 => match &io_buffer {
312+
IOBuffer::U32(vec) => try_map_scalars_to_real(&vec, |val| {
313+
R::from_u32(val).ok_or_else(|| {
314+
anyhow!("Cannot convert an attribute value from u32 to Real type")
315+
})
316+
})
317+
.map(|v| AttributeData::ScalarReal(v)),
318+
IOBuffer::F32(vec) => try_map_scalars_to_real(&vec, |val| {
319+
R::from_f32(val).ok_or_else(|| {
320+
anyhow!("Cannot convert an attribute value from f32 to Real type")
321+
})
322+
})
323+
.map(|v| AttributeData::ScalarReal(v)),
324+
IOBuffer::F64(vec) => try_map_scalars_to_real(&vec, |val| {
325+
R::from_f64(val).ok_or_else(|| {
326+
anyhow!("Cannot convert an attribute value from f64 to Real type")
327+
})
328+
})
329+
.map(|v| AttributeData::ScalarReal(v)),
330+
_ => Err(anyhow!("Unsupported IOBuffer scalar data type")),
331+
},
332+
3 => match &io_buffer {
333+
IOBuffer::F32(coords) => {
334+
particles_from_coords(coords).map(|p| AttributeData::Vector3Real(p))
335+
}
336+
IOBuffer::F64(coords) => {
337+
particles_from_coords(coords).map(|p| AttributeData::Vector3Real(p))
338+
}
339+
_ => Err(anyhow!("Unsupported IOBuffer vector data type")),
340+
},
341+
_ => Err(anyhow!(
342+
"Unsupported number of components ({}) in VTK IO buffer",
343+
num_comp
344+
)),
345+
}
346+
}
347+
348+
fn try_map_scalars_to_real<R: Real, T: Copy, F: Fn(T) -> Result<R, anyhow::Error>>(
349+
io_buffer: &[T],
350+
f: F,
351+
) -> Result<Vec<R>, anyhow::Error> {
352+
io_buffer
353+
.iter()
354+
.copied()
355+
.map(f)
356+
.try_collect_with_capacity(io_buffer.len())
357+
}
358+
336359
/// Tries to convert a vector of consecutive coordinate triplets into a vector of `Vector3`, also converts between floating point types
337360
fn particles_from_coords<RealOut: Real, RealIn: Real>(
338361
coords: &Vec<RealIn>,

0 commit comments

Comments
 (0)