用Python和wxPython进行3D/4D图形绘制?

14 投票
5 回答
5731 浏览
提问于 2025-04-17 03:55

我在日常工作中是一名博士生,主要做地质建模。在业余时间(主要是为了好玩),我在学习Python,并尝试写一个简单的程序来查看3D地质模型。

地质模型 http://img710.imageshack.us/img710/6503/sgems.png geo model2

这个地质模型其实就是一个3D的网格,每个网格单元都有一些值(右边的图就是这样)。所以我希望我的查看器能够像右边的图片那样显示一个3D网格模型。此外,我还希望它能够显示模型在x、y和z方向上的截面(左边的图展示了这一点)。

我还希望这些模型能够围绕三个轴旋转,并且可以放大和缩小。

我做了一些初步的调查(主要是在这里),看起来VisVis和VTK是两个可能的选择。我打算使用wxPython来做主要的图形界面,看来这两个选项都可以和wxPython一起使用,至少从我目前的了解来看是这样的。

我有一些问题:

  1. 我说VisVis和VTK适合我想做的事情,这样说对吗?它们之间有哪个更好用吗?

  2. 这两个选项中,哪个实现起来更简单?

  3. 还有其他我应该考虑的选项吗?

请记住,我对Python还算是新手,对wxPython更是完全陌生。

5 个回答

7

这里有一个简单的例子,展示了如何使用Mayavi的mlab接口来处理一些地质数据:

from mayavi import mlab
import geoprobe

vol = geoprobe.volume('Volumes/example.vol')
data = vol.load()  #"data" here is just a 3D numpy array of uint8's

fig = mlab.figure(bgcolor=(1., 1., 1.), fgcolor=(0., 0., 0.), size=(800,800))
grid = mlab.pipeline.scalar_field(data)

# Have things display in kilometers with no vertical exxageration
# Each voxel actually represents a 12.5 by 18.5 by 5 meter volume.
grid.spacing = [vol.dxW / 1000, vol.dyW / 1000, vol.dz / 1000]

# Now, let's display a few cut planes. These are interactive, and are set up to 
# be dragged around through the volume. If you'd prefer non-interactive cut 
# planes, have a look at mlab.pipeline.scalar_cut_plane instead.
orientations = ['x', 'x', 'y', 'z']
starting_positions = [vol.nx//4, 3*vol.nx//4, vol.ny//2, vol.nz]
for orientation, start_pos in zip(orientations, starting_positions):
    plane = mlab.pipeline.image_plane_widget(grid, colormap='gray',
            plane_orientation='%s_axes' % orientation, slice_index=start_pos)

    # High values should be black, low values should be white...
    plane.module_manager.scalar_lut_manager.reverse_lut = True

mlab.show()

在这里输入图片描述

(数据和处理数据格式的代码(geoprobe模块)可以在这里找到:http://code.google.com/p/python-geoprobe/

虽然我同意从长远来看学习VTK会更好,但使用Mayavi你可以很快上手。它的一个大优点是,你不需要费劲去把数据转换成VTK格式。TVTK和Mayavi允许你直接使用numpy数组。

10

在我的情况下,我直接选择了使用Python的VTK绑定。老实说,我觉得用VTK比用Mayavi简单,部分原因是文档更好(有很多很多的例子!)。我感觉Mayavi在我完成任务的路上增加了额外的复杂性。不过tom10说得对,等你开始后,使用Mayavi可能会更简单。

另外,Mayavi提供了一个叫做TVTK的库,它是VTK绑定的一个更符合Python风格的版本,但最后我选择了普通的VTK,以减少依赖项的数量。不过你可以去看看,也许它正是你所寻找的。

一开始,我觉得这个教程非常有帮助。虽然它是关于tcl的,不是Python,但翻译例子很简单,而且它能帮助你理解VTK的工作方式。

此外,为了帮助你入门,你可以查看VTK Wiki上的例子。如果这些例子不够,你还可以查看C++例子,然后把它们翻译成Python。翻译并不难,因为方法和属性的名称是相同的。如果你这样做,建议你把这些例子添加到wiki上。源代码中还有更多例子,链接在这里:source

在学习VTK的过程中,你会(重新)发现Ipython真是太棒了!能够随时使用整个VTK命名空间帮助很大。

如果你需要更具体的帮助,vtk-users邮件列表非常活跃。最后,还有关于VTK的书籍,其中一些是免费的!不过它们不是关于Python的。

我没有尝试过将wxPython和VTK一起使用,但这是因为我更喜欢PyQt4而不是wxPython。根据我所知,VTK与这两个库的集成没有问题。无论如何,在花时间编写GUI之前,建议你仔细查看ParaView。它可能已经能满足你的需求,如果不能,它也是可用Python脚本编写的!不过我自己从来没有检查过。

13

你要找的东西叫做 体素 可视化,或者 体素网格 之类的。可以考虑一下 MayaVi(我自己没用过,但一直在关注),它似乎有一些非常接近的功能 在这里

还有 Paraview,它是基于 VTK 构建的,和 MayaVi 类似,也可能是个不错的选择。

我觉得直接使用 VTK 来做可视化会比较困难,因为它太底层了,可能会让你感到沮丧。不过,你需要将数据保存为 VTK 数据集,这样才能在 MayaVi 或 Paraview 中打开;这并不难,你只需要选择正确的结构(比如 vtkGrid、vtkUnstructuredGrid 等等)。

撰写回答