【问题标题】:Visualizing a 3D datastructure可视化 3D 数据结构
【发布时间】:2012-09-11 03:15:23
【问题描述】:

我有一个 C 代码中的 3D 数据结构,我想将其可视化为 3D 空间中的框和点。所以我有一堆坐标,一些用于点,一些用于框,我想以 3D 形式绘制这些坐标以可视化数据结构。有没有人做过类似的事情的经验?我开始尝试使用 paraview。我的计划是生成一个 paraview 状态文件(xml 类型文件),然后用 paraview 打开它。问题是那些状态文件庞大而复杂。为了尝试找出 xml 结构,我在 paraview 中创建了 Boxes 和 Point 源,然后查看了它生成的状态文件。看起来很糟糕。

我只想能够以简约的方式显示一个带有这些坐标的框和一个带有这些坐标的点。谁有想法?不必一定在 C 或 paraview 中,因为我可以输出坐标并输入生成最终产品的任何内容。如果 Python + Matlab 能正常工作,它也能正常工作。

【问题讨论】:

  • 我认为 paraview 是我的选择。您是否尝试使用 VTK 文件?它们真的没有那么复杂。并且可以编写二进制文件,这对于大型数据集很有用。
  • 你想显示的盒子,你的意思是把坐标系设置到那个“盒子”或者画一个盒子然后在3D中绘制一个点?
  • 没有尝试 vtk 文件。 paraview可以导入vtk文件吗?
  • 框我的意思是除了 3D 空间中的点之外,我还想在 3D 空间中绘制一个立方体。并且最好能够以交互方式拖动空间(paraview 似乎更擅长)。

标签: matlab 3d visualization paraview


【解决方案1】:

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

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

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

Matlab 似乎非常擅长绘制数学图形,但我对它的相当陈旧的记忆是它非常缓慢且操作起来很麻烦。

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

如果它需要一些用户交互、一个独立的应用程序、更复杂的渲染并且数据集并不庞大,或者您可以将其编译为 C#(即不使用指针),您可能想看看 Unity。它为您简化了一个数量级的 3D 渲染,您只需要编写 C# 来生成您想要渲染的网格/粒子并将一些简单的相机控件放入(或导入您的 collada 文件)。棘手的一点是,如果您是新手,则需要一两天时间来熟悉为您的目的生成网格。

或者,您可以通过 HTML5 在 WebGL 中对其进行编码,或者更好地使用其他人的 WebGL 系统来为您完成!

如果您选择这条路线,这里有一些值得一看的项目。我最喜欢的是 PlayCanvas,如果您只需要生成它们,我相信它也会获取您的 collada 文件。

还有 SceneJS.org,它更原始,还没有亲自尝试过,但也应该提到它。

【讨论】:

    【解决方案2】:

    既然您的数据似乎并不复杂...为什么不将其导出为 CSV 文件?

    您可以从ParaViewMATLAB 等打开它...此外,它是一个非常简单的实现。

    如果您的数据不会变得比这更复杂,我会选择这个。

    编码愉快!

    【讨论】:

      【解决方案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,您将获得所需的结果。这是一个简单的例子,所有东西都是统一的:

      所以我只是将我的 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")
      

      【讨论】:

        猜你喜欢
        • 2011-06-20
        • 2020-09-16
        • 1970-01-01
        • 2010-09-11
        • 1970-01-01
        • 2019-09-15
        • 1970-01-01
        • 1970-01-01
        • 2013-10-15
        相关资源
        最近更新 更多