Closed Clonkk closed 4 years ago
Without seeing the full traceback, it's difficult to guess what the issue is, but I'm guessing that the mapper we're using isn't a genuine VTK mapper and doesn't have that property. Can you upload the mesh you're using along with the full code that generates this error?
Thanks!
Hi, thanks for your help. Here are the full error message :
Traceback (most recent call last):
File "./py_vista_render.py", line 129, in <module>
p.export_vtkjs(vtkjs_file_path)
File "/home/user/.local/lib/python3.8/site-packages/pyvista/plotting/plotting.py", line 3546, in export_vtkjs
return export_plotter_vtkjs(self, filename, compress_arrays=compress_arrays)
File "/home/user/.local/lib/python3.8/site-packages/pyvista/plotting/export_vtkjs.py", line 478, in export_plotter_vtkjs
scalarVisibility = mapper.GetScalarVisibility()
AttributeError: 'MapperHelper' object has no attribute 'GetScalarVisibility'
It happens no matter the data. I tried using np.random.rand(140, ,130, 480) and it happens as well.
For reference here is the full code that reproducde the error :
def display_3d(DX, DY, DT, C):
DIMX = (DX)
DIMY = (DY)
DIMT = (DT * C)
local_cmap = "plasma"
local_cmap = "viridis"
values = np.random.rand(140, 130, 480)
# Create the spatial reference
grid = pv.UniformGrid()
# Set the grid dimensions: shape + 1 because we want to inject our values on
# the CELL data
grid.dimensions = np.array(values.shape) + 1
# Edit the spatial reference
grid.origin = (0, 0, 0) # The bottom left corner of the data set
# These are the cell sizes along each axis
grid.spacing = (DIMX, DIMY, DIMT)
# Add the data values to the cell data
grid.cell_arrays["values"] = values.flatten(
order="F") # Flatten the array!
# Now plot the grid!
# grid.plot(show_edges=True)
p = pv.Plotter()
vol = p.add_volume(
grid,
mapper='open_gl',
cmap=local_cmap,
opacity="linear_r",
blending="maximum",
n_colors=256,
show_scalar_bar=True,
)
p.set_background("lightgrey")
return p
DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")
vtkjs_file_path = os.path.join(DATA_DIR, "vtkjs_data_export")
C = 1565.0
DX = 0.0001059999995050021
DY = 0.0001059999995050021
DT = 1.666666626931601e-08
p = display_3d(DX, DY, DT, C)
p.export_vtkjs(vtkjs_file_path)
p.show()
The error happens when I try to export a volume and not a mesh.
If I do add_mesh
the export works. What I want is to export a volume; From the documentation I've read it seemed possible.
I'm using Python 3.8 and PyVista 0.25.3 installed using pip.
Interesting. I'd try converting the uniform grid to an unstructured mesh (see cast_to_unstructured_grid), and then saving that.
I modified the code to use an unstructured grid as suggested :
ugrid = pv.Common.cast_to_unstructured_grid(grid)
# ...
p.add_volume(
ugrid,
#...
)
But it fails with an error saying volume are not supported with unstructured grid :
Traceback (most recent call last):
File "./py_vista_render.py", line 124, in <module>
p = display_3d(acq_3d_data, DX, DY, DT, C)
File "./py_vista_render.py", line 51, in display_3d
vol = p.add_volume(
File "/home/user/.local/lib/python3.8/site-packages/pyvista/plotting/plotting.py", line 1915, in add_volume
raise TypeError('Type {} not supported for volume rendering at this time. Use `pyvista.UniformGrid`.'.format(type(volume)))
TypeError: Type <class 'pyvista.core.pointset.UnstructuredGrid'> not supported for volume rendering at this time. Use `pyvista.UniformGrid`.
If that's not the intended behaviour maybe we should open an issue (or move this one to avoid duplication) on the PyVista repo ?
Looks like vtk.vtkImageData
isn't supported within the legacy exporter. However, the latest VTK supports this with:
import vtk
vwrite = vtk.vtkJSONDataSetWriter()
vwrite.SetInputData(vol)
vwrite.SetFileName('stuff') # directory
vwrite.Update()
I suggest you try updating to vtk>=9.0
and trying this out. You should be able to use a pyvista.UniformGrid
as the input data.
Just to clairify, in SetInputData is it the result of p.add_volume(#...)
or the uniform grid or the Plotter ?
I'll test this today or tomorrow and get back to you ! Thanks for the help
The input to SetInputData
will be the grid
you have it in your display_3d
function.
Hello, Thanks for your help ! After looking through the VTK API, I ended using it directly for exporting datas from Numpy and I use PyVista only for the plotting part.
In case anyone has a similar need here is the code to generate a VTI File containing a Volume (with spacing) :
def toVtkImageData(a, DIMX, DIMY, DIMT):
importer = vtk.vtkImageImport()
#For some reason you need to reverse the shape
importer.SetDataExtent(0,a.shape[2]-1,0,a.shape[1]-1,0,a.shape[0]-1)
importer.SetWholeExtent(0,a.shape[2]-1,0,a.shape[1]-1,0,a.shape[0]-1)
importer.SetDataSpacing(DIMT, DIMY, DIMX)
#Set data pointer
importer.SetImportVoidPointer(a)
importer.Update()
return importer.GetOutput()
def make_vti_from_numpy(data_matrix, DX, DY, DT, C):
DIMX = (DX)
DIMY = (DY)
DIMT = (DT * C)
# For VTK to be able to use the data, it must be stored as a VTK-image. This can be done by the vtkImageImport-class which
# imports raw data and stores it.
dataImporter = toVtkImageData(data_matrix, DIMX, DIMY, DIMT)
filename = "data/vtkjs_data_export2.vti"
writer = vtk.vtkXMLImageDataWriter()
writer.SetFileName(filename)
writer.SetDataModeToBinary()
writer.SetInputData(dataImporter)
writer.Write()
export_vtkjs fails on a volume and I don't understand why. If I show the volume, it display correctly.
Here is the code :
Here is the error (EDIT with full error message as requested) :