14

My goal is to get a .obj file from a nifty (.nii) format using python, with the purpose of open it on Unity. I know that the "scikit-image" package has a module called "measure" which has the Marching cube algorithm implemented. I apply the marching cube algorithm to my data and I obtain the results I expect:

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

I can then plot the data:

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()

enter image description here

I have looked for functions to save the data (verts,faces normals, values) as a .obj but I haven't found one. Thus, I decided to build it myself.

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()

But when I import the data to unity I got the following result:

enter image description here

enter image description here

So my questions are the followings:

  • What I'm doing wrong in the .obj making process?
  • Is there a module or function that do this in a better way?
  • Is it possible at all to do what I want?

Thank you.

More examples:

Python:

enter image description here

Unity:

enter image description here

3
  • 1
    What about your result is wrong compared to how you want it to be? Would you like it to be more smooth or? Commented Feb 17, 2018 at 19:31
  • Clearly the faces are wrong, I will try to debug it by creating the simplest figures, like a cube and then see what order they should be written, that is my plan. The .obj making process is somehow wrong, I still don't know why as it should be very simple. Commented Feb 17, 2018 at 19:56
  • Well I wasn't sure if it was the faces or an error in the mesh construction. Your plan sounds like a good idea with starting out with simpler meshes. Good way to debug. Commented Feb 17, 2018 at 20:02

1 Answer 1

24

Solution: After hours of debugging, the solution was very simple! Just add +1 to the faces data given by applying the marching cubes. The problem was that Python considered the verts as starting from 0 and unity consider them as starting from 1. That is why they didn't match! You welcome.

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

faces=faces +1

Success!

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.