neurolabusc / nii2mesh

Convert NIfTI volume to triangulated mesh using marching cubes
https://rordenlab.github.io/nii2meshWeb/
Other
150 stars 18 forks source link

segfault when meshing a volume with non-zero voxels on the bounding-box #2

Closed fangq closed 2 years ago

fangq commented 2 years ago

while I was testing the below command as part of PR #1

cd src
make JSON=1
cd ../data
 ../src/nii2mesh digimouse.jnii -i 0.5 -v 1 test.bmsh

I got a segfault in several computers I tested. However, running valgrind with the above command completed without a problem. I traced the crash to the marchingCubes function.

The volume digimouse.jnii contains segmentation labels from 0 to 21. Setting -i 0.5, I meant to extract the exterior surface. in such case, the hi bbx corner matches the maximum z-axis (104)

marching cubes (190x496x104): lo: [8 20 4] hi: [174 466 104], isolevel: 0.500000

if I remove -i 0.5, and let nii2mesh to choose the default isolevel, the program runs without an error, it prints the below parameters, note that the bbx bounded by lo/hi are no longer align with the outer boundary

marching cubes (190x496x104): lo: [26 171 12], hi: [156 332 95], isolevel= 7.975141

so I suspected that the marchingCubes function has some robustness issues when processing surfaces along the exterior bbx of the volume.

do you know what is the expected behavior for the marching-cubes module in such case? as I mentioned, when running valgrind, it did output a valid mesh, see below

segfault_digimouse

digimouse_i0 5

neurolabusc commented 2 years ago

Curious.

  1. Did you try compiling with OLD=1 make -j which will use the classic marching cubes instead of Lewiner's tables?
  2. If you use Clang, I find the sanitize mode is a great way to isolate problems. You can try this
    g++ -O1 -g -fsanitize=address -fno-omit-frame-pointer  ....
  3. Feel free to share the problematic file with me.
  4. The rationale for this project is a minimal test case for an AFNI bug. So it would be a good opportunity to sort this out.
fangq commented 2 years ago
  1. Did you try compiling with OLD=1 make -j which will use the classic marching cubes instead of Lewiner's tables?

using OLD=1, this error does not appear, so, it is related to the Lewiner's marching cube code

  1. If you use Clang, I find the sanitize mode is a great way to isolate problems. You can try this

I am getting a few errors when compiling with g++/clang++, I admit that I have been mostly using gcc.

  1. Feel free to share the problematic file with me.

the file, digimouse.nii, can be found from checking out the main repo at https://github.com/NeuroJSON/nii2mesh, and the file is located under data/. You will need to build nii2mesh using JSON=1 to read the .jnii file. If you do not build JSON=1, you can test this .nii.gz file.

digimouse.nii.gz