Marching Cubes 纯 C++ 实现
- 法线计算:通过梯度计算进行实现,法线的方向可以通过参数进行方向的修改
在 Marching Cubes 算法中,主要存在 Ambitious face 和 Internal ambiguity 这两种歧义。如下图所示:
歧义类型 | Ambitious face | Internal ambiguity |
---|---|---|
歧义图例 | ||
产生原因 | 两对顶点正负情况对内一样,对间相反,导致可以有两种切分方式 | 内部到底是否联通不确定,导致同一个 configuration 可能产生不同的情况 |
解决方案 | 插值得到双曲线渐近线的交点的体素值(具体公式见论文),根据公式可以简化为比较 AC-BD 比较确定该选哪种方案[HTML_REMOVED]NielsonHamann1991[HTML_REMOVED] | 看看能否找到中间的横截面,使得 AC > BD,如果可以找到,证明中间有区域是联通的 |
解决了歧义之后,还需要对 256 种情况进行具体的分析,将其映射为 15 个大类(最初 MC 提出时的 15 种 base case),每个大类有几种小类代表歧义的不同解决方案。
参考 marching_cubes_jgt
这篇论文进行的实现(这篇文章给出了原始代码),能够解决原始 Marching Cubes 的歧义问题,保证生成的等值面一定是流形。这篇文章的方法也是 skimage.measure.marching_cubes_lewiner
实现的。
- 通过 case table 将 256 种情况映射到两个编号
a, b
,其中a
表示原始 MC 论文里面的 15 种情况,值在 0-14 之间。b
则表示每种情况下更具体的情况,主要用来解决歧义问题。 - 通过 test table 来进行插值和
流水线
- 运行 Marching Cubes 生成 obj
- 使用 tinyobjloader 加载并直接使用 Qt 组件进行展示
-
可以使用 Qt UI 组件调节等值面参数等得到不同的效果
-
使用 CUDA 进行加速
参考资料
- lorensen1987, cited by 17154
- 最开始提出的 Marching Cubes 算法并没有解决歧义性问题,因此可能存在裂缝(crack),造成非流形的情况。
- Ambiguity in Marching Cubes
- Efficient implementation of Marching Cubes’ cases with topological guarantees
- 解决了歧义性问题,保证产生的等值面一定是流形,代价仅仅是引入了较大的 lookup table。
skimage.measure.marching_cubes_lewiner
- THOMAS LEWINER’s C++ implementation (ref for lookup table)
- Marching Cubes 33
- The asymptotic decider
- https://www.youtube.com/watch?v=Pi96vMb2r4M
- https://github.com/tinyobjloader/tinyobjloader