From 7b5c294b2ca4b7d24065a847aafb80852e468cbc Mon Sep 17 00:00:00 2001 From: Maik Date: Thu, 15 Aug 2024 11:03:07 +0200 Subject: [PATCH 1/3] Added check for empty polydata topology Fix a bug that occurs, when an topology type (verts, lines, polys, strips) are defined in the .vtk file but contain no data. --- src/xml.rs | 104 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 68 insertions(+), 36 deletions(-) diff --git a/src/xml.rs b/src/xml.rs index 0152a62..dda78e8 100644 --- a/src/xml.rs +++ b/src/xml.rs @@ -2574,42 +2574,74 @@ impl TryFrom for model::Vtk { + number_of_strips + number_of_polys + number_of_verts; - let verts = verts - .map(|verts| { - verts.into_vertex_numbers( - number_of_verts, - appended_data, - encoding_info, - ) - }) - .transpose()?; - let lines = lines - .map(|lines| { - lines.into_vertex_numbers( - number_of_lines, - appended_data, - encoding_info, - ) - }) - .transpose()?; - let strips = strips - .map(|strips| { - strips.into_vertex_numbers( - number_of_strips, - appended_data, - encoding_info, - ) - }) - .transpose()?; - let polys = polys - .map(|polys| { - polys.into_vertex_numbers( - number_of_polys, - appended_data, - encoding_info, - ) - }) - .transpose()?; + let verts = match verts { + Some(Topo { + ref connectivity, + ref offsets, + }) if !connectivity.data.is_empty() && !offsets.data.is_empty() => { + verts + .map(|verts| { + verts.into_vertex_numbers( + number_of_verts, + appended_data, + encoding_info, + ) + }) + .transpose()? + } + _ => None, + }; + let lines = match lines { + Some(Topo { + ref connectivity, + ref offsets, + }) if !connectivity.data.is_empty() && !offsets.data.is_empty() => { + lines + .map(|lines| { + lines.into_vertex_numbers( + number_of_lines, + appended_data, + encoding_info, + ) + }) + .transpose()? + } + _ => None, + }; + let strips = match strips { + Some(Topo { + ref connectivity, + ref offsets, + }) if !connectivity.data.is_empty() && !offsets.data.is_empty() => { + strips + .map(|strips| { + strips.into_vertex_numbers( + number_of_strips, + appended_data, + encoding_info, + ) + }) + .transpose()? + } + _ => None, + }; + let polys = match polys { + Some(Topo { + ref connectivity, + ref offsets, + }) if !connectivity.data.is_empty() && !offsets.data.is_empty() => { + polys + .map(|polys| { + polys.into_vertex_numbers( + number_of_polys, + appended_data, + encoding_info, + ) + }) + .transpose()? + } + _ => None, + }; Ok(model::Piece::Inline(Box::new(model::PolyDataPiece { points: points.unwrap().data.into_io_buffer( number_of_points, From 4aed629c7005d6e6c3b8c12d351df8687f0558d7 Mon Sep 17 00:00:00 2001 From: Maik Simon Mikoszek Date: Fri, 16 Aug 2024 09:39:36 +0200 Subject: [PATCH 2/3] Revert "Added check for empty polydata topology" This reverts commit 7b5c294b2ca4b7d24065a847aafb80852e468cbc. --- src/xml.rs | 104 +++++++++++++++++++---------------------------------- 1 file changed, 36 insertions(+), 68 deletions(-) diff --git a/src/xml.rs b/src/xml.rs index dda78e8..0152a62 100644 --- a/src/xml.rs +++ b/src/xml.rs @@ -2574,74 +2574,42 @@ impl TryFrom for model::Vtk { + number_of_strips + number_of_polys + number_of_verts; - let verts = match verts { - Some(Topo { - ref connectivity, - ref offsets, - }) if !connectivity.data.is_empty() && !offsets.data.is_empty() => { - verts - .map(|verts| { - verts.into_vertex_numbers( - number_of_verts, - appended_data, - encoding_info, - ) - }) - .transpose()? - } - _ => None, - }; - let lines = match lines { - Some(Topo { - ref connectivity, - ref offsets, - }) if !connectivity.data.is_empty() && !offsets.data.is_empty() => { - lines - .map(|lines| { - lines.into_vertex_numbers( - number_of_lines, - appended_data, - encoding_info, - ) - }) - .transpose()? - } - _ => None, - }; - let strips = match strips { - Some(Topo { - ref connectivity, - ref offsets, - }) if !connectivity.data.is_empty() && !offsets.data.is_empty() => { - strips - .map(|strips| { - strips.into_vertex_numbers( - number_of_strips, - appended_data, - encoding_info, - ) - }) - .transpose()? - } - _ => None, - }; - let polys = match polys { - Some(Topo { - ref connectivity, - ref offsets, - }) if !connectivity.data.is_empty() && !offsets.data.is_empty() => { - polys - .map(|polys| { - polys.into_vertex_numbers( - number_of_polys, - appended_data, - encoding_info, - ) - }) - .transpose()? - } - _ => None, - }; + let verts = verts + .map(|verts| { + verts.into_vertex_numbers( + number_of_verts, + appended_data, + encoding_info, + ) + }) + .transpose()?; + let lines = lines + .map(|lines| { + lines.into_vertex_numbers( + number_of_lines, + appended_data, + encoding_info, + ) + }) + .transpose()?; + let strips = strips + .map(|strips| { + strips.into_vertex_numbers( + number_of_strips, + appended_data, + encoding_info, + ) + }) + .transpose()?; + let polys = polys + .map(|polys| { + polys.into_vertex_numbers( + number_of_polys, + appended_data, + encoding_info, + ) + }) + .transpose()?; Ok(model::Piece::Inline(Box::new(model::PolyDataPiece { points: points.unwrap().data.into_io_buffer( number_of_points, From 068dcf6b55cf4124529ae4a17d73d0420745ac49 Mon Sep 17 00:00:00 2001 From: Maik Simon Mikoszek Date: Fri, 16 Aug 2024 10:56:57 +0200 Subject: [PATCH 3/3] Return empty String if `data` is empty in `into_field_array()` and added test --- src/xml.rs | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/xml.rs b/src/xml.rs index 0152a62..61f5382 100644 --- a/src/xml.rs +++ b/src/xml.rs @@ -1566,7 +1566,11 @@ impl DataArray { buf } DataArrayFormat::Ascii => { - let string = data[0].clone().into_string(); + let string = if data.is_empty() { + "".to_string() + } else { + data[0].clone().into_string() + }; let slice = string.as_str(); fn parse_num_seq(s: &str) -> std::result::Result, ValidationError> where @@ -3797,4 +3801,41 @@ mod tests { assert_eq!(xml_round_trip.clone(), vtk_round_trip.try_into()?); Ok(()) } + + #[test] + fn empty_polydata_topology() { + use super::Data::Data; + use super::DataArray as XMLDataArray; + use crate::IOBuffer; + let data = XMLDataArray { + name: "PolyData".to_string(), + scalar_type: ScalarType::Float32, + format: DataArrayFormat::Ascii, + offset: None, + num_comp: 1, + range_min: Some(0.1), + range_max: Some(0.3), + data: vec![Data("0.1 0.2 0.3".to_string())], + }; + let data_empty = XMLDataArray { + name: "PolyData".to_string(), + scalar_type: ScalarType::Float32, + format: DataArrayFormat::Ascii, + offset: None, + num_comp: 1, + range_min: None, + range_max: None, + data: vec![], + }; + let encoding_info = EncodingInfo { + byte_order: model::ByteOrder::BigEndian, + header_type: ScalarType::Float64, + compressor: Compressor::None, + compression_level: 0, + }; + let data_fa = data.into_field_array(3, None, encoding_info); + let data_empty_fa = data_empty.into_field_array(0, None, encoding_info); + assert_eq!(data_fa.unwrap().data, IOBuffer::F32(vec![0.1, 0.2, 0.3])); + assert_eq!(data_empty_fa.unwrap().data, IOBuffer::F32(vec![])); + } }