Forceflow / cuda_voxelizer

CUDA Voxelizer to convert polygon meshes into annotated voxel grids
MIT License
595 stars 98 forks source link

Some axis-aligned surfaces do not generate voxels #7

Closed chaosink closed 4 years ago

chaosink commented 6 years ago

failure

The testing OBJ file: http://s000.tinyupload.com/index.php?file_id=68607642443901015496

Forceflow commented 6 years ago

Interesting. Probably a rounding error. Will look into this!

Forceflow commented 6 years ago

For a temporary, ugly fix: pad your models with some temp triangles so their bounding box is slightly bigger than the object you're trying to voxelize.

chaosink commented 6 years ago

non-border Not only at the border surface.

Forceflow commented 6 years ago

Ugh, that means it's even worse. I'm going to pull up the paper I used for the algorithm again, need some time to dig into this. I remember testing this tool on an AABox for sanity, and it did not fail the way you demonstrate.

You using the latest GLM version? I doubt it's a GLM bug, but you never know.

Will look into this, but need some time to step through the whole algorithm again and dust it off in my head.

For a real ugly temporary fix ... you guessed it ... slightly rotate your model. :)

chaosink commented 6 years ago

I also suspect the bug comes from GLM. But I test on GLM-0.9.8.5 (the link in README) and GLM-0.9.9.3 (the latest version), and the bug occurs for the both.

Forceflow commented 5 years ago

I also suspect the bug comes from GLM. But I test on GLM-0.9.8.5 (the link in README) and GLM-0.9.9.3 (the latest version), and the bug occurs for the both.

I don't understand ... from that, I would conclude it's not a GLM bug.

Forceflow commented 5 years ago

Finally, some further research on this problem: The problem goes away if you voxelize at a non-cubic size (for example, 257 instead of 256).

I think there is an edge case where a triangle lies perfectly on a voxel cube's side (as if it was part of the side itself), and the algorithm sometimes counts it as "yep, it touches this voxel" and as "nope not in this voxel".

A very ugly fix is offsetting the bounding box calculations by a small epsilon:

float epsilon = 0.00001f;
answer.min = answer.min - glm::vec3(epsilon, epsilon, epsilon);
answer.max = answer.max + glm::vec3(epsilon, epsilon, epsilon);
return answer;
Forceflow commented 5 years ago

fix

Forceflow commented 4 years ago

Marking this as "ugly" fixed. Some day I'll dig into the nitty gritty of the edge case where this happens, but for now, this'll do. I've been testing a ton of models lately haven't encountered this again.