我正在尝试使用VTK的python包装器在场景中显示几个字形,每个字形都有自己的颜色和旋转。不幸的是,vtk只考虑了轮换(使用vtkTensorGlyph
)。相反,当我使用vtkGlyph3D
时,只考虑颜色。
这是一段准备好使用vtkTensorGlyph
的代码。每个立方体应该有一个随机颜色,但相反,它们都是相同的颜色。我再次阅读并阅读了VTK的文档,但我还没有找到任何解决方案。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import vtk
import scipy.linalg as sc
import random as ra
import numpy as np
import itertools
points = vtk.vtk.vtkPoints() # where to locate each glyph in the scene
tensors = vtk.vtkDoubleArray() # rotation for each glyph
tensors.SetNumberOfComponents(9)
colors = vtk.vtkUnsignedCharArray() # should be the color for each glyph
colors.SetNumberOfComponents(3)
# let's make 10 cubes in the scene
for i in range(0, 50, 5):
points.InsertNextPoint(i, i, i) # position of a glyph
colors.InsertNextTuple3(ra.randint(0, 255), ra.randint(0, 255), ra.randint(0, 255) ) # pick random color
rot = list(itertools.chain(*np.reshape(sc.orth(np.random.rand(3, 3)).transpose(), (1, 9)).tolist())) # random rotation matrix (row major)
tensors.InsertNextTuple9(*rot)
polydata = vtk.vtkPolyData() # create the polydatas
polydata.SetPoints(points)
polydata.GetPointData().SetTensors(tensors)
polydata.GetPointData().SetScalars(colors)
cubeSource = vtk.vtkCubeSource()
cubeSource.Update()
glyphTensor = vtk.vtkTensorGlyph()
glyphTensor.SetColorModeToScalars() # is it really work ?
try:
glyphTensor.SetInput(polydata)
except AttributeError:
glyphTensor.SetInputData(polydata)
glyphTensor.SetSourceConnection(cubeSource.GetOutputPort())
glyphTensor.ColorGlyphsOn() # should not color all cubes independently ?
glyphTensor.ThreeGlyphsOff()
glyphTensor.ExtractEigenvaluesOff()
glyphTensor.Update()
# next is usual vtk code
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(glyphTensor.GetOutputPort())
actor = vtk.vtkActor()
actor.SetMapper(mapper)
ren = vtk.vtkRenderer()
ren.SetBackground(0.2, 0.5, 0.3)
ren.AddActor(actor)
renwin = vtk.vtkRenderWindow()
renwin.AddRenderer(ren)
iren = vtk.vtkRenderWindowInteractor()
iren.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
iren.SetRenderWindow(renwin)
renwin.Render()
iren.Initialize()
renwin.Render()
iren.Start()
答案 0 :(得分:1)
我终于成功了。
如果我很好理解,字形需要一个表面,特别是组成这个表面的每个点上的法线。每个法线给出每个字形的方向。
vtk源代码中的Examples/VisualizationAlgorithms/Python/spikeF.py
示例说明了我的意思。
这是一个用颜色和旋转独立字形的小例子。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from vtk import *
# Let's create a surface with 3 points unconnected.
points = vtkPoints()
points.InsertNextPoint(1, 0, 0)
points.InsertNextPoint(0, 0, 0)
points.InsertNextPoint(0, 1, 0)
polydata = vtkPolyData()
polydata.SetPoints(points)
colors = vtkUnsignedCharArray()
colors.SetNumberOfComponents(3)
colors.SetNumberOfTuples(polydata.GetNumberOfPoints())
colors.InsertTuple3(0, 147, 25, 98)
colors.InsertTuple3(1, 32, 84, 247)
colors.InsertTuple3(2, 198, 214, 36)
polydata.GetPointData().SetScalars(colors)
# Now, let's control normal on each point composing or 'fake' surface
# We should say, let's give a direction to each point, a normal in strange for a point.
pointNormalsArray = vtkDoubleArray()
pointNormalsArray.SetNumberOfComponents(3)
pointNormalsArray.SetNumberOfTuples(polydata.GetNumberOfPoints())
pN1 = [1.0, 0.0, 0.0]
pN2 = [0.0, 1.0, 0.0]
pN3 = [0.0, 0.0, 1.0]
pointNormalsArray.SetTuple(0, pN1)
pointNormalsArray.SetTuple(1, pN2)
pointNormalsArray.SetTuple(2, pN3)
polydata.GetPointData().SetNormals(pointNormalsArray)
sources = vtkConeSource()
sources.SetResolution(6)
sources.Update()
glyph = vtkGlyph3D()
try:
glyph.SetInput(polydata)
except AttributeError:
glyph.SetInputData(polydata)
glyph.SetSourceConnection(sources.GetOutputPort())
glyph.SetColorModeToColorByScalar()
glyph.SetVectorModeToUseNormal()
glyph.ScalingOff()
glyph.Update()
mapper = vtkPolyDataMapper()
mapper.SetInputConnection(glyph.GetOutputPort())
actor = vtkActor()
actor.SetMapper(mapper)
ren = vtkRenderer()
ren.SetBackground(0.2, 0.5, 0.3)
ren.AddActor(actor)
renwin = vtk.vtkRenderWindow()
renwin.AddRenderer(ren)
iren = vtk.vtkRenderWindowInteractor()
iren.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
iren.SetRenderWindow(renwin)
renwin.Render()
iren.Initialize()
renwin.Render()
iren.Start()
顺便说一句,有一个更简单的解决方案,包括创建一个源,以及所需的任何映射器和actor。实际上,很容易为每个演员提供颜色和方向。问题是,对于很多演员(我的机器上大约5000个),表演对于互动来说真的很糟糕。
答案 1 :(得分:1)
您可以通过以下方式对vtkTensorGlyphs进行不同的着色。我将使用不同的彩色张量字形向您展示我的C ++代码的一些片段。我希望你可以将类似的东西集成到你的python代码中:
vtkSmartPointer<vtkFloatArray> colors = vtkSmartPointer<vtkFloatArray>::New();
vtkSmartPointer<vtkPolyData> data = vtkSmartPointer<vtkPolyData>::New();
//Add for each single object the following data to colors:
float color[3] = {r, g, b};
colors->InsertNextTupleValue(color);
//Then proceed here after adding all colors
colors->SetName("colors");
colors->SetNumberOfComponents(3);
//Add all necessary information to the vtkPolyData element, including the color information
data->GetPointData()->SetScalars(colors);
...
tensorGlyph->SetInputData(data);
tensorGlyph->ColorGlyphsOn();
tensorGlyph->SetColorModeToScalars();
尽管VTK开发人员可能希望使用RGB元组进行颜色定义,但您只需使用第一个参数“r”。在[0,1]的区间内改变“r”将导致不同的颜色。
使用VTK 6.1.0