It is practically impossible to prepare a software to properly deal with nan values everywhere. It would have enormous performance impact and would complicate algorithms and display pipelines at an unreasonable level. Also, meaning of “properly deal with nan” depends on the use case. Points/cells with nan values could be removed, skipped (interpolated using nearby valid values), displayed with a transparent value or special color, …?
I would recommend to get rid of the nan values as soon as you can (right after importing the mesh). For example by converting them to a value that makes sense for your application and maybe by applying further processing (e.g., remove regions with nan valued scalar by using threshold filter).
For example what is wrong with this pretty simple snippet of code:
// preparing rectangular grid
ptrdiff_t nX = 10;
ptrdiff_t nY = 10;
vtkNew<vtkPoints> pts;
pts->SetNumberOfPoints(nX*nY);
vtkNew<vtkDoubleArray> scalars;
scalars->SetName("my_scalars");
scalars->SetNumberOfTuples(nX*nY);
double vals[3];
for (ptrdiff_t y = 0; y < nY; y++){
for (ptrdiff_t x = 0; x < nX; x++){
vals[0] = x;
vals[1] = y;
vals[2] = 0;
pts->SetPoint(x + y*nX, vals);
scalars->SetValue(x + y*nX, x+y);
}
}
// creating polydata and adding it to the scene
vtkNew<vtkPolyData> polyData;
polyData->SetPoints(pts);
polyData->GetPointData()->SetScalars(scalars);
qSlicerApplication* app = qSlicerApplication::application();
vtkSlicerModelsLogic* modelsLogic =
vtkSlicerModelsLogic::SafeDownCast(app->moduleLogic("Models"));
vtkMRMLModelNode* modelNode =
modelsLogic->AddModel(polyData);
I’m trying to represent rectangular grid and set scalars to points.
After running the app I can see that the model is added but no any coloring applied
Here is the code I use to test it in python.
The mesh (mesh and points I guess share the same meaning) is named vpoints and varray is scalars (any random numbers):
# variable prefixed with `v` is treated as `vtk` object
import numpy as np
nx = 10
ny = 10
rng = np.random.default_rng(12345)
array = rng.random((nx*ny))
vpoints = vtk.vtkPoints()
vpoints.SetNumberOfPoints(nx*ny)
varray = vtk.vtkDoubleArray()
varray.SetNumberOfComponents(1)
varray.SetName("my_scalar")
varray.SetNumberOfTuples(nx*ny)
for y in range(0, ny):
for x in range(0, nx):
ind = x + y*nx
vpoints.SetPoint(ind, [x,y,0])
varray.SetValue(ind, array[ind])
vpoly = vtk.vtkPolyData()
vpoly.SetPoints(vpoints)
vpoly.GetPointData().SetScalars(varray) # this returns 0 - is it ok?
modelNode = slicer.modules.models.logic().AddModel(vpoly)
This code generates a pointset and puts it into a polydata object, but there is nothing displayable here (there are no cells, just points). If you want to display some shape at each point position then you can use vpoly as input to a vtkGlyph3D filter (along with some glyph source, source as a sphere source). The output of that filter will be displayable.