seung-lab / zmesh

Marching Cubes & Mesh Simplification on multi-label 3D images.
GNU General Public License v3.0
58 stars 8 forks source link

How to combine surfaces from chunks (or how to deal with a real large region) #21

Closed HHHit closed 2 years ago

HHHit commented 2 years ago

I am trying to generate the surface mesh of a very larger object (the bounding box is around 8000x8000x1400 voxels), which requires a very large memory. I am wondering if there is a way to combine the meshes generated from each chunck? (like 800x800x140 voxels) Thanks

william-silversmith commented 2 years ago

Hi HHHit! I work on another system that is exactly for this problem. Check out https://github.com/seung-lab/igneous if you are working in the neuroglancer ecosystem. Otherwise, you can use cloudvolume.Mesh.concatenate

HHHit commented 2 years ago

Thanks for replying! Currently, I am trying to generate a .obj file for the object. Just to make sure, I can first use zmesh to generate the surface mesh for each chunk (from binary 3D segmentation) and then concatenate them using cloudvolume.Mesh.concatenate, is that right? I quickly looked into the code of cloudvolume.Mesh.concatenate, it seems to simply combine the array of vertices, faces. But what about that faces between chunks, can it also connect the vertices between chunks?

william-silversmith commented 2 years ago

If you make sure to mesh with 1 voxel overlap, the edges will line up exactly. You can then use the cloudvolume calls to remove duplicate vertices which should yield a proper mesh.

HHHit commented 2 years ago

I am still confused about how to transfer from Zmesh to cloudvolume.Mesh. What if I obtained the faces and vertices of the meshes from two chunks separately, how can I use cloudvolume.Mesh.concatenate to combine these two?

william-silversmith commented 2 years ago

The zmesh Mesh is code that's copied from cloudvolume and stripped down. Just do:

from cloudvolume import Mesh
m1 = zmesh.get_mesh(...)
m1 = Mesh(m1.vertices, m1.faces)
...
mesh = Mesh.concatenate(m1, m2)
mesh = mesh.consolidate() # if you don't have self-contacts
mesh = mesh.deduplicate_chunk_boundaries(chunk_size=(512,512,512)) # if 512,512,512 is your chunk size