public void set_slice(DenseGrid2f slice, int slice_i, int dimension) { if (dimension == 0) { for (int k = 0; k < nk; ++k) { for (int j = 0; j < nj; ++j) { Buffer[slice_i + ni * (j + nj * k)] = slice[j, k]; } } } else if (dimension == 1) { for (int k = 0; k < nk; ++k) { for (int i = 0; i < ni; ++i) { Buffer[i + ni * (slice_i + nj * k)] = slice[i, k]; } } } else { for (int j = 0; j < nj; ++j) { for (int i = 0; i < ni; ++i) { Buffer[i + ni * (j + nj * slice_i)] = slice[i, j]; } } } }
public void set_max(DenseGrid2f grid2) { for (int k = 0; k < Buffer.Length; ++k) { Buffer[k] = Math.Max(Buffer[k], grid2.Buffer[k]); } }
public void swap(DenseGrid2f g2) { Util.gDevAssert(ni == g2.ni && nj == g2.nj); var tmp = g2.Buffer; g2.Buffer = this.Buffer; this.Buffer = tmp; }
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; }
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); }
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); } }
public DenseGrid2f get_slice(int slice_i, int dimension) { DenseGrid2f slice; if (dimension == 0) { slice = new DenseGrid2f(nj, nk, 0); for (int k = 0; k < nk; ++k) { for (int j = 0; j < nj; ++j) { slice[j, k] = Buffer[slice_i + ni * (j + nj * k)]; } } } else if (dimension == 1) { slice = new DenseGrid2f(ni, nk, 0); for (int k = 0; k < nk; ++k) { for (int i = 0; i < ni; ++i) { slice[i, k] = Buffer[i + ni * (slice_i + nj * k)]; } } } else { slice = new DenseGrid2f(ni, nj, 0); for (int j = 0; j < nj; ++j) { for (int i = 0; i < ni; ++i) { slice[i, j] = Buffer[i + ni * (j + nj * slice_i)]; } } } return(slice); }
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"); }
public void copy(DenseGrid2f copy) { Array.Copy(copy.Buffer, this.Buffer, this.Buffer.Length); }
public DenseGrid2f(DenseGrid2f copy) { Buffer = new float[copy.Buffer.Length]; Array.Copy(copy.Buffer, Buffer, Buffer.Length); ni = copy.ni; nj = copy.nj; }