Example #1
0
        public static double EstimateRefinementCells(IGH_GeometricGoo geo, double baseCellSize)
        {
            var regionName        = Geometry.getUserString(geo, "ComputeName");
            var refinementDetails = Geometry.getUserString(geo, "ComputeRefinementRegion");

            if (string.IsNullOrEmpty(regionName) || string.IsNullOrEmpty(refinementDetails))
            {
                return(0.0);
            }

            var details = new RefinementDetails().FromJson(refinementDetails);

            details.CellSize = baseCellSize;
            var cellSize = baseCellSize / Math.Pow(2, int.Parse(details.Levels.Split(' ')[1]));
            var mesh     = new Mesh();

            geo.CastTo(out mesh);

            return(mesh.Volume() / Math.Pow(cellSize, 3));
        }
Example #2
0
        public static double EstimateSurfaceAreaCells(IGH_GeometricGoo geo, double baseCellSize)
        {
            var surfaceName = Geometry.getUserString(geo, "ComputeName");
            var levels      = Geometry.getUserString(geo, "ComputeMeshLevels");

            if (string.IsNullOrEmpty(surfaceName) || string.IsNullOrEmpty(levels))
            {
                return(0.0);
            }

            var meshLevel = new MeshLevelDetails().FromJson(levels);

            meshLevel.CellSize = baseCellSize;
            var cellSize = baseCellSize / Math.Pow(2, meshLevel.Level.Min);
            var mesh     = new Mesh();

            geo.CastTo(out mesh);
            var area = AreaMassProperties.Compute(mesh).Area;

            return((area / Math.Pow(cellSize, 2)) * 4);
        }
Example #3
0
        /// <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)
        {
            Mesh topoMesh = new Mesh();

            DA.GetData <Mesh>("Topography Mesh", ref topoMesh);

            GH_Structure <IGH_GeometricGoo> featureGoo = new GH_Structure <IGH_GeometricGoo>();

            DA.GetDataTree <IGH_GeometricGoo>("Feature Geometry", out featureGoo);

            ///Reserve one processor for GUI
            totalMaxConcurrancy = System.Environment.ProcessorCount - 1;

            ///Tells us how many threads were using
            //Message = totalMaxConcurrancy + " threads";


            ///Get Rtree of points and flat mesh for processing in detailed feature mesh projection
            Mesh topoFlat = new Mesh();

            Point3d[] topoFlatPoints = null;
            RTree     rTree          = new RTree();

            if (!fast)
            {
                topoFlat = topoMesh.DuplicateMesh();
                for (int i = 0; i < topoFlat.Vertices.Count; i++)
                {
                    Point3f v = topoFlat.Vertices[i];
                    v.Z = 0;
                    topoFlat.Vertices.SetVertex(i, v);
                }

                topoFlatPoints = topoFlat.Vertices.ToPoint3dArray();
                rTree          = RTree.CreateFromPointArray(topoFlatPoints);
            }

            ///Create a dictionary that works in parallel
            var gooTree = new System.Collections.Concurrent.ConcurrentDictionary <GH_Path, List <IGH_GeometricGoo> >();

            ///Multi-threading the loop
            System.Threading.Tasks.Parallel.ForEach(featureGoo.Paths,
                                                    new System.Threading.Tasks.ParallelOptions {
                MaxDegreeOfParallelism = totalMaxConcurrancy
            },
                                                    pth =>
            {
                ///Create containers for translating from GH Goo
                Point3d pt               = new Point3d();
                Polyline pLine           = null;
                PolylineCurve pLineCurve = null;
                Curve curve              = null;
                Mesh mesh       = new Mesh();
                Surface surface = null;
                Brep brep       = new Brep();

                ///Output container list
                List <IGH_GeometricGoo> gGooList = new List <IGH_GeometricGoo>();
                List <IGH_GeometricGoo> fGooList = new List <IGH_GeometricGoo>();
                var branchFeatures    = featureGoo.get_Branch(pth);
                BoundingBox branchBox = new BoundingBox();

                if (branchFeatures.Count > 0)
                {
                    foreach (var bGoo in branchFeatures)
                    {
                        ///Get geometry type(s) in branch
                        string geomType       = string.Empty;
                        IGH_GeometricGoo fGoo = GH_Convert.ToGeometricGoo(bGoo);

                        if (fGoo != null && fGoo.IsValid)
                        {
                            if (grouped)
                            {
                                ///Need to duplicate geometry or else move vector piles on similar to the following
                                ///https://www.grasshopper3d.com/forum/topics/c-component-refresh-problem
                                fGooList.Add(fGoo.DuplicateGeometry());
                                branchBox.Union(fGoo.Boundingbox);
                            }

                            geomType = fGoo.TypeName;

                            switch (geomType)
                            {
                            case "Point":
                                fGoo.CastTo <Point3d>(out pt);
                                gGooList.Add(ProjectPointToTopo(topoMesh, pt));
                                break;

                            case "Line":
                            case "Polyline":
                                fGoo.CastTo <Polyline>(out pLine);

                                if (fast)
                                {
                                    gGooList.Add(ProjectPolylineToTopo(topoMesh, pLine));
                                }
                                else
                                {
                                    ///Lock topoMesh so it's not accessed by mutliple threads at once in a "deadlock"
                                    ///https://docs.microsoft.com/en-us/dotnet/standard/threading/managed-threading-best-practices
                                    lock (topoMesh)
                                    {
                                        gGooList.AddRange(ProjectCurveToTopo(topoMesh, pLine.ToNurbsCurve()));
                                    }
                                }

                                break;

                            case "PolylineCurve":
                                fGoo.CastTo <PolylineCurve>(out pLineCurve);
                                if (fast)
                                {
                                    gGooList.Add(ProjectPolylineToTopo(topoMesh, pLineCurve.ToPolyline()));
                                }
                                else
                                {
                                    lock (topoMesh)
                                    {
                                        gGooList.AddRange(ProjectCurveToTopo(topoMesh, pLineCurve.ToNurbsCurve()));
                                    }
                                }
                                break;

                            case "Curve":
                                fGoo.CastTo <Curve>(out curve);
                                if (fast)
                                {
                                    if (curve.TryGetPolyline(out pLine))
                                    {
                                        gGooList.Add(ProjectPolylineToTopo(topoMesh, pLine));
                                    }
                                    else
                                    {
                                        gGooList.AddRange(ProjectCurveToTopo(topoMesh, curve));
                                    }
                                }
                                else
                                {
                                    lock (topoMesh)
                                    {
                                        gGooList.AddRange(ProjectCurveToTopo(topoMesh, curve));
                                    }
                                }
                                break;

                            case "Mesh":
                                fGoo.CastTo <Mesh>(out mesh);
                                if (mesh.IsClosed)
                                {
                                    gGooList.Add(ProjectSolidMeshToTopo(topoMesh, mesh));
                                }
                                else
                                {
                                    if (fast)
                                    {
                                        gGooList.Add(ProjectMeshToTopoFast(topoMesh, mesh));
                                    }
                                    else
                                    {
                                        lock (topoMesh)
                                        {
                                            gGooList.Add(ProjectMeshToTopoSlow(topoMesh, topoFlat, topoFlatPoints, rTree, mesh));
                                        }
                                    }
                                }
                                break;

                            case "Surface":
                                fGoo.CastTo <Surface>(out surface);
                                gGooList.Add(ProjectSurfaceToTopoFast(topoMesh, surface));
                                break;

                            case "Brep":
                                fGoo.CastTo <Brep>(out brep);
                                gGooList.Add(ProjectBrepToTopo(topoMesh, brep));
                                break;

                            default:
                                AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Not able to move " + geomType + " geometry to mesh" +
                                                  ". Geometry must be a Point, Curve, Mesh, Surface or Brep.");
                                break;
                            }
                        }
                        else
                        {
                        }
                    }

                    ///Move objects in branch a minimum distance if grouped selected
                    ///If only one feature in a branch, not need to group
                    if (grouped && gGooList.Count > 1)
                    {
                        ///Get the minimum move vector
                        Point3d lowestPoint = new Point3d();
                        double minDistance  = double.MaxValue;
                        Vector3d minimumVec = new Vector3d();
                        foreach (var gi in gGooList)
                        {
                            if (gi != null)
                            {
                                Point3d gGooMin     = gi.Boundingbox.Min;
                                Vector3d distVector = gGooMin - branchBox.Min;
                                if (distVector.Length < minDistance && distVector.Length > 0 && distVector.IsValid)
                                {
                                    lowestPoint = gGooMin;
                                    minDistance = distVector.Length;
                                    minimumVec  = new Vector3d(0, 0, distVector.Z);
                                }
                            }
                        }

                        ///Move orignal feature geometry the minimum move vector
                        if (minDistance != double.MaxValue)
                        {
                            Transform transform = Transform.Translation(minimumVec);
                            for (int f = 0; f < fGooList.Count; f++)
                            {
                                fGooList[f].Transform(transform);
                            }
                            gooTree[pth] = fGooList;
                        }
                    }
                    else
                    {
                        gooTree[pth] = gGooList;
                    }
                }
            });
            ///End of multi-threaded loop


            ///Convert dictionary to regular old data tree
            GH_Structure <IGH_GeometricGoo> gTree = new GH_Structure <IGH_GeometricGoo>();

            foreach (KeyValuePair <GH_Path, List <IGH_GeometricGoo> > g in gooTree)
            {
                gTree.AppendRange(g.Value, g.Key);
            }

            topoFlat.Dispose();
            topoMesh.Dispose();

            DA.SetDataTree(0, gTree);
        }