/// <summary> /// Adds more cells and positives to the bitmap used for mold generation /// </summary> /// <param name="bmp"></param> /// <returns></returns> private Bitmap3 BitmapOffset(Bitmap3 bmp) { Bitmap3 mold_bmp = new Bitmap3(new Vector3i(bmp.Dimensions.x + 2, bmp.Dimensions.y + 2, bmp.Dimensions.z + 2)); //extra offsets to expand positive cells foreach (Vector3i idx in bmp.Indices()) { //needs to be positive for use to be interested if (!bmp.Get(idx)) { continue; } //for x mold_bmp.Set(new Vector3i(idx.x - 1, idx.y, idx.z), true); mold_bmp.Set(new Vector3i(idx.x + 1, idx.y, idx.z), true); //for y mold_bmp.Set(new Vector3i(idx.x, idx.y - 1, idx.z), true); mold_bmp.Set(new Vector3i(idx.x, idx.y + 1, idx.z), true); //for z mold_bmp.Set(new Vector3i(idx.x, idx.y, idx.z - 1), true); mold_bmp.Set(new Vector3i(idx.x, idx.y, idx.z + 1), true); } return(mold_bmp); }
public static Bitmap3 createNewObjectForPriniting(List <int> path, Dictionary <Tuple <int, int, int, int>, int> sumDic, Vector3i newObjDim, Bitmap3 oldObj) { Bitmap3 voxPrintResult = new Bitmap3(newObjDim); foreach (Vector3i idx in voxPrintResult.Indices()) //initialize object { voxPrintResult.Set(idx, false); } for (int i = 0; i < path.Count - 1; i++) { //-1 because we want to take every time the range Zj to Zi where Zj > Zi int zj = path[i] - path.Last(); int zi = path[i + 1] - path.Last(); for (int x = 0; x < voxPrintResult.Dimensions.x; x++) { for (int z = 0; z < voxPrintResult.Dimensions.z; z++) { Tuple <int, int, int, int> key = new Tuple <int, int, int, int>(zi, zj, x, z); if ((sumDic.ContainsKey(key) && sumDic[key] >= 0) || isCoulumnInObj(oldObj, zi, zj, x, z)) { for (int y = zi; y < zj; y++) { voxPrintResult.Set(createVector(x, y, z), true); } } } } } return(voxPrintResult); }
public static void test_voxel_surface() { //DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj"); DMesh3 mesh = TestUtil.LoadTestInputMesh("holey_bunny_2.obj"); DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh, autoBuild: true); AxisAlignedBox3d bounds = mesh.CachedBounds; int numcells = 64; double cellsize = bounds.MaxDim / numcells; MeshSignedDistanceGrid levelSet = new MeshSignedDistanceGrid(mesh, cellsize); levelSet.UseParallel = true; levelSet.Compute(); Bitmap3 bmp = new Bitmap3(levelSet.Dimensions); foreach (Vector3i idx in bmp.Indices()) { float f = levelSet[idx.x, idx.y, idx.z]; bmp.Set(idx, (f < 0) ? true : false); } //AxisAlignedBox3d bounds = mesh.CachedBounds; //int numcells = 32; //double cellsize = bounds.MaxDim / numcells; //ShiftGridIndexer3 indexer = new ShiftGridIndexer3(bounds.Min-2*cellsize, cellsize); //Bitmap3 bmp = new Bitmap3(new Vector3i(numcells, numcells, numcells)); //foreach (Vector3i idx in bmp.Indices()) { // Vector3d v = indexer.FromGrid(idx); // bmp.Set(idx, spatial.IsInside(v)); //} //spatial.WindingNumber(Vector3d.Zero); //Bitmap3 bmp = new Bitmap3(new Vector3i(numcells+3, numcells+3, numcells+3)); //gParallel.ForEach(bmp.Indices(), (idx) => { // Vector3d v = indexer.FromGrid(idx); // bmp.SafeSet(idx, spatial.WindingNumber(v) > 0.8); //}); VoxelSurfaceGenerator voxGen = new VoxelSurfaceGenerator(); voxGen.Voxels = bmp; voxGen.ColorSourceF = (idx) => { return(new Colorf((float)idx.x, (float)idx.y, (float)idx.z) * (1.0f / numcells)); }; voxGen.Generate(); DMesh3 voxMesh = voxGen.Meshes[0]; Util.WriteDebugMesh(voxMesh, "c:\\scratch\\temp.obj"); TestUtil.WriteTestOutputMesh(voxMesh, "voxel_surf.obj", true, true); }
public static Bitmap3 createVoxelizedRepresentation(String objPath) { DMesh3 mesh = StandardMeshReader.ReadMesh(objPath); int num_cells = 128; double cell_size = mesh.CachedBounds.MaxDim / num_cells; MeshSignedDistanceGrid sdf = new MeshSignedDistanceGrid(mesh, cell_size); sdf.Compute(); //** voxels**// Bitmap3 bmp = new Bitmap3(sdf.Dimensions); Console.WriteLine(bmp.Dimensions.x + " " + bmp.Dimensions.y + " " + bmp.Dimensions.z); foreach (Vector3i idx in bmp.Indices()) { float f = sdf[idx.x, idx.y, idx.z]; bmp.Set(idx, (f < 0) ? true : false); //for bunny only removes bottom if (idx.y < 8) { bmp.Set(idx, false); } if (test) //take only one line from top { if (idx.z != 50 || idx.x != 60) { bmp.Set(idx, false); } else { bmp.Set(idx, true); Console.WriteLine(bmp.Get(idx)); } } } return(bmp); }
protected override void SolveInstance(IGH_DataAccess DA) { int num_cells = 128; DMesh3_goo dMsh_goo = null; DA.GetData(0, ref dMsh_goo); DA.GetData(1, ref num_cells); DMesh3 dMsh_copy = new DMesh3(dMsh_goo.Value); double cell_size = dMsh_copy.CachedBounds.MaxDim / num_cells; DMeshAABBTree3 spatial = new DMeshAABBTree3(dMsh_copy, autoBuild: true); AxisAlignedBox3d bounds = dMsh_copy.CachedBounds; double cellsize = bounds.MaxDim / num_cells; ShiftGridIndexer3 indexer = new ShiftGridIndexer3(bounds.Min, cellsize); Bitmap3 bmp = new Bitmap3(new Vector3i(num_cells, num_cells, num_cells)); foreach (Vector3i idx in bmp.Indices()) { g3.Vector3d v = indexer.FromGrid(idx); bmp.Set(idx, spatial.IsInside(v)); } VoxelSurfaceGenerator voxGen = new VoxelSurfaceGenerator(); voxGen.Voxels = bmp; voxGen.Generate(); DMesh3 voxMesh = voxGen.Meshes[0]; var vecSize = dMsh_copy.CachedBounds.Extents; var box = dMsh_copy.GetBounds(); // Scale voxel mesh //MeshTransforms.Scale(voxMesh,) DA.SetData(0, voxMesh); }
public static DMesh3 MineCraft(DMesh3 mesh, int num_cells, out double scalefactor) { DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh, autoBuild: true); AxisAlignedBox3d bounds = mesh.CachedBounds; double cellsize = bounds.MaxDim / num_cells; scalefactor = cellsize; ShiftGridIndexer3 indexer = new ShiftGridIndexer3(bounds.Min, cellsize); Bitmap3 bmp = new Bitmap3(new Vector3i(num_cells, num_cells, num_cells)); foreach (Vector3i idx in bmp.Indices()) { g3.Vector3d v = indexer.FromGrid(idx); if (spatial.IsInside(v)) { bmp.Set(idx, true); } else { bmp.Set(idx, false); } } VoxelSurfaceGenerator voxGen = new VoxelSurfaceGenerator(); voxGen.Voxels = bmp; voxGen.Generate(); DMesh3 voxMesh = voxGen.Meshes[0]; return(voxMesh); }
public override Schematic WriteSchematic() { DMesh3 mesh = StandardMeshReader.ReadMesh(_path); AxisAlignedBox3d bounds = mesh.CachedBounds; DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh, autoBuild: true); double cellsize = mesh.CachedBounds.MaxDim / _gridSize; ShiftGridIndexer3 indexer = new ShiftGridIndexer3(bounds.Min, cellsize); MeshSignedDistanceGrid sdf = new MeshSignedDistanceGrid(mesh, cellsize); sdf.Compute(); Bitmap3 bmp = new Bitmap3(sdf.Dimensions); Schematic schematic = new Schematic() { Blocks = new HashSet <Block>(), Width = (ushort)bmp.Dimensions.x, Height = (ushort)bmp.Dimensions.y, Length = (ushort)bmp.Dimensions.z }; LoadedSchematic.WidthSchematic = schematic.Width; LoadedSchematic.HeightSchematic = schematic.Height; LoadedSchematic.LengthSchematic = schematic.Length; if (_winding_number != 0) { spatial.WindingNumber(Vector3d.Zero); // seed cache outside of parallel eval using (ProgressBar progressbar = new ProgressBar()) { List <Vector3i> list = bmp.Indices().ToList(); int count = 0; gParallel.ForEach(bmp.Indices(), (idx) => { Vector3d v = indexer.FromGrid(idx); bmp.SafeSet(idx, spatial.WindingNumber(v) > _winding_number); count++; progressbar.Report(count / (float)list.Count); }); } if (!_excavate) { foreach (Vector3i idx in bmp.Indices()) { if (bmp.Get(idx)) { schematic.Blocks.Add(new Block((ushort)idx.x, (ushort)idx.y, (ushort)idx.z, Color.White.ColorToUInt())); } } } } else { using (ProgressBar progressbar = new ProgressBar()) { int count = bmp.Indices().Count(); List <Vector3i> list = bmp.Indices().ToList(); for (int i = 0; i < count; i++) { Vector3i idx = list[i]; float f = sdf[idx.x, idx.y, idx.z]; bool isInside = f < 0; bmp.Set(idx, (f < 0)); if (!_excavate && isInside) { schematic.Blocks.Add(new Block((ushort)idx.x, (ushort)idx.y, (ushort)idx.z, Color.White.ColorToUInt())); } progressbar.Report((i / (float)count)); } } } if (_excavate) { foreach (Vector3i idx in bmp.Indices()) { if (bmp.Get(idx) && IsBlockConnectedToAir(bmp, idx)) { schematic.Blocks.Add(new Block((ushort)idx.x, (ushort)idx.y, (ushort)idx.z, Color.White.ColorToUInt())); } } } return(schematic); }