コード例 #1
0
        static void smooth(DenseGrid2f grid, DenseGrid2f tmp, float alpha, int rounds)
        {
            if (tmp == null)
            {
                tmp = new DenseGrid2f(grid.ni, grid.nj, 0);
            }

            int ni = grid.ni, nj = grid.nj;

            for (int k = 0; k < rounds; ++k)
            {
                tmp.assign_border(1, 1);
                for (int j = 1; j < nj - 1; ++j)
                {
                    for (int i = 1; i < ni - 1; ++i)
                    {
                        float avg = grid[i - 1, j] + grid[i - 1, j + 1]
                                    + grid[i, j + 1] + grid[i + 1, j + 1]
                                    + grid[i + 1, j] + grid[i + 1, j - 1]
                                    + grid[i, j - 1] + grid[i - 1, j - 1];
                        avg      /= 8.0f;
                        tmp[i, j] = (1 - alpha) * grid[i, j] + (alpha) * avg;
                    }
                }
                grid.copy(tmp);
            }
        }
コード例 #2
0
        static void diffuse(DenseGrid2f grid, float t, Func <int, int, bool> skipF)
        {
            int         ni = grid.ni, nj = grid.nj;
            DenseGrid2f dilated = new DenseGrid2f(grid);

            for (int j = 1; j < nj - 1; ++j)
            {
                for (int i = 1; i < ni - 1; ++i)
                {
                    if (skipF != null && skipF(i, j))
                    {
                        continue;
                    }
                    if (grid[i, j] < 0)
                    {
                        foreach (Vector2i o in gIndices.GridOffsets8)
                        {
                            float df = (o.LengthSquared > 1) ? -1f : -0.707f;
                            df *= t;
                            dilated[i + o.x, j + o.y] = Math.Min(dilated[i + o.x, j + o.y], df);
                            //dilated[i + o.x, j + o.y] += df;
                        }
                    }
                }
            }
            grid.swap(dilated);
        }
コード例 #3
0
        static DenseGrid2i binarize(DenseGrid2f grid, float thresh = 0)
        {
            DenseGrid2i result = new DenseGrid2i();

            result.resize(grid.ni, grid.nj);
            int size = result.size;

            for (int k = 0; k < size; ++k)
            {
                result[k] = (grid[k] < thresh) ? 1 : 0;
            }
            return(result);
        }
コード例 #4
0
        void process_version2(DenseGrid3f supportGrid, DenseGridTrilinearImplicit distanceField)
        {
            int      ni = supportGrid.ni, nj = supportGrid.nj, nk = supportGrid.nk;
            float    dx     = (float)CellSize;
            Vector3f origin = this.GridOrigin;

            // sweep values down layer by layer
            DenseGrid2f prev = supportGrid.get_slice(nj - 1, 1);
            DenseGrid2f tmp  = new DenseGrid2f(prev);

            Bitmap3 bmp = new Bitmap3(new Vector3i(ni, nj, nk));

            for (int j = nj - 2; j >= 0; j--)
            {
                // skeletonize prev layer
                DenseGrid2i prev_skel = binarize(prev, 0.0f);
                skeletonize(prev_skel, null, 2);
                //dilate_loners(prev_skel, null, 2);

                if (j == 0)
                {
                    dilate(prev_skel, null, true);
                    dilate(prev_skel, null, true);
                }

                for (int k = 1; k < nk - 1; ++k)
                {
                    for (int i = 1; i < ni - 1; ++i)
                    {
                        bmp[new Vector3i(i, j, k)] = (prev_skel[i, k] == 1) ? true : false;
                    }
                }

                smooth(prev, tmp, 0.5f, 5);

                DenseGrid2f cur = supportGrid.get_slice(j, 1);
                cur.set_min(prev);

                for (int k = 1; k < nk - 1; ++k)
                {
                    for (int i = 1; i < ni - 1; ++i)
                    {
                        float skelf = prev_skel[i, k] > 0 ? -1.0f : int.MaxValue;
                        cur[i, k] = Math.Min(cur[i, k], skelf);

                        if (cur[i, k] < 0)
                        {
                            Vector3d cell_center = new Vector3f(i * dx, j * dx, k * dx) + origin;
                            if (distanceField.Value(ref cell_center) < -CellSize)
                            {
                                cur[i, k] = 1;
                            }
                        }
                    }
                }

                for (int k = 1; k < nk - 1; ++k)
                {
                    for (int i = 1; i < ni - 1; ++i)
                    {
                        if (is_loner(prev_skel, i, k))
                        {
                            foreach (Vector2i d in gIndices.GridOffsets8)
                            {
                                float f = 1.0f / (float)Math.Sqrt(d.x * d.x + d.y * d.y);
                                cur[i + d.x, k + d.y] += -0.25f * f;
                            }
                        }
                    }
                }

                for (int k = 1; k < nk - 1; ++k)
                {
                    for (int i = 1; i < ni - 1; ++i)
                    {
                        supportGrid[i, j, k] = cur[i, k];
                    }
                }

                prev.swap(cur);
            }


            VoxelSurfaceGenerator gen = new VoxelSurfaceGenerator()
            {
                Voxels = bmp
            };

            gen.Generate();
            Util.WriteDebugMesh(gen.Meshes[0], "c:\\scratch\\binary.obj");
        }