c++ 朴素曲面网络算法:如何连接顶点形成三角形?

hujrc8aj  于 2023-05-02  发布在  其他
关注(0)|答案(1)|浏览(140)

我正试图实现朴素的表面网络算法(在c++,opengl)所描述的here。我知道我需要插值穿过曲面的边的端点,然后我需要找到这些插值结果的质心。我不明白的是:我现在有一个单一的顶点为每个非平凡细胞,我如何将这些顶点排列成三角形,形成一个网格?

deyfvvtc

deyfvvtc1#

假设SDF在半整数坐标i处采样。例如,f[0][0][0]是单元格中间的值,该单元格跨越(0,0,0)和(1,1,1)之间的3D空间。如果要使用类似minecraft的立方体网格对其进行体素化,则可以沿着以下方式执行操作:

for each integer x,y,z {
    // X-major
    if(f[z][y][x-1]*f[z][y][x] < 0) {
        v0 = EmitVertex(vec3(x,y,z));
        v1 = EmitVertex(vec3(x,y+1,z));
        v2 = EmitVertex(vec3(x,y,z+1));
        v3 = EmitVertex(vec3(x,y+1,z+1));
        if(f[z][y][x] < 0) {
            // flip order so normal points along negative X
            swap(v0, v3);
        }
        EmitTriangle(v0, v1, v2);
        EmitTriangle(v2, v1, v3);
    }

    // do the same for Y and Z directions
    // ...
}

(Note:我省略了处理f[z][y][x] == 0的复杂性。)
对于表面网络,代码基本上保持相同。您可以使用单元格中心的值(例如:例如f[-1/0][-1/0][-1/0]),以计算位于这些单元之间的顶点的扰动位置p[0][0][0]。平均p[0][0][0] == vec3(0,0,0),但它可以是(-0.5,-0.5,-0.5)和(0.然后运行与上面相同的代码,但不是EmitVertex(vec3(x,y,z)),它将在整数位置发出顶点,而是使用扰动位置:EmitVertex(p[z][y][x])

// precompute vertex locations
for each integer x,y,z {
    p[z][y][x] = vec3(x,y,z) + deviation(
        f[z-1][y-1][x-1], f[z-1][y-1][x], f[z-1][y][x-1], f[z-1][y][x],
        f[z][y-1][x-1], f[z][y-1][x], f[z][y][x-1], f[z][y][x]
    );
}

// generate mesh
for each integer x,y,z {
    // X-major
    if(f[z][y][x-1]*f[z][y][x] < 0) {
        v0 = EmitVertex(p[z][y][x]);
        v1 = EmitVertex(p[z][y+1][x]);
        v2 = EmitVertex(p[z+1][y][x]);
        v3 = EmitVertex(p[z+1][y+1][x]);
        // same as before ...
    }

    // do the same for Y and Z directions
    // ...
}

相关问题