elrnv / vtkio

Visualization ToolKit (VTK) file parser and writer
Apache License 2.0
56 stars 13 forks source link

CELL_DATA count for StructuredGrid is always 1 #48

Closed Siimeloni closed 1 month ago

Siimeloni commented 2 months ago

When writing StructuredGrid to a file, ParaView only found one cell attribute value instead of the same amount as cells. This causes an error when importing the file in ParaView, because the CELL_DATA count is always 1. When looking into the writer.rs file, I realized that for StructuredGrids the num_cells argument of the write_attributes() function in line 729 is never calculated and is always 1.

https://github.com/elrnv/vtkio/blob/master/src/writer.rs#L729

Instead, the number of cells should probably be calculated and replace the constant 1. However I am not exactly sure what the best way to calculate these is. My current workaround is the following:

let num_cells: usize;
if data.cell.len() != 0 {
    num_cells = match &data.cell[0] {
        Attribute::DataArray(data) => data.num_elem(),
        Attribute::Field { name, data_array } => todo!(),
    };
} else {
    num_cells = 1;
}

self.write_attributes::<BO>(data, num_points, num_cells)?;

But this seems kinda bloated and does not address all cases, like the Attribute::Field match arm or empty data structures. Maybe there is a more efficient way to implement this?

elrnv commented 2 months ago

Nice find think you! It seems like it's undocumented. Here is what I found in the docs:

Structured Grid. The file format supports 1D, 2D, and 3D structured grid datasets. The dimensions nx, ny, nz must be greater than or equal to 1. The point coordinates are defined by the data in the POINTS section. This consists of x-y-z data values for each point.

DATASET STRUCTURED_GRID
DIMENSIONS nx ny nz
POINTS n dataType
p0x p0y p0z
p1x p1y p1z
…
p(n-1)x p(n-1)y p(n-1)z

It is perhaps easiest to use what paraview outputs. Strange that structured grids even need CELL_DATA. It seems the questions is: Should we ignore CELL_DATA or is paraview/vtk actually using this field? Then follow up: if we need to output it, can we compute number of cells using the dimensions? (like (dim[0] - 1)*(dim[1] - 1)*(dim[2] - 1) or something of the sort).

Siimeloni commented 2 months ago

Hi, thanks for the reply. I think it totally makes sense to use the dimensions to calculate the cell count. I totally ignored them for some reason. I redid the code the way you mentioned. This also makes the code much shorter. I will open a PR containing these minor changes, if that is okay with you.

Regarding CELL_DATA <value> I think that it is indeed a necessary line for paraview. The value is used to tell how many attribute values are expected in the following attribute. I don't know if paraview has an implicit method to calculate this value if it is missing, but if it is included it will probably be safer. Also it is nice to have the value included in the file, because if you encounter an error you can check easily if there is a problem with dimensions, vector lengths etc.

elrnv commented 1 month ago

Fixed by #49