static void skeletonize_layer(DenseGrid3i grid, int j, int dilation_rounds = 1)
        {
            DenseGrid2i layer = grid.get_slice(j, 1);
            DenseGrid2i tmp = new DenseGrid2i(layer.ni, layer.nj, 0);

            for (int k = 0; k < dilation_rounds; ++k) {
                tmp.assign(0);
                dilate(layer, tmp);
            }

            bool done = false;
            while (!done) {
                int sum_before = layer.sum();
                tmp.assign(0);
                skeletonize_pass(layer, tmp, 0);
                tmp.assign(0);
                skeletonize_pass(layer, tmp, 1);
                int sum_after = layer.sum();
                if (sum_before == sum_after)
                    break;
            }

            for (int i = 0; i < grid.ni; ++i)
                for (int k = 0; k < grid.nk; ++k)
                    grid[i, j, k] = layer[i, k];
        }
        static void skeletonize(DenseGrid2i grid, DenseGrid2i tmp, int dilation_rounds = 1)
        {
            if ( tmp == null )
                tmp = new DenseGrid2i(grid.ni, grid.nj, 0);

            for (int k = 0; k < dilation_rounds; ++k) {
                tmp.clear();
                dilate(grid, tmp);
            }

            bool done = false;
            while (!done) {
                int sum_before = grid.sum();
                tmp.clear();
                skeletonize_pass(grid, tmp, 0);
                tmp.clear();
                skeletonize_pass(grid, tmp, 1);
                int sum_after = grid.sum();
                if (sum_before == sum_after)
                    break;
            }
        }