问题
I have 2d array (of size 20x30) of doubles:
double a[20*30];
How to visualize it using VTK? It is extremely difficult to find proper documentation. The closest example which I found is this, however it uses as input 3 unsigned chars which represents color. As I understand I should use vtkScalarsToColors class to somehow map scalars to colors, but I can't figure out how to put everything into single piece of code.
回答1:
What you probably want to do is to assign scalars to points or cells of a surface or volume mesh. VTK then can take care of the visualization. This is demonstrated in the following example: ScalarBarActor. For the basic usage, follow the Scalars example.
However, you need to provide the suitable mesh yourself to which you want to map the values. From your question, it is not entirely clear what you mean with "how to visualize a 2d array" of values. If you want to assign scalar values in a planar 20x30 grid, you need to first create a surface object (of type vtkPolyData) with triangular or quadrangular cells, and then assign the values to the points of the mesh using surface->GetPointData()->SetScalars()
, as demonstrated in the above examples.
Convenient in this case would be the vtkPlaneSource, look here for the corresponding example. The number of grid points you can set by using SetXResolution()
or SetYResolution()
respectively. (In case this is not clear: vtkPlaneSource
inherits vtkPolyDataAlgorithm, to access the underlying vtkPolyData
object, use the method GetOutput()
)
Update: I added sample code that demonstrates the procedure - in python, for better readability.
# This code has been written by normanius under the CC BY-SA 4.0 license.
# License: https://creativecommons.org/licenses/by-sa/4.0/
# Author: normanius: https://stackoverflow.com/users/3388962/normanius
# Date: August 2018
# Reference: https://stackoverflow.com/a/51754466/3388962
import vtk
import numpy as np
###########################################################
# CREATE ARRAY VALUES
###########################################################
# Just create some fancy looking values for z.
n = 100
m = 50
xmin = -1; xmax = 1
ymin = -1; ymax = 1
x = np.linspace(xmin, xmax, n)
y = np.linspace(ymin, ymax, m)
x, y = np.meshgrid(x, y)
x, y = x.flatten(), y.flatten()
z = (x+y)*np.exp(-3.0*(x**2+y**2))
###########################################################
# CREATE PLANE
###########################################################
# Create a planar mesh of quadriliterals with nxm points.
# (SetOrigin and SetPointX only required if the extent
# of the plane should be the same. For the mapping
# of the scalar values, this is not required.)
plane = vtk.vtkPlaneSource()
plane.SetResolution(n-1,m-1)
plane.SetOrigin([xmin,ymin,0]) # Lower left corner
plane.SetPoint1([xmax,ymin,0])
plane.SetPoint2([xmin,ymax,0])
plane.Update()
# Map the values to the planar mesh.
# Assumption: same index i for scalars z[i] and mesh points
nPoints = plane.GetOutput().GetNumberOfPoints()
assert(nPoints == len(z))
# VTK has its own array format. Convert the input
# array (z) to a vtkFloatArray.
scalars = vtk.vtkFloatArray()
scalars.SetNumberOfValues(nPoints)
for i in range(nPoints):
scalars.SetValue(i, z[i])
# Assign the scalar array.
plane.GetOutput().GetPointData().SetScalars(scalars)
###########################################################
# WRITE DATA
###########################################################
writer = vtk.vtkXMLPolyDataWriter()
writer.SetFileName('output.vtp')
writer.SetInputConnection(plane.GetOutputPort())
writer.Write() # => Use for example ParaView to see scalars
###########################################################
# VISUALIZATION
###########################################################
# This is a bit annoying: ensure a proper color-lookup.
colorSeries = vtk.vtkColorSeries()
colorSeries.SetColorScheme(vtk.vtkColorSeries.BREWER_DIVERGING_SPECTRAL_10)
lut = vtk.vtkColorTransferFunction()
lut.SetColorSpaceToHSV()
nColors = colorSeries.GetNumberOfColors()
zMin = np.min(z)
zMax = np.max(z)
for i in range(0, nColors):
color = colorSeries.GetColor(i)
color = [c/255.0 for c in color]
t = zMin + float(zMax - zMin)/(nColors - 1) * i
lut.AddRGBPoint(t, color[0], color[1], color[2])
# Mapper.
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(plane.GetOutputPort())
mapper.ScalarVisibilityOn()
mapper.SetScalarModeToUsePointData()
mapper.SetLookupTable(lut)
mapper.SetColorModeToMapScalars()
# Actor.
actor = vtk.vtkActor()
actor.SetMapper(mapper)
# Renderer.
renderer = vtk.vtkRenderer()
renderer.SetBackground([0.5]*3)
# Render window and interactor.
renderWindow = vtk.vtkRenderWindow()
renderWindow.SetWindowName('Demo')
renderWindow.AddRenderer(renderer)
renderer.AddActor(actor)
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(renderWindow)
renderWindow.Render()
interactor.Start()
The result will look similar to this:
来源:https://stackoverflow.com/questions/51747494/how-to-visualize-2d-array-of-doubles-in-vtk