谁能为我提供用于进行立方体竞赛的最小三角表?

时间:2019-05-26 18:46:48

标签: lookup-tables marching-cubes symmetry

行进立方体算法使用一个表从256种可能的角组合(“个案”)中查找任何给定立方体配置的三角形顶点的所有边索引。根据{{​​3}} 在最简单的情况下(不考虑歧义情况),任何情况下最多有4个三角形,或者说每种情况下最多12个三角形顶点,这意味着表格必须具有256 * 12个条目。现在观察对称性,即对于案例索引n> 127,条目与案例255-n相同,每隔第二和第3个三角形顶点索引交换一次,就可以将表大小减少一半,只有128 * 12个条目。 谁能为我提供这么小的查询表?

我知道this 每个案例最多包含5个三角形。我不知道为什么5个而不是4个,可能对于模棱两可的情况?此外,此表与应用的交换也不对称。

另外还有一个table (1),具有256 * 12加上终止符“ -1”,这正是我要寻找的,但是此表在某些情况下会在表面上产生孔,至少在table (2)。 对于第二张表,我在互联网上其他任何地方都找不到合适的拐角和边缘索引。有人知道吗?

下面显示的是我将使用对称技巧读取表的OpenCL C代码:

uint marching_cubes(const float3* p, const float* v, const float iso, float3* t) { // input: 8 positions p with 8 values v, isovalue; output: returns number of triangles, 12 triangle vertices t
    const uchar triangle_table[128*12] = { // termination value 15
        +++ insert table here +++
    };
    int cube = 0; // determine case index of which vertices are inside of the isosurface
    #pragma unroll
    for(uint i=0; i<8; i++) cube |= (v[i]<iso)<<i;
    if(cube==0 || cube==255) return 0; // cube is entirely inside/outside of the surface
    float3 vertex[12]; // find the vertices where the surface intersects the cube
    vertex[ 0] = interpolate_vertex(p[0], p[1], v[0], v[1], iso); // calculate vertices on all 12 edges
    vertex[ 1] = interpolate_vertex(p[1], p[2], v[1], v[2], iso);
    vertex[ 2] = interpolate_vertex(p[2], p[3], v[2], v[3], iso);
    vertex[ 3] = interpolate_vertex(p[3], p[0], v[3], v[0], iso);
    vertex[ 4] = interpolate_vertex(p[4], p[5], v[4], v[5], iso);
    vertex[ 5] = interpolate_vertex(p[5], p[6], v[5], v[6], iso);
    vertex[ 6] = interpolate_vertex(p[6], p[7], v[6], v[7], iso);
    vertex[ 7] = interpolate_vertex(p[7], p[4], v[7], v[4], iso);
    vertex[ 8] = interpolate_vertex(p[0], p[4], v[0], v[4], iso);
    vertex[ 9] = interpolate_vertex(p[1], p[5], v[1], v[5], iso);
    vertex[10] = interpolate_vertex(p[2], p[6], v[2], v[6], iso);
    vertex[11] = interpolate_vertex(p[3], p[7], v[3], v[7], iso);
    uint tn=0, lookup; // number of triangles, temporary lookup index
    const bool ch = cube<128;
    cube = (ch?cube:255-case)*12; // invert index when it is above 127
    for(uint i=0; i<12&&triangle_table[cube+i]!=15; i+=3) { // create the triangles
        lookup = triangle_table[cube+i+(ch?2:1)]; t[3*tn+2] = vertex[lookup]; // swap triangle points 2 and 3 if case index is above 127
        lookup = triangle_table[cube+i+(ch?1:2)]; t[3*tn+1] = vertex[lookup]; // swap triangle points 2 and 3 if case index is above 127
        lookup = triangle_table[cube+i         ]; t[3*tn++] = vertex[lookup]; // increment triangle number tn
    }
    return tn; // return number of triangles
}

编辑:将表(1)与表(2)进行比较后,我意识到corner and edge indexing对于两个表确实是相同的。没有对称技巧,表(1)可以完美工作,而表(2)严格执行14种不同的corner and edge indexing,会在表面上产生孔。将表(1)中的5个三角形的条目替换为表(2)中的相应条目,也会产生孔。看来cases不适用于倒角,这里需要5个三角形。

0 个答案:

没有答案