在Python中从3D数组创建.obj文件

14

我的目标是使用Python从nifty(.nii)格式获取.obj文件,并将其用于Unity。我知道“scikit-image”包有一个叫做“measure”的模块,其中实现了Marching cube算法。我将Marching cube算法应用到我的数据上,并获得了我期望的结果:

verts, faces, normals, values = measure.marching_cubes_lewiner(nifty_data, 0)

我可以将数据绘制出来:

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(verts[:, 0], verts[:,1], faces, verts[:, 2],
                linewidth=0.2, antialiased=True)
plt.show()

在此输入图像描述

我曾寻找将数据(顶点、面法线、值)保存为.obj格式的函数,但未能找到。因此,我决定自己构建。

thefile = open('test.obj', 'w')
for item in verts:
  thefile.write("v {0} {1} {2}\n".format(item[0],item[1],item[2]))

for item in normals:
  thefile.write("vn {0} {1} {2}\n".format(item[0],item[1],item[2]))

for item in faces:
  thefile.write("f {0}//{0} {1}//{1} {2}//{2}\n".format(item[0],item[1],item[2]))  

thefile.close()

但是当我将数据导入到Unity中时,我得到了以下结果:

图片描述

图片描述

所以我的问题如下:

  • 在.obj制作过程中我做错了什么?
  • 是否有更好的模块或功能可以完成这项工作?
  • 我想要的东西是否可能实现?

谢谢。

更多例子:

Python:

图片描述

Unity:

图片描述


1
相较于您期望的结果,您的结果有何错误之处?您希望它更加平滑吗? - Doh09
明显的,这些面是错误的。我将尝试通过创建最简单的图形(如立方体),然后查看它们应该被编写的顺序来调试它。.obj文件生成过程出了些问题,我仍然不知道原因,因为它应该非常简单。 - Diego Orellana
我不确定是面部还是网格构造中的错误。你的计划听起来很不错,从简单的网格开始。这是一个很好的调试方法。 - Doh09
1个回答

24

解决方案:经过数小时的调试,问题非常简单!只需要在应用 Marching Cubes 算法得到的面数据中加上 +1 即可。问题出在 Python 将 verts 视为从零开始,而 Unity 则将其视为从1开始。这就是为什么它们不匹配的原因!不客气。

verts、faces、normals、values = measure.marching_cubes_lewiner(nifty_data, 0)

faces = faces + 1

成功了!

进入图片描述


哇!非常感谢你。你帮我省了好几个小时的调试时间。谢谢! - Shubham Agrawal

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