Как экспортировать 3D визуализированную сцену vtk в paraview, используя python?
Я написал код для создания цилиндрических объектов с использованием vtk в Python. Этот код отлично работает, когда он создает трехмерную сцену, где я могу масштабировать или поворачивать цилиндры, которые я сделал. Проблема в том, что я хочу экспортировать эту визуализированную сцену в paraview, чтобы просмотреть и сохранить ее для последующих работ. Как я могу это сделать? Вот код, который создает Y-образную форму с цилиндрами:
import vtk
import numpy as np
'''
Adding multiple Actors to one renderer scene using VTK package with python api.
Each cylinder is an Actor with three input specifications: Startpoint, Endpoint and radius.
After creating all the Actors, the preferred Actors will be added to a list and that list will be our input to the
renderer scene.
A list or numpy array with appropriate 3*1 shape could be used to specify starting and ending points.
There are two alternative ways to apply the transform.
1) Use vtkTransformPolyDataFilter to create a new transformed polydata.
This method is useful if the transformed polydata is needed
later in the pipeline
To do this, set USER_MATRIX = True
2) Apply the transform directly to the actor using vtkProp3D's SetUserMatrix.
No new data is produced.
To do this, set USER_MATRIX = False
'''
USER_MATRIX = True
def cylinder_object(startPoint, endPoint, radius, my_color="DarkRed"):
colors = vtk.vtkNamedColors()
# Create a cylinder.
# Cylinder height vector is (0,1,0).
# Cylinder center is in the middle of the cylinder
cylinderSource = vtk.vtkCylinderSource()
cylinderSource.SetRadius(radius)
cylinderSource.SetResolution(50)
# Generate a random start and end point
# startPoint = [0] * 3
# endPoint = [0] * 3
rng = vtk.vtkMinimalStandardRandomSequence()
rng.SetSeed(8775070) # For testing.8775070
# Compute a basis
normalizedX = [0] * 3
normalizedY = [0] * 3
normalizedZ = [0] * 3
# The X axis is a vector from start to end
vtk.vtkMath.Subtract(endPoint, startPoint, normalizedX)
length = vtk.vtkMath.Norm(normalizedX)
vtk.vtkMath.Normalize(normalizedX)
# The Z axis is an arbitrary vector cross X
arbitrary = [0] * 3
for i in range(0, 3):
rng.Next()
arbitrary[i] = rng.GetRangeValue(-10, 10)
vtk.vtkMath.Cross(normalizedX, arbitrary, normalizedZ)
vtk.vtkMath.Normalize(normalizedZ)
# The Y axis is Z cross X
vtk.vtkMath.Cross(normalizedZ, normalizedX, normalizedY)
matrix = vtk.vtkMatrix4x4()
# Create the direction cosine matrix
matrix.Identity()
for i in range(0, 3):
matrix.SetElement(i, 0, normalizedX[i])
matrix.SetElement(i, 1, normalizedY[i])
matrix.SetElement(i, 2, normalizedZ[i])
# Apply the transforms
transform = vtk.vtkTransform()
transform.Translate(startPoint) # translate to starting point
transform.Concatenate(matrix) # apply direction cosines
transform.RotateZ(-90.0) # align cylinder to x axis
transform.Scale(1.0, length, 1.0) # scale along the height vector
transform.Translate(0, .5, 0) # translate to start of cylinder
# Transform the polydata
transformPD = vtk.vtkTransformPolyDataFilter()
transformPD.SetTransform(transform)
transformPD.SetInputConnection(cylinderSource.GetOutputPort())
# Create a mapper and actor for the arrow
mapper = vtk.vtkPolyDataMapper()
actor = vtk.vtkActor()
if USER_MATRIX:
mapper.SetInputConnection(cylinderSource.GetOutputPort())
actor.SetUserMatrix(transform.GetMatrix())
else:
mapper.SetInputConnection(transformPD.GetOutputPort())
actor.SetMapper(mapper)
actor.GetProperty().SetColor(colors.GetColor3d(my_color))
return actor
def render_scene(my_actor_list):
renderer = vtk.vtkRenderer()
for arg in my_actor_list:
renderer.AddActor(arg)
namedColors = vtk.vtkNamedColors()
renderer.SetBackground(namedColors.GetColor3d("SlateGray"))
window = vtk.vtkRenderWindow()
window.SetWindowName("Oriented Cylinder")
window.AddRenderer(renderer)
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(window)
# Visualize
window.Render()
interactor.Start()
if __name__ == '__main__':
my_list = []
p0 = np.array([0, 0, 0])
p1 = np.array([0, 10, 0])
p2 = np.array([7, 17, 0])
p3 = np.array([-5, 15, 0])
my_list.append(cylinder_object(p0, p1, 1, "Red"))
my_list.append(cylinder_object(p1, p2, 0.8, "Green"))
my_list.append(cylinder_object(p1, p3, 0.75, "Navy"))
render_scene(my_list)
У меня есть несколько актеров, где все они отображаются вместе в одной сцене, могу ли я передать каждого актера в vtk.vtkSTLWriter
? это кажется не работает!
2 ответа
То, что вы ищете, это подклассы vtkExporter
класс, который согласно связанному документу:
vtkExporter - абстрактный класс, который экспортирует сцену в файл. Он очень похож на vtkWriter за исключением того, что писатель записывает только геометрические и топологические данные для объекта, где экспортер может записывать свойства материала, освещение, параметры камеры и т. Д.
Как видно из диаграммы наследования класса, существует около 15 классов, которые поддерживают экспорт такой сцены в файл, который можно просмотреть в соответствующих программах чтения.
ИМХО тот, с которым вам больше всего повезет, это vtkVRMLExporter
класс, так как это довольно распространенный формат. При этом я не верю, что Paraview поддерживает файлы VRML (по крайней мере, на основе некоторых довольно древних сообщений, которые я нашел), но я уверен, что MayaVi поддерживает.
В качестве альтернативы вы можете, как вы упомянули, экспортировать объекты в файлы STL, но файлы STL просто содержат координаты треугольника и информацию о том, как они соединяются. Такие файлы не могут описывать информацию о сцене, такую как камера или информация об освещении. Кроме того, в последний раз я проверял, что один STL-файл может содержать только один объект, так что ваши три цилиндра в конечном итоге будут объединены, поэтому, вероятно, это не то, что вам нужно.
Я добавил эти коды, и он создал VRML
файл из моей отрендеренной сцены.
exporter = vtk.vtkVRMLExporter()
exporter.SetRenderWindow(window)
exporter.SetFileName("cylinders.wrl")
exporter.Write()
exporter.Update()