/// <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());
            }
        }
Esempio n. 2
0
        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);
            }
        }