Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fully de-duplicate vertices in MarchingCube algorithm #83

Open
empet opened this issue Jul 13, 2021 · 2 comments
Open

Fully de-duplicate vertices in MarchingCube algorithm #83

empet opened this issue Jul 13, 2021 · 2 comments

Comments

@empet
Copy link

empet commented Jul 13, 2021

Recently I started using Meshing.isosurface(), with MarchingCubes as method. The docs say that
setting reduceverts=true (default: true) will merge vertices within a voxel to reduce mesh size by around 30%
and with slight performance improvement.

I called both Meshing.isosurface() and skimage.measure.marching_cubes_lewiner(), a Python function from scikit-image,
to extrude a brain within a volumetric data of size (91, 109, 91).
The number of vertices of the corresponding mesh, returned by Meshing function is (345752) almost 4 times greater
than that returned by skimage function (86473).
345752/86473 = 3.99, i.e. it is exaggerated.

Here are the two blocks of code:

using Meshing
using NPZ           
brain_vol = npzread("MNI152.npy") # https://github.com/empet/Datasets/blob/master/MNI152.npy
verts, triangles =  isosurface(brain_vol, MarchingCubes(iso=1.25, reduceverts=true, eps=1e-05))
length(verts),  length(triangles)
(345752, 172932) 
            
#unique vertices:
uni_verts = unique(i -> verts[i], 1:length(verts))
length(uni_verts)
89264 

respectively:

import numpy as np
from skimage import measure            
brain_vol= np.load("MNI152.npy")
verts, triangles = measure.marching_cubes_lewiner(brain_vol, 1.25)[:2] 
len(verts), len(triangles)
(86473, 173070)

The corresponding Jupyter Notebook has the size of 111MB, vs 25MB, when using Python scikit-image.
Otherwise the mesh plot is great in both cases:
iso-brain

@sjkelly
Copy link
Member

sjkelly commented Jul 15, 2021

Cool render, thanks for sharing!

This is expected behavior for MarchingCubes. reduceverts is only merging vertices where it is computationally cheap to do so. I assume scikit is merging vertices across the whole mesh, which requires additional memory during computation, but saves on the vertex count in the end. A simple approach to accomplish the de-duplication of vertex references is through a dictionary. This should be okay for simple meshes, but performance would likely scale poorly with Julia's Dict. Erizo has a fast implementation of this.

MarchingTetrahedra does assure the uniqueness property, but it generates far more triangles. This may be an approach if you need connectivity information, but be aware that it generates far more triangles.

@sjkelly sjkelly changed the title Exaggerated number of vertices returned by isosurface with MarchingCube algorithm Fully de-duplicate vertices in MarchingCube algorithm Jul 15, 2021
@empet empet closed this as completed Jul 16, 2021
@sjkelly sjkelly reopened this Jul 19, 2021
@sjkelly
Copy link
Member

sjkelly commented Jul 19, 2021

To be clear, I think this should be a supported feature, so reopening.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants