可视化3D数据结构

4
我有一个用C代码编写的3D数据结构,我想将其可视化为三维空间中的盒子和点。因此,我有一堆坐标,其中一些是点,另一些是盒子,我想在三维空间中绘制这些以可视化数据结构。有没有人做过类似的事情?我开始尝试使用paraview。我的计划是生成一个paraview statefile(xml类型文件),然后只需用paraview打开它。问题是这些状态文件非常庞大且复杂。为了尝试弄清楚xml结构,我在paraview中创建了盒子和点源,然后查看它生成的状态文件。看起来很糟糕。
我只想以简约的方式显示具有这些坐标的盒子和点。有没有人有任何想法?不一定要使用C或paraview,因为我可以输出坐标并在任何输入中生成最终产品。如果能够实现,Python + Matlab也可以。

我认为Paraview会是我的选择。你尝试使用过VTK文件吗?它们并不是那么复杂。而且你可以编写二进制文件,这对于大型数据集非常有用。 - angainor
你想要展示的那个盒子,是指将坐标系设置为该“盒子”,还是在三维空间中绘制一个盒子并标注一个点? - macduff
没有尝试过vtk文件。ParaView可以导入vtk文件吗? - user926914
我所说的“盒子”,是指我想在三维空间中绘制一个立方体,除了在三维空间中绘制点之外。最理想的情况是能够交互地拖动空间(似乎Paraview更擅长此项功能)。 - user926914
3个回答

3

我想到了一个不错的折中方案。我按照这里描述的git代码开始:

http://www.shocksolution.com/microfluidics-and-biotechnology/visualization/python-vtk-paraview/

这只是一个Python文件。该代码的要点在于,它允许您提供点的x、y、z位置和半径,并输出VTK格式的XML文件。因此,为了制作粒子效果,我只需将x、y、z位置及所有粒子的常数半径传递给它。然后我只需在数据集上制作球形标志。

对于盒子,我使用完全相同的代码。对于每个盒子,我仍然输出其x、y、z坐标,其中x、y、z值是盒子中心的坐标。然后,对于“半径”参数,我使用立方体的边长。这是有效的,因为在ParaView中,我只需为盒子的数据点设置标志,使用盒子标志并通过缩放标量比例来控制标量值。如果您不将盒子标志定向并将标量因子设置为1,则会得到所需的结果。这是一个简单的统一示例:

Simple Uniform Tree

因此,我只需将我的C数据结构中的坐标输出到CSV文件中,然后在Python中提取文件并使用链接中的代码,并用ParaView打开结果。以下是我如何使用该链接中的代码:

from vtktools import VTK_XML_Serial_Unstructured
import sys

if len(sys.argv) > 2:
    treeFile = sys.argv[1]
    bodyFile = sys.argv[2]
else:
    print 'No input files'
    exit(4)

x = []
y = []
z = []
r = []

f = open(treeFile, 'r')
for line in f:
    v = line.split(',')
    x.append(float(v[0].strip()))
    y.append(float(v[1].strip()))
    z.append(float(v[2].strip()))
    r.append(float(v[3].strip()))
f.close()

temp = treeFile.split('/')
if (len(temp) == 1):
    temp = temp[0]
else:
    temp = temp[-1]
tree_writer = VTK_XML_Serial_Unstructured()
tree_writer.snapshot(temp.split('.',1)[0] + '.vtu', x, y, z, [], [], [], [], [], [], r)
tree_writer.writePVD("octree.pvd")
x = []
y = []
z = []
r = []

f = open(bodyFile, 'r')
for line in f:
    v = line.split(',')
    x.append(float(v[0].strip()))
    y.append(float(v[1].strip()))
    z.append(float(v[2].strip()))
    r.append(float(v[3].strip()))
f.close()

temp = bodyFile.split('/')
if (len(temp) == 1):
    temp = temp[0]
else:
    temp = temp[-1]
body_writer = VTK_XML_Serial_Unstructured()
body_writer.snapshot(temp.split('.',1)[0] + '.vtu', x, y, z, [], [], [], [], [], [], r)
body_writer.writePVD("distribution.pvd")

2
由于您的数据似乎不太复杂...为什么不将其导出为CSV文件呢?
您可以从ParaViewMATLAB等软件中打开它...此外,这是一个非常直接的实现。
如果您的数据不会变得更加复杂,我会选择这种方法。
祝编码愉快!

0

如果您的算法是纯C,并且生成静态或预先制作的动画数据,您可能希望将其导出为XML格式或专有格式,这将打开许多选项。

Collada是一种XML格式,旨在以软件不可知的方式表示3D对象,绝对值得一看。然后,您可以在许多应用程序中打开它进行查看,甚至包括Max和Maya,这意味着无需编码即可查看它。还有可用的引擎可以本地读取这些导出文件。

至于其他特定的可视化方式,这可能是一个完全开放的答案,因此取决于您要尝试可视化的项目数量以及需要多少交互,以下是一些建议,但我知道这只是冰山一角。

Matlab似乎非常擅长绘制数学图形,但我对它的记忆已经过时了,它非常缓慢而且笨重。

如果它只是简单的Gouraud阴影纹理,而您想要完全控制,那么就选择本地OpenGL程序,因为这里没有太可怕的东西。这也意味着您可以保留C代码。缺点是它需要更长时间,特别是如果您需要处理相机控制或“像素质量”问题。也就是说,如果您正在寻找阴影,动画,着色器效果等,请继续阅读...

如果需要用户交互、一个独立的应用程序、更复杂的渲染以及数据集并不是很大,或者你可以将其编译为C#(即没有使用指针),那么你可能想要看一下Unity。它能够使3D渲染简单了许多,你只需要编写C#代码生成你想要渲染的网格/粒子,并添加一些简单的相机控制(或导入你的collada文件)。其中棘手的部分是,如果你是新手,需要花一两天时间熟悉如何生成适合你目的的网格。

另外,你还可以通过HTML5中的WebGL进行编码,或者更好的方法是使用别人的WebGL系统来完成!

如果你选择这种方式,有一些值得一看的项目。我最喜欢的是PlayCanvas,我相信它也可以使用你的collada文件,如果你只需要生成它们的话。

还有SceneJS.org,它更加原始,我个人还没有尝试过,但如果你感兴趣的话,我也要提一下。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接