简体   繁体   English

如何使用python将3D vtk渲染的场景导出到paraview?

[英]How to export a 3D vtk rendered scene to paraview using python?

I've wrote a code to produce cylinder objects using vtk in python. 我已经编写了一个代码在python中使用vtk生成圆柱对象。 This code works fine where it produces a 3D scene where i can zoom or turn around the cylinders which i have been made. 此代码在产生3D场景的地方效果很好,在这里我可以缩放或旋转已制成的圆柱体。 The problem is i want to export this rendered scene to paraview to view and save it for later works. 问题是我想将此渲染的场景导出到paraview,以查看并保存以供以后使用。 How can i do this? 我怎样才能做到这一点? Here is the code that produce a Y-shape with cylinders: 以下是产生带有圆柱体的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中带有Python的3D Y形

I have multiple actors where all of them are rendered together in one render scene, can i pass each actor into a vtk.vtkSTLWriter ? 我有多个演员,所有演员都在一个渲染场景中一起渲染,我可以将每个演员传递到vtk.vtkSTLWriter吗? this seems not working! 这似乎不起作用!

What you're looking for is subclasses of the vtkExporter class which, as per the linked doco: 您正在寻找的是vtkExporter类的 ,根据链接的doco:

vtkExporter is an abstract class that exports a scene to a file. vtkExporter是将场景导出到文件的抽象类。 It is very similar to vtkWriter except that a writer only writes out the geometric and topological data for an object, where an exporter can write out material properties, lighting, camera parameters etc. 它与vtkWriter非常相似,不同之处在于写入器只写出对象的几何和拓扑数据,而输出者可以在其中写出材料特性,照明,相机参数等。

As you can see from the inheritance diagram of the class there's about 15 classes that support exporting such a scene into a file that can be viewed in appropriate readers. 从类的继承图中可以看到,大约有15个类支持将此类场景导出到文件中,并可以在适当的阅读器中查看。

IMHO the one you'll have the most luck with is the vtkVRMLExporter class as it's a fairly common format. 恕我直言,最让您幸运的是vtkVRMLExporter类,因为它是一种相当常见的格式。 That being said I don't believe Paraview supports VRML files (at least based on some pretty ancient posts I've found) but I'm pretty sure MayaVi does. 话虽这么说,但我不相信Paraview支持VRML文件(至少基于我发现的一些非常古老的帖子),但是我确定MayaVi可以。

Alternatively you could, as you mentioned, export objects into STL files but STL files simply contain triangle coordinates and info on how they connect. 或者,您可以如上所述将对象导出到STL文件中,但是STL文件仅包含三角形坐标和有关其连接方式的信息。 Such files cannot possibly describe info re the scene such as camera or lighting information. 这样的文件可能无法描述场景信息,例如相机或照明信息。 Also last I checked a single STL file can only contain a single object so your three cylinders would end up being a merged object so its probably not what you want. 最后我检查了一个STL文件只能包含一个对象,因此您的三个柱面最终将成为一个合并对象,因此可能不是您想要的。

I added these codes and it created a VRML file from my rendered scene. 我添加了这些代码,它从渲染的场景创建了一个VRML文件。

exporter = vtk.vtkVRMLExporter()
exporter.SetRenderWindow(window)
exporter.SetFileName("cylinders.wrl")
exporter.Write()
exporter.Update()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM