/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { try { var vg = default(ScalarGrid3D); double isolevel = 0.5f; DA.GetData(0, ref vg); DA.GetData(1, ref isolevel); var values = new List <bool>(); if (vg == null || !vg.IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The (input) scalargrid was invalid"); return; } var mesh = new Mesh(); // increase the grid with one pixel; so we actually start at a negative point; var gridSize = vg.SizeUVW + new Point3i(1, 1, 1); //List<int> cubeindexlist = new List<int>(); for (var i = 0; i < gridSize.SelfProduct(); i++) { //this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Test: " + i.ToString()); var pts = new Point3i[8]; pts[0] = Point3i.IndexToPointUvw(gridSize, i); pts[1] = pts[0] + new Point3i(1, 0, 0); pts[2] = pts[0] + new Point3i(1, 1, 0); pts[3] = pts[0] + new Point3i(0, 1, 0); pts[4] = pts[0] + new Point3i(0, 0, 1); pts[5] = pts[0] + new Point3i(1, 0, 1); pts[6] = pts[0] + new Point3i(1, 1, 1); pts[7] = pts[0] + new Point3i(0, 1, 1); var val = new float[8]; // populate the value grid with information float sum = 0; for (var j = 0; j < 8; j++) { var gridpt = pts[j] - new Point3i(1, 1, 1); if ((!(new Point3i(0, 0, 0) > gridpt || gridpt >= vg.SizeUVW))) { val[j] = vg[gridpt]; } else { val[j] = 0; } sum = sum + val[j]; } // non homogeneus if (Math.Abs(sum) > RhinoMath.ZeroTolerance && Math.Abs(sum - 8) > RhinoMath.ZeroTolerance) { Polygonise(vg, pts, val, Convert.ToSingle(isolevel), ref mesh, out var cubeindex); } //cubeindexlist.Add(cubeindex); } mesh.Normals.ComputeNormals(); mesh.Compact(); DA.SetData(0, mesh); //DA.SetDataList(1, cubeindexlist); } catch (Exception e) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.ToString() + e.StackTrace.ToString()); } }
private void IncreaseGrid(ref VoxelGrid3D vg, int count) { var trueCount = vg.CountNonZero; var possibleLocations = new List <int>(); var foundRoof = false; for (var z = vg.SizeUVW.Z - 1; z >= 0; z--) { if (foundRoof) { break; } for (var y = 0; y < vg.SizeUVW.Y; y++) { for (var x = 0; x < vg.SizeUVW.X; x++) { var pt = new Point3i(x, y, z); if (vg[pt] != true) { continue; } foundRoof = true; possibleLocations.Add(Point3i.PointUvwToIndex(vg.SizeUVW, pt)); } } } // location division // goal-current // difference: the first x voxels get extra. // then add x voxels to each location. var difference = count - trueCount; var height = Convert.ToInt32(Math.Floor((double)difference / possibleLocations.Count)); var rest = difference % possibleLocations.Count; for (var i = 0; i < possibleLocations.Count; i++) { var makeheight = height; if (rest > 0) { makeheight += 1; rest--; } for (var j = 1; j <= makeheight; j++) { var pt = new Point3i(0, 0, j); var position = Point3i.IndexToPointUvw(vg.SizeUVW, possibleLocations[i]) + pt; vg[position] = true; } } if (vg.CountNonZero != count) { // the grid is empty / reaches to the roof. // add from the bottom. IncreaseGridFromBottom(ref vg, count); } }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="da">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess da) { try { var vg = default(VoxelGrid3D); double isolevel = 0.5f; da.GetData(0, ref vg); da.GetData(1, ref isolevel); if (vg == null || !vg.IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The (input) voxelgrid was invalid"); return; } if (isolevel < 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The iso level should be larger than 0 and smaller than 1"); } isolevel = Math.Max(isolevel, RhinoMath.ZeroTolerance); if (isolevel > 1) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The iso level should be larger than 0 and smaller than 1"); isolevel = 1; } var m = new Mesh(); // increase the grid with one pixel; so we actually start at a negative point; var size = vg.SizeUVW + new Point3i(1, 1, 1); //List<int> cubeindexlist = new List<int>(); for (var i = 0; i < size.SelfProduct(); i++) { //this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Test: " + i.ToString()); var pts = new Point3i[8]; pts[0] = Point3i.IndexToPointUvw(size, i); pts[1] = pts[0] + new Point3i(1, 0, 0); pts[2] = pts[0] + new Point3i(1, 1, 0); pts[3] = pts[0] + new Point3i(0, 1, 0); pts[4] = pts[0] + new Point3i(0, 0, 1); pts[5] = pts[0] + new Point3i(1, 0, 1); pts[6] = pts[0] + new Point3i(1, 1, 1); pts[7] = pts[0] + new Point3i(0, 1, 1); var val = new float[8]; // populate the value grid with information float sum = 0; for (var j = 0; j < 8; j++) { var gridpt = pts[j] - new Point3i(1, 1, 1); if (!(new Point3i(0, 0, 0) > gridpt || gridpt >= vg.SizeUVW) && vg[gridpt]) { val[j] = 1.0f; } else { val[j] = 0.0f; } sum += val[j]; } // non homogeneus if (Math.Abs(sum) > RhinoMath.ZeroTolerance && Math.Abs(sum - 8) > RhinoMath.ZeroTolerance) { Polygonise(vg, pts, val, Convert.ToSingle(isolevel), ref m, out _); } //cubeindexlist.Add(cubeindex); } m.Normals.ComputeNormals(); m.Compact(); da.SetData(0, m); //DA.SetDataList(1, cubeindexlist); } catch (Exception e) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e + e.StackTrace); } }