【问题标题】:Estimating size of marching cubes output geometry估计行进立方体输出几何的大小
【发布时间】:2020-11-29 23:13:48
【问题描述】:

有没有一种方法可以快速估计行进立方体算法将产生多少几何图形?就像对 num verts + num faces 或 STL 文件大小的粗略估计一样?

我正在尝试实施预三角检查,告诉用户降低分辨率(即使用更少的样本数,跨越更大的空间区域),或者在无意中尝试生成多区域之前减小域大小GB-large STL 文件的隐式曲面网格,任何切片软件都无法处理。

在最坏的情况下,我可能会生成一大堆具有不同设置的 STL 来找出这些值。

【问题讨论】:

    标签: marching-cubes


    【解决方案1】:

    修改 Marching Cubes 代码使其仅计算顶点数和三角形数并不难。我认为您提出的这个选项可能很有用。您只需确定顶点(以及法线和颜色)和三角形的索引存储在代码的哪一部分中。对于我们编写的 C 语言的 Marching Cubes 33 代码 (marching_cubes_33_c_library_v4, MC33_libraries),顶点存储在 MC33_storePointNormal 函数中。不是调用 MC33_storePointNormal,而是简单地将顶点计数器增加 1。在这种特定情况下,存储三角形索引的代码被删除,只剩下三角形数量的计数器增量。

    我做了一个函数,统计顶点和三角形的个数,并计算曲面占用的内存量:

    // modified from calculate_isosurface function
    unsigned long long memory_of_isosurface (MC33 * M, float iso, unsigned int * nV, unsigned int * nT);
    

    此函数调用 MC33_findCase_count 函数而不是调用 MC33_findCase 函数。您只需将两个函数的代码复制到 source/marching_cubes_33.c 文件的末尾,并将 memory_of_isosurface 函数的声明放在 include/marching_cubes_33.h 文件中。

    我对只计数的函数进行了基准测试,执行时间减少了 12% 到 32% 之间。

    重要提示:由于帖子篇幅原因,我删除了部分代码,switch (c>>8)。这部分代码必须从 MC33_findCase 函数中复制。

    // modified from MC33_findCase
    
    void MC33_findCase_count(MC33 *M, unsigned int x, unsigned int y, unsigned int z, unsigned int i, float *v)
    {
        unsigned int p[13] = {FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF,FF};
        int f[6];
        unsigned int ti[3];
        unsigned int c, m, k;
        const unsigned short int *pcase = MC33_all_tables;
        c = pcase[i&0x80? i^0xFF: i];
        m = (i^c)&0x80;
        k = c&0x7F;
        switch (c>>8)
        {
            /* copy here the missing code part from the MC33_findCase function */
        }
        while (i)
        {
            i = *(++pcase);
            for (k = 3; k;)
            {
                c = i&0x0F;
                if (p[c] == FF)
                {
                    switch (c)
                    {
                    case 0:
                        if (z || x)
                            p[0] = M->Oy[y][x];
                        else
                        {
                            if (v[0] == 0)
                            {
                                if (p[3] != FF)
                                    p[0] = p[3];
                                else if (p[8] != FF)
                                    p[0] = p[8];
                                else if (y && signbf(v[3]))
                                    p[0] = M->Lz[y][0];
                                else if (y && signbf(v[4]))
                                    p[0] = M->Ox[y][0];
                                else if (y? sbf(M->iso - M->F[0][y - 1][0]): 0)
                                    p[0] = M->Oy[y - 1][0];
                                else
                                    p[0] = M->nV++;
                            }
                            else if (v[1] == 0)
                            {
                                if (p[1] != FF)
                                    p[0] = p[1];
                                else if (p[9] != FF)
                                    p[0] = p[9];
                                else
                                    p[0] = M->nV++;
                            }
                            else
                                p[0] = M->nV++;
    
                            M->Oy[y][0] = p[0];
                        }
                        break;
                    case 1:
                        if (x)
                            p[1] = M->Lz[y + 1][x];
                        else
                        {
                            if (v[1] == 0)
                            {
                                if (p[0] != FF)
                                    p[1] = p[0];
                                else if (p[9] != FF)
                                    p[1] = p[9];
                                else if (z && signbf(v[0]))
                                    p[1] = M->Oy[y][0];
                                else if (z && signbf(v[5]))
                                    p[1] = M->Ox[y + 1][0];
                                else if (z && y + 1 < M->ny? sbf(M->iso - M->F[z][y + 2][0]): 0)
                                    p[1] = M->Oy[y + 1][0];
                                else if (z? sbf(M->iso - M->F[z - 1][y + 1][0]): 0)
                                    p[1] = M->Lz[y + 1][0];
                                else
                                    p[1] = M->nV++;
                            }
                            else if (v[2] == 0)
                            {
                                if (p[2] != FF)
                                    p[1] = p[2];
                                else if (p[10] != FF)
                                    p[1] = p[10];
                                else
                                    p[1] = M->nV++;
                            }
                            else
                                p[1] = M->nV++;
                            M->Lz[y + 1][0] = p[1];
                        }
                        break;
                    case 2:
                        if (x)
                            p[2] = M->Ny[y][x];
                        else
                        {
                            if (v[3] == 0)
                            {
                                if (p[3] != FF)
                                    p[2] = p[3];
                                else if (p[11] != FF)
                                    p[2] = p[11];
                                else if (y && signbf(v[0]))
                                    p[2] = M->Lz[y][0];
                                else if (y && signbf(v[7]))
                                    p[2] = M->Nx[y][0];
                                else if (y? sbf(M->iso - M->F[z + 1][y - 1][0]): 0)
                                    p[2] = M->Ny[y - 1][0];
                                else
                                    p[2] = M->nV++;
                            }
                            else if (v[2] == 0)
                            {
                                if (p[1] != FF)
                                    p[2] = p[1];
                                else if (p[10] != FF)
                                    p[2] = p[10];
                                else
                                    p[2] = M->nV++;
                            }
                            else
                                p[2] = M->nV++;
                            M->Ny[y][0] = p[2];
                        }
                        break;
                    case 3:
                        if (y || x)
                            p[3] = M->Lz[y][x];
                        else
                        {
                            if (v[0] == 0)
                            {
                                if (p[0] != FF)
                                    p[3] = p[0];
                                else if (p[8] != FF)
                                    p[3] = p[8];
                                else if (z && signbf(v[1]))
                                    p[3] = M->Oy[0][0];
                                else if (z && signbf(v[4]))
                                    p[3] = M->Ox[0][0];
                                else if (z? sbf(M->iso - M->F[z - 1][0][0]): 0)
                                    p[3] = M->Lz[0][0];
                                else
                                    p[3] = M->nV++;
                            }
                            else if (v[3] == 0)
                            {
                                if (p[2] != FF)
                                    p[3] = p[2];
                                else if (p[11] != FF)
                                    p[3] = p[11];
                                else
                                    p[3] = M->nV++;
                            }
                            else
                                p[3] = M->nV++;
                            M->Lz[0][0] = p[3];
                        }
                        break;
                    case 4:
                        if (z)
                            p[4] = M->Oy[y][x + 1];
                        else
                        {
                            if (v[4] == 0)
                            {
                                if (p[8] != FF)
                                    p[4] = p[8];
                                else if (p[7] != FF)
                                    p[4] = p[7];
                                else if (y && signbf(v[0]))
                                    p[4] = M->Ox[y][x];
                                else if (y && signbf(v[7]))
                                    p[4] = M->Lz[y][x + 1];
                                else if (y? sbf(M->iso - M->F[0][y - 1][x + 1]): 0)
                                    p[4] = M->Oy[y - 1][x + 1];
                                else if (y && x + 1 < M->nx? sbf(M->iso - M->F[0][y][x + 2]): 0)
                                    p[4] = M->Ox[y][x + 1];
                                else
                                    p[4] = M->nV++;
                            }
                            else if (v[5] == 0)
                            {
                                if (p[9] != FF)
                                    p[4] = p[9];
                                else if (p[5] != FF)
                                    p[4] = p[5];
                                else
                                    p[4] = M->nV++;
                            }
                            else
                                p[4] = M->nV++;
                            M->Oy[y][x + 1] = p[4];
                        }
                        break;
                    case 5:
                        if (v[5] == 0)
                        {
                            if (signbf(v[4]))
                            {
                                if (z)
                                {
                                    p[5] = p[4] = M->Oy[y][x + 1];
                                    if (signbf(v[1]))
                                        p[9] = p[5];
                                }
                                else
                                {
                                    if (p[4] != FF)
                                        p[5] = p[4];
                                    else if (p[9] != FF)
                                        p[5] = p[9];
                                    else
                                        p[5] = M->nV++;
                                }
                            }
                            else if (signbf(v[1]))
                            {
                                if (z)
                                    p[5] = p[9] = M->Ox[y + 1][x];
                                else
                                {
                                    if (p[9] != FF)
                                        p[5] = p[9];
                                    else
                                        p[5] = M->Ox[y + 1][x] = p[9] = M->nV++;
                                }
                            }
                            else
                            {
                                if (z && x + 1 < M->nx? sbf(M->iso - M->F[z][y + 1][x + 2]): 0)
                                    p[5] = M->Ox[y + 1][x + 1];
                                else if (z && y + 1 < M->ny? sbf(M->iso - M->F[z][y + 2][x + 1]): 0)
                                    p[5] = M->Oy[y + 1][x + 1];
                                else if (z? sbf(M->iso - M->F[z - 1][y + 1][x + 1]): 0)
                                    p[5] = M->Lz[y + 1][x + 1];
                                else
                                    p[5] = M->nV++;
                            }
                        }
                        else if (v[6] == 0)
                        {
                            if (p[6] == FF)
                            {
                                if (p[10] == FF)
                                {
                                    p[5] = M->nV++;
                                    if (signbf(v[2])) M->Nx[y + 1][x] = p[10] = p[5];
                                    if (signbf(v[7])) M->Ny[y][x + 1] = p[6] = p[5];
                                }
                                else
                                {
                                    p[5] = p[10];
                                    if (signbf(v[7])) M->Ny[y][x + 1] = p[6] = p[5];
                                }
                            }
                            else
                            {
                                p[5] = p[6];
                                if (signbf(v[2])) M->Nx[y + 1][x] = p[10] = p[5];
                            }
                        }
                        else
                            p[5] = M->nV++;
                        M->Lz[y + 1][x + 1] = p[5];
                        break;
                    case 6:
                        if (v[7] == 0)
                        {
                            if (signbf(v[3]))
                            {
                                if (y)
                                {
                                    p[6] = p[11] = M->Nx[y][x];
                                    if (signbf(v[4]))
                                        p[7] = p[6];
                                }
                                else
                                {
                                    if (p[11] != FF)
                                        p[6] = p[11];
                                    else if (p[7] != FF)
                                        p[6] = p[7];
                                    else
                                        p[6] = M->nV++;
                                }
                            }
                            else if (signbf(v[4]))
                            {
                                if (y)
                                    p[6] = p[7] = M->Lz[y][x + 1];
                                else if (p[7] != FF)
                                    p[6] = p[7];
                                else
                                    p[6] = M->Lz[y][x + 1] = p[7] = M->nV++;
                            }
                            else
                            {
                                if (y? sbf(M->iso - M->F[z + 1][y - 1][x + 1]): 0)
                                    p[6] = M->Ny[y - 1][x + 1];
                                else if (y && x + 1 < M->nx? sbf(M->iso - M->F[z + 1][y][x + 2]): 0)
                                    p[6] = M->Nx[y][x + 1];
                                else
                                    p[6] = M->nV++;
                            }
                        }
                        else if (v[6] == 0)
                        {
                            if (p[5] == FF)
                            {
                                if (p[10] == FF)
                                {
                                    p[6] = M->nV++;
                                    if (signbf(v[5])) M->Lz[y + 1][x + 1] = p[5] = p[6];
                                    if (signbf(v[2])) M->Nx[y + 1][x] = p[10] = p[6];
                                }
                                else
                                {
                                    p[6] = p[10];
                                    if (signbf(v[5])) M->Lz[y + 1][x + 1] = p[5] = p[6];
                                }
                            }
                            else
                            {
                                p[6] = p[5];
                                if (signbf(v[2])) M->Nx[y + 1][x] = p[10] = p[6];
                            }
                        }
                        else
                            p[6] = M->nV++;
                        M->Ny[y][x + 1] = p[6];
                        break;
                    case 7:
                        if (y)
                            p[7] = M->Lz[y][x + 1];
                        else
                        {
                            if (v[4] == 0)
                            {
                                if (p[8] != FF)
                                    p[7] = p[8];
                                else if (p[4] != FF)
                                    p[7] = p[4];
                                else if (z && signbf(v[0]))
                                    p[7] = M->Ox[0][x];
                                else if (z && x + 1 < M->nx? sbf(M->iso - M->F[z][0][x + 2]): 0)
                                    p[7] = M->Ox[0][x + 1];
                                else if (z? sbf(M->iso - M->F[z - 1][0][x + 1]): 0)
                                    p[7] = M->Lz[0][x + 1];
                                else
                                    p[7] = M->nV++;
                            }
                            else if (v[7] == 0)
                            {
                                if (p[6] != FF)
                                    p[7] = p[6];
                                else if (p[11] != FF)
                                    p[7] = p[11];
                                else
                                    p[7] = M->nV++;
                            }
                            else
                                p[7] = M->nV++;
                            M->Lz[0][x + 1] = p[7];
                        }
                        break;
                    case 8:
                        if (z || y)
                            p[8] = M->Ox[y][x];
                        else
                        {
                            if (v[0] == 0)
                            {
                                if (p[3] != FF)
                                    p[8] = p[3];
                                else if (p[0] != FF)
                                    p[8] = p[0];
                                else if (x && signbf(v[3]))
                                    p[8] = M->Lz[0][x];
                                else if (x && signbf(v[1]))
                                    p[8] = M->Oy[0][x];
                                else if (x? sbf(M->iso - M->F[0][0][x - 1]): 0)
                                    p[8] = M->Ox[0][x - 1];
                                else
                                    p[8] = M->nV++;
                            }
                            else if (v[4] == 0)
                            {
                                if (p[4] != FF)
                                    p[8] = p[4];
                                else if (p[7] != FF)
                                    p[8] = p[7];
                                else
                                    p[8] = M->nV++;
                            }
                            else
                                p[8] = M->nV++;
                            M->Ox[0][x] = p[8];
                        }
                        break;
                    case 9:
                        if (z)
                            p[9] = M->Ox[y + 1][x];
                        else
                        {
                            if (v[1] == 0)
                            {
                                if (p[0] != FF)
                                    p[9] = p[0];
                                else if (p[1] != FF)
                                    p[9] = p[1];
                                else if (x && signbf(v[0]))
                                    p[9] = M->Oy[y][x];
                                else if (x && signbf(v[2]))
                                    p[9] = M->Lz[y + 1][x];
                                else if (x? sbf(M->iso - M->F[0][y + 1][x - 1]): 0)
                                    p[9] = M->Ox[y + 1][x - 1];
                                else
                                    p[9] = M->nV++;
                            }
                            else if (v[5] == 0)
                            {
                                if (p[5] != FF)
                                    p[9] = p[5];
                                else if (p[4] != FF)
                                    p[9] = p[4];
                                else
                                    p[9] = M->nV++;
                            }
                            else
                                p[9] = M->nV++;
                            M->Ox[y + 1][x] = p[9];
                        }
                        break;
                    case 10:
                        if (v[2] == 0)
                        {
                            if (signbf(v[1]))
                            {
                                if (x)
                                {
                                    p[10] = p[1] = M->Lz[y + 1][x];
                                    if (signbf(v[3])) p[2] = p[10];
                                }
                                else
                                {
                                    if (p[1] != FF)
                                        p[10] = p[1];
                                    else if (p[2] != FF)
                                        p[10] = p[2];
                                    else
                                        p[10] = M->nV++;
                                }
                            }
                            else if (signbf(v[3]))
                            {
                                if (x)
                                    p[10] = p[2] = M->Ny[y][x];
                                else
                                    p[10] = M->nV++;
                            }
                            else
                            {
                                if (x? sbf(M->iso - M->F[z + 1][y + 1][x - 1]): 0)
                                    p[10] = M->Nx[y + 1][x - 1];
                                else
                                    p[10] = M->nV++;
                            }
                        }
                        else if (v[6] == 0)
                        {
                            if (p[6] == FF)
                            {
                                if (p[5] == FF)
                                {
                                    p[10] = M->nV++;
                                    if (signbf(v[5])) M->Lz[y + 1][x + 1] = p[5] = p[10];
                                    if (signbf(v[7])) M->Ny[y][x + 1] = p[6] = p[10];
                                }
                                else
                                {
                                    p[10] = p[5];
                                    if (signbf(v[7])) M->Ny[y][x + 1] = p[6] = p[10];
                                }
                            }
                            else
                            {
                                p[10] = p[6];
                                if (signbf(v[5])) M->Lz[y + 1][x + 1] = p[5] = p[10];
                            }
                        }
                        else
                            p[10] = M->nV++;
                        M->Nx[y + 1][x] = p[10];
                        break;
                    case 11:
                        if (y)
                            p[11] = M->Nx[y][x];
                        else
                        {
                            if (v[3] == 0)
                            {
                                if (p[3] != FF)
                                    p[11] = p[3];
                                else if (p[2] != FF)
                                    p[11] = p[2];
                                else if (x && signbf(v[0]))
                                    p[11] = M->Lz[0][x];
                                else if (x? sbf(M->iso - M->F[z + 1][0][x - 1]): 0)
                                    p[11] = M->Nx[0][x - 1];
                                else
                                    p[11] = M->nV++;
                            }
                            else if (v[7] == 0)
                            {
                                if (p[6] != FF)
                                    p[11] = p[6];
                                else if (p[7] != FF)
                                    p[11] = p[7];
                                else
                                    p[11] = M->nV++;
                            }
                            else
                                p[11] = M->nV++;
                            M->Nx[0][x] = p[11];
                        }
                    break;
                    default:
                        p[12] = M->nV++;
                    }
                }
                ti[--k] = p[c];
                i >>= 4;
            }
            if (ti[0] != ti[1] && ti[0] != ti[2] && ti[1] != ti[2])
                M->nT++;
        }
    }
    
    // modified from calculate_isosurface function
    unsigned long long memory_of_isosurface(MC33 *M, float iso, unsigned int *nV, unsigned int *nT)
    {
        unsigned int x, y, z, nx = M->nx, ny = M->ny, nz = M->nz;
        GRD_data_type ***F = M->F, **F0, **F1, *V00, *V01, *V11, *V10;
        float V[12];
        float *v1 = V, *v2 = V + 4;
        M->nT = M->nV = 0;
        M->iso = iso;
        for (z = 0; z != nz; ++z)
        {
            F0 = *F;
            F1 = *(++F);
            for (y = 0; y != ny; ++y)
            {
                V00 = *F0;
                V01 = *(++F0);
                V10 = *F1;
                V11 = *(++F1);
                v2[0] = iso - *V00;
                v2[1] = iso - *V01;
                v2[2] = iso - *V11;
                v2[3] = iso - *V10;
                unsigned int i = signbf(v2[3]) != 0;
                if (signbf(v2[2])) i |= 2;
                if (signbf(v2[1])) i |= 4;
                if (signbf(v2[0])) i |= 8;
                for (x = 0; x != nx; ++x)
                {
                    {float *P = v1; v1 = v2; v2 = P;}
                    v2[0] = iso - *(++V00);
                    v2[1] = iso - *(++V01);
                    v2[2] = iso - *(++V11);
                    v2[3] = iso - *(++V10);
                    i = ((i&0x0F)<<4)|(signbf(v2[3]) != 0);
                    if (signbf(v2[2])) i |= 2;
                    if (signbf(v2[1])) i |= 4;
                    if (signbf(v2[0])) i |= 8;
                    if (i && i^0xFF)
                    {
                        if (v1 > v2) {float *t = v2; float *s = t + 8; *s = *t; *(++s) = *(++t); *(++s) = *(++t); *(++s) = *(++t);}                        
                        MC33_findCase_count(M,x,y,z,i,v1);
                    }
                }
            }
            {unsigned int** P = M->Ox; M->Ox = M->Nx; M->Nx = P;}
            {unsigned int** P = M->Oy; M->Oy = M->Ny; M->Ny = P;}
        }
        *nV = M->nV;
        *nT = M->nT;
        // number of vertices * (size of vertex and normal + size of color ) + number of triangle * size of triangle + size of struct surface
        return (*nV) * (6 * sizeof(float) + sizeof(int)) + (*nT) * (3 * sizeof(int)) + sizeof(surface);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-25
      • 2014-02-21
      • 1970-01-01
      相关资源
      最近更新 更多