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"); }