From 8a9ae4694cb55435af373eab1b64c07da3568ec1 Mon Sep 17 00:00:00 2001 From: xunuo Date: Fri, 29 Dec 2023 21:50:51 +0800 Subject: [PATCH] Add project files. --- AnalComps/EdgeBundlingComponent.cs | 387 +++++++ AnalComps/IsovistRegionComponent.cs | 1267 +++++++++++++++++++++++ AnalComps/PolygonPOIComponent.cs | 115 ++ AnalComps/WaterRunoffComponent.cs | 928 +++++++++++++++++ CapableArchiTool.csproj | 72 ++ CapableArchiTool.sln | 25 + CapableArchiToolInfo.cs | 26 + InfoComps/PluginVersionComponent.cs | 65 ++ ManaComps/CustomGUIComponent.cs | 1070 +++++++++++++++++++ ManaComps/DeletePlaceholderComponent.cs | 78 ++ ManaComps/DetectRuntimeComponent.cs | 267 +++++ ManaComps/EasyDisconnectComponent.cs | 270 +++++ ManaComps/GroupEnableComponent.cs | 139 +++ ManaComps/GroupPreviewComponent.cs | 132 +++ Properties/Resources.Designer.cs | 183 ++++ Properties/Resources.resx | 157 +++ Resources/Custom GUI.png | Bin 0 -> 1385 bytes Resources/Delete Placeholder.png | Bin 0 -> 1195 bytes Resources/Detect Runtime.png | Bin 0 -> 1260 bytes Resources/Easy WireCut.png | Bin 0 -> 1141 bytes Resources/Edge Bundling.png | Bin 0 -> 1484 bytes Resources/Isovist Region.png | Bin 0 -> 969 bytes Resources/Mass Enable.png | Bin 0 -> 1149 bytes Resources/Mass Preview.png | Bin 0 -> 1049 bytes Resources/POI Heat Map.png | Bin 0 -> 1481 bytes Resources/Plugin Icon.png | Bin 0 -> 1508 bytes Resources/Plugin Version.png | Bin 0 -> 1461 bytes Resources/Water Runoff.png | Bin 0 -> 1322 bytes Utils/CustomPluginProperties.cs | 16 + Utils/TabProperties.cs | 23 + 30 files changed, 5220 insertions(+) create mode 100644 AnalComps/EdgeBundlingComponent.cs create mode 100644 AnalComps/IsovistRegionComponent.cs create mode 100644 AnalComps/PolygonPOIComponent.cs create mode 100644 AnalComps/WaterRunoffComponent.cs create mode 100644 CapableArchiTool.csproj create mode 100644 CapableArchiTool.sln create mode 100644 CapableArchiToolInfo.cs create mode 100644 InfoComps/PluginVersionComponent.cs create mode 100644 ManaComps/CustomGUIComponent.cs create mode 100644 ManaComps/DeletePlaceholderComponent.cs create mode 100644 ManaComps/DetectRuntimeComponent.cs create mode 100644 ManaComps/EasyDisconnectComponent.cs create mode 100644 ManaComps/GroupEnableComponent.cs create mode 100644 ManaComps/GroupPreviewComponent.cs create mode 100644 Properties/Resources.Designer.cs create mode 100644 Properties/Resources.resx create mode 100644 Resources/Custom GUI.png create mode 100644 Resources/Delete Placeholder.png create mode 100644 Resources/Detect Runtime.png create mode 100644 Resources/Easy WireCut.png create mode 100644 Resources/Edge Bundling.png create mode 100644 Resources/Isovist Region.png create mode 100644 Resources/Mass Enable.png create mode 100644 Resources/Mass Preview.png create mode 100644 Resources/POI Heat Map.png create mode 100644 Resources/Plugin Icon.png create mode 100644 Resources/Plugin Version.png create mode 100644 Resources/Water Runoff.png create mode 100644 Utils/CustomPluginProperties.cs create mode 100644 Utils/TabProperties.cs diff --git a/AnalComps/EdgeBundlingComponent.cs b/AnalComps/EdgeBundlingComponent.cs new file mode 100644 index 0000000..281d836 --- /dev/null +++ b/AnalComps/EdgeBundlingComponent.cs @@ -0,0 +1,387 @@ +using System; +using System.Collections; +using System.Collections.Generic; + +using Rhino; +using Rhino.Geometry; + +using Grasshopper; +using Grasshopper.Kernel; + +using System.Linq; + + +namespace CapableArchiTool.AnalComps +{ + public class EdgeBundlingComponent : GH_Component + { + /// + /// Initializes a new instance of the EdgeBundlingComponent class. + /// + public EdgeBundlingComponent() + : base("Edge Bundling", "Bundling", + "A static edge bundling method based on kernel density estimation", + "Capable Archi Tool", "02 Analysis") + { + } + + /// + /// Registers all the input parameters for this component. + /// + protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) + { + pManager.AddLineParameter("Lines", "L", "Lines to be calculated.", GH_ParamAccess.list); + pManager.AddIntegerParameter("Iteration", "I", "Number of iterations.The calculation will be long if the " + + "number is large than 10.", GH_ParamAccess.item, 5); + pManager.AddIntegerParameter("Smoothness", "S", "Smoothness of the output curves.", GH_ParamAccess.item, 10); + pManager.AddIntegerParameter("KernelSize", "K", "Radius of kernel in pixels.", GH_ParamAccess.item, 5); + pManager.AddNumberParameter("Value", "V", "Value of density remap", GH_ParamAccess.item, 2); + pManager.AddBooleanParameter("Run", "R", "Run calculation.", GH_ParamAccess.item, false); + } + + /// + /// Registers all the output parameters for this component. + /// + protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) + { + pManager.AddTextParameter("Information", "Info", "Information of the algorithm", GH_ParamAccess.item); + pManager.AddCurveParameter("Polylines", "P", "Polylines that are generated.", GH_ParamAccess.list); + pManager.AddMeshParameter("Mesh", "M", "Mesh of density map.", GH_ParamAccess.item); + } + + /// + /// This is the method that actually does the work. + /// + /// The DA object is used to retrieve from inputs and store in outputs. + protected override void SolveInstance(IGH_DataAccess DA) + { + + List lines = new List(); + int iteration = 0; + int smoothness = 0; + int kernelsize = 0; + double value = 0; + bool run = false; + + DA.SetData(0, info); + + if (!DA.GetDataList(0, lines)) return; + if (!DA.GetData(1, ref iteration)) return; + if (!DA.GetData(2, ref smoothness)) return; + if (!DA.GetData(3, ref kernelsize)) return; + if (!DA.GetData(4, ref value)) return; + if (!DA.GetData(5, ref run)) return; + + if(!run) return; + + List pt1 = new List(); + List pt2 = new List(); + List allpoints = new List(); + + //Extraction of beginning and end of the lines + //also used for bounding box generation + for (int i = 0; i < lines.Count; i++) + { + pt1.Add(lines[i].From); + pt2.Add(lines[i].To); + allpoints.Add(lines[i].From); + allpoints.Add(lines[i].To); + } + BoundingBox BB = new BoundingBox(allpoints); + double width = BB.Max.X - BB.Min.X; + double height = BB.Max.Y - BB.Min.Y; + + // Sample Parameters + double splitDistance = 0.005 * Math.Min(width, height); + double removeDistance = splitDistance / 2.0; + + // Splatting & Accumulation Parameters + int AccResolution_x = 300; + int AccResolution_y = Convert.ToInt32((double)AccResolution_x * height / width); + + double[,] Kernel = GetKernel((kernelsize * 2 + 1)); + double[,] AccMap = new double[2, 2]; + + // Gradient Application Parameters + int GradientW = (kernelsize * 3 + 1); + double attractionFactor = 1.0; + + //Lines are sampled to the minimum resolution + //It differs from previous algorithm which split by 2 at each step + Point3d[][] linespt = Resample_points(splitDistance, pt1, pt2); + + for (int i = 0; i < iteration; i++) + { + // Resampling + Resample(splitDistance, removeDistance, ref linespt); + + // Splatting + AccMap = ComputeSplatting(AccResolution_x, AccResolution_y, Kernel, (kernelsize * 2 + 1), linespt, BB); + + // Apply Gradient + ApplyGradient(ref linespt, GradientW, attractionFactor, AccMap, AccResolution_x, AccResolution_y, BB); + + // Smooth trajectories + for (int j = 0; j < smoothness; j++) + { + SmoothTrajectories(ref linespt); + } + } + + List listCurves = new List(); + for (int r = 0; r < linespt.Length; r++) + { + List listPoint = new List(); + for (int s = 0; s < linespt[r].Length; s++) + { + listPoint.Add(linespt[r][s]); + } + listCurves.Add(new Polyline(listPoint)); + } + + //List of heights for mesh generation + List listHeights = new List(); + for (int j = 0; j < AccResolution_y; j++) + { + for (int i = 0; i < AccResolution_x; i++) + { + listHeights.Add(AccMap[i, j]); + } + } + + Mesh mesh = DensityMap(BB, AccResolution_x - 1, AccResolution_y - 1, listHeights, value); + + DA.SetDataList(1, listCurves); + DA.SetData(2, mesh); + + //DA.SetData(2, BB); + //DA.SetData(3, AccResolution_x - 1); + //DA.SetData(4, AccResolution_y - 1); + //DA.SetDataList(5, listHeights); + + + } + + //Information + private string info = + "This C# code instance algorithm of Kernel Density Estimation-based Edge Bundling is created by Antoine LHUILLIER, and is based on " + + "work from Christophe Hurter, Alexandru Telea, and Ozan Ersoy, Graph Bundling by Kernel Density Estimation. " + + "EuroVis 2012.Computer Graphics Forum journal.\r\n" + + "Extremely appreciate for their contribution.\r\n" + + "More details on the website:\r\n" + + "https://www.grasshopper3d.com/forum/topics/kernel-density-estimation-based-edge-bundling\r\n" + + "http://recherche.enac.fr/~hurter/KDEEB/KDEEB.html"; + + //Method + public double[,] GetKernel(int KernSize) + { + // Creates the kernel Structure + double[,] Kernel = new double[KernSize, KernSize]; + double id; + double jd; + double n = ((double)KernSize - 1.0) / 2.0; + double centerDist; + + // Fill the structure for a circular gradiant Kernel + for (int i = 0; i < KernSize; i++) + { + for (int j = 0; j < KernSize; j++) + { + id = (double)i; + jd = (double)j; + centerDist = Math.Sqrt((jd - n) * (jd - n) + (id - n) * (id - n)); + //Epanechnikov Kernel (1-distance²) + Kernel[i, j] = Math.Max(0.0, 1.0 - (centerDist / n) * (centerDist / n)); + } + } + return Kernel; + } + public double[,] ComputeSplatting(int AccResolution_x, int AccResolution_y, double[,] Kernel, int KernelSize, Point3d[][] lines, BoundingBox BB) + { + double[,] AccMap = new double[AccResolution_x, AccResolution_y]; + int ix; + int iy; + int itabx; + int itaby; + + for (int i_l = 0; i_l < lines.Length; i_l++) + { + for (int i_p = 0; i_p < lines[i_l].Length; i_p++) + { + ix = Convert.ToInt32((lines[i_l][i_p].X - BB.Min.X) / (BB.Max.X - BB.Min.X) * ((double)AccResolution_x - 1.0)); + iy = Convert.ToInt32((lines[i_l][i_p].Y - BB.Min.Y) / (BB.Max.Y - BB.Min.Y) * ((double)AccResolution_y - 1.0)); + for (int i = 0; i < KernelSize; i++) + { + for (int j = 0; j < KernelSize; j++) + { + itabx = (ix + i - (KernelSize - 1) / 2); + itaby = (iy + j - (KernelSize - 1) / 2); + if ((itabx >= 0) && (itabx < AccResolution_x) && (itaby >= 0) && (itaby < AccResolution_y)) + { + AccMap[itabx, itaby] += Kernel[i, j]; + } + } + } + } + } + return AccMap; + } + + public Vector3d GetLocalGradient(int gradientW, double[,] AccMap, int AccResolution_x, int AccResolution_y, Point3d pt, BoundingBox BB) + { + int i_x; + int i_y; + + Vector3d localGradient = new Vector3d(); + for (int i = 0; i < gradientW; i++) + { + for (int j = 0; j < gradientW; j++) + { + i_x = Convert.ToInt32((pt.X - BB.Min.X) / (BB.Max.X - BB.Min.X) * ((double)AccResolution_x - 1.0)); + i_y = Convert.ToInt32((pt.Y - BB.Min.Y) / (BB.Max.Y - BB.Min.Y) * ((double)AccResolution_y - 1.0)); + + if ((i_x + i - gradientW / 2) >= 0 + && (i_x + i - gradientW / 2) < AccResolution_x + && (i_y + j - gradientW / 2) >= 0 + && (i_y + j - gradientW / 2) < AccResolution_y) + { + double localDensity = AccMap[i_x + i - gradientW / 2, i_y + j - gradientW / 2]; + double dX = ((double)i - (double)gradientW / 2.0) * (BB.Max.X - BB.Min.X) / ((double)AccResolution_x - 1.0); + double dY = ((double)j - (double)gradientW / 2.0) * (BB.Max.Y - BB.Min.Y) / ((double)AccResolution_y - 1.0); + localGradient.X += localDensity * dX; + localGradient.Y += localDensity * dY; + } + } + } + return localGradient; + } + + private void ApplyGradient(ref Point3d[][] lines, int gradientW, double attracFactor, double[,] AccMap, int AccResolution_x, int AccResolution_y, BoundingBox BB) + { + + double dx = (BB.Max.X - BB.Min.X) / ((double)AccResolution_x - 1.0); + double dy = (BB.Max.Y - BB.Min.Y) / ((double)AccResolution_y - 1.0); + // Apply the Gradient for each points + for (int i_l = 0; i_l < lines.Length; i_l++) + { + for (int i_p = 1; i_p < lines[i_l].Length - 1; i_p++) + { + // Get the gradient value at the current point + Vector3d localGradient = GetLocalGradient(gradientW, AccMap, AccResolution_x, AccResolution_y, lines[i_l][i_p], BB); + + // Normalizing the localGradient. + if (localGradient.X != 0 || localGradient.Y != 0) + { + localGradient.Unitize(); + } + // Move each point by the gradient vector associated within + lines[i_l][i_p].X = lines[i_l][i_p].X + attracFactor * localGradient.X * dx; + lines[i_l][i_p].Y = lines[i_l][i_p].Y + attracFactor * localGradient.Y * dy; + } + } + } + /// Sampling extrapolate a new point from two point if thoose are too far from each other. + /// But also can suppress a point if he is to close to another. + /// Sampling is done only one vertices from the same trajectory. + public Point3d[][] Resample_points(double splitDist, List pt1, List pt2) + { + Point3d[][] tempPoint3d = new Point3d[pt1.Count][]; + + for (int i = 0; i < pt1.Count; i++) + { + List tmpPoint3dList = new List(); + //tmpPoint3dList.Add(pt1[i]); + double distance = pt1[i].DistanceTo(pt2[i]); + int n_points = Math.Max(3, Convert.ToInt32(distance / splitDist)); + // Sampling on each lines (= trajectory) + for (int j = 0; j <= n_points; j++) + { + tmpPoint3dList.Add(pt1[i] + (pt2[i] - pt1[i]) * j / n_points); + } + tempPoint3d[i] = tmpPoint3dList.ToArray(); + } + return tempPoint3d; + } + /// Sampling extrapolate a new point from two point if thoose are too far from each other. + /// But also can suppress a point if he is to close to another. + /// Sampling is done only one vertices from the same trajectory. + public void Resample(double splitDist, double removeDist, ref Point3d[][] tempPoint3d) + { + for (int i = 0; i < tempPoint3d.Length; i++) + { + List tmpPoint3dList = new List + { + tempPoint3d[i][0] + }; + // Sampling on each lines (= trajectory) + for (int j = 0; j < tempPoint3d[i].Length - 1; j++) + { + Point3d currentPoint = tempPoint3d[i][j]; + Point3d nextPoint = tempPoint3d[i][j + 1]; + double dist = currentPoint.DistanceTo(nextPoint); + // Test if the next point is too far or too close + if (dist > splitDist) + { + tmpPoint3dList.Add(new Point3d((currentPoint + nextPoint) / 2)); + } + if (!(dist < removeDist) || j == tempPoint3d[i].Length - 2) + { + tmpPoint3dList.Add(nextPoint); + } + } + tempPoint3d[i] = tmpPoint3dList.ToArray(); + } + } + //Laplacian smoothing + public void SmoothTrajectories(ref Point3d[][] CurrentTraj) + { + for (int i = 0; i < CurrentTraj.Length; i++) + { + for (int j = 1; j < CurrentTraj[i].Length - 1; j++) + { + CurrentTraj[i][j] = (CurrentTraj[i][j - 1] + CurrentTraj[i][j] + CurrentTraj[i][j + 1]) / 3; + } + } + } + + //Create density map mesh + public Mesh DensityMap(BoundingBox b, int x, int y, List h, double v) + { + //Get the mesh region. + Interval width = new Interval(0, b.Max.X - b.Min.X); + Interval heigth = new Interval(0, b.Max.Y - b.Min.Y); + //Get the origin of map and create a mesh based on it. + Point3d origin = new Point3d(b.Min.X, b.Min.Y, 0); + Plane meshplane = new Plane(origin, Plane.WorldXY.Normal); + Mesh planemesh = Mesh.CreateFromPlane(meshplane, width, heigth, x, y); + //Calculate the maximum of density. + double hmax = h.Max(); + //Replace the mesh points + for (int i = 0; i < planemesh.Vertices.Count; i++) + { + //Remap the density. + float vdensity = (float) (v * h[i] / hmax); + //Replace points. + Point3f pt = new Point3f(planemesh.Vertices[i].X, planemesh.Vertices[i].Y, vdensity); + planemesh.Vertices[i] = pt; + } + return planemesh; + } + + /// + /// Provides an Icon for the component. + /// + protected override System.Drawing.Bitmap Icon => Properties.Resources.Edge_Bundling; + + + /// + /// Gets the unique ID for this component. Do not change this ID after release. + /// + public override Guid ComponentGuid + { + get { return new Guid("9A6C1904-CC01-453C-8F9A-A240EB419B0D"); } + } + + public override GH_Exposure Exposure => GH_Exposure.hidden; + } +} \ No newline at end of file diff --git a/AnalComps/IsovistRegionComponent.cs b/AnalComps/IsovistRegionComponent.cs new file mode 100644 index 0000000..8a3adce --- /dev/null +++ b/AnalComps/IsovistRegionComponent.cs @@ -0,0 +1,1267 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Drawing; + +using Grasshopper.Kernel.Types; +using Grasshopper.Kernel; +using Grasshopper.Kernel.Parameters; +using Rhino.Geometry; +using Rhino.Geometry.Intersect; +using Rhino.Geometry.Collections; + + +using System.Windows.Forms; +using GH_IO.Serialization; +using Grasshopper; + +namespace CapableArchiTool.AnalComps +{ + public class IsovistRegionComponent : GH_Component + { + /// + /// Initializes a new instance of the VisualRegionComponent class. + /// + public IsovistRegionComponent() + : base("Isovist Region", "Isovist", + "Create the isovist region in 2D or 3D.", + "Capable Archi Tool", "02 Analysis") + { + } + + /// + /// Registers all the input parameters for this component. + /// + protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) + { + pManager.AddPointParameter("Origin", "O", "The visual eye position in space.", GH_ParamAccess.item, Point3d.Origin); + pManager.AddVectorParameter("Direction", "D", "The direction of sightview line", GH_ParamAccess.item, Vector3d.XAxis); + pManager.AddNumberParameter("Horizontal Angle", "H", "The horizontal angle of sightview.", GH_ParamAccess.item, Math.PI / 4); + pManager.AddNumberParameter("Radius", "R", "The radius of the sightview region, same as the length of sightview lines.", GH_ParamAccess.item, 50); + pManager.AddIntegerParameter("Density", "D", "The sightview line density of sightview region. The higher density it has, the more sightview lines is contains." + Environment.NewLine + + "The value of density in 3D mode should be a interger above 0, and in 3D mode it should be a double between 0 and 1.", GH_ParamAccess.item, 20); + pManager.AddGeometryParameter("Context", "C", "The context buildings or terrian in the environment.", GH_ParamAccess.list); + pManager.AddBooleanParameter("Run", "Run", "Run this calculation.", GH_ParamAccess.item, false); + + pManager[5].Optional = true; + + Grasshopper.CentralSettings.CanvasFullNamesChanged += OnCanvasFullNamesChanged; + } + + /// + /// Registers all the output parameters for this component. + /// + protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) + { + pManager.AddGeometryParameter("Isovist", "I", "The isovist region.", GH_ParamAccess.item); + } + + private void OnCanvasFullNamesChanged() => UpdateIONames(); + + /// + /// This is the method that actually does the work. + /// + /// The DA object is used to retrieve from inputs and store in outputs. + + //Get the SDK version. + //private readonly Version v = typeof(Curve).Assembly.GetName().Version; + + Line renderArrow = new Line(); + List brepCornerLines = new List(); + List meshCornerLines = new List(); + bool fieldRun = false; + + protected override void SolveInstance(IGH_DataAccess DA) + { + //Declare the variables. + Point3d origin = new Point3d(); + Vector3d direction = new Vector3d(); + double hAngle = 0; + double pAngle = 0; + double radius = 0; + double density = 0.5; + int count = 10; + List context = new List(); + bool run = false; + + DA.GetData(0, ref origin); + DA.GetData(1, ref direction); + if (direction == Vector3d.Zero) direction = Vector3d.XAxis; + DA.GetData(2, ref hAngle); + + int flag = 0; + + if (isMode2D) + { + if (hAngle <= 0 || hAngle > Math.PI * 2) + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The horizontal angle should between (0, 2π]."); + flag++; + } + DA.GetData(3, ref radius); + if (radius <= 0) + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The radius should be positive."); + flag++; + } + DA.GetData(4, ref count); + if (count <= 0) + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The density should be positive."); + flag++; + } + if (flag != 0) return; + + DA.GetData(6, ref run); + + Vector3d v = direction; + v.Unitize(); + renderArrow = new Line(origin, v * radius); + + //Visualize the view region. + NurbsCurve nurbs = MoveAndRoatateFrustumArc(CreateArcFrustum(radius, hAngle), origin, direction); + Brep frustumBrep = CreateFrustumBrep(nurbs, origin, hAngle); + + //Calculate the isovist. + if (!run) + DA.SetData(0, frustumBrep); + else + { + if (!DA.GetDataList(5, context) || context.Count == 0) + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The context is empty."); + return; + } + + List intersectPts = MakeIntersection(FrustumLines(nurbs, origin, count), context, true, origin); + DA.SetData(0, IsovistBrep(hAngle, intersectPts, origin)); + } + } + else + { + if (hAngle <= 0 || hAngle > Math.PI * 2) + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The horizontal angle should between (0, 2π]."); + flag++; + } + DA.GetData(3, ref pAngle); + if (pAngle <= 0 || pAngle > Math.PI) + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The pitch angle should between (0, π]."); + flag++; + } + DA.GetData(4, ref radius); + if (radius <= 0) + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The radius should be positive."); + flag++; + } + DA.GetData(5, ref density); + if (density <= 0) + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The density should be positive."); + flag++; + } + if (flag != 0) return; + + DA.GetData(7, ref run); + + fieldRun = run; + + Vector3d v = direction; + v.Unitize(); + renderArrow = new Line(origin, v * radius); + + Mesh FrustumMesh = new Mesh(); + List FrustumLines = new List(); + + + //Generate the frustum brep. + Brep FrustumBrep = MoveAndRoatateFrustumBrep(CreateFrustumBrep(radius, hAngle, pAngle), origin, direction); + + //Visualize the view region. + //if (versionint >= 7) + //{ + // Brep FrustumBrep = TransformFrustumBrep(CreateFrustumBrep(radius, hAngle, pAngle), origin, direction); + // List frustumLine = QuadremeshCreateFrustumLine(FrustumBrep, origin, density, out Mesh frustumMesh); + // FrustumLines = frustumLine; + // FrustumMesh = frustumMesh; + //} + //else + //{ + // List starVectors = CreateStarLikeVectorAndMesh(density, out Mesh sphereMesh); + // List frustumVectors = CreateFrustumVectorAndMesh(sphereMesh, starVectors, hAngle, pAngle, out Mesh frustumMesh); + // List frustumLine = CreateFrustumLineAndMesh(frustumMesh, frustumVectors, direction, origin, radius, out Mesh frustumMesh2); + // FrustumLines = frustumLine; + // FrustumMesh = frustumMesh2; + //} + + //Calculate the isovist. + if (!run) + { + DA.SetData(0, FrustumBrep); + } + else + { + if (!DA.GetDataList(6, context) || context.Count == 0) + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The context is empty."); + return; + }; + FrustumMesh = SimpleMesh(FrustumBrep, density); + FrustumLines = CreateRayLines(FrustumMesh, origin); + List intersectPts = MakeIntersection(FrustumLines, context, false, origin); + Mesh IsoFrustumMesh = IsovistMesh(FrustumMesh, intersectPts, origin); + + DA.SetData(0, IsoFrustumMesh); + } + } + } + + + //2D Intersection + //Create region arc and brep according to certain radius and horizontal span. + private ArcCurve CreateArcFrustum(double radius, double hAngle) + { + Arc arc = new Arc(Plane.WorldXY, Point3d.Origin, radius, hAngle); + ArcCurve arcCrv = new ArcCurve(arc); + arcCrv.Rotate(-hAngle / 2, Vector3d.ZAxis, Point3d.Origin); + return arcCrv; + } + + //Rotate the arc frustum with direction and move it to the origin. + private NurbsCurve MoveAndRoatateFrustumArc(ArcCurve arc, Point3d Origin, Vector3d Direction) + { + double hangle = Vector3d.VectorAngle(Vector3d.XAxis, new Vector3d(Direction.X, Direction.Y, 0)); + if (Direction.Y < 0) hangle = 2 * Math.PI - hangle; + + Transform hRotate = Transform.Rotation(hangle, Vector3d.ZAxis, Point3d.Origin); + arc.Transform(hRotate); + + Transform move = Transform.Translation(new Vector3d(Origin)); + arc.Transform(move); + + return arc.ToNurbsCurve(); + } + + //Generate the isovist brep. + private Brep CreateFrustumBrep(NurbsCurve crv, Point3d origin, double hAngle) + { + if (hAngle != Math.PI * 2) + { + Point3d pt1 = crv.PointAtStart; + Point3d pt2 = crv.PointAtEnd; + LineCurve lc1 = new LineCurve(origin, pt1); + LineCurve lc2 = new LineCurve(origin, pt2); + + List edges = new List { lc1, lc2, crv }; + Brep[] frustumBrep = Brep.CreatePlanarBreps(edges, 0.01); + return frustumBrep[0]; + + } + else + { + List edges = new List { crv }; + Brep[] frustumBrep = Brep.CreatePlanarBreps(edges, 0.01); + return frustumBrep[0]; + } + } + + #region old version of creating frustum lines + ////Create star-like vector on World-XY plane, and create the view frustm, determined by the horizontal span. + //private List CreateStarLikeVectorOnPlane(int density, double hAngle) + //{ + // double segRadius = 2 * Math.PI / density; + // List StarVectors = new List(); + // for (int i = 0; i < density; i++) + // { + // if (i * segRadius <= hAngle / 2 || 2 * Math.PI - i * segRadius <= hAngle / 2) + // { + // Vector3d V = new Vector3d(Math.Cos(i * segRadius), Math.Sin(i * segRadius), 0); + // V.Unitize(); + // StarVectors.Add(V); + // } + // } + // return StarVectors; + //} + + ////Generate new frustum lines according to the radius, direction and origin of sightview, and the region plane surface of sightview. + //private List CreateFrustumLineAndBrep(List FrustumVectors, double radius, Vector3d Direction, Point3d Origin, out Brep regionBrep, double hAngle) + //{ + // Vector3d Dir = new Vector3d(Direction.X, Direction.Y, 0); + // double rAngle = Vector3d.VectorAngle(Vector3d.XAxis, Dir); + // List FrustumLine = new List(); + // foreach (Vector3d V in FrustumVectors) + // { + // V.Rotate(rAngle, Vector3d.ZAxis); + // FrustumLine.Add(new Line(Origin, V, radius)); + // } + + // //Create the sightview region preview. + // List lineEndPts = new List(); + // for (int i = 0; i < FrustumLine.Count; i++) lineEndPts.Add(FrustumLine[i].To); + + // List EdgeLines = new List(); + + // if (hAngle == 2 * Math.PI) + // { + // for (int i = 0; i < lineEndPts.Count - 1; i++) + // { + // EdgeLines.Add(new LineCurve(new Line(lineEndPts[i], lineEndPts[i + 1]))); + // } + // EdgeLines.Add(new LineCurve(new Line(lineEndPts.Last(), lineEndPts.First()))); + // Brep isovistBrep = Brep.CreateEdgeSurface(EdgeLines); + // regionBrep = isovistBrep; + // } + // else + // { + // //Sort the intersect points. + // List NewPoint3d = new List(); + // for (int i = 0; i < (FrustumLine.Count - 1) / 2; i++) + // { + // NewPoint3d.Add(lineEndPts[i]); + // } + // NewPoint3d.Add(Origin); + // for (int i = (FrustumLine.Count - 1) / 2 + 1; i < FrustumLine.Count; i++) + // { + // NewPoint3d.Add(lineEndPts[i]); + // } + // //Create edge lines. + // for (int i = 0; i < NewPoint3d.Count - 1; i++) + // { + // EdgeLines.Add(new LineCurve(new Line(NewPoint3d[i], NewPoint3d[i + 1]))); + // } + // EdgeLines.Add(new LineCurve(new Line(NewPoint3d.Last(), NewPoint3d.First()))); + // Brep[] isovistBrep = Brep.CreatePlanarBreps(EdgeLines, 0.1); + // regionBrep = isovistBrep[0]; + // } + + // return FrustumLine; + //} + #endregion + + //Divide the arc and create frustum lines. + private List FrustumLines(NurbsCurve crv, Point3d origin, int density) + { + List ls = new List(); + crv.DivideByCount(density, true, out Point3d[] pts); + for(int i = 0; i < pts.Length; i++) + { + Line l = new Line(origin, pts[i]); + ls.Add(l); + } + return ls; + } + + //Calculate the interection. + private List IntersectLineAndContext2D(List frustumLine, List context, Point3d origin) + { + List IntersectLinePts = new List(); + List IntersectToPts = new List(); + + foreach (Line L in frustumLine) + { + List IntersectPts = new List(); + foreach (Object Con in context) + { + if (Con is GH_Surface) + { + GH_Surface surface = Con as GH_Surface; + Surface ConSurface = null; + GH_Convert.ToSurface(surface, ref ConSurface, 0); + + Intersection.CurveBrep(L.ToNurbsCurve(), ConSurface.ToBrep(), 0.1, out _, out Point3d[] intersectpts); + if (intersectpts.Length != 0) + foreach (Point3d pt in intersectpts) + { + IntersectPts.Add(pt); + } + } + + if (Con is GH_Brep) + { + GH_Brep brep = Con as GH_Brep; + Brep ConBrep = new Brep(); + GH_Convert.ToBrep(brep, ref ConBrep, 0); + + Intersection.CurveBrep(L.ToNurbsCurve(), ConBrep, 0.1, out _, out Point3d[] intersectpts); + if (intersectpts.Length != 0) + foreach (Point3d pt in intersectpts) + { + IntersectPts.Add(pt); + } + } + + if (Con is GH_Mesh) + { + GH_Mesh mesh = Con as GH_Mesh; + Mesh ConMesh = new Mesh(); + GH_Convert.ToMesh(mesh, ref ConMesh, 0); + + Point3d[] intersectpts = Intersection.MeshLine(ConMesh, L); + if (intersectpts.Length != 0) + foreach (Point3d pt in intersectpts) + { + IntersectPts.Add(pt); + } + } + } + if (IntersectPts.Count != 0) + { + List distance = new List(); + foreach (Point3d pt in IntersectPts) distance.Add((new Line(origin, pt)).Length); + IntersectLinePts.Add(IntersectPts[distance.IndexOf(distance.Min())]); + } + else IntersectLinePts.Add(L.To); + } + foreach (Point3d pt in IntersectLinePts) + { + IntersectToPts.Add(new Point3d(pt.X, pt.Y, origin.Z)); + } + + return IntersectToPts; + } + + //Create isovist region brep. + private Brep IsovistBrep(double hAngle, List intersectPts, Point3d origin) + { + if (hAngle != 2 * Math.PI) + { + LineCurve l1 = new LineCurve(intersectPts.First(), origin); + LineCurve l2 = new LineCurve(intersectPts.Last(), origin); + PolylineCurve pl = new PolylineCurve(intersectPts); + Brep[] frustumBrep = Brep.CreatePlanarBreps(new List { l1, l2, pl }, 0.01); + if (frustumBrep != null) return frustumBrep[0]; + else + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The sighview point is too close to the context surface."); + return null; + } + } + else + { + intersectPts.Add(intersectPts.First()); + PolylineCurve pl = new PolylineCurve(intersectPts); + Brep[] frustumBrep = Brep.CreatePlanarBreps(new List { pl }, 0.01); + if (frustumBrep != null) return frustumBrep[0]; + else + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The sighview point is too close to the context surface."); + return null; + } + } + } + + + //3D Intersection + //Create frustum according to certain radius sphere and horizontal span and pitch span. + private Brep CreateFrustumBrep(double radius, double hAngle, double pAngle) + { + Sphere sphere = new Sphere(Point3d.Origin, radius); + sphere.Rotate(Math.PI, Vector3d.ZAxis); + Brep sphereBrep = Brep.CreateFromSphere(sphere); + + if (hAngle == Math.PI * 2 && pAngle == Math.PI) return sphereBrep; + if (hAngle == Math.PI * 2 && pAngle != Math.PI) + { + Vector3d v = new Vector3d(radius, 0, 0); + v.Rotate(-pAngle / 2, Vector3d.YAxis); + + Plane upperPlane = new Plane(0, 0, 1, -v.Z); + Plane lowerPlane = new Plane(0, 0, 1, v.Z); + + Point3d pt1 = new Point3d(2 * radius, 2 * radius, v.Z); + Point3d pt3 = new Point3d(-2 * radius, -2 * radius, v.Z); + + Rectangle3d uprec = new Rectangle3d(upperPlane, pt1, pt3); + Rectangle3d lorec = new Rectangle3d(lowerPlane, pt1, pt3); + PolylineCurve upplc = uprec.ToPolyline().ToPolylineCurve(); + PolylineCurve loplc = lorec.ToPolyline().ToPolylineCurve(); + Brep upperBrep = Brep.CreatePlanarBreps(upplc, 0.1)[0]; + Brep lowerBrep = Brep.CreatePlanarBreps(loplc, 0.1)[0]; + List cutterBreps = new List { upperBrep, lowerBrep }; + + Brep[] splitBrep = sphereBrep.Split(cutterBreps, 0.1); + return splitBrep[2]; + + } + if (hAngle != Math.PI * 2 && pAngle == Math.PI) + { + Vector3d v1 = new Vector3d(radius * 2, 0, 0); + v1.Rotate(hAngle / 2, Vector3d.ZAxis); + Vector3d v2 = new Vector3d(radius * 2, 0, 0); + v2.Rotate(-hAngle / 2, Vector3d.ZAxis); + + Line l1 = new Line(new Point3d(0, 0, radius * 2), v1); + LineCurve lc1 = new LineCurve(l1); + Line l2 = new Line(new Point3d(0, 0, radius * 2), v2); + LineCurve lc2 = new LineCurve(l2); + LineCurve[] upperlc = new LineCurve[] { lc1, lc2 }; + + Line l3 = new Line(new Point3d(0, 0, -radius * 2), v1); + LineCurve lc3 = new LineCurve(l3); + Line l4 = new Line(new Point3d(0, 0, -radius * 2), v2); + LineCurve lc4 = new LineCurve(l4); + LineCurve[] lowerlc = new LineCurve[] { lc3, lc4 }; + + Curve[] joinedUpperCrv = LineCurve.JoinCurves(upperlc, 0.1); + Curve[] joinedLowerCrv = LineCurve.JoinCurves(lowerlc, 0.1); + + Curve[] loftCrv = new Curve[2] { joinedUpperCrv[0], joinedLowerCrv[0] }; + + Brep[] loftBrep = Brep.CreateFromLoft(loftCrv, Point3d.Unset, Point3d.Unset, LoftType.Straight, false); + + Brep[] splitBrep = sphereBrep.Split(loftBrep, 0.1); + + //for (int i = 0; i < splitBrep.Length; i++) + //{ + // Line l = new Line(new Point3d(0, 0, 0), new Point3d(radius * 2, 0, 0)); + // LineCurve lc = new LineCurve(l); + // bool isIntersect = Intersection.CurveBrep(lc, splitBrep[i], 0.1, out _, out _); + // if (isIntersect) return splitBrep[i]; + //} + + return splitBrep[1]; + } + if (hAngle != Math.PI * 2 && pAngle != Math.PI) + { + Brep preFrustumBrep = new Brep(); + + Vector3d v = new Vector3d(radius, 0, 0); + v.Rotate(-pAngle / 2, Vector3d.YAxis); + + Plane upperPlane = new Plane(0, 0, 1, -v.Z); + Plane lowerPlane = new Plane(0, 0, 1, v.Z); + + Point3d pt1 = new Point3d(2 * radius, 2 * radius, v.Z); + Point3d pt3 = new Point3d(-2 * radius, -2 * radius, v.Z); + + Rectangle3d uprec = new Rectangle3d(upperPlane, pt1, pt3); + Rectangle3d lorec = new Rectangle3d(lowerPlane, pt1, pt3); + PolylineCurve upplc = uprec.ToPolyline().ToPolylineCurve(); + PolylineCurve loplc = lorec.ToPolyline().ToPolylineCurve(); + Brep upperBrep = Brep.CreatePlanarBreps(upplc, 0.1)[0]; + Brep lowerBrep = Brep.CreatePlanarBreps(loplc, 0.1)[0]; + List cutterBreps = new List { upperBrep, lowerBrep }; + + Brep[] splitBrep = sphereBrep.Split(cutterBreps, 0.1); + preFrustumBrep = splitBrep[2]; + + Vector3d v1 = new Vector3d(radius * 2, 0, 0); + v1.Rotate(hAngle / 2, Vector3d.ZAxis); + Vector3d v2 = new Vector3d(radius * 2, 0, 0); + v2.Rotate(-hAngle / 2, Vector3d.ZAxis); + + Line l1 = new Line(new Point3d(0, 0, radius * 2), v1); + LineCurve lc1 = new LineCurve(l1); + Line l2 = new Line(new Point3d(0, 0, radius * 2), v2); + LineCurve lc2 = new LineCurve(l2); + LineCurve[] upperlc = new LineCurve[] { lc1, lc2 }; + + Line l3 = new Line(new Point3d(0, 0, -radius * 2), v1); + LineCurve lc3 = new LineCurve(l3); + Line l4 = new Line(new Point3d(0, 0, -radius * 2), v2); + LineCurve lc4 = new LineCurve(l4); + LineCurve[] lowerlc = new LineCurve[] { lc3, lc4 }; + + Curve[] joinedUpperCrv = LineCurve.JoinCurves(upperlc, 0.1); + Curve[] joinedLowerCrv = LineCurve.JoinCurves(lowerlc, 0.1); + + Curve[] loftCrv = new Curve[2] { joinedUpperCrv[0], joinedLowerCrv[0] }; + + Brep[] loftBrep = Brep.CreateFromLoft(loftCrv, Point3d.Unset, Point3d.Unset, LoftType.Straight, false); + + Brep[] splitBrep2 = preFrustumBrep.Split(loftBrep, 0.1); + return splitBrep2[1]; + + } + return null; + } + + //Rotate the frustum with direction and move it to the origin. + private Brep MoveAndRoatateFrustumBrep(Brep Frustum, Point3d Origin, Vector3d Direction) + { + //Get frust line through ray according to the direction, radius and position of sightview. + double pangle = Vector3d.VectorAngle(Direction, new Vector3d(Direction.X, Direction.Y, 0)); + if (Direction.X == 0 && Direction.Y == 0) pangle = Direction.Z <= 0 ? 0.5 * Math.PI : 1.5 * Math.PI; + else pangle = Direction.Z <= 0 ? pangle : 2 * Math.PI - pangle; + + Transform pRotate = Transform.Rotation(pangle, Vector3d.YAxis, Point3d.Origin); + + double hangle = Vector3d.VectorAngle(Vector3d.XAxis, new Vector3d(Direction.X, Direction.Y, 0)); + if (Direction.Y < 0) hangle = 2 * Math.PI - hangle; + + Transform hRotate = Transform.Rotation(hangle, Vector3d.ZAxis, Point3d.Origin); + + Frustum.Transform(pRotate); + Frustum.Transform(hRotate); + + Transform move = Transform.Translation(new Vector3d(Origin)); + + Frustum.Transform(move); + + //List bs = new List(); + //Brep frustumBrep = new Brep(); + //if (Frustum.Edges != null) + //{ + // foreach (BrepEdge edge in Frustum.Edges) + // { + // Curve crv = edge.DuplicateCurve(); + // Point3d pt1 = crv.PointAtStart; + // Point3d pt2 = crv.PointAtEnd; + + // LineCurve crv1 = new LineCurve(pt1, Origin); + // LineCurve crv2 = new LineCurve(pt2, Origin); + + // List crvs = new List { crv, crv1, crv2 }; + + // Brep[] b = Brep.CreatePlanarBreps(crvs, 0.01); + // bs.AddRange(b.ToList()); + // } + // bs.Add(Frustum); + // frustumBrep = Brep.JoinBreps(bs, 0.01)[0]; + //} + + Point3d[] brepPts = Frustum.DuplicateVertices(); + brepCornerLines.Clear(); + meshCornerLines.Clear(); + for (int i = 0; i < brepPts.Length; i++) + { + brepCornerLines.Add(new Line(Origin, brepPts[i])); + } + + return Frustum; + } + + //Transform the brep to mesh, the default method is simple mesh, if the rhino version is beyond 7, the quadremesh is valid. + private Mesh SimpleMesh(Brep Frustum, double density) + { + MeshingParameters meshParam = new MeshingParameters(density); + Mesh[] mesh = Mesh.CreateFromBrep(Frustum, meshParam); + return mesh[0]; + } + + //Get lines which are created from origin to vertices on mesh. + List CreateRayLines(Mesh FrustumMesh, Point3d Origin) + { + List FrustumLine = new List(); + foreach (Point3d pt in FrustumMesh.Vertices) + { + FrustumLine.Add(new Line(Origin, pt)); + } + return FrustumLine; + } + + #region old version of creating the frustum brep + ////Quad Remesh the frustum brep to mesh, and get lines which are created from origin to vertices on mesh. + //private List QuadremeshCreateFrustumLine(Brep Frustum, Point3d Origin, int density, out Mesh FrustumMesh) + //{ + // QuadRemeshParameters para = new QuadRemeshParameters + // { + // AdaptiveQuadCount = false, + // AdaptiveSize = 50, + // DetectHardEdges = true, + // PreserveMeshArrayEdgesMode = 1, + // TargetQuadCount = density + // }; + + // Mesh QuadFrustumMesh = Mesh.QuadRemeshBrep(Frustum, para); + // QuadFrustumMesh.Vertices.CombineIdentical(true, true); + + // List FrustumLine = new List(); + // foreach (Point3d pt in QuadFrustumMesh.Vertices) + // { + // FrustumLine.Add(new Line(Origin, pt)); + // } + + // FrustumMesh = QuadFrustumMesh; + // return FrustumLine; + //} + + + ////Create star-like vector and the sphere mesh, which is determined by a cube. + //private List CreateStarLikeVectorAndMesh(int density, out Mesh SphereMesh) + //{ + // List StarVectors = new List(); + + // Box VectorBox = new Box(Plane.WorldXY, new Interval(-1.0, 1.0), new Interval(-1.0, 1.0), new Interval(-1.0, 1.0)); + // Mesh BoxMesh = Mesh.CreateFromBox(VectorBox, density, density, density); + // BoxMesh.Vertices.CombineIdentical(true, true); + + // for (int i = 0; i < BoxMesh.Vertices.Count; i++) + // { + // Vector3d StarVector = BoxMesh.Vertices[i] - Plane.WorldXY.Origin; + // StarVector.Unitize(); + // StarVectors.Add(StarVector); + // BoxMesh.Vertices[i] = new Point3f((float)StarVector.X, (float)StarVector.Y, (float)StarVector.Z); + // } + + // SphereMesh = BoxMesh; + // return StarVectors; + //} + + ////Create the view frustum, which contains the sight vector and frustum mesh, determined by the horizontal span and pitch sapn. + //private List CreateFrustumVectorAndMesh(Mesh SphereMesh, List StarVectors, double hAngle, double pAngle, out Mesh FrustumMesh) + //{ + // List PreFrustumVector = new List(); + // List FaceIndex = new List(); + + // for (int i = 0; i < StarVectors.Count; i++) + // { + // double coshA = new Vector3d(StarVectors[i].X, StarVectors[i].Y, 0) * Vector3d.XAxis; + // double sinpA = Math.Abs(StarVectors[i] * Vector3d.ZAxis); + + // //Get the certain vector in the span. + // if (coshA <= 1 && coshA >= Math.Cos(hAngle / 2) && sinpA >= 0 && sinpA <= Math.Sin(pAngle / 2)) + // { + // PreFrustumVector.Add(StarVectors[i]); + // } + // else foreach (int index in SphereMesh.Vertices.GetVertexFaces(i)) FaceIndex.Add(index); + // } + + // //Delete mesh face. + // List FaceIndexNoRepeat = FaceIndex.Distinct().ToList(); + // SphereMesh.Faces.DeleteFaces(FaceIndexNoRepeat); + // FrustumMesh = SphereMesh; + + // //Get new points order. + // Point3d[] points = FrustumMesh.Vertices.ToPoint3dArray(); + // List FrustumVector = new List(); + // for (int i = 0; i < points.Length; i++) FrustumVector.Add(new Vector3d(points[i].X, points[i].Y, points[i].Z)); + + // return FrustumVector; + //} + + ////Generate new frustum lines according to the radius, direction and origin of sightview, and the mesh with correct radius, direction and position. + //private List CreateFrustumLineAndMesh(Mesh PreFrustumMesh, List FrustumVectors, Vector3d Direction, Point3d Origin, double radius, out Mesh FrustumMesh) + //{ + // //Get frust line through ray according to the direction, radius and position of sightview. + // double pangle = Vector3d.VectorAngle(Direction, new Vector3d(Direction.X, Direction.Y, 0)); + // if (Direction.X == 0 && Direction.Y == 0) pangle = Direction.Z <= 0 ? 0.5 * Math.PI : 1.5 * Math.PI; + // else pangle = Direction.Z <= 0 ? pangle : 2 * Math.PI - pangle; + + // double hangle = Vector3d.VectorAngle(Vector3d.XAxis, new Vector3d(Direction.X, Direction.Y, 0)); + // if (Direction.Y < 0) hangle = 2 * Math.PI - hangle; + // //double radian = Vector3d.VectorAngle(Direction, Vector3d.XAxis); + // //Vector3d axis = Vector3d.CrossProduct(Vector3d.XAxis, Direction); + + // List FrustumLine = new List(); + // foreach (Vector3d V in FrustumVectors) + // { + // //V.Rotate(radian, axis); + + // V.Rotate(pangle, Vector3d.YAxis); + // V.Rotate(hangle, Vector3d.ZAxis); + + // Line line = new Line(Origin, V, radius); + // FrustumLine.Add(line); + // } + + // //Rotate, expand and move the FrustumMesh. + // for (int i = 0; i < PreFrustumMesh.Vertices.Count; i++) + // { + // PreFrustumMesh.Vertices[i] = (Point3f)FrustumLine[i].To; + // } + + // FrustumMesh = PreFrustumMesh; + // return FrustumLine; + //} + #endregion + + //Calculate the interection. + private List IntersectLineAndContext3D(List FrustumLine, List Context, Point3d Origin) + { + List IntersectLinePts = new List(); + + foreach (Line L in FrustumLine) + { + List IntersectPts = new List(); + foreach (Object Con in Context) + { + if (Con is GH_Surface) + { + GH_Surface surface = Con as GH_Surface; + Surface ConSurface = null; + GH_Convert.ToSurface(surface, ref ConSurface, 0); + + Intersection.CurveBrep(L.ToNurbsCurve(), ConSurface.ToBrep(), 0.1, out _, out Point3d[] intersectpts); + if (intersectpts.Length != 0) + foreach (Point3d pt in intersectpts) + { + IntersectPts.Add(pt); + } + } + + if (Con is GH_Brep) + { + GH_Brep brep = Con as GH_Brep; + Brep ConBrep = new Brep(); + GH_Convert.ToBrep(brep, ref ConBrep, 0); + + Intersection.CurveBrep(L.ToNurbsCurve(), ConBrep, 0.1, out _, out Point3d[] intersectpts); + if (intersectpts.Length != 0) + foreach (Point3d pt in intersectpts) + { + IntersectPts.Add(pt); + } + } + + if (Con is GH_Mesh) + { + GH_Mesh mesh = Con as GH_Mesh; + Mesh ConMesh = new Mesh(); + GH_Convert.ToMesh(mesh, ref ConMesh, 0); + + Point3d[] intersectpts = Intersection.MeshLine(ConMesh, L); + if (intersectpts.Length != 0) + foreach (Point3d pt in intersectpts) + { + IntersectPts.Add(pt); + } + } + } + if (IntersectPts.Count != 0) + { + List distance = new List(); + foreach (Point3d pt in IntersectPts) distance.Add((new Line(Origin, pt)).Length); + IntersectLinePts.Add(IntersectPts[distance.IndexOf(distance.Min())]); + } + else IntersectLinePts.Add(L.To); + } + return IntersectLinePts; + } + + //Create isovist isovist mesh. + private Mesh IsovistMesh(Mesh FrustumMesh, List IntersectPts, Point3d Origin) + { + for (int i = 0; i < FrustumMesh.Vertices.Count; i++) + { + FrustumMesh.Vertices[i] = (Point3f)IntersectPts[i]; + } + + //Polyline[] pls = FrustumMesh.GetNakedEdges(); + //Mesh sideMesh = new Mesh(); + //if(pls.Length != 0) + //{ + // for(int i = 0; i < pls.Length; i++) + // { + // Point3d pt1 = pls[i].First; + // Point3d pt2 = pls[i].Last; + // List pts = new List { pt1, pt2, Origin }; + // Mesh mesh = new Mesh(); + // mesh.Vertices.AddVertices(pts); + // mesh.Faces.AddFace(0, 1, 2); + + // sideMesh.Append(mesh); + // } + + // FrustumMesh.Append(sideMesh); + //} + + return FrustumMesh; + } + + //Convert context to mesh object and make line-ray intersection. + private List MakeIntersection(List FrustumLine, List Context, bool is2D, Point3d Origin) + { + List IntersectLinePts = new List(); + MeshingParameters meshParam = new MeshingParameters(1); + + Mesh allContext = new Mesh(); + + foreach (Object Con in Context) + { + if (Con is GH_Surface) + { + GH_Surface surface = Con as GH_Surface; + Surface conSurface = null; + GH_Convert.ToSurface(surface, ref conSurface, 0); + + Brep conBrep = conSurface.ToBrep(); + + Mesh[] mesh = Mesh.CreateFromBrep(conBrep, meshParam); + foreach (Mesh m in mesh.ToList()) + { + allContext.Append(m); + } + } + + if (Con is GH_Brep) + { + GH_Brep brep = Con as GH_Brep; + Brep conBrep = new Brep(); + GH_Convert.ToBrep(brep, ref conBrep, 0); + + Mesh[] mesh = Mesh.CreateFromBrep(conBrep, meshParam); + foreach (Mesh m in mesh.ToList()) + { + allContext.Append(m); + } + } + + if (Con is GH_Mesh) + { + GH_Mesh mesh = Con as GH_Mesh; + Mesh conMesh = new Mesh(); + GH_Convert.ToMesh(mesh, ref conMesh, 0); + + allContext.Append(conMesh); + } + } + + if (is2D == true) + { + foreach (Line l in FrustumLine) + { + Point3d[] pt = Intersection.MeshLine(allContext, l); + if (pt.Length != 0) + { + IntersectLinePts.Add(new Point3d(pt[0].X, pt[0].Y, Origin.Z)); + } + else + { + IntersectLinePts.Add(l.To); + } + } + } + else + { + foreach (Line l in FrustumLine) + { + Point3d[] pt = Intersection.MeshLine(allContext, l); + if (pt.Length != 0) + { + IntersectLinePts.Add(pt[0]); + } + else + { + IntersectLinePts.Add(l.To); + } + } + + foreach (Line l in brepCornerLines) + { + Point3d[] pt = Intersection.MeshLine(allContext, l); + if (pt.Length == 0) + meshCornerLines.Add(new Line(Origin, l.To)); + else + meshCornerLines.Add(new Line(Origin, pt[0])); + } + } + + + return IntersectLinePts; + } + + //Calculate the target + //Area + + + //Initialize the component. + bool isMode2D = true; + + IEnumerator ParamEnum; + readonly List paramList = new List(); + + private void Mode2DParaRegister() + { + Param_Number paramRadius = new Param_Number + { + Name = "Radius", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Radius" : "R", + Description = "The radius of the sightview region, same as the length of sightview lines.", + Access = GH_ParamAccess.item + }; + Param_Integer paramDensity = new Param_Integer + { + Name = "Density", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Density" : "D", + Description = "The sightview line density of sightview region. The higher density it has, the more sightview lines is contains." + Environment.NewLine + + "The value of density in 3D mode should be a interger above 0, and in 3D mode it should be a double between 0 and 1.", + Access = GH_ParamAccess.item + }; + Param_Geometry paramContext = new Param_Geometry + { + Name = "Context", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Context" : "C", + Description = "The context buildings or terrian in the environment.", + Access = GH_ParamAccess.list + }; + Param_Boolean paramRun = new Param_Boolean + { + Name = "Run", + NickName = "Run", + Description = "Run this calculation.", + Access = GH_ParamAccess.item + }; + Param_Geometry paramIsovist = new Param_Geometry + { + Name = "Isovist", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Isovist" : "I", + Description = "The isovist region.", + Access = GH_ParamAccess.item + }; + + paramRadius.SetPersistentData(50); + paramDensity.SetPersistentData(20); + paramRun.SetPersistentData(false); + paramContext.Optional = true; + + Params.RegisterInputParam(paramRadius); + Params.RegisterInputParam(paramDensity); + Params.RegisterInputParam(paramContext); + Params.RegisterInputParam(paramRun); + Params.RegisterOutputParam(paramIsovist); + } + + private void Mode3DParaRegister() + { + Param_Number paramPitchAngle = new Param_Number + { + Name = "Pitch Angle", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Pitch Angle" : "P", + Description = "The Pitch angle of sightview.", + Access = GH_ParamAccess.item + }; + Param_Number paramRadius = new Param_Number + { + Name = "Radius", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Radius" : "R", + Description = "The radius of the sightview region, same as the length of sightview lines.", + Access = GH_ParamAccess.item + }; + Param_Number paramDensity = new Param_Number + { + Name = "Density", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Density" : "D", + Description = "The sightview line density of sightview region. The higher density it has, the more sightview lines is contains." + Environment.NewLine + + "The value of density in 3D mode should be a interger above 0, and in 3D mode it should be a double between 0 and 1.", + Access = GH_ParamAccess.item + }; + Param_Geometry paramContext = new Param_Geometry + { + Name = "Context", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Context" : "C", + Description = "The context buildings or terrian in the environment.", + Access = GH_ParamAccess.list + }; + Param_Boolean paramRun = new Param_Boolean + { + Name = "Run", + NickName = "Run", + Description = "Run this calculation.", + Access = GH_ParamAccess.item + }; + Param_Geometry paramIsovist = new Param_Geometry + { + Name = "Isovist", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Isovist" : "I", + Description = "The isovist region.", + Access = GH_ParamAccess.item + }; + + paramPitchAngle.SetPersistentData(Math.PI / 4); + paramRadius.SetPersistentData(50); + paramDensity.SetPersistentData(0.5); + paramRun.SetPersistentData(false); + paramContext.Optional = true; + + Params.RegisterInputParam(paramPitchAngle); + Params.RegisterInputParam(paramRadius); + Params.RegisterInputParam(paramDensity); + Params.RegisterInputParam(paramContext); + Params.RegisterInputParam(paramRun); + Params.RegisterOutputParam(paramIsovist); + } + + //Add the label. + public void UpdateMessage() + { + base.Message = (isMode2D ? "2D Mode" : "3D Mode"); + } + + protected override void AppendAdditionalComponentMenuItems(ToolStripDropDown menu) + { + ToolStripMenuItem Mode2DChecked = new ToolStripMenuItem + { + Text = "2D Mode", + Checked = isMode2D + }; + Mode2DChecked.Click += new EventHandler((o, e) => + { + if (!isMode2D) + { + isMode2D = true; + + UpdateMessage(); + + ParamEnum = Params.GetEnumerator(); + while (ParamEnum.MoveNext()) + { + IGH_Param param = ParamEnum.Current; + if (param.Name != "Origin" && param.Name != "Direction" && param.Name != "Horizontal Angle") + { + paramList.Add(param); + } + } + ParamEnum.Reset(); + + foreach (IGH_Param param in paramList) + { + Params.UnregisterParameter(param); + } + paramList.Clear(); + + Mode2DParaRegister(); + Params.OnParametersChanged(); + ExpireSolution(true); + } + }); + + + ToolStripMenuItem Mode3DChecked = new ToolStripMenuItem + { + Text = "3D Mode", + Checked = !isMode2D + }; + Mode3DChecked.Click += new EventHandler((o, e) => + { + if (isMode2D) + { + isMode2D = false; + + UpdateMessage(); + + ParamEnum = Params.GetEnumerator(); + while (ParamEnum.MoveNext()) + { + IGH_Param param = ParamEnum.Current; + if (param.Name != "Origin" && param.Name != "Direction" && param.Name != "Horizontal Angle") + { + paramList.Add(param); + } + } + ParamEnum.Reset(); + + foreach (IGH_Param param in paramList) + { + Params.UnregisterParameter(param); + } + paramList.Clear(); + + Mode3DParaRegister(); + Params.OnParametersChanged(); + ExpireSolution(true); + } + }); + + menu.Items.Add(Mode2DChecked); + menu.Items.Add(Mode3DChecked); + + return; + } + + private void UpdateIONames() + { + if (isMode2D) + { + Params.Input[3].NickName = CentralSettings.CanvasFullNames ? "Radius" : "R"; + Params.Input[4].NickName = CentralSettings.CanvasFullNames ? "Density" : "D"; + Params.Input[5].NickName = CentralSettings.CanvasFullNames ? "Context" : "C"; + } + + else + { + Params.Input[3].NickName = CentralSettings.CanvasFullNames ? "Pitch Angle" : "P"; + Params.Input[4].NickName = CentralSettings.CanvasFullNames ? "Radius" : "R"; + Params.Input[5].NickName = CentralSettings.CanvasFullNames ? "Density" : "D"; + Params.Input[6].NickName = CentralSettings.CanvasFullNames ? "Context" : "C"; + } + + Params.Output[0].NickName = CentralSettings.CanvasFullNames ? "Isovist" : "I"; + + Params.OnParametersChanged(); + ExpireSolution(true); + } + + public override bool Write(GH_IWriter writer) + { + writer.SetBoolean("Mode", isMode2D); + return base.Write(writer); + } + + public override bool Read(GH_IReader reader) + { + if (reader.ItemExists("Mode")) + { + isMode2D = reader.GetBoolean("Mode"); + + ParamEnum = Params.GetEnumerator(); + while (ParamEnum.MoveNext()) + { + IGH_Param param = ParamEnum.Current; + if (param.Name != "Origin" && param.Name != "Direction" && param.Name != "Horizontal Angle") + { + paramList.Add(param); + } + } + ParamEnum.Reset(); + + foreach (IGH_Param param in paramList) + { + Params.UnregisterParameter(param); + } + paramList.Clear(); + + + if (isMode2D) Mode2DParaRegister(); + else Mode3DParaRegister(); + Params.OnParametersChanged(); + ExpireSolution(true); + } + return base.Read(reader); + } + + public override void AddedToDocument(GH_Document document) + { + base.AddedToDocument(document); + UpdateMessage(); + ExpireSolution(true); + } + + Color color = Color.DarkRed; + + public override void DrawViewportWires(IGH_PreviewArgs args) + { + base.DrawViewportWires(args); + args.Display.DrawArrow(renderArrow, color); + if (!isMode2D) + { + if (!fieldRun) + { + foreach (Line l in brepCornerLines) + args.Display.DrawLine(l, color); + } + else + { + foreach (Line l in meshCornerLines) + args.Display.DrawLine(l, color); + } + } + } + + /// + /// Provides an Icon for the component. + /// + protected override System.Drawing.Bitmap Icon => Properties.Resources.Isovist_Region; + + + /// + /// Gets the unique ID for this component. Do not change this ID after release. + /// + public override Guid ComponentGuid + { + get { return new Guid("CA5B065B-977A-499F-B101-D4704B956F99"); } + } + } +} \ No newline at end of file diff --git a/AnalComps/PolygonPOIComponent.cs b/AnalComps/PolygonPOIComponent.cs new file mode 100644 index 0000000..fed6120 --- /dev/null +++ b/AnalComps/PolygonPOIComponent.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.IO; + +using Grasshopper.Kernel; +using Rhino.Geometry; + +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace CapableArchiTool.AnalComps +{ + public class PolygonPOIComponent : GH_Component + { + /// + /// Initializes a new instance of the POIHeatMapMesh class. + /// + public PolygonPOIComponent() + : base("Polygon POI", "POI", + "Grab POI data within a polygon plot, use the Amap API.", + "Capable Archi Tool", "02 Analysis") + { + } + + /// + /// Registers all the input parameters for this component. + /// + protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) + { + pManager.AddTextParameter("Polygon", "P", "Set the corner points of the polygon, " + + "should use the format like 'longitude1,latitude1|longitude2,latitude2|longitude3,latitude3|...'", + GH_ParamAccess.item); + pManager.AddTextParameter("Keywords", "K", "The Keywords of data that are being searched, " + + "should use the format like 'keyword1|keyword2|keyword3|...'", GH_ParamAccess.item); + pManager[1].Optional = true; + pManager.AddTextParameter("Type", "T", "The types of data that are being searched, " + + "should use the format like 'type1|type2|type3|...'", GH_ParamAccess.item); + pManager[2].Optional = true; + pManager.AddIntegerParameter("Offset", "O", "The amount of data that will be recorded on every page, " + + "larger than 25 will probably cause error.", GH_ParamAccess.item); + pManager[3].Optional = true; + pManager.AddIntegerParameter("Page", "P", "The current page.", GH_ParamAccess.item); + pManager[4].Optional = true; + pManager.AddTextParameter("API Key", "A", "The key that applied from Amap to use API.", GH_ParamAccess.item); + pManager.AddBooleanParameter("Run", "Run", "Run this component.", GH_ParamAccess.item, false); + } + + /// + /// Registers all the output parameters for this component. + /// + protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) + { + pManager.AddGenericParameter("Json", "J", "The json file that return from website.", GH_ParamAccess.item); + } + + /// + /// This is the method that actually does the work. + /// + /// The DA object is used to retrieve from inputs and store in outputs. + protected override void SolveInstance(IGH_DataAccess DA) + { + string polygon = null; + string keywords = null; + string type = null; + int offset = 20; + int page = 1; + string key = null; + bool run = false; + + string url = "https://restapi.amap.com/v3/place/polygon?"; + + if (!DA.GetData(0, ref polygon)) return; + else + url += "polygon=" + polygon; + if (DA.GetData(1, ref keywords)) + url += "&keywords=" + keywords; + if (DA.GetData(2, ref type)) + url += "&types=" + type; + if (DA.GetData(3, ref offset)) + url += "&offset=" + offset; + if (DA.GetData(4, ref page)) + url += "&page=" + page; + if (!DA.GetData(5, ref key)) return; + else + url += "&output=json&key=" + key; + if (!DA.GetData(6, ref run)) return; + + if(run) + { + HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); + HttpWebResponse response = (HttpWebResponse)request.GetResponse(); + StreamReader reader = new StreamReader(response.GetResponseStream()); + string json = reader.ReadToEnd(); + + DA.SetData(0, json); + } + } + + + /// + /// Provides an Icon for the component. + /// + protected override System.Drawing.Bitmap Icon => Properties.Resources.POI_Heat_Map; + + + /// + /// Gets the unique ID for this component. Do not change this ID after release. + /// + public override Guid ComponentGuid + { + get { return new Guid("4080B609-6818-4DC0-96A4-61132731106A"); } + } + } +} \ No newline at end of file diff --git a/AnalComps/WaterRunoffComponent.cs b/AnalComps/WaterRunoffComponent.cs new file mode 100644 index 0000000..dbdeead --- /dev/null +++ b/AnalComps/WaterRunoffComponent.cs @@ -0,0 +1,928 @@ +using System; +using System.Collections.Generic; + +using Rhino; +using Grasshopper; +using Grasshopper.Kernel; +using Rhino.Geometry; +using Grasshopper.Kernel.Data; +using Grasshopper.Kernel.Types; +using Grasshopper.Kernel.Parameters; + +using Rhino.Geometry.Intersect; +using System.Windows.Forms; + +using Grasshopper.GUI.Canvas; + + +namespace CapableArchiTool.AnalComps +{ + public class WaterRunoffComponent : GH_Component + { + /// + /// Initializes a new instance of the WaterRunoffComponent class. + /// + public WaterRunoffComponent() + : base("Water Runoff", "WaterRunoff", + "Simulate rainwater runoff in a mountainous region", + "Capable Archi Tool", "02 Analysis") + { + } + + /// + /// Registers all the input parameters for this component. + /// + protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) + { + pManager.AddGeometryParameter("Terrain", "T", "Terrain that will be calculated water runoff.", GH_ParamAccess.item); + pManager.AddRectangleParameter("Region", "R", "Rectangle region that raindrop will be generated.", GH_ParamAccess.item); + pManager.AddIntegerParameter("Density", "D", "Waterdrop density in rectangle region.", GH_ParamAccess.item); + pManager.AddIntegerParameter("Seed", "S", "Seed of the random points.", GH_ParamAccess.item); + pManager.AddNumberParameter("Length", "L", "The length of step every time the waterdrop will take in resultant force direction.", GH_ParamAccess.item); + pManager.AddIntegerParameter("Iteration", "I", "The iteration that the calculation proceeds on.", GH_ParamAccess.item); + pManager.AddBooleanParameter("Run", "Run", "Run this calculation.", GH_ParamAccess.item, false); + + Grasshopper.CentralSettings.CanvasFullNamesChanged += OnCanvasFullNamesChanged; + } + + /// + /// Registers all the output parameters for this component. + /// + protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) + { + pManager.AddPointParameter("Points", "Pts", "Every waterdrop point on the water runoff path.", GH_ParamAccess.tree); + pManager.AddCurveParameter("Path", "P", "The water runoff path.", GH_ParamAccess.list); + //pManager.AddMeshParameter("Area", "A", "Different water runoff area.", GH_ParamAccess.item); + } + + private void OnCanvasFullNamesChanged() => UpdateIONames(); + + + + /// + /// This is the method that actually does the work. + /// + /// The DA object is used to retrieve from inputs and store in outputs. + protected override void SolveInstance(IGH_DataAccess DA) + { + object terrian = new object(); + Rectangle3d region = new Rectangle3d(); + int density = 0; + int seed = 0; + double length = 0; + int iteration = 0; + bool run = false; + + int xCount = 0; + int yCount = 0; + + List sourcePoints = new List(); + + switch (Mode) + { + case 0: + if (!DA.GetData(0, ref terrian)) return; + if (!DA.GetData(1, ref region)) return; + if (!DA.GetData(2, ref density)) return; + if (!DA.GetData(3, ref seed)) return; + if (!DA.GetData(4, ref length)) return; + if (!DA.GetData(5, ref iteration)) return; + if (!DA.GetData(6, ref run)) return; + break; + + case 1: + if (!DA.GetData(0, ref terrian)) return; + if (!DA.GetData(1, ref region)) return; + if (!DA.GetData(2, ref xCount)) return; + if (!DA.GetData(3, ref yCount)) return; + if (!DA.GetData(4, ref length)) return; + if (!DA.GetData(5, ref iteration)) return; + if (!DA.GetData(6, ref run)) return; + break; + + case 2: + if (!DA.GetData(0, ref terrian)) return; + if (!DA.GetData(1, ref region)) return; + if (!DA.GetDataList(2, sourcePoints)) return; + if (!DA.GetData(3, ref length)) return; + if (!DA.GetData(4, ref iteration)) return; + if (!DA.GetData(5, ref run)) return; + break; + } + + if (!run) return; + + //Detect whether the object is among surface, Brep and mesh, if true, detect whether the object is plane. + bool isplane = IsPlane(terrian, out int type); + if (type == 0) + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The input object is not among surface, Brep and mesh!"); + return; + } + if (isplane) + { + AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The input object is plane!"); + return; + } + + //Generate points. + List sourcePts = new List(); + + switch (Mode) + { + case 0: + sourcePts = Random2DPoints(terrian, region, bb, density, seed, type); + break; + case 1: + sourcePts = Serial2DPoints(terrian, region, bb, xCount, yCount, type); + break; + case 2: + sourcePts = Custom3DPoints(terrian, region, bb, sourcePoints, type); + break; + } + + + GH_Structure pts = new GH_Structure(); + List pathCrvs = new List(); + int pathID = 0; + + //Loop every point in the pointlist and move it. + foreach (Point3d pt in sourcePts) + { + List crvPts = new List(); + GH_Path path = new GH_Path(pathID); + pts.Append(new GH_Point(pt), path); + crvPts.Add(pt); + + pathID++; + int i = 0; + Point3d cpt1 = FindClosestPoint(terrian, pt, type); + Point3d mpt, cpt2 = new Point3d(); + Vector3d moveDir = new Vector3d(); + + double cpt1X = 0; + double cpt2X = 0; + + //Begin the loop + do + { + moveDir = GeteResultantForce(terrian, cpt1, type); + moveDir.Unitize(); + mpt = MovePoint(cpt1, moveDir, length); + cpt2 = FindClosestPoint(terrian, mpt, type); + GH_Point ghp = new GH_Point(cpt2); + pts.Append(ghp, path); + crvPts.Add(cpt2); + + cpt1X = cpt1.X; + cpt2X = cpt2.X; + + cpt1 = cpt2; + i++; + } + while (!DetectOutOfRegion(region, mpt) && i < iteration && cpt1X != cpt2X); + + PolylineCurve pathCrv = new PolylineCurve(crvPts); + pathCrv.ToNurbsCurve(); + if(pathCrv.IsValid) pathCrvs.Add(pathCrv); + } + + //Output + DA.SetDataTree(0, pts); + DA.SetDataList(1, pathCrvs); + } + + BoundingBox bb = new BoundingBox(); + + //Check the input terrian type. + //public int CheckType( + + //Detect whether the object is among surface, Brep and mesh, if true, detect whether the object is plane, + //when the object is surface, type = 1, brep type = 2, mesh type = 3, otherwise type = 0, + //and if object is plane, return true, or return false. + public bool IsPlane(object terrian, out int type) + { + if (terrian is GH_Surface) + { + GH_Surface ter = terrian as GH_Surface; + bb = ter.Boundingbox; + type = 1; + } + else if (terrian is GH_Brep) + { + GH_Brep ter = terrian as GH_Brep; + bb = ter.Boundingbox; + type = 2; + } + else if (terrian is GH_Mesh) + { + GH_Mesh ter = terrian as GH_Mesh; + bb = ter.Boundingbox; + type = 3; + } + else type = 0; + + if ((bb.Max.Z - bb.Min.Z) == 0) return true; + else return false; + } + + //Randomly generate points in certain rectangular. + public List Random2DPoints(object ter, Rectangle3d rec, BoundingBox bb, int density, int seed, int type) + { + List ptlist = new List(); + Random rand = new Random(seed); + for (int i = 0; i < density; i++) + { + double x = rec.Corner(0).X + rand.NextDouble() * rec.Width; + double y = rec.Corner(0).Y + rand.NextDouble() * rec.Height; + double z = bb.Center.Z + bb.Max.Z - bb.Min.Z; + Point3d pt = new Point3d(x, y, z); + double proZ = ProZ(ter, pt, type, bb, out bool isIntersect); + if (isIntersect) ptlist.Add(new Point3d(x, y, proZ)); + } + return ptlist; + } + + //Serially generate points in certain rectangular. + public List Serial2DPoints(object ter, Rectangle3d rec, BoundingBox bb, int xcount, int ycount, int type) + { + List ptlist = new List(); + double xstep = rec.Width / (xcount - 1); + double ystep = rec.Height / (xcount - 1); + double z = bb.Center.Z + bb.Max.Z - bb.Min.Z; + for (int i = 0; i < xcount; i++) + { + double x = rec.Corner(0).X + i * xstep; + for (int j = 0; j < ycount; j++) + { + double y = rec.Corner(0).Y + j * ystep; + Point3d pt = new Point3d(x, y, z); + double proZ = ProZ(ter, pt, type, bb, out bool isIntersect); + if (isIntersect) ptlist.Add(new Point3d(x, y, proZ)); + } + } + return ptlist; + } + + //Adjust points position that user input. + public List Custom3DPoints(object ter, Rectangle3d rec, BoundingBox bb, List pts, int type) + { + double xmin = rec.Corner(0).X; + double xmax = rec.Corner(2).X; + double ymin = rec.Corner(0).Y; + double ymax = rec.Corner(2).Y; + List ptlist = new List(); + foreach (Point3d inputPt in pts) + { + if (inputPt.X >= xmin && inputPt.X <= xmax && inputPt.Y >= ymin && inputPt.Y <= ymax) + { + Point3d pt = new Point3d(inputPt.X, inputPt.Y, bb.Center.Z + bb.Max.Z - bb.Min.Z); + double proZ = ProZ(ter, pt, type, bb, out bool isIntersect); + if (isIntersect) ptlist.Add(new Point3d(inputPt.X, inputPt.Y, proZ)); + } + } + return ptlist; + } + + //Project point to the terrian and get the Z coordinate. + public double ProZ(object obj, Point3d pt, int type, BoundingBox bb, out bool isIntersect) + { + double len = bb.Max.Z - bb.Min.Z; + Line l = new Line(pt, -Vector3d.ZAxis, 2 * len); + switch (type) + { + case 1: + GH_Surface srf = obj as GH_Surface; + Surface rhSrf = null; + GH_Convert.ToSurface(srf, ref rhSrf, 0); + Intersection.CurveBrep(l.ToNurbsCurve(), rhSrf.ToBrep(), 0.1, out _, out Point3d[] srfpt); + isIntersect = !(srfpt.Length == 0); + if (isIntersect == false) + { + return 0; + } + else return srfpt[0].Z; + case 2: + GH_Brep brep = obj as GH_Brep; + Brep rhBrep = new Brep(); + GH_Convert.ToBrep(brep, ref rhBrep, 0); + Intersection.CurveBrep(l.ToNurbsCurve(), rhBrep, 0.1, out _, out Point3d[] breppt); + isIntersect = !(breppt.Length == 0); + if (isIntersect == false) + { + return 0; + } + else return breppt[0].Z; + case 3: + GH_Mesh mesh = obj as GH_Mesh; + Mesh rhMesh = new Mesh(); + GH_Convert.ToMesh(mesh, ref rhMesh, 0); + Point3d[] intersectpt = Intersection.MeshLine(rhMesh, l); + if (intersectpt.Length == 0) + { + isIntersect = false; + return 0; + } + else + { + isIntersect = true; + return intersectpt[0].Z; + } + default: + { + isIntersect = false; + return 0; + } + } + } + + + //Get the resultant force direction. + public Vector3d GeteResultantForce(object obj, Point3d pt, int type) + { + switch (type) + { + //Input object is surface. + case 1: + { + GH_Surface srf = obj as GH_Surface; + Surface rhSrf = null; + GH_Convert.ToSurface(srf, ref rhSrf, 0); + rhSrf.ClosestPoint(bb.Center, out double u, out double v); + Vector3d centernor = rhSrf.NormalAt(u, v); + Brep srfBrep = rhSrf.ToBrep(); + if (centernor.Z < 0) srfBrep.Flip(); + + //Surface normal at certain point. + srfBrep.ClosestPoint(pt, out Point3d cpt, out ComponentIndex ci, out double s, out double t, double.MaxValue, out Vector3d normal); + normal.Unitize(); + Vector3d resultant = (-Vector3d.ZAxis) + normal * (Vector3d.Multiply(Vector3d.ZAxis, normal) / normal.Length); + return resultant; + } + + //Input object is brep. + case 2: + { + GH_Brep brep = obj as GH_Brep; + Brep rhBrep = new Brep(); + GH_Convert.ToBrep(brep, ref rhBrep, 0); + rhBrep.ClosestPoint(bb.Center, out Point3d ccpt, out ComponentIndex ci, out double s, out double t, double.MaxValue, out Vector3d centernor); + if (centernor.Z < 0) rhBrep.Flip(); + + //Brep normal at certain point. + rhBrep.ClosestPoint(pt, out Point3d cpt, out ComponentIndex ci2, out double s2, out double t2, double.MaxValue, out Vector3d normal); + normal.Unitize(); + Vector3d resultant = (-Vector3d.ZAxis) + normal * (Vector3d.Multiply(Vector3d.ZAxis, normal) / normal.Length); + return resultant; + } + + //Input object is mesh. + case 3: + { + GH_Mesh mesh = obj as GH_Mesh; + Mesh rhMesh = new Mesh(); + GH_Convert.ToMesh(mesh, ref rhMesh, 0); + rhMesh.ClosestPoint(bb.Center, out Point3d centerPointOnMesh, out Vector3d centernor, double.MaxValue); + if (centernor.Z < 0) rhMesh.Flip(true, true, true); + + //Mesh normal at certain point. + rhMesh.ClosestPoint(pt, out Point3d pointOnMesh, out Vector3d normal, double.MaxValue); + normal.Unitize(); + Vector3d resultant = (-Vector3d.ZAxis) + normal * (Vector3d.Multiply(Vector3d.ZAxis, normal) / normal.Length); + return resultant; + } + + default: return Vector3d.Zero; + } + } + + //Find the closest point the terrian + public Point3d FindClosestPoint(object obj, Point3d pt, int type) + { + switch (type) + { + case 1: + { + GH_Surface srf = obj as GH_Surface; + Surface rhSrf = null; + GH_Convert.ToSurface(srf, ref rhSrf, 0); + rhSrf.ClosestPoint(pt, out double u, out double v); + return rhSrf.PointAt(u, v); + } + case 2: + { + GH_Brep brep = obj as GH_Brep; + Brep rhBrep = new Brep(); + GH_Convert.ToBrep(brep, ref rhBrep, 0); + return rhBrep.ClosestPoint(pt); + } + case 3: + { + GH_Mesh mesh = obj as GH_Mesh; + Mesh rhMesh = new Mesh(); + GH_Convert.ToMesh(mesh, ref rhMesh, 0); + return rhMesh.ClosestPoint(pt); + } + default: return Point3d.Origin; + } + } + + //Move the point to the next position. + public Point3d MovePoint(Point3d pt, Vector3d dir, double step) + { + Point3d npt = pt + dir * step; + return npt; + } + + //Dectect whether the point is out of region. + public bool DetectOutOfRegion(Rectangle3d rec, Point3d pt) + { + double xmin = rec.Corner(0).X; + double xmax = rec.Corner(2).X; + double ymin = rec.Corner(0).Y; + double ymax = rec.Corner(2).Y; + if (pt.X <= xmin || pt.X >= xmax || pt.Y <= ymin || pt.Y >= ymax) + { + return true; + } + return false; + } + + + + + //Detect whether the angle between velocity and the gravity is smaller than threshold, which means that the waterdrop is sinking into a hollow. + //public bool AngleSmallerThanThreshold(Vector3d v, double threshold) + //{ + // double angle = Vector3d.VectorAngle(v, -Vector3d.ZAxis); + // if (angle < threshold) + // return true; + // else return false; + //} + + + //Get the Gaussian curvature at certain point + //public double GaussianCurvature(object obj, Point3d pt, int type) + //{ + // switch (type) + // { + // case 1: + // { + // GH_Surface srf = obj as GH_Surface; + // Surface rhSrf = null; + // GH_Convert.ToSurface(srf, ref rhSrf, 0); + // rhSrf.ClosestPoint(pt, out double u, out double v); + // SurfaceCurvature sc = rhSrf.CurvatureAt(u, v); + // return sc.Gaussian; + // } + // case 2: + // { + // GH_Brep brep = obj as GH_Brep; + // Brep rhBrep = new Brep(); + // GH_Convert.ToBrep(brep, ref rhBrep, 0); + // rhBrep.ClosestPoint(pt, out Point3d cpt, out ComponentIndex ci, out double s, out double t, 0.1, out Vector3d normal); + // if(ci.ComponentIndexType == ComponentIndexType.BrepFace) + // { + // Surface face = rhBrep.Faces[ci.Index]; + // SurfaceCurvature sc = face.CurvatureAt(s, t); + // return sc.Gaussian; + // } + // return 1; + // } + // case 3: + // { + // GH_Mesh mesh = obj as GH_Mesh; + // Mesh rhMesh = new Mesh(); + // GH_Convert.ToMesh(mesh, ref rhMesh, 0); + // } + // default: return 1; + // } + //} + + private bool randomChecked = true; + private bool orderedChecked = false; + private bool customChecked = false; + + private int modeType; + public int Mode + { + get { return modeType; } + set + { + modeType = value; + if (modeType == 0) + { + Message = "Random"; + randomChecked = true; + orderedChecked = false; + customChecked = false; + } + else if (modeType == 1) + { + Message = "Ordered"; + randomChecked = false; + orderedChecked = true; + customChecked = false; + } + else if (modeType == 2) + { + Message = "Custom"; + randomChecked = false; + orderedChecked = false; + customChecked = true; + } + } + } + + + protected override void AppendAdditionalComponentMenuItems(ToolStripDropDown menu) + { + ToolStripMenuItem RandomChecked = new ToolStripMenuItem(); + RandomChecked.Text = "Random Points"; + RandomChecked.Checked = randomChecked; + RandomChecked.Click += new EventHandler((o, e) => + { + if (orderedChecked || customChecked) + { + Params.Clear(); + OutputRegister(); + RandomCheckedParaRegister(); + Params.OnParametersChanged(); + ExpireSolution(true); + } + }); + + + ToolStripMenuItem OrderedChecked = new ToolStripMenuItem(); + OrderedChecked.Text = "Ordered Points"; + OrderedChecked.Checked = orderedChecked; + OrderedChecked.Click += new EventHandler((o, e) => + { + if (randomChecked || customChecked) + { + Params.Clear(); + OutputRegister(); + OrderedCheckedParaRegister(); + Params.OnParametersChanged(); + ExpireSolution(true); + } + }); + + ToolStripMenuItem CustomChecked = new ToolStripMenuItem(); + CustomChecked.Text = "Custom Points"; + CustomChecked.Checked = customChecked; + CustomChecked.Click += new EventHandler((o, e) => + { + if (randomChecked || orderedChecked) + { + Params.Clear(); + OutputRegister(); + CustomCheckedParaRegister(); + Params.OnParametersChanged(); + ExpireSolution(true); + } + + }); + + menu.Items.Add(RandomChecked); + menu.Items.Add(OrderedChecked); + menu.Items.Add(CustomChecked); + + return; + } + + + public void RandomCheckedParaRegister() + { + Param_Geometry paramTerrain = new Param_Geometry + { + Name = "Terrain", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Terrain" : "T", + Description = "Terrain that will be calculated water runoff.", + Access = GH_ParamAccess.item + }; + + Param_Rectangle paramRegion = new Param_Rectangle + { + Name = "Region", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Region" : "R", + Description = "Rectangle region that raindrop will be generated.", + Access = GH_ParamAccess.item + }; + + Param_Integer paramDensity = new Param_Integer + { + Name = "Density", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Density" : "D", + Description = "Waterdrop density in rectangle region.", + Access = GH_ParamAccess.item + }; + + Param_Integer paramSeed = new Param_Integer + { + Name = "Seed", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Seed" : "S", + Description = "Seed of the random points.", + Access = GH_ParamAccess.item + }; + + Param_Number paramLength = new Param_Number + { + Name = "Length", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Length" : "L", + Description = "The length of step every time the waterdrop will take in resultant force direction.", + Access = GH_ParamAccess.item + }; + + Param_Integer paramIteration = new Param_Integer + { + Name = "Iteration", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Iteration" : "I", + Description = "The iteration that the calculation proceeds on.", + Access = GH_ParamAccess.item + }; + + Param_Boolean paramRun = new Param_Boolean + { + Name = "Run", + NickName = "Run", + Description = "Run calculation.", + Access = GH_ParamAccess.item + }; + + paramRun.SetPersistentData(false); + + Params.RegisterInputParam(paramTerrain); + Params.RegisterInputParam(paramRegion); + Params.RegisterInputParam(paramDensity); + Params.RegisterInputParam(paramSeed); + Params.RegisterInputParam(paramLength); + Params.RegisterInputParam(paramIteration); + Params.RegisterInputParam(paramRun); + + Mode = 0; + } + + public void OrderedCheckedParaRegister() + { + Param_Geometry paramTerrain = new Param_Geometry + { + Name = "Terrain", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Terrain" : "T", + Description = "Terrain that will be calculated water runoff.", + Access = GH_ParamAccess.item + }; + + Param_Rectangle paramRegion = new Param_Rectangle + { + Name = "Region", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Region" : "R", + Description = "Rectangle region that raindrop will be generated.", + Access = GH_ParamAccess.item + }; + + Param_Integer paramXCount = new Param_Integer + { + Name = "Xcount", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Xcount" : "X", + Description = "The points amount in X direction.", + Access = GH_ParamAccess.item + }; + + Param_Integer paramYCount = new Param_Integer + { + Name = "Ycount", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Ycount" : "Y", + Description = "The points amount in Y direction.", + Access = GH_ParamAccess.item + }; + + Param_Number paramLength = new Param_Number + { + Name = "Length", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Length" : "L", + Description = "The length of step every time the waterdrop will take in resultant force direction.", + Access = GH_ParamAccess.item + }; + + Param_Integer paramIteration = new Param_Integer + { + Name = "Iteration", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Iteration" : "I", + Description = "The iteration that the calculation proceeds on.", + Access = GH_ParamAccess.item + }; + + Param_Boolean paramRun = new Param_Boolean + { + Name = "Run", + NickName = "Run", + Description = "Run calculation.", + Access = GH_ParamAccess.item + }; + + paramRun.SetPersistentData(false); + + Params.RegisterInputParam(paramTerrain); + Params.RegisterInputParam(paramRegion); + Params.RegisterInputParam(paramXCount); + Params.RegisterInputParam(paramYCount); + Params.RegisterInputParam(paramLength); + Params.RegisterInputParam(paramIteration); + Params.RegisterInputParam(paramRun); + + Mode = 1; + } + + public void CustomCheckedParaRegister() + { + Param_Geometry paramTerrain = new Param_Geometry + { + Name = "Terrain", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Terrain" : "T", + Description = "Terrain that will be calculated water runoff.", + Access = GH_ParamAccess.item + }; + + Param_Rectangle paramRegion = new Param_Rectangle + { + Name = "Region", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Region" : "R", + Description = "Rectangle region that raindrop will be generated.", + Access = GH_ParamAccess.item + }; + + Param_Point paramCustomPoints = new Param_Point + { + Name = "Points", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Points" : "P", + Description = "The waterdrop points that user defines.", + Access = GH_ParamAccess.list + }; + + Param_Number paramLength = new Param_Number + { + Name = "Length", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Length" : "L", + Description = "The length of step every time the waterdrop will take in resultant force direction.", + Access = GH_ParamAccess.item + }; + + Param_Integer paramIteration = new Param_Integer + { + Name = "Iteration", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Iteration" : "I", + Description = "The iteration that the calculation proceeds on.", + Access = GH_ParamAccess.item + }; + + Param_Boolean paramRun = new Param_Boolean + { + Name = "Run", + NickName = "Run", + Description = "Run calculation.", + Access = GH_ParamAccess.item + }; + + paramRun.SetPersistentData(false); + + Params.RegisterInputParam(paramTerrain); + Params.RegisterInputParam(paramRegion); + Params.RegisterInputParam(paramCustomPoints); + Params.RegisterInputParam(paramLength); + Params.RegisterInputParam(paramIteration); + Params.RegisterInputParam(paramRun); + + Mode = 2; + } + + public void OutputRegister() + { + Param_Point paramOutPoints = new Param_Point + { + Name = "Points", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Points" : "Pts", + Description = "Every waterdrop point on the water runoff path.", + Access = GH_ParamAccess.tree + }; + + Param_Curve paramOutPath = new Param_Curve + { + Name = "Path", + NickName = Grasshopper.CentralSettings.CanvasFullNames ? "Path" : "P", + Description = "The water runoff path.", + Access = GH_ParamAccess.list + }; + + Params.RegisterOutputParam(paramOutPoints); + Params.RegisterOutputParam(paramOutPath); + } + + private void UpdateIONames() + { + if (Mode == 0) + { + Params.Input[0].NickName = CentralSettings.CanvasFullNames ? "Terrain" : "T"; + Params.Input[1].NickName = CentralSettings.CanvasFullNames ? "Region" : "R"; + Params.Input[2].NickName = CentralSettings.CanvasFullNames ? "Density" : "D"; + Params.Input[3].NickName = CentralSettings.CanvasFullNames ? "Seed" : "S"; + Params.Input[4].NickName = CentralSettings.CanvasFullNames ? "Length" : "L"; + Params.Input[5].NickName = CentralSettings.CanvasFullNames ? "Iteration" : "I"; + Params.Input[6].NickName = CentralSettings.CanvasFullNames ? "Run" : "Run"; + + Params.Output[0].NickName = CentralSettings.CanvasFullNames ? "Points" : "Pts"; + Params.Output[1].NickName = CentralSettings.CanvasFullNames ? "Path" : "P"; + } + + else if (Mode == 1) + { + Params.Input[0].NickName = CentralSettings.CanvasFullNames ? "Terrain" : "T"; + Params.Input[1].NickName = CentralSettings.CanvasFullNames ? "Region" : "R"; + Params.Input[2].NickName = CentralSettings.CanvasFullNames ? "Xcount" : "X"; + Params.Input[3].NickName = CentralSettings.CanvasFullNames ? "Ycount" : "Y"; + Params.Input[4].NickName = CentralSettings.CanvasFullNames ? "Length" : "L"; + Params.Input[5].NickName = CentralSettings.CanvasFullNames ? "Iteration" : "I"; + Params.Input[6].NickName = CentralSettings.CanvasFullNames ? "Run" : "Run"; + + Params.Output[0].NickName = CentralSettings.CanvasFullNames ? "Points" : "Pts"; + Params.Output[1].NickName = CentralSettings.CanvasFullNames ? "Path" : "P"; + } + else if (Mode == 2) + { + Params.Input[0].NickName = CentralSettings.CanvasFullNames ? "Terrain" : "T"; + Params.Input[1].NickName = CentralSettings.CanvasFullNames ? "Region" : "R"; + Params.Input[2].NickName = CentralSettings.CanvasFullNames ? "Points" : "P"; + Params.Input[3].NickName = CentralSettings.CanvasFullNames ? "Length" : "L"; + Params.Input[4].NickName = CentralSettings.CanvasFullNames ? "Iteration" : "I"; + Params.Input[5].NickName = CentralSettings.CanvasFullNames ? "Run" : "Run"; + + Params.Output[0].NickName = CentralSettings.CanvasFullNames ? "Points" : "Pts"; + Params.Output[1].NickName = CentralSettings.CanvasFullNames ? "Path" : "P"; + } + + Params.OnParametersChanged(); + ExpireSolution(true); + } + + public override void AddedToDocument(GH_Document document) + { + Func myFunction = delegate (int x) + { + if (x == 0) return "Random"; + else if (x == 1) return "Ordered"; + else return "Custom"; + }; + + base.AddedToDocument(document); + base.Message = myFunction(Mode); + ExpireSolution(true); + } + + public override bool Write(GH_IO.Serialization.GH_IWriter writer) + { + // First add our own field. + writer.SetInt32("Mode", Mode); + // Then call the base class implementation. + return base.Write(writer); + } + public override bool Read(GH_IO.Serialization.GH_IReader reader) + { + if (reader.ItemExists("Mode")) + { + Params.Clear(); + OutputRegister(); + + // First read our own field. + Mode = reader.GetInt32("Mode"); + + if (Mode == 0) + RandomCheckedParaRegister(); + else if (Mode == 1) + OrderedCheckedParaRegister(); + else if (Mode == 2) + CustomCheckedParaRegister(); + + Instances.RedrawCanvas(); + Params.OnParametersChanged(); + ExpireSolution(true); + + } + // Then call the base class implementation. + return base.Read(reader); + } + + /// + /// Provides an Icon for the component. + /// + protected override System.Drawing.Bitmap Icon => Properties.Resources.Water_Runoff; + + + /// + /// Gets the unique ID for this component. Do not change this ID after release. + /// + public override Guid ComponentGuid + { + get { return new Guid("4CDE9051-2B00-4F41-874F-2CEE76945282"); } + } + } +} \ No newline at end of file diff --git a/CapableArchiTool.csproj b/CapableArchiTool.csproj new file mode 100644 index 0000000..d78c81c --- /dev/null +++ b/CapableArchiTool.csproj @@ -0,0 +1,72 @@ + + + + net48 + 1.0 + CapableArchiTool + Description of CapableArchiTool + .gha + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + D:\Rhino 7.34\System\Rhino.exe + + /runscript="_-RunScript ( + Set GH = Rhino.GetPlugInObject(""Grasshopper"") + Call GH.OpenDocument(""E:\工作事务\项目开发\Grasshopper\CapableArchiTool\Debug File.gh"") + )" + Program + + + \ No newline at end of file diff --git a/CapableArchiTool.sln b/CapableArchiTool.sln new file mode 100644 index 0000000..e7fb551 --- /dev/null +++ b/CapableArchiTool.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.2.32526.322 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CapableArchiTool", "CapableArchiTool.csproj", "{7E401A72-8B12-4BBA-AA1A-F3F1127AA2C6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7E401A72-8B12-4BBA-AA1A-F3F1127AA2C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7E401A72-8B12-4BBA-AA1A-F3F1127AA2C6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7E401A72-8B12-4BBA-AA1A-F3F1127AA2C6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7E401A72-8B12-4BBA-AA1A-F3F1127AA2C6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {53ABEA15-B726-474C-929F-94299C9B0FEE} + EndGlobalSection +EndGlobal diff --git a/CapableArchiToolInfo.cs b/CapableArchiToolInfo.cs new file mode 100644 index 0000000..4757d76 --- /dev/null +++ b/CapableArchiToolInfo.cs @@ -0,0 +1,26 @@ +using Grasshopper; +using Grasshopper.Kernel; +using System; +using System.Drawing; + +namespace CapableArchiTool +{ + public class CapableArchiToolInfo : GH_AssemblyInfo + { + public override string Name => "CapableArchiTool"; + + //Return a 24x24 pixel bitmap to represent this GHA library. + public override Bitmap Icon => Properties.Resources.Plugin_Icon; + + //Return a short string describing the purpose of this GHA library. + public override string Description => "A tiny toolbox."; + + public override Guid Id => new Guid("67E060C9-E40F-48D8-AE70-3229B29CF709"); + + //Return a string identifying you or your company. + public override string AuthorName => "wunuooo"; + + //Return a string representing your preferred contact details. + public override string AuthorContact => "Contact me:xuwunuo@foxmail.com."; + } +} \ No newline at end of file diff --git a/InfoComps/PluginVersionComponent.cs b/InfoComps/PluginVersionComponent.cs new file mode 100644 index 0000000..045b257 --- /dev/null +++ b/InfoComps/PluginVersionComponent.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; + +using Grasshopper.Kernel; +using Rhino.Geometry; + +namespace CapableArchiTool.InfoComps +{ + public class PluginVersionComponent : GH_Component + { + /// + /// Initializes a new instance of the ShowVersionComponent class. + /// + public PluginVersionComponent() + : base("Plugin Version", "Version", + "Show the plugin version", + "Capable Archi Tool", "00 Information") + { + } + + /// + /// Registers all the input parameters for this component. + /// + protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) + { + } + + /// + /// Registers all the output parameters for this component. + /// + protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) + { + pManager.AddTextParameter("Version", "V", "Plugin version (semantic).", GH_ParamAccess.item); + //pManager.AddIntegerParameter("Major", "Ma", "", GH_ParamAccess.item); + //pManager.AddIntegerParameter("Minor", "Mi", "", GH_ParamAccess.item); + //pManager.AddIntegerParameter("Patch", "P", "", GH_ParamAccess.item); + } + + /// + /// This is the method that actually does the work. + /// + /// The DA object is used to retrieve from inputs and store in outputs. + protected override void SolveInstance(IGH_DataAccess DA) + { + DA.SetData(0, CapableArchiTool.Utils.CustomPluginProperties.Version); + //DA.SetData(1, Utils.CustomPluginProperties.MAJOR_VERSION); + //DA.SetData(2, Utils.CustomPluginProperties.MINOR_VERSION); + //DA.SetData(3, Utils.CustomPluginProperties.PATCH_VERSION); + } + + /// + /// Provides an Icon for the component. + /// + protected override System.Drawing.Bitmap Icon => Properties.Resources.Plugin_Version; + + + /// + /// Gets the unique ID for this component. Do not change this ID after release. + /// + public override Guid ComponentGuid + { + get { return new Guid("205227B0-867E-4375-B0CC-A5EEAD0D26D5"); } + } + } +} \ No newline at end of file diff --git a/ManaComps/CustomGUIComponent.cs b/ManaComps/CustomGUIComponent.cs new file mode 100644 index 0000000..e5fe8ce --- /dev/null +++ b/ManaComps/CustomGUIComponent.cs @@ -0,0 +1,1070 @@ +using System; +using System.Collections.Generic; +using System.Drawing; + +using Grasshopper; +using Grasshopper.Kernel; +using Grasshopper.Kernel.Parameters; +using Grasshopper.GUI.Canvas; +using Rhino.Geometry; +using System.Windows.Forms; +using GH_IO.Serialization; + +namespace CapableArchiTool.ManaComps +{ + public class CustomGUIComponent : GH_Component + { + /// + /// Initializes a new instance of the CustomCanvasComponent class. + /// + public CustomGUIComponent() + : base("Custom GUI", "GUI", + "Change the GHI of canvas", + "Capable Archi Tool", "01 Management") + { + } + + /// + /// Registers all the input parameters for this component. + /// + protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) + { + pManager.AddBooleanParameter("Custom", "C", "Set true to custom canvas.", GH_ParamAccess.item, false); + pManager.AddBooleanParameter("Run", "R", "Set true to make the change come into effect.", GH_ParamAccess.item, false); + pManager.AddIntegerParameter("QuickPattern", "QuickPattern", "Set the canvas appearance to the pattern" + Environment.NewLine + "0 - Default, 1 - DayMode, 2 - NightMode", GH_ParamAccess.item, 0); + } + + /// + /// Registers all the output parameters for this component. + /// + protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) + { + } + + /// + /// This is the method that actually does the work. + /// + /// The DA object is used to retrieve from inputs and store in outputs. + protected override void SolveInstance(IGH_DataAccess DA) + { + bool isCustomed = false; + bool isRun = false; + int quickPattern = 0; + + if (!DA.GetData(0, ref isCustomed)) return; + if (!DA.GetData(1, ref isRun)) return; + + if (isCustomed && isRun) + { + if (part == "Quick Pattern") + { + if (!DA.GetData(2, ref quickPattern)) return; + if (quickPattern == 0) UseDefaultPattern(); + if (quickPattern == 1) UseDayModePattern(); + if (quickPattern == 2) UseNightModePattern(); + } + else if (part == "Normal Component") + { + Color unselectedFillColor = default(Color); + Color unselectedEdgeColor = default(Color); + Color unselectedTextColor = default(Color); + Color selectedFillColor = default(Color); + Color selectedEdgeColor = default(Color); + Color selectedTextColor = default(Color); + DA.GetData(2, ref unselectedFillColor); + DA.GetData(3, ref unselectedEdgeColor); + DA.GetData(4, ref unselectedTextColor); + DA.GetData(5, ref selectedFillColor); + DA.GetData(6, ref selectedEdgeColor); + DA.GetData(7, ref selectedTextColor); + GH_Skin.palette_normal_standard = new GH_PaletteStyle(unselectedFillColor, unselectedEdgeColor, unselectedTextColor); + GH_Skin.palette_normal_selected = new GH_PaletteStyle(selectedFillColor, selectedEdgeColor, selectedTextColor); + } + else if (part == "Hidden Component") + { + Color unselectedFillColor = default(Color); + Color unselectedEdgeColor = default(Color); + Color unselectedTextColor = default(Color); + Color selectedFillColor = default(Color); + Color selectedEdgeColor = default(Color); + Color selectedTextColor = default(Color); + DA.GetData(2, ref unselectedFillColor); + DA.GetData(3, ref unselectedEdgeColor); + DA.GetData(4, ref unselectedTextColor); + DA.GetData(5, ref selectedFillColor); + DA.GetData(6, ref selectedEdgeColor); + DA.GetData(7, ref selectedTextColor); + GH_Skin.palette_hidden_standard = new GH_PaletteStyle(unselectedFillColor, unselectedEdgeColor, unselectedTextColor); + GH_Skin.palette_hidden_selected = new GH_PaletteStyle(selectedFillColor, selectedEdgeColor, selectedTextColor); + } + else if (part == "Disabled Component") + { + Color unselectedFillColor = default(Color); + Color unselectedEdgeColor = default(Color); + Color unselectedTextColor = default(Color); + Color selectedFillColor = default(Color); + Color selectedEdgeColor = default(Color); + Color selectedTextColor = default(Color); + DA.GetData(2, ref unselectedFillColor); + DA.GetData(3, ref unselectedEdgeColor); + DA.GetData(4, ref unselectedTextColor); + DA.GetData(5, ref selectedFillColor); + DA.GetData(6, ref selectedEdgeColor); + DA.GetData(7, ref selectedTextColor); + GH_Skin.palette_locked_standard = new GH_PaletteStyle(unselectedFillColor, unselectedEdgeColor, unselectedTextColor); + GH_Skin.palette_locked_selected = new GH_PaletteStyle(selectedFillColor, selectedEdgeColor, selectedTextColor); + } + else if (part == "Warning Component") + { + Color unselectedFillColor = default(Color); + Color unselectedEdgeColor = default(Color); + Color unselectedTextColor = default(Color); + Color selectedFillColor = default(Color); + Color selectedEdgeColor = default(Color); + Color selectedTextColor = default(Color); + DA.GetData(2, ref unselectedFillColor); + DA.GetData(3, ref unselectedEdgeColor); + DA.GetData(4, ref unselectedTextColor); + DA.GetData(5, ref selectedFillColor); + DA.GetData(6, ref selectedEdgeColor); + DA.GetData(7, ref selectedTextColor); + GH_Skin.palette_warning_standard = new GH_PaletteStyle(unselectedFillColor, unselectedEdgeColor, unselectedTextColor); + GH_Skin.palette_warning_selected = new GH_PaletteStyle(selectedFillColor, selectedEdgeColor, selectedTextColor); + } + else if (part == "Error Component") + { + Color unselectedFillColor = default(Color); + Color unselectedEdgeColor = default(Color); + Color unselectedTextColor = default(Color); + Color selectedFillColor = default(Color); + Color selectedEdgeColor = default(Color); + Color selectedTextColor = default(Color); + DA.GetData(2, ref unselectedFillColor); + DA.GetData(3, ref unselectedEdgeColor); + DA.GetData(4, ref unselectedTextColor); + DA.GetData(5, ref selectedFillColor); + DA.GetData(6, ref selectedEdgeColor); + DA.GetData(7, ref selectedTextColor); + GH_Skin.palette_error_standard = new GH_PaletteStyle(unselectedFillColor, unselectedEdgeColor, unselectedTextColor); + GH_Skin.palette_error_selected = new GH_PaletteStyle(selectedFillColor, selectedEdgeColor, selectedTextColor); + } + else if (part == "Component Label") + { + Color unselectedFillColor = default(Color); + Color unselectedEdgeColor = default(Color); + Color unselectedTextColor = default(Color); + Color selectedFillColor = default(Color); + Color selectedEdgeColor = default(Color); + Color selectedTextColor = default(Color); + DA.GetData(2, ref unselectedFillColor); + DA.GetData(3, ref unselectedEdgeColor); + DA.GetData(4, ref unselectedTextColor); + DA.GetData(5, ref selectedFillColor); + DA.GetData(6, ref selectedEdgeColor); + DA.GetData(7, ref selectedTextColor); + + GH_Skin.palette_black_standard.Fill = unselectedFillColor; + GH_Skin.palette_black_standard.Edge = unselectedEdgeColor; + GH_Skin.palette_black_standard.Text = unselectedTextColor; + GH_Skin.palette_black_selected.Fill = selectedFillColor; + GH_Skin.palette_black_selected.Edge = selectedEdgeColor; + GH_Skin.palette_black_selected.Text = selectedTextColor; + } + else if (part == "Galapagos") + { + Color unselectedFillColor = default(Color); + Color unselectedEdgeColor = default(Color); + Color selectedFillColor = default(Color); + Color selectedEdgeColor = default(Color); + DA.GetData(2, ref unselectedFillColor); + DA.GetData(3, ref unselectedEdgeColor); + DA.GetData(4, ref selectedFillColor); + DA.GetData(5, ref selectedEdgeColor); + + GH_Skin.palette_pink_standard.Fill = unselectedFillColor; + GH_Skin.palette_pink_standard.Edge = unselectedEdgeColor; + GH_Skin.palette_pink_selected.Fill = selectedFillColor; + GH_Skin.palette_pink_selected.Edge = selectedEdgeColor; + } + else if (part == "Wire") + { + Color normalColor = default(Color); + Color emptyeColor = default(Color); + Color selectedStartColor = default(Color); + Color selectedEndColor = default(Color); + DA.GetData(2, ref normalColor); + DA.GetData(3, ref emptyeColor); + DA.GetData(4, ref selectedStartColor); + DA.GetData(5, ref selectedEndColor); + GH_Skin.wire_default = normalColor; + GH_Skin.wire_empty = emptyeColor; + GH_Skin.wire_selected_a = selectedStartColor; + GH_Skin.wire_selected_b = selectedEndColor; + } + else if (part == "Panel") + { + Color panelColor = default(Color); + DA.GetData(2, ref panelColor); + GH_Skin.panel_back = panelColor; + } + else if (part == "Group") + { + Color groupColor = default(Color); + DA.GetData(2, ref groupColor); + GH_Skin.group_back = groupColor; + } + else if (part == "Canvas") + { + bool monochromatic = false; + DA.GetData(2, ref monochromatic); + + if (!monochromatic) + { + Color canvasBack = default(Color); + Color canvasGrid = default(Color); + int canvasGridCol = 0; + int canvasGridRow = 0; + Color canvasEdge = default(Color); + Color canvasShade = default(Color); + int canvasShadeSize = 0; + if (!DA.GetData(3, ref canvasBack)) return; + if (!DA.GetData(4, ref canvasGrid)) return; + if (!DA.GetData(5, ref canvasGridCol)) return; + if (!DA.GetData(6, ref canvasGridRow)) return; + if (!DA.GetData(7, ref canvasEdge)) return; + if (!DA.GetData(8, ref canvasShade)) return; + if (!DA.GetData(9, ref canvasShadeSize)) return; + GH_Skin.canvas_mono = false; + GH_Skin.canvas_back = canvasBack; + GH_Skin.canvas_grid = canvasGrid; + GH_Skin.canvas_grid_col = canvasGridCol; + GH_Skin.canvas_grid_row = canvasGridRow; + GH_Skin.canvas_edge = canvasEdge; + GH_Skin.canvas_shade = canvasShade; + GH_Skin.canvas_shade_size = canvasShadeSize; + } + + else if (monochromatic) + { + Color monochromaticColor = default(Color); + if (!DA.GetData(10, ref monochromaticColor)) return; + + GH_Skin.canvas_mono = true; + GH_Skin.canvas_mono_color = monochromaticColor; + } + + } + else if (part == "Load&Save") + { + bool load = false; + bool save = false; + DA.GetData(2, ref load); + DA.GetData(3, ref save); + + if (load) GH_Skin.LoadSkin(); + if (save) GH_Skin.SaveSkin(); + } + } + } + + + private ToolStripComboBox partComboBox; + + private string part = "Quick Pattern"; + + IEnumerator ParamEnum; + + List paramList = new List(); + + + private void InputParaRegister(string text) + { + if (text == "Quick Pattern") + { + Param_Integer DefaultPattern = new Param_Integer + { + Name = "QuickPattern", + NickName = "QuickPattern", + Description = "Set the canvas appearance to the pattern, 0 - Default, 1 - DayMode, 2 - NightMode", + Access = GH_ParamAccess.item + }; + + DefaultPattern.SetPersistentData(0); + Params.RegisterInputParam(DefaultPattern); + } + + if (text == "Normal Component") + { + Param_Colour UnselectedFillColor = new Param_Colour + { + Name = "Unselected Fill Color", + NickName = "Unselected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour UnselectedEdgeColor = new Param_Colour + { + Name = "Unselected Edge Color", + NickName = "Unselected Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour UnselectedTextColor = new Param_Colour + { + Name = "Unselected Text Color", + NickName = "Unselected Text Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedFillColor = new Param_Colour + { + Name = "Selected Fill Color", + NickName = "Selected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedEdgeColor = new Param_Colour + { + Name = "Selected Edge Color", + NickName = "Selected Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedTextColor = new Param_Colour + { + Name = "Selected Text Color", + NickName = "Selected Text Color", + Access = GH_ParamAccess.item + }; + + UnselectedFillColor.SetPersistentData(GH_Skin.palette_normal_standard.Fill); + UnselectedEdgeColor.SetPersistentData(GH_Skin.palette_normal_standard.Edge); + UnselectedTextColor.SetPersistentData(GH_Skin.palette_normal_standard.Text); + SelectedFillColor.SetPersistentData(GH_Skin.palette_normal_selected.Fill); + SelectedEdgeColor.SetPersistentData(GH_Skin.palette_normal_selected.Edge); + SelectedTextColor.SetPersistentData(GH_Skin.palette_normal_selected.Text); + + Params.RegisterInputParam(UnselectedFillColor); + Params.RegisterInputParam(UnselectedEdgeColor); + Params.RegisterInputParam(UnselectedTextColor); + Params.RegisterInputParam(SelectedFillColor); + Params.RegisterInputParam(SelectedEdgeColor); + Params.RegisterInputParam(SelectedTextColor); + } + + if (text == "Hidden Component") + { + Param_Colour UnselectedFillColor = new Param_Colour + { + Name = "Unselected Fill Color", + NickName = "Unselected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour UnselectedEdgeColor = new Param_Colour + { + Name = "Unselected Edge Color", + NickName = "Unselected Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour UnselectedTextColor = new Param_Colour + { + Name = "Unselected Text Color", + NickName = "Unselected Text Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedFillColor = new Param_Colour + { + Name = "Selected Fill Color", + NickName = "Selected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedEdgeColor = new Param_Colour + { + Name = "Selected Edge Color", + NickName = "Selected Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedTextColor = new Param_Colour + { + Name = "Selected Text Color", + NickName = "Selected Text Color", + Access = GH_ParamAccess.item + }; + + UnselectedFillColor.SetPersistentData(GH_Skin.palette_hidden_standard.Fill); + UnselectedEdgeColor.SetPersistentData(GH_Skin.palette_hidden_standard.Edge); + UnselectedTextColor.SetPersistentData(GH_Skin.palette_hidden_standard.Text); + SelectedFillColor.SetPersistentData(GH_Skin.palette_hidden_selected.Fill); + SelectedEdgeColor.SetPersistentData(GH_Skin.palette_hidden_selected.Edge); + SelectedTextColor.SetPersistentData(GH_Skin.palette_hidden_selected.Text); + + Params.RegisterInputParam(UnselectedFillColor); + Params.RegisterInputParam(UnselectedEdgeColor); + Params.RegisterInputParam(UnselectedTextColor); + Params.RegisterInputParam(SelectedFillColor); + Params.RegisterInputParam(SelectedEdgeColor); + Params.RegisterInputParam(SelectedTextColor); + } + + if (text == "Disabled Component") + { + Param_Colour UnselectedFillColor = new Param_Colour + { + Name = "Unselected Fill Color", + NickName = "Unselected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour UnselectedEdgeColor = new Param_Colour + { + Name = "Unselected Edge Color", + NickName = "Unselected Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour UnselectedTextColor = new Param_Colour + { + Name = "Unselected Text Color", + NickName = "Unselected Text Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedFillColor = new Param_Colour + { + Name = "Selected Fill Color", + NickName = "Selected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedEdgeColor = new Param_Colour + { + Name = "Selected Edge Color", + NickName = "Selected Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedTextColor = new Param_Colour + { + Name = "Selected Text Color", + NickName = "Selected Text Color", + Access = GH_ParamAccess.item + }; + + UnselectedFillColor.SetPersistentData(GH_Skin.palette_locked_standard.Fill); + UnselectedEdgeColor.SetPersistentData(GH_Skin.palette_locked_standard.Edge); + UnselectedTextColor.SetPersistentData(GH_Skin.palette_locked_standard.Text); + SelectedFillColor.SetPersistentData(GH_Skin.palette_locked_selected.Fill); + SelectedEdgeColor.SetPersistentData(GH_Skin.palette_locked_selected.Edge); + SelectedTextColor.SetPersistentData(GH_Skin.palette_locked_selected.Text); + + Params.RegisterInputParam(UnselectedFillColor); + Params.RegisterInputParam(UnselectedEdgeColor); + Params.RegisterInputParam(UnselectedTextColor); + Params.RegisterInputParam(SelectedFillColor); + Params.RegisterInputParam(SelectedEdgeColor); + Params.RegisterInputParam(SelectedTextColor); + } + + if (text == "Warning Component") + { + Param_Colour UnselectedFillColor = new Param_Colour + { + Name = "Unselected Fill Color", + NickName = "Unselected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour UnselectedEdgeColor = new Param_Colour + { + Name = "Unselected Edge Color", + NickName = "Unselected Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour UnselectedTextColor = new Param_Colour + { + Name = "Unselected Text Color", + NickName = "Unselected Text Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedFillColor = new Param_Colour + { + Name = "Selected Fill Color", + NickName = "Selected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedEdgeColor = new Param_Colour + { + Name = "Selected Edge Color", + NickName = "Selected Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedTextColor = new Param_Colour + { + Name = "Selected Text Color", + NickName = "Selected Text Color", + Access = GH_ParamAccess.item + }; + + UnselectedFillColor.SetPersistentData(GH_Skin.palette_warning_standard.Fill); + UnselectedEdgeColor.SetPersistentData(GH_Skin.palette_warning_standard.Edge); + UnselectedTextColor.SetPersistentData(GH_Skin.palette_warning_standard.Text); + SelectedFillColor.SetPersistentData(GH_Skin.palette_warning_selected.Fill); + SelectedEdgeColor.SetPersistentData(GH_Skin.palette_warning_selected.Edge); + SelectedTextColor.SetPersistentData(GH_Skin.palette_warning_selected.Text); + + Params.RegisterInputParam(UnselectedFillColor); + Params.RegisterInputParam(UnselectedEdgeColor); + Params.RegisterInputParam(UnselectedTextColor); + Params.RegisterInputParam(SelectedFillColor); + Params.RegisterInputParam(SelectedEdgeColor); + Params.RegisterInputParam(SelectedTextColor); + } + + if (text == "Error Component") + { + Param_Colour UnselectedFillColor = new Param_Colour + { + Name = "Unselected Fill Color", + NickName = "Unselected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour UnselectedEdgeColor = new Param_Colour + { + Name = "Unselected Edge Color", + NickName = "Unselected Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour UnselectedTextColor = new Param_Colour + { + Name = "Unselected Text Color", + NickName = "Unselected Text Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedFillColor = new Param_Colour + { + Name = "Selected Fill Color", + NickName = "Selected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedEdgeColor = new Param_Colour + { + Name = "Selected Edge Color", + NickName = "Selected Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedTextColor = new Param_Colour + { + Name = "Selected Text Color", + NickName = "Selected Text Color", + Access = GH_ParamAccess.item + }; + + UnselectedFillColor.SetPersistentData(GH_Skin.palette_error_standard.Fill); + UnselectedEdgeColor.SetPersistentData(GH_Skin.palette_error_standard.Edge); + UnselectedTextColor.SetPersistentData(GH_Skin.palette_error_standard.Text); + SelectedFillColor.SetPersistentData(GH_Skin.palette_error_selected.Fill); + SelectedEdgeColor.SetPersistentData(GH_Skin.palette_error_selected.Edge); + SelectedTextColor.SetPersistentData(GH_Skin.palette_error_selected.Text); + + Params.RegisterInputParam(UnselectedFillColor); + Params.RegisterInputParam(UnselectedEdgeColor); + Params.RegisterInputParam(UnselectedTextColor); + Params.RegisterInputParam(SelectedFillColor); + Params.RegisterInputParam(SelectedEdgeColor); + Params.RegisterInputParam(SelectedTextColor); + } + + if (text == "Component Label") + { + Param_Colour UnselectedFillColor = new Param_Colour + { + Name = "Unselected Fill Color", + NickName = "Unselected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour UnselectedEdgeColor = new Param_Colour + { + Name = "Unselected Edge Color", + NickName = "Unselected Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour UnselectedTextColor = new Param_Colour + { + Name = "Unselected Text Color", + NickName = "Unselected Text Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedFillColor = new Param_Colour + { + Name = "Selected Fill Color", + NickName = "Selected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedEdgeColor = new Param_Colour + { + Name = "Selected Edge Color", + NickName = "Selected Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedTextColor = new Param_Colour + { + Name = "Selected Text Color", + NickName = "Selected Text Color", + Access = GH_ParamAccess.item + }; + + UnselectedFillColor.SetPersistentData(GH_Skin.palette_black_standard.Fill); + UnselectedEdgeColor.SetPersistentData(GH_Skin.palette_black_standard.Edge); + UnselectedTextColor.SetPersistentData(GH_Skin.palette_black_standard.Text); + SelectedFillColor.SetPersistentData(GH_Skin.palette_black_selected.Fill); + SelectedEdgeColor.SetPersistentData(GH_Skin.palette_black_selected.Edge); + SelectedTextColor.SetPersistentData(GH_Skin.palette_black_selected.Text); + + Params.RegisterInputParam(UnselectedFillColor); + Params.RegisterInputParam(UnselectedEdgeColor); + Params.RegisterInputParam(UnselectedTextColor); + Params.RegisterInputParam(SelectedFillColor); + Params.RegisterInputParam(SelectedEdgeColor); + Params.RegisterInputParam(SelectedTextColor); + } + + if (text == "Galapagos") + { + Param_Colour UnselectedFillColor = new Param_Colour + { + Name = "Unselected Fill Color", + NickName = "Unselected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour UnselectedEdgeColor = new Param_Colour + { + Name = "Unselected Edge Color", + NickName = "Unselected Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedFillColor = new Param_Colour + { + Name = "Selected Fill Color", + NickName = "Selected Fill Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedEdgeColor = new Param_Colour + { + Name = "Selected Edge Color", + NickName = "Selected Edge Color", + Access = GH_ParamAccess.item + }; + + UnselectedFillColor.SetPersistentData(GH_Skin.palette_pink_standard.Fill); + UnselectedEdgeColor.SetPersistentData(GH_Skin.palette_pink_standard.Edge); + SelectedFillColor.SetPersistentData(GH_Skin.palette_pink_selected.Fill); + SelectedEdgeColor.SetPersistentData(GH_Skin.palette_pink_selected.Edge); + + Params.RegisterInputParam(UnselectedFillColor); + Params.RegisterInputParam(UnselectedEdgeColor); + Params.RegisterInputParam(SelectedFillColor); + Params.RegisterInputParam(SelectedEdgeColor); + } + + if (text == "Wire") + { + Param_Colour NormalColor = new Param_Colour + { + Name = "Normal Color", + NickName = "Normal Color", + Access = GH_ParamAccess.item + }; + Param_Colour EmptyeColor = new Param_Colour + { + Name = "Emptye Color", + NickName = "Emptye Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedStartColor = new Param_Colour + { + Name = "Selected Start Color", + NickName = "Selected Start Color", + Access = GH_ParamAccess.item + }; + Param_Colour SelectedEndColor = new Param_Colour + { + Name = "Selected End Color", + NickName = "Selected End Color", + Access = GH_ParamAccess.item + }; + + NormalColor.SetPersistentData(GH_Skin.wire_default); + EmptyeColor.SetPersistentData(GH_Skin.wire_empty); + SelectedStartColor.SetPersistentData(GH_Skin.wire_selected_a); + SelectedEndColor.SetPersistentData(GH_Skin.wire_selected_b); + + Params.RegisterInputParam(NormalColor); + Params.RegisterInputParam(EmptyeColor); + Params.RegisterInputParam(SelectedStartColor); + Params.RegisterInputParam(SelectedEndColor); + } + + if (text == "Panel") + { + Param_Colour PanelColor = new Param_Colour + { + Name = "Panel Color", + NickName = "Panel Color", + Access = GH_ParamAccess.item + }; + + PanelColor.SetPersistentData(GH_Skin.panel_back); + + Params.RegisterInputParam(PanelColor); + } + + if (text == "Group") + { + Param_Colour GroupColor = new Param_Colour + { + Name = "Group Color", + NickName = "Group Color", + Access = GH_ParamAccess.item + }; + + GroupColor.SetPersistentData(GH_Skin.group_back); + + Params.RegisterInputParam(GroupColor); + } + + if (text == "Canvas") + { + Param_Boolean MonochromaticOnOff = new Param_Boolean + { + Name = "Monochromatic On/Off", + NickName = "Monochromatic On/Off", + Access = GH_ParamAccess.item + }; + Param_Colour BackgroundColor = new Param_Colour + { + Name = "Background Color", + NickName = "Background Color", + Access = GH_ParamAccess.item + }; + Param_Colour GridlineColor = new Param_Colour + { + Name = "Gridline Color", + NickName = "Gridline Color", + Access = GH_ParamAccess.item + }; + Param_Integer GridlineWidth = new Param_Integer + { + Name = "Gridline Width", + NickName = "Gridline Width", + Access = GH_ParamAccess.item + }; + Param_Integer GridlineHeight = new Param_Integer + { + Name = "Gridline Height", + NickName = "Gridline Height", + Access = GH_ParamAccess.item + }; + Param_Colour EdgeColor = new Param_Colour + { + Name = "Edge Color", + NickName = "Edge Color", + Access = GH_ParamAccess.item + }; + Param_Colour ShadowColor = new Param_Colour + { + Name = "Shadow Color", + NickName = "Shadow Color", + Access = GH_ParamAccess.item + }; + Param_Integer ShadowSize = new Param_Integer + { + Name = "Shadow Size", + NickName = "Shadow Size", + Access = GH_ParamAccess.item + }; + Param_Colour MonochromaticColor = new Param_Colour + { + Name = "Monochromatic Color", + NickName = "Monochromatic Color", + Access = GH_ParamAccess.item + }; + + MonochromaticOnOff.SetPersistentData(false); + BackgroundColor.SetPersistentData(GH_Skin.canvas_back); + GridlineColor.SetPersistentData(GH_Skin.canvas_grid); + GridlineWidth.SetPersistentData(GH_Skin.canvas_grid_col); + GridlineHeight.SetPersistentData(GH_Skin.canvas_grid_row); + EdgeColor.SetPersistentData(GH_Skin.canvas_edge); + ShadowColor.SetPersistentData(GH_Skin.canvas_shade); + ShadowSize.SetPersistentData(GH_Skin.canvas_shade_size); + MonochromaticColor.SetPersistentData(GH_Skin.canvas_mono_color); + + Params.RegisterInputParam(MonochromaticOnOff); + Params.RegisterInputParam(BackgroundColor); + Params.RegisterInputParam(GridlineColor); + Params.RegisterInputParam(GridlineWidth); + Params.RegisterInputParam(GridlineHeight); + Params.RegisterInputParam(EdgeColor); + Params.RegisterInputParam(ShadowColor); + Params.RegisterInputParam(ShadowSize); + Params.RegisterInputParam(MonochromaticColor); + } + + if (text == "Load&Save") + { + Param_Boolean LoadXml = new Param_Boolean + { + Name = "Load gui.xml", + NickName = "Load gui.xml", + Access = GH_ParamAccess.item + }; + Param_Boolean SaveXml = new Param_Boolean + { + Name = "Save gui.xml", + NickName = "Save gui.xml", + Access = GH_ParamAccess.item + }; + + LoadXml.SetPersistentData(false); + SaveXml.SetPersistentData(false); + + Params.RegisterInputParam(LoadXml); + Params.RegisterInputParam(SaveXml); + } + + base.Message = text; + ExpireSolution(true); + } + + protected override void AppendAdditionalComponentMenuItems(ToolStripDropDown menu) + { + base.AppendAdditionalComponentMenuItems(menu); + Menu_AppendItem(menu, "Settings:"); + partComboBox = new ToolStripComboBox(); + partComboBox.ComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + partComboBox.ComboBox.BindingContext = new BindingContext(); + partComboBox.ComboBox.Width = 200; + partComboBox.ComboBox.DataSource = GUIfeature; + partComboBox.ComboBox.SelectedIndexChanged += Feature_SelectedIndexChanged; + partComboBox.ComboBox.SelectedIndex = GUIfeature.IndexOf(part); + menu.Items.Add(partComboBox); + } + + private void Feature_SelectedIndexChanged(object sender, EventArgs e) + { + string text = partComboBox.SelectedItem as string; + if (text != part && text != null) + { + part = partComboBox.SelectedItem as string; + ParamEnum = Params.GetEnumerator(); + + while (ParamEnum.MoveNext()) + { + IGH_Param param = ParamEnum.Current; + if (param.Name != "Custom" && param.Name != "Run") + { + paramList.Add(param); + } + } + ParamEnum.Reset(); + + foreach (IGH_Param param in paramList) + { + Params.UnregisterInputParameter(param); + } + paramList.Clear(); + + Instances.RedrawCanvas(); + Params.OnParametersChanged(); + InputParaRegister(text); + ExpireSolution(true); + } + } + + private List GUIfeature = new List { "Quick Pattern", "Normal Component", "Hidden Component", "Disabled Component", + "Warning Component", "Error Component", "Component Label", "Galapagos", "Wire", "Panel", "Group", "Canvas", "Load&Save" }; + + private void UseDefaultPattern() + { + GH_Skin.palette_normal_standard = new GH_PaletteStyle(Color.FromArgb(255, 200, 200, 200), Color.FromArgb(255, 50, 50, 50), Color.FromArgb(255, 0, 0, 0)); + GH_Skin.palette_normal_selected = new GH_PaletteStyle(Color.FromArgb(255, 130, 215, 50), Color.FromArgb(255, 0, 50, 0), Color.FromArgb(255, 0, 25, 0)); + + GH_Skin.palette_hidden_standard = new GH_PaletteStyle(Color.FromArgb(255, 140, 140, 155), Color.FromArgb(255, 35, 35, 35), Color.FromArgb(255, 0, 0, 0)); + GH_Skin.palette_hidden_selected = new GH_PaletteStyle(Color.FromArgb(255, 80, 180, 10), Color.FromArgb(255, 0, 35, 0), Color.FromArgb(255, 0, 25, 0)); + + GH_Skin.palette_locked_standard = new GH_PaletteStyle(Color.FromArgb(255, 120, 120, 120), Color.FromArgb(255, 90, 90, 90), Color.FromArgb(255, 70, 70, 70)); + GH_Skin.palette_locked_selected = new GH_PaletteStyle(Color.FromArgb(255, 110, 150, 115), Color.FromArgb(255, 40, 70, 40), Color.FromArgb(255, 75, 100, 65)); + + GH_Skin.palette_warning_standard = new GH_PaletteStyle(Color.FromArgb(255, 255, 140, 20), Color.FromArgb(255, 80, 10, 0), Color.FromArgb(255, 0, 0, 0)); + GH_Skin.palette_warning_selected = new GH_PaletteStyle(Color.FromArgb(255, 185, 205, 0), Color.FromArgb(255, 0, 50, 0), Color.FromArgb(255, 0, 0, 0)); + + GH_Skin.palette_error_standard = new GH_PaletteStyle(Color.FromArgb(255, 200, 0, 0), Color.FromArgb(255, 60, 0, 0), Color.FromArgb(255, 0, 0, 0)); + GH_Skin.palette_error_selected = new GH_PaletteStyle(Color.FromArgb(255, 125, 155, 0), Color.FromArgb(255, 0, 50, 0), Color.FromArgb(255, 255, 255, 255)); + + GH_Skin.palette_black_standard.Fill = Color.FromArgb(255, 50, 50, 50); + GH_Skin.palette_black_standard.Edge = Color.FromArgb(255, 0, 0, 0); + GH_Skin.palette_black_standard.Text = Color.FromArgb(255, 255, 255, 255); + GH_Skin.palette_black_selected.Fill = Color.FromArgb(255, 25, 60, 25); + GH_Skin.palette_black_selected.Edge = Color.FromArgb(255, 0, 35, 0); + GH_Skin.palette_black_selected.Text = Color.FromArgb(255, 190, 250, 180); + + GH_Skin.palette_pink_standard.Fill = Color.FromArgb(255, 255, 0, 125); + GH_Skin.palette_pink_standard.Edge = Color.FromArgb(255, 100, 0, 50); + GH_Skin.palette_pink_selected.Fill = Color.FromArgb(255, 160, 210, 30); + GH_Skin.palette_pink_selected.Edge = Color.FromArgb(255, 0, 50, 0); + + GH_Skin.wire_default = Color.FromArgb(150, 0, 0, 0); + GH_Skin.wire_empty = Color.FromArgb(180, 255, 60, 0); + GH_Skin.wire_selected_a = Color.FromArgb(255, 125, 210, 40); + GH_Skin.wire_selected_b = Color.FromArgb(50, 0, 0, 0); + + GH_Skin.panel_back = Color.FromArgb(255, 255, 250, 90); + GH_Skin.group_back = Color.FromArgb(150, 170, 135, 225); + + GH_Skin.canvas_back = Color.FromArgb(255, 212, 208, 200); + GH_Skin.canvas_grid = Color.FromArgb(30, 0, 0, 0); + GH_Skin.canvas_grid_col = 150; + GH_Skin.canvas_grid_row = 50; + GH_Skin.canvas_edge = Color.FromArgb(255, 0, 0, 0); + GH_Skin.canvas_shade = Color.FromArgb(80, 0, 0, 0); + GH_Skin.canvas_shade_size = 30; + GH_Skin.canvas_mono = false; + GH_Skin.canvas_mono_color = Color.FromArgb(255, 212, 208, 200); + } + + private void UseDayModePattern() + { + GH_Skin.palette_normal_standard = new GH_PaletteStyle(Color.FromArgb(255, 200, 200, 200), Color.FromArgb(255, 50, 50, 50), Color.FromArgb(255, 0, 0, 0)); + GH_Skin.palette_normal_selected = new GH_PaletteStyle(Color.FromArgb(255, 130, 215, 50), Color.FromArgb(255, 0, 50, 0), Color.FromArgb(255, 0, 25, 0)); + + GH_Skin.palette_hidden_standard = new GH_PaletteStyle(Color.FromArgb(255, 140, 140, 155), Color.FromArgb(255, 35, 35, 35), Color.FromArgb(255, 0, 0, 0)); + GH_Skin.palette_hidden_selected = new GH_PaletteStyle(Color.FromArgb(255, 80, 180, 10), Color.FromArgb(255, 0, 35, 0), Color.FromArgb(255, 0, 25, 0)); + + GH_Skin.palette_locked_standard = new GH_PaletteStyle(Color.FromArgb(255, 120, 120, 120), Color.FromArgb(255, 90, 90, 90), Color.FromArgb(255, 70, 70, 70)); + GH_Skin.palette_locked_selected = new GH_PaletteStyle(Color.FromArgb(255, 110, 150, 115), Color.FromArgb(255, 40, 70, 40), Color.FromArgb(255, 75, 100, 65)); + + GH_Skin.palette_warning_standard = new GH_PaletteStyle(Color.FromArgb(255, 255, 140, 20), Color.FromArgb(255, 80, 10, 0), Color.FromArgb(255, 0, 0, 0)); + GH_Skin.palette_warning_selected = new GH_PaletteStyle(Color.FromArgb(255, 185, 205, 0), Color.FromArgb(255, 0, 50, 0), Color.FromArgb(255, 0, 0, 0)); + + GH_Skin.palette_error_standard = new GH_PaletteStyle(Color.FromArgb(255, 200, 0, 0), Color.FromArgb(255, 60, 0, 0), Color.FromArgb(255, 0, 0, 0)); + GH_Skin.palette_error_selected = new GH_PaletteStyle(Color.FromArgb(255, 125, 155, 0), Color.FromArgb(255, 0, 50, 0), Color.FromArgb(255, 255, 255, 255)); + + GH_Skin.palette_black_standard.Fill = Color.FromArgb(255, 50, 50, 50); + GH_Skin.palette_black_standard.Edge = Color.FromArgb(255, 0, 0, 0); + GH_Skin.palette_black_standard.Text = Color.FromArgb(255, 255, 255, 255); + GH_Skin.palette_black_selected.Fill = Color.FromArgb(255, 25, 60, 25); + GH_Skin.palette_black_selected.Edge = Color.FromArgb(255, 0, 35, 0); + GH_Skin.palette_black_selected.Text = Color.FromArgb(255, 190, 250, 180); + + GH_Skin.palette_pink_standard.Fill = Color.FromArgb(255, 255, 0, 125); + GH_Skin.palette_pink_standard.Edge = Color.FromArgb(255, 100, 0, 50); + GH_Skin.palette_pink_selected.Fill = Color.FromArgb(255, 160, 210, 30); + GH_Skin.palette_pink_selected.Edge = Color.FromArgb(255, 0, 50, 0); + + GH_Skin.wire_default = Color.FromArgb(150, 0, 0, 0); + GH_Skin.wire_empty = Color.FromArgb(180, 255, 60, 0); + GH_Skin.wire_selected_a = Color.FromArgb(255, 125, 210, 40); + GH_Skin.wire_selected_b = Color.FromArgb(50, 0, 0, 0); + + GH_Skin.panel_back = Color.FromArgb(255, 255, 255, 255); + GH_Skin.group_back = Color.FromArgb(150, 255, 255, 255); + + GH_Skin.canvas_back = Color.FromArgb(255, 255, 255, 255); + GH_Skin.canvas_grid = Color.FromArgb(30, 0, 0, 0); + GH_Skin.canvas_grid_col = 150; + GH_Skin.canvas_grid_row = 50; + GH_Skin.canvas_edge = Color.FromArgb(255, 0, 0, 0); + GH_Skin.canvas_shade = Color.FromArgb(80, 0, 0, 0); + GH_Skin.canvas_shade_size = 30; + } + + private void UseNightModePattern() + { + GH_Skin.palette_normal_standard = new GH_PaletteStyle(Color.FromArgb(255, 120, 120, 120), Color.FromArgb(255, 50, 50, 50), Color.FromArgb(255, 0, 0, 0)); + GH_Skin.palette_normal_selected = new GH_PaletteStyle(Color.FromArgb(255, 130, 215, 50), Color.FromArgb(255, 0, 50, 0), Color.FromArgb(255, 0, 25, 0)); + GH_Skin.palette_hidden_standard = new GH_PaletteStyle(Color.FromArgb(255, 60, 60, 60), Color.FromArgb(255, 35, 35, 35), Color.FromArgb(255, 0, 0, 0)); + GH_Skin.palette_hidden_selected = new GH_PaletteStyle(Color.FromArgb(255, 80, 180, 10), Color.FromArgb(255, 0, 35, 0), Color.FromArgb(255, 0, 25, 0)); + GH_Skin.palette_locked_standard = new GH_PaletteStyle(Color.FromArgb(255, 40, 40, 40), Color.FromArgb(255, 90, 90, 90), Color.FromArgb(255, 70, 70, 70)); + GH_Skin.palette_locked_selected = new GH_PaletteStyle(Color.FromArgb(255, 110, 150, 115), Color.FromArgb(255, 40, 70, 40), Color.FromArgb(255, 75, 100, 65)); + GH_Skin.palette_warning_standard = new GH_PaletteStyle(Color.FromArgb(255, 255, 140, 20), Color.FromArgb(255, 80, 10, 0), Color.FromArgb(255, 0, 0, 0)); + GH_Skin.palette_warning_selected = new GH_PaletteStyle(Color.FromArgb(255, 185, 205, 0), Color.FromArgb(255, 0, 50, 0), Color.FromArgb(255, 0, 0, 0)); + GH_Skin.palette_error_standard = new GH_PaletteStyle(Color.FromArgb(255, 200, 0, 0), Color.FromArgb(255, 60, 0, 0), Color.FromArgb(255, 0, 0, 0)); + GH_Skin.palette_error_selected = new GH_PaletteStyle(Color.FromArgb(255, 125, 155, 0), Color.FromArgb(255, 0, 50, 0), Color.FromArgb(255, 255, 255, 255)); + + GH_Skin.palette_black_standard.Fill = Color.FromArgb(255, 50, 50, 50); + GH_Skin.palette_black_standard.Edge = Color.FromArgb(255, 0, 0, 0); + GH_Skin.palette_black_standard.Text = Color.FromArgb(255, 255, 255, 255); + GH_Skin.palette_black_selected.Fill = Color.FromArgb(255, 25, 60, 25); + GH_Skin.palette_black_selected.Edge = Color.FromArgb(255, 0, 35, 0); + GH_Skin.palette_black_selected.Text = Color.FromArgb(255, 190, 250, 180); + GH_Skin.palette_pink_standard.Fill = Color.FromArgb(255, 255, 0, 125); + GH_Skin.palette_pink_standard.Edge = Color.FromArgb(255, 100, 0, 50); + GH_Skin.palette_pink_selected.Fill = Color.FromArgb(255, 160, 210, 30); + GH_Skin.palette_pink_selected.Edge = Color.FromArgb(255, 0, 50, 0); + + GH_Skin.wire_default = Color.FromArgb(150, 100, 240, 220); + GH_Skin.wire_empty = Color.FromArgb(180, 255, 60, 0); + GH_Skin.wire_selected_a = Color.FromArgb(255, 125, 210, 40); + GH_Skin.wire_selected_b = Color.FromArgb(50, 0, 0, 0); + + GH_Skin.panel_back = Color.FromArgb(255, 150, 150, 150); + GH_Skin.group_back = Color.FromArgb(150, 30, 30, 30); + + GH_Skin.canvas_back = Color.FromArgb(255, 50, 50, 50); + GH_Skin.canvas_grid = Color.FromArgb(150, 200, 200, 200); + GH_Skin.canvas_grid_col = 150; + GH_Skin.canvas_grid_row = 50; + GH_Skin.canvas_edge = Color.FromArgb(255, 0, 0, 0); + GH_Skin.canvas_shade = Color.FromArgb(80, 150, 150, 150); + GH_Skin.canvas_shade_size = 30; + } + + + public override bool Write(GH_IWriter writer) + { + writer.SetString("part", part); + return base.Write(writer); + } + + public override bool Read(GH_IReader reader) + { + if (reader.ItemExists("part")) + { + part = reader.GetString("part"); + ParamEnum = Params.GetEnumerator(); + + while (ParamEnum.MoveNext()) + { + IGH_Param param = ParamEnum.Current; + if (param.Name != "Custom" && param.Name != "Run") + { + paramList.Add(param); + } + } + ParamEnum.Reset(); + + foreach (IGH_Param param in paramList) + { + Params.UnregisterInputParameter(param); + } + paramList.Clear(); + + Instances.RedrawCanvas(); + Params.OnParametersChanged(); + InputParaRegister(part); + ExpireSolution(true); + } + return base.Read(reader); + } + + public override void AddedToDocument(GH_Document document) + { + base.AddedToDocument(document); + base.Message = part; + ExpireSolution(true); + } + + /// + /// Provides an Icon for the component. + /// + protected override System.Drawing.Bitmap Icon => Properties.Resources.Custom_GUI; + + + /// + /// Gets the unique ID for this component. Do not change this ID after release. + /// + public override Guid ComponentGuid + { + get { return new Guid("9B3E40D9-0C03-4E57-9D3A-B397C53D9934"); } + } + } +} \ No newline at end of file diff --git a/ManaComps/DeletePlaceholderComponent.cs b/ManaComps/DeletePlaceholderComponent.cs new file mode 100644 index 0000000..f6f2795 --- /dev/null +++ b/ManaComps/DeletePlaceholderComponent.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Grasshopper; + +using Grasshopper.Kernel; +using Rhino.Geometry; + +namespace CapableArchiTool.ManaComps +{ + public class DeletePlaceholderComponent : GH_Component + { + GH_Document GrasshopperDocument; + + /// + /// Initializes a new instance of the DeletePlacehloderComponent class. + /// + public DeletePlaceholderComponent() + : base("Delete Placeholder", "Delete", + "Delete the placeholder components in this grasshopper file.", + "Capable Archi Tool", "01 Management") + { + } + + /// + /// Registers all the input parameters for this component. + /// + protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) + { + pManager.AddBooleanParameter("Delete", "D", "Delete the placeholder components.", GH_ParamAccess.item, false); + } + + /// + /// Registers all the output parameters for this component. + /// + protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) + { + } + + /// + /// This is the method that actually does the work. + /// + /// The DA object is used to retrieve from inputs and store in outputs. + protected override void SolveInstance(IGH_DataAccess DA) + { + bool delete = false; + + if (!DA.GetData(0, ref delete)) return; + + GrasshopperDocument = Instances.ActiveCanvas.Document; + + if (GrasshopperDocument == null) return; + + if(delete) + { + IList comps = GrasshopperDocument.Objects; + IList delcomps = comps.Where(o => o.GetType().ToString() == "Grasshopper.Kernel.Components.GH_PlaceholderComponent").ToList(); + if (delcomps == null || delcomps.Count == 0) return; + GrasshopperDocument.ScheduleSolution(0, d => GrasshopperDocument.RemoveObjects(delcomps, false)); + } + } + + /// + /// Provides an Icon for the component. + /// + protected override System.Drawing.Bitmap Icon => Properties.Resources.Delete_Placeholder; + + + /// + /// Gets the unique ID for this component. Do not change this ID after release. + /// + public override Guid ComponentGuid + { + get { return new Guid("3265D645-96B0-49BB-A233-534720FBB1A2"); } + } + } +} \ No newline at end of file diff --git a/ManaComps/DetectRuntimeComponent.cs b/ManaComps/DetectRuntimeComponent.cs new file mode 100644 index 0000000..63f9f96 --- /dev/null +++ b/ManaComps/DetectRuntimeComponent.cs @@ -0,0 +1,267 @@ +using System; +using System.Collections.Generic; + +using Grasshopper; +using Grasshopper.Kernel; + +using System.Drawing; +using System.Windows.Forms; + +using Grasshopper.Kernel.Special; +using System.Linq.Expressions; + +namespace CapableArchiTool.ManaComps +{ + public class DetectRuntimeComponent : GH_Component + { + GH_Document GrasshopperDocument; + + /// + /// Initializes a new instance of the RuntimeDetectionComponent class. + /// + public DetectRuntimeComponent() + : base("Detect Runtime", "Runtime", + "Dectect the component whose runtime is over the threshold and group it.", + "Capable Archi Tool", "01 Management") + { + } + + /// + /// Registers all the input parameters for this component. + /// + protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) + { + pManager.AddBooleanParameter("Group", "G", "Group the component whose runtime is over threshold.", GH_ParamAccess.item); + pManager.AddBooleanParameter("UnGroup", "UG", "UnGroup the component whose is grouped.", GH_ParamAccess.item); + pManager.AddIntegerParameter("Threshold", "T", "The threshold of runtime(milliseconds).", GH_ParamAccess.item); + pManager.AddColourParameter("Color", "C", "The color of group.", GH_ParamAccess.item); + pManager.AddTextParameter("Label", "L", "The label of group.", GH_ParamAccess.item); + } + + /// + /// Registers all the output parameters for this component. + /// + protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) + { + } + + /// + /// This is the method that actually does the work. + /// + /// The DA object is used to retrieve from inputs and store in outputs. + protected override void SolveInstance(IGH_DataAccess DA) + { + Boolean g = false; + Boolean ug = false; + int threshold = 0; + Color color = new Color(); + String label = null; + + if (!DA.GetData(0, ref g)) return; + if (!DA.GetData(1, ref ug)) return; + if (!DA.GetData(2, ref threshold)) return; + if (!DA.GetData(3, ref color)) return; + if (!DA.GetData(4, ref label)) return; + + //It is possible for the OnPingDocument() to return null. + //GrasshopperDocument = this.OnPingDocument(); + GrasshopperDocument = Instances.ActiveCanvas.Document; + + // Group + if (g) + { + // Ungroup previously made groups + UngroupghGroups(ghGroups); + UngroupghGroup(ghGroup); + + // Get slow active objects + List guids = GetSlowActiveObjectsGuid + (GrasshopperDocument.ActiveObjects(), threshold); + + // Group slow active objects + if(Together) + { + ghGroup = GroupActiveObjectsTogether(guids, color, label); + } + else + { + ghGroups = GroupActiveObjects(guids, color, label); + } + + } + + // Ungroup + if (ug) + { + // Ungroup previously made groups + if (Together) + { + UngroupghGroup(ghGroup); + } + else + { + UngroupghGroups(ghGroups); + } + + } + + } + + private bool istogether = false; + public bool Together + { + get { return istogether; } + set + { + istogether = value; + if (istogether) + { + Message = "Multiple"; + } + else + { + Message = "Single"; + } + } + } + + + protected override void AppendAdditionalComponentMenuItems(ToolStripDropDown menu) + { + // Append the item to the menu, making sure it's always enabled and checked if Absolute is True. + ToolStripMenuItem item = Menu_AppendItem(menu, "Multiple", Menu_TogetherClicked, true, Together); + // Specifically assign a tooltip text to the menu item. + item.ToolTipText = "The long-runtime components will be grouped together when checked."; + } + + private void Menu_TogetherClicked(object sender, EventArgs e) + { + RecordUndoEvent("Multiple"); + Together = !Together; + ExpireSolution(true); + } + + public override void AddedToDocument(GH_Document document) + { + base.AddedToDocument(document); + base.Message = (istogether) ? "Multiple" : "Single" ; + ExpireSolution(true); + } + public override bool Write(GH_IO.Serialization.GH_IWriter writer) + { + // First add our own field. + writer.SetBoolean("Multiple", Together); + // Then call the base class implementation. + return base.Write(writer); + } + public override bool Read(GH_IO.Serialization.GH_IReader reader) + { + if (reader.ItemExists("Multiple")) + { + // First read our own field. + Together = reader.GetBoolean("Multiple"); + } + // Then call the base class implementation. + return base.Read(reader); + } + + // Persistent variables + GH_Group ghGroup = new GH_Group(); + List ghGroups = new List(); + + // Get all objects that run slower than a given threshold in milliseconds + List GetSlowActiveObjectsGuid(List activeObjects, int threshold) + { + List guids = new List(); + + foreach (IGH_ActiveObject activeObject in activeObjects) + { + if (activeObject.ProcessorTime.TotalMilliseconds > threshold) + { + guids.Add(activeObject.InstanceGuid); + } + } + + return guids; + } + + + // Individually group each active object with a given colour and label + List GroupActiveObjects(List guids, Color colour, string text) + { + List ghGroups = new List(); + + foreach (Guid guid in guids) + { + GH_Group ghGroup = new GH_Group + { + Colour = colour, + NickName = text + }; + GrasshopperDocument.AddObject(ghGroup, false, GrasshopperDocument.ObjectCount); + ghGroup.AddObject(guid); + ghGroup.ExpireCaches(); + ghGroups.Add(ghGroup); + } + return ghGroups; + } + + // Group every active object in a group with a given colour and label + GH_Group GroupActiveObjectsTogether(List guids, Color colour, string text) + { + GH_Group ghGroup = new GH_Group + { + Colour = colour, + NickName = text + }; + ghGroup.ExpireCaches(); + + GrasshopperDocument.AddObject(ghGroup, false, GrasshopperDocument.ObjectCount); + foreach (Guid guid in guids) + { + ghGroup.AddObject(guid); + ghGroup.ExpireCaches(); + } + return ghGroup; + } + + // Ungroup all groups previously made + void UngroupghGroups(List ghGroups) + { + GrasshopperDocument.ScheduleSolution(0, callback => + { + for (int i = 0; i < ghGroups.Count; i++) + { + GrasshopperDocument.RemoveObject(ghGroups[i], false); + if (i >= ghGroups.Count) + { + ghGroups.Clear(); + } + } + }); + } + // Ungroup the group previously made + void UngroupghGroup(GH_Group ghGroup) + { + GrasshopperDocument.ScheduleSolution(0, callback => + { + GrasshopperDocument.RemoveObject(ghGroup, false); + ghGroup = null; + }); + } + + /// + /// Provides an Icon for the component. + /// + protected override System.Drawing.Bitmap Icon => Properties.Resources.Detect_Runtime; + + + /// + /// Gets the unique ID for this component. Do not change this ID after release. + /// + public override Guid ComponentGuid + { + get { return new Guid("22B03768-5DBF-4EB5-AD92-278B84936D34"); } + } + } +} \ No newline at end of file diff --git a/ManaComps/EasyDisconnectComponent.cs b/ManaComps/EasyDisconnectComponent.cs new file mode 100644 index 0000000..2db5f4a --- /dev/null +++ b/ManaComps/EasyDisconnectComponent.cs @@ -0,0 +1,270 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using System.Diagnostics; + +using Grasshopper; +using Grasshopper.Kernel; +using Grasshopper.GUI; +using Grasshopper.GUI.Canvas; +using Grasshopper.Kernel.Attributes; +using Grasshopper.GUI.Canvas.Interaction; + +namespace CapableArchiTool.ManaComps +{ + public class EasyDisconnectComponent : GH_Component + { + + /// + /// Initializes a new instance of the EasyWirecutComponent class. + /// + public EasyDisconnectComponent() + : base("Easy Disconnect", "Disconnect", + "Cut the wire with one click.", + "Capable Archi Tool", "01 Management") + { + } + + // Double click to switch the component. + public class EasyDisconnectAttributes : GH_ComponentAttributes + { + public EasyDisconnectAttributes(EasyDisconnectComponent owner) + : base(owner) + { + } + public override GH_ObjectResponse RespondToMouseDoubleClick(GH_Canvas sender, GH_CanvasMouseEvent e) + { + if (base.Owner is EasyDisconnectComponent easyWirecutComponent) + { + easyWirecutComponent.CompActive(); + return GH_ObjectResponse.Handled; + } + return base.RespondToMouseDoubleClick(sender, e); + } + } + + /// + /// Registers all the input parameters for this component. + /// + protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) + { + } + + /// + /// Registers all the output parameters for this component. + /// + protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) + { + pManager.AddTextParameter("Message", "M", "Running message", GH_ParamAccess.item); + } + + /// + /// This is the method that actually does the work. + /// + /// The DA object is used to retrieve from inputs and store in outputs. + protected override void SolveInstance(IGH_DataAccess DA) + { + canvas = Instances.ActiveCanvas; + + Instances.ActiveCanvas.MouseDown -= MouseDown; + Instances.ActiveCanvas.MouseDown += MouseDown; + Instances.ActiveCanvas.MouseUp -= MouseUp; + Instances.ActiveCanvas.MouseUp += MouseUp; + + DA.SetData(0, Text()); + } + + GH_Canvas canvas; + + public PointF mousePosition; + + public bool isActive = true; + + public bool isCapableDelete = false; + + public bool isLargerThanDelay = false; + + private int delaySpanll = 200; + private int delaySpanul = 600; + + private int mouseHold = 0; + + private bool isWireInteraction = false; + + public DateTime beforeDT; + public DateTime afterDT; + + private void MouseDown(object sender, MouseEventArgs e) + { + if (e.Button != MouseButtons.Left) return; + if (canvas.ActiveInteraction != null && + (canvas.ActiveInteraction is Grasshopper.GUI.Canvas.Interaction.GH_WireInteraction || + canvas.ActiveInteraction is Grasshopper.GUI.Canvas.Interaction.GH_RewireInteraction)) + { + isWireInteraction = true; + return; + } + + beforeDT = System.DateTime.Now; + + if (isActive && e.Button == MouseButtons.Left) + { + IGH_Param source = null; + IGH_Param target = null; + mousePosition = Instances.ActiveCanvas.CursorCanvasPosition; + bool isNearWire = Instances.ActiveCanvas.Document.FindWireAt(mousePosition, 8f, ref source, ref target); + + if (isNearWire) isCapableDelete = true; + } + } + + private void MouseUp(object sender, MouseEventArgs e) + { + if (e.Button != MouseButtons.Left) return; + if (isWireInteraction) + { + isWireInteraction = false; + return; + } + + afterDT = System.DateTime.Now; + + TimeSpan ts = afterDT.Subtract(beforeDT); + mouseHold = (int)ts.TotalMilliseconds; + + if (isActive && isCapableDelete) + { + IGH_Param source = null; + IGH_Param target = null; + mousePosition = Instances.ActiveCanvas.CursorCanvasPosition; + bool isNearWire = Instances.ActiveCanvas.Document.FindWireAt(mousePosition, 8f, ref source, ref target); + + if (mouseHold > delaySpanll && mouseHold < delaySpanul && isNearWire) + { + target.RecordUndoEvent("Removed"); + target.RemoveSource(source); + target.Attributes.GetTopLevel.DocObject.ExpireSolution(true); + ExpireSolution(true); + isCapableDelete = false; + } + } + ExpireSolution(true); + } + + + public void CompActive() + { + isActive = !isActive; + UpdateMessage(); + ExpireSolution(true); + } + + public override void CreateAttributes() + { + m_attributes = new EasyDisconnectAttributes(this); + } + + public void UpdateMessage() + { + base.Message = (isActive ? "Active" : "Inactive"); + } + + public string Text() + { + if (isActive) + { + return $"The mousedown span is between {delaySpanll} and {delaySpanul} milliseconds.\n" + + $"The recent valid left mousedown event lasts {mouseHold} milliseconds."; + } + return "Component is inactive."; + } + + public override void AddedToDocument(GH_Document document) + { + base.AddedToDocument(document); + UpdateMessage(); + ExpireSolution(true); + } + + public override void RemovedFromDocument(GH_Document document) + { + isActive = false; + base.RemovedFromDocument(document); + ExpireSolution(true); + } + + protected override void AppendAdditionalComponentMenuItems(ToolStripDropDown menu) + { + base.AppendAdditionalComponentMenuItems(menu); + Menu_AppendItem(menu, "Span"); + Menu_AppendTextItem(menu, "", KeyDown, null, true); + } + + private void KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Enter) + { + TextChanged(sender, ((Grasshopper.GUI.GH_MenuTextBox)sender).Text); + } + ExpireSolution(true); + } + + private void TextChanged(object sender, string text) + { + string[] span = text.Split(',', ',', ' '); + bool isParseLower = int.TryParse(span[0], out int lowerLimit); + bool isParseUpper = int.TryParse(span[1], out int upperLimit); + + if (isParseLower && isParseUpper && lowerLimit > 0 && upperLimit > 0 && upperLimit > lowerLimit) + { + delaySpanll = lowerLimit; + delaySpanul = upperLimit; + } + ExpireSolution(true); + } + + + public override bool Write(GH_IO.Serialization.GH_IWriter writer) + { + // add field. + writer.SetInt32("Delayll", delaySpanll); + writer.SetInt32("Delayul", delaySpanul); + writer.SetBoolean("isActive", isActive); + // call the base class implementation. + return base.Write(writer); + } + + public override bool Read(GH_IO.Serialization.GH_IReader reader) + { + // read field. + if (reader.ItemExists("Delayll")) + { + delaySpanll = reader.GetInt32("Delayll"); + } + if (reader.ItemExists("Delayul")) + { + delaySpanul = reader.GetInt32("Delayul"); + } + if (reader.ItemExists("isActive")) + { + isActive = reader.GetBoolean("isActive"); + } + // call the base class implementation. + return base.Read(reader); + } + + /// + /// Provides an Icon for the component. + /// + protected override System.Drawing.Bitmap Icon => Properties.Resources.Easy_WireCut; + + + /// + /// Gets the unique ID for this component. Do not change this ID after release. + /// + public override Guid ComponentGuid + { + get { return new Guid("586309E3-CAE9-425C-8B40-C88F4466ACF3"); } + } + } +} \ No newline at end of file diff --git a/ManaComps/GroupEnableComponent.cs b/ManaComps/GroupEnableComponent.cs new file mode 100644 index 0000000..65a6ffb --- /dev/null +++ b/ManaComps/GroupEnableComponent.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; + +using Grasshopper; +using Grasshopper.Kernel; + +using Grasshopper.Kernel.Special; + +namespace CapableArchiTool.ManaComps +{ + public class GroupEnableComponent : GH_Component + { + GH_Component GrasshopperComponent; + GH_Document GrasshopperDocument; + + /// + /// Initializes a new instance of the MassEnableComponent class. + /// + public GroupEnableComponent() + : base("Group Enable", "Enable", + "Control whether to enable all the components in the group that the MassEnableComponent is in, " + + "except the MassEnableComponent itself.", + "Capable Archi Tool", "01 Management") + { + } + + /// + /// Registers all the input parameters for this component. + /// + protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) + { + pManager.AddBooleanParameter("Enable", "E", "Enable all the components in this group except MassEnableComponent.", GH_ParamAccess.item); + pManager.AddBooleanParameter("Run", "R", "Run this component.", GH_ParamAccess.item); + } + + /// + /// Registers all the output parameters for this component. + /// + protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) + { + } + + /// + /// This is the method that actually does the work. + /// + /// The DA object is used to retrieve from inputs and store in outputs. + protected override void SolveInstance(IGH_DataAccess DA) + { + bool enable = false; + bool run = false; + + if (!DA.GetData(0, ref enable)) return; + if (!DA.GetData(1, ref run)) return; + if (!run) return; + + GrasshopperComponent = this; + GrasshopperDocument = Instances.ActiveCanvas.Document; + + Guid groupGuid = GroupGuid(GroupsGuid(), out bool succeed); + if (!succeed) return; + EnableGroupComponents(groupGuid, enable); + } + + //Return all the group guids. + public List GroupsGuid() + { + List groupguids = new List(); + foreach (var obj in GrasshopperDocument.Objects) + { + if (obj.GetType().ToString() == "Grasshopper.Kernel.Special.GH_Group") + { + groupguids.Add(obj.InstanceGuid); + } + } + return groupguids; + } + + //Find the group where this component is in and return its guid. + public Guid GroupGuid(List guids, out bool succeed) + { + foreach (var guid in guids) + { + IGH_DocumentObject obj = GrasshopperDocument.FindObject(guid, false); + GH_Group group = obj as GH_Group; + List comps = group.ObjectsRecursive(); + foreach (IGH_DocumentObject comp in comps) + { + if (comp.InstanceGuid == GrasshopperComponent.InstanceGuid) + { + succeed = true; + return guid; + } + } + } + succeed = false; + return Guid.Empty; + } + + //Change the enable property. + public void EnableGroupComponents(Guid guid, bool enable) + { + GrasshopperDocument.ScheduleSolution(0, callback => + { + IGH_DocumentObject obj = GrasshopperDocument.FindObject(guid, false); + GH_Group group = obj as GH_Group; + foreach (IGH_DocumentObject groupobj in group.ObjectsRecursive()) + { + if (groupobj is IGH_ActiveObject) + { + if (groupobj.InstanceGuid != GrasshopperComponent.InstanceGuid + && groupobj.ComponentGuid.ToString() != "2e78987b-9dfb-42a2-8b76-3923ac8bd91a" + && groupobj.ComponentGuid.ToString() != "a8b97322-2d53-47cd-905e-b932c3ccd74e") + { + IGH_ActiveObject comp = groupobj as IGH_ActiveObject; + comp.Locked = !enable; + comp.ExpireSolution(true); + } + } + } + } + ); + + } + + /// + /// Provides an Icon for the component. + /// + protected override System.Drawing.Bitmap Icon => Properties.Resources.Group_Enable; + + + /// + /// Gets the unique ID for this component. Do not change this ID after release. + /// + public override Guid ComponentGuid + { + get { return new Guid("5DEDB994-D2F7-4B3B-A10A-25B987ABBE51"); } + } + } +} \ No newline at end of file diff --git a/ManaComps/GroupPreviewComponent.cs b/ManaComps/GroupPreviewComponent.cs new file mode 100644 index 0000000..03a250a --- /dev/null +++ b/ManaComps/GroupPreviewComponent.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; + +using Grasshopper; +using Grasshopper.Kernel; + +using Grasshopper.Kernel.Special; + +namespace CapableArchiTool.ManaComps +{ + public class GroupPreviewComponent : GH_Component + { + GH_Component GrasshopperComponent; + GH_Document GrasshopperDocument; + + /// + /// Initializes a new instance of the MassPreviewComponent class. + /// + public GroupPreviewComponent() + : base("Group Preview", "Preview", + "Control whether to preview all the components in the group that the MassPreviewComponent is in, " + + "except the MassPreviewComponent itself.", + "Capable Archi Tool", "01 Management") + { + } + + /// + /// Registers all the input parameters for this component. + /// + protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) + { + pManager.AddBooleanParameter("Preview", "P", "Preview all the components in this group except MassPreviewComponent.", GH_ParamAccess.item); + pManager.AddBooleanParameter("Run", "R", "Run this component.", GH_ParamAccess.item); + } + + /// + /// Registers all the output parameters for this component. + /// + protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) + { + } + + /// + /// This is the method that actually does the work. + /// + /// The DA object is used to retrieve from inputs and store in outputs. + protected override void SolveInstance(IGH_DataAccess DA) + { + bool preview = false; + bool run = false; + + if (!DA.GetData(0, ref preview)) return; + if (!DA.GetData(1, ref run)) return; + if (!run) return; + + GrasshopperComponent = this; + GrasshopperDocument = Instances.ActiveCanvas.Document; + + Guid groupGuid = GroupGuid(GroupsGuid(), out bool succeed); + if (!succeed) return; + PreviewGroupComponents(groupGuid, preview); + } + + //Return all the group guids. + public List GroupsGuid() + { + List groupguids = new List(); + foreach (var obj in GrasshopperDocument.Objects) + { + if (obj.GetType().ToString() == "Grasshopper.Kernel.Special.GH_Group") + { + groupguids.Add(obj.InstanceGuid); + } + } + return groupguids; + } + + //Find the group where this component is in and return its guid. + public Guid GroupGuid(List guids, out bool succeed) + { + foreach (var guid in guids) + { + IGH_DocumentObject obj = GrasshopperDocument.FindObject(guid, false); + GH_Group group = obj as GH_Group; + List comps = group.ObjectsRecursive(); + foreach (IGH_DocumentObject comp in comps) + { + if (comp.InstanceGuid == GrasshopperComponent.InstanceGuid) + { + succeed = true; + return guid; + } + } + } + succeed = false; + return Guid.Empty; + } + + //Change the preview property. + public void PreviewGroupComponents(Guid guid, bool preview) + { + IGH_DocumentObject obj = GrasshopperDocument.FindObject(guid, false); + GH_Group group = obj as GH_Group; + foreach (IGH_DocumentObject groupobj in group.ObjectsRecursive()) + { + if(groupobj is IGH_PreviewObject) + { + if(groupobj.InstanceGuid != GrasshopperComponent.InstanceGuid) + { + IGH_PreviewObject precomp = groupobj as IGH_PreviewObject; + precomp.Hidden = !preview; + } + } + } + } + + + /// + /// Provides an Icon for the component. + /// + protected override System.Drawing.Bitmap Icon => Properties.Resources.Group_Preview; + + + /// + /// Gets the unique ID for this component. Do not change this ID after release. + /// + public override Guid ComponentGuid + { + get { return new Guid("2CB4543B-C142-4CF5-9A85-DED6CBFF3A81"); } + } + } +} \ No newline at end of file diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs new file mode 100644 index 0000000..49de80d --- /dev/null +++ b/Properties/Resources.Designer.cs @@ -0,0 +1,183 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace CapableArchiTool.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CapableArchiTool.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Custom_GUI { + get { + object obj = ResourceManager.GetObject("Custom GUI", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Delete_Placeholder { + get { + object obj = ResourceManager.GetObject("Delete Placeholder", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Detect_Runtime { + get { + object obj = ResourceManager.GetObject("Detect Runtime", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Easy_WireCut { + get { + object obj = ResourceManager.GetObject("Easy WireCut", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Edge_Bundling { + get { + object obj = ResourceManager.GetObject("Edge Bundling", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Group_Enable { + get { + object obj = ResourceManager.GetObject("Group Enable", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Group_Preview { + get { + object obj = ResourceManager.GetObject("Group Preview", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Isovist_Region { + get { + object obj = ResourceManager.GetObject("Isovist Region", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Plugin_Icon { + get { + object obj = ResourceManager.GetObject("Plugin Icon", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Plugin_Version { + get { + object obj = ResourceManager.GetObject("Plugin Version", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap POI_Heat_Map { + get { + object obj = ResourceManager.GetObject("POI Heat Map", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Water_Runoff { + get { + object obj = ResourceManager.GetObject("Water Runoff", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Properties/Resources.resx b/Properties/Resources.resx new file mode 100644 index 0000000..cb3d024 --- /dev/null +++ b/Properties/Resources.resx @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\Custom GUI.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Delete Placeholder.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Detect Runtime.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Easy WireCut.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Edge Bundling.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Mass Enable.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Mass Preview.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Isovist Region.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Plugin Icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Plugin Version.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\POI Heat Map.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\Resources\Water Runoff.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/Resources/Custom GUI.png b/Resources/Custom GUI.png new file mode 100644 index 0000000000000000000000000000000000000000..33ca5870e9fbefade1145a865165f40c220d3495 GIT binary patch literal 1385 zcmYLJeN0nV6faahlm}IZX^S7Q&RGpI9=s*8Ir|1-3ezb%hin>Jih|4h0MUT6^cA|4 z5UPkytt0xxEp8fzXhrLWwzNQPVN^pVMxt#+#8Ra#h;4bV@2=HR{y68{+)SFKjb0a!kOSRJf<_CQpPiY$ zIjdH9Zka$J@PDEKa6T^ozyvy9RsccJyBlGXEV?+K+)J1`1nnA)(8`96(P$?`64G#}wy(fmi1LTAdy@S08AEJgxdukX_KU?D&%d<3=b`K0RTUXP~~W1 z;sduI~=7r7E3AEB?oJF%p zYUIi7WOpwZdT!m3Q+~u!BrGs%Ek_fj1??tGln@{A;kI&hY5>45Bt@uaO#9GYw~UPN z0fv}yg7nbt35i^Ax?;?M^FL(XO!8`bJoW88Ns{BI`1hoS zTPoIKpKV21PYn*(Jkm2fVdc{MYj6nT`MljO8$-8J#h&)HJ0$X@y^-?S^@o{nnnACj z%V=42w&x#X*OQKy|60av{h%VpDVpp&=N%isWaTKE#RGz81UVkhxs^KAGGW&bA#^_@ zV=g9{DJptLapAn&oQ;LYwrnoAEgsE#rf1gYsR5$Xd{uHcukRwT#NKaSQ9B!}@?sy1Q++sguixCku zfm{3Pf#|$?s8tikVgPIm#U*{YqcFBD2?X5l$1b9BF fD7gEkk969{MK>=mS^M~#0F>-6)@L?n2&(@Bh^eh7 literal 0 HcmV?d00001 diff --git a/Resources/Delete Placeholder.png b/Resources/Delete Placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..fad19083a2aa9d0353ce3a0bdd0ff43cf9210443 GIT binary patch literal 1195 zcmZvcdrVVT9LF!-?Fw>vgfX~~S%}^0l&QA^5)5Mv4+S=0#Nh_f+S`IW9AJwZ5<&3N zS*bJwB$M!vR|x1J2qWV$!&+|^vx>@!`{Y%EZr>M1OXAzhN$y8RA)}_nOmg~H5*{*&GMbXzNep6jg3h zUSZ&Jr{d4n)ivl}I(Ch?ihZ$eq=Uige)vGQ@}h8|ir2Ny!+Rn#;=)_`F=;~mZWvZ( z{a0UyUSjo`#)XwuQ{90bSB}|~%LOSO5&UR^kVO;xpjbkiL{;AC?^7sDg`;&rIVb10 zf2alV7dT#O1?7A+Vc+o0f~zQ%F>z`#^O8%ikQjGtcY1?ZVly`J**>G**uOe!b1o)3 zAu@(3WxKnB^m}(k9BVWj7~ao>l^2_QcVhg)YJWljsAuDBH&IJ-Yunsau^4*nI%nS{ z+C;?3IZWkRzL!MD{jqdLmhLMN-_Vr+6m^oJC|y&`q(Om)|{r#K|u_s;p? z6CQ@8OiOlDMHPm$q-oRMUdi0hpB(6m)YRs+EH6KOu{24yQyi)m`6Q%0^C%j5&f?Ak zfMv4T@)(^)Gm(WLLs|K%bD~({_Sv02r;^Ofnu^J)bq?%5%0VQ7atuqPS|R5XWD*PZACEu~MiaE-^5*w|p_A{~mq|mL Q4w{M-d@L-W(T~Xf7oAfgK>z>% literal 0 HcmV?d00001 diff --git a/Resources/Detect Runtime.png b/Resources/Detect Runtime.png new file mode 100644 index 0000000000000000000000000000000000000000..087c98fd1f11aa9a3d2d50cbb6ae1cbbce6b14c0 GIT binary patch literal 1260 zcmYLIZ7^JC6u#`bK6)iuYuqbM7K0+fWvi(s!mbsBVN)a|ne4SJK|5JVq={rKAy*O~ z-F6aIlCeHIA`@jzGd@au+%3W;D4h{S*i@@+f<=<0uDxAVn;++Wf4t{B?{l7Wp6k5u zAagStGXMb0LxQ=V>uz`>OhDZ^{gv;E?lKhx$DRcMTK+~Dq${o00DxW=!evJVUl)|S zU>K%L0w_wrZN$dssLNrsP$Y~X4v!zMjPpU<)#GAMDz=M8qitrfi-m$jHI{%~6Rt$G zcSsTVxfhB$_|e7Gx=htOML~J)6N#s8|8P4lBNVB&)Bi#w zcNJdx`Y=Qpdr7miRT^C;Ka+)$t7|fq#t#JJzl_G$BKX+e-0Wh!@bV{YQz$j|Sq8tmj#zc3H+|bF%E7{48M~i?XN% zKhg`%i4lp2w=VhG_bBpBuj9S;9d7h9lcO>*Lj3p%>g?+5CAGPO%H<87mq~S5MauJV z9P&#AeXU|A{$Qc#CItb<8jBakNhf%QP37W|WN@c>G?;D`2s#>F1dR|EFxDp;6esP* zLsGY)m&rxr+PA|`Tcy={074GXpN++Iy{_+opjMCl2@)%7jQ0%#v%psSM86Z}xNNF} z1>fI|)&!ffPPAw~tUdqt6)UK<=&qnSQ)9r)31~2JKJJNbF(OKD_)jm_Q#z5UB#G5b zqJ;{>qzxCm6}PG`!C}4}xQs81$CBa_E-e4GFXsEgI(x-@)jcG4bu|jsQr<#d-(;^S zX(?i}K_ay)PXD8h!D7s02G@H43-brVbQ?A$9a#e==4;h!$TaPFsCmRe56 zNgFfvDk7Y=foYzH<-ZO;jFG5nKwV#(5S*1x_lWd?{yiYUA)%K|3pve89<-cn`~!vJ zC=*$#J}s0VDM`TM1PRUB6>r6Zg)k^Yl?nOzkL|G5&zvx^cXB$2Pl;_^XgB@+OZ&%$ zCG4Ppt16;!4dRQ}0Nf!~k{q8w7DU(+k@(;#u`I)fk`z+;<+SYJ~i8te<)^>66-Qw!rY;E0~J4NgB z0dmJbVa7bFm}<-D>+DtLPg>~rnQcE1H>|O?q5p-s9f4{;g)p0hd8E{Qxsg6b;#sK7&$0{2NJhvagw96IvdBSK%^9L=<{4#VB#JJ fQVKNFhWcU};Cn!9KiblTY)Bsx7|yNZU|0SH;@2P0 literal 0 HcmV?d00001 diff --git a/Resources/Easy WireCut.png b/Resources/Easy WireCut.png new file mode 100644 index 0000000000000000000000000000000000000000..2f006b5d54cf7a55b50449c3444641267f486f13 GIT binary patch literal 1141 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9G0-5|_ZdRqK90|Se? zr;B5VM`zLk&4h#mpdyC<|D6sxIi5XvY2#nNkj+yX8yUfZNlwpNRMSuX`}w_Ix!GBa zKh!53u6|=fe}BJYVCdZ5sjZ9q9j&MICS8`40ND>RZ6gDV#m$>H&X|f!vRL|bx}n9B z3`4HI&$n3IeT(%=gdyerib>$YRt|1^qQLwsXyMaaM@lD>^em}lHe}C})>C5T@CUaqK zcj8R6lf$hVwFsAVq~tgRIHn~n=$`tm-~Rvpn%c^8!HsRk1_lNY zw<_g0I_z(3+L16r!(99G`u+dQ4F3F5_1uE+jZ#MA5{~@v&?(I)CcSNsudDyOX<}oi zBctN&14jgGE_Rz%rSZ?`<&%JgrP7RJJ8wi@>5t#{_v!8acwe6R_IHyXJe`#A;pOCK zq7TlcCna_!q&^q<{psuLmG^mg{~MS9oda==)7AqE16n7({2$ZyzvsWCq{O>FzYhog z{Cb=JohZA${m&ggp4PM_x%JAMBD|C3gr(XeD5^W}HIxP6yeaAJN(9_Q@rLS=J# zd2xGtdzS{7{fFlI=yJFI`~N@x@P_(F%j$V}rc2C_m@+}esPUowV@s$Wbm&ZwDe=59Kocw%2!KJLb&8*ZQ%Cr>Buee*avDiS`zWhKIlJ|HtFQ zvxsNTnQjRguChPB`^9n)$#E`!ol)-Z;~(v3H+DX}|9^e`UCDFjezh%R3sUfFOls@) zalLxUOXg}pB|H)rS&4PO*!Sj2ZGz^E!>|Zhq?-oI*GNoehEG?Ozhph=RRTqur>mdK II;Vst0B~*uw*UYD literal 0 HcmV?d00001 diff --git a/Resources/Edge Bundling.png b/Resources/Edge Bundling.png new file mode 100644 index 0000000000000000000000000000000000000000..bf0c4d076724618b245532f90742bbb32048ccae GIT binary patch literal 1484 zcmYk6e^k;}6u=?s8#zL=k}v55wM_eoa#m(8()>Z2nx{-DQ9x1KDFrpHHdK`PRs3<( z%`B%KEiJ7uquQn|4f(35WwcJ4HJd=%oJ-BL6cG6ix77Z)@7{OLyZ7Du?&m&nP@vyR zvvp=D6l&#uy7xho2Im9|m{#?v&$TACf=@q^ghFBR<^-MmfG~qXElb<)?HNoLM^-tr z*=*Ax6oOpZ8Z&Ro+oZdjT$bKWsiSb~Uvl`z*c`g*Vxb+Wxxickd`h8E{&$J=w(6T! z_db<5`#mYW64r02iAFG%GjC_MAL<;e{^tS*n$|TvH`XX=SJy??8(#SM>ETKQhod3J z*b~g85YI!t+Pp&Plh-VSh>sa|{VQW7cRq(m&!2?l7uvV|;gu0BzY%tHtLI&|^t0MZ z%6X?1RHxj@YqLg$?D3~@9YMF=l~h=m*H&DSSimitmBjPJGVoqO$?0??w#YD3n6V0}?7AvEi89EFV zst}6ABcEz>RtWyr3%Gi|Wy2X7;=y@On>ofTVu{g>UmTQdH z3vqYNBI_nPtrk6QqSkC7XN~C(;(9Anxj}0N+9?Jl%@@iu@241I*=)6j>*r!q1K>e$ z4gyn4y%-jEb4N#eRS((i2ocmaJtL+Wbq{21ZQpXVS<89EwAtAQRpbuk_{g83jT&<5 z?m(4gROgEu%XfUAk%9gYgDj5+NibeLG*>y$@mq!772im2aF{%>g=;)3O-Xd0xC2l-Z|O%~ff)nW;_rlFUo!{r8oF=4`u7fC(rx= zU=H!Q8goTZI@)ofA=D;ac5`5Y3fRTt0bbNHh=MEHSqt zL>-1^31coE>CxPODZfVdqrC9;2;v; z0!3K2II3$M9h>Qp)bnc?PQV<&9h3|BuxAVEvU|Xp1ZZOejq>dzVvYvwtx7=tbHiawjb2xM9Z=rBnlgRA!vbBK~%A(UDOk4ZoQ3{)kVE zqc6aT*j7^0rRYKbZg>e3aImL(MybM$NF+Gk9@&7^l8?xdz0(C0H?;0cKyQN-y!-YW z0vL{Z#rUX#XWH(m2JuS@BbsA_N-a5V$pfpdEnOH3hN(e$6R|Ap(zHG(;c0!XIw$zt+NhvXE6y|ipexL(+lddq2Uk^-(SfKb{U)3Vl<$Proif=6 zKBVei8Z?W`_dgeT;Uur#T`;N?^;X8u>JemO*!n`{_>Ch)Q?OI%1mHSOy#wP&ZW5DC(!$b7d!J`2AQMr literal 0 HcmV?d00001 diff --git a/Resources/Isovist Region.png b/Resources/Isovist Region.png new file mode 100644 index 0000000000000000000000000000000000000000..084763f2d58fcd03fe7f84d4f6ab42c269db9850 GIT binary patch literal 969 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9G0-5|_ZdRqK9kWuaF z;uzx5nY2JNAt3>%h~fYLMY?H3Gm}(Kwzd7Y;n~9z#M8sW#dC&dRt!IXOO5^hlh6MD z|F3as#*D~)|8L(ueDuJ90}$hr94Btnosg37Z~mDB2VNXLaz^Ll`}g;c^YHLUOHPTo zW++kRZS*HSAoa)j1wcIthd+LscJKe}-#)^hv?N$sS{}N^)PMPOt8eGss02P{W@fOH zo1z!YzH;;Tx5wA7{0V5Ue|=B$!~FWwM<%46P}BeMZPT|WyzZ|f^J*ghI_dtg0ctWo zT+gQ0w%OZfkMrU{p85};?w*xBzJA3aRtX7EumJ;sDf+;hkS*>(9p^tD+2XV;`22sP zD|(eD6Le0W{?I)uq*ZaDVan^zQX} zhk2}vzHJf#TBv=egpCap7ht15d_VsF%klMg@A@($b;Muf9Lv#EKes^p@L`2hANv!3 ze>}}&Y%cfn`&;?b#%#?Ont?&X1jKU^&i=3e`0wB81Qz2r|Lc#L^YD0lJO~TcCYFmE zPnNHjPY(Dcap^(X(}SP?e2=e_ivM^1#Njh%J~TE*KltTsIQi~=lbm|vKj{;grT@)u zY+m64H^8a$NqV+anW2F}g8_@rZ~YS=+8t$OcK(+Tk(eQ|L*k!dLlAqRn1O)-#1~12 zw0}=-od3|inE@D>acpjEc`F{y0S3Vvmzn2ajyjajXnZ)FO>M(Nn+I2z5B2cK@ci%G z($Lt*2o8xu`Hpgrv)lIbm`nb1o~)))&T);6!@Ni4W5gg_xC@jl+J%$Ip1O=tMFANw`KJ_Z(<^OtfL(4Qh_-q0TL*rWF2OPGiQz-y|7csAEejQ)z4*} HQ$iB}fF-R* literal 0 HcmV?d00001 diff --git a/Resources/Mass Enable.png b/Resources/Mass Enable.png new file mode 100644 index 0000000000000000000000000000000000000000..f51e3ac478126497518301135e561e560533a012 GIT binary patch literal 1149 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9G0-5|_ZdRqK90|Se` zr;B5VM`zLk&4h#mpdyC<|C3y{Cmi4Ve;dyk9M1aAptTM zq{=aD!{2-Lwr*-|&OHB5eim02W^NWyKJ3HB*2c4efti^ZtjuZS1AFFX7PH>@`|FY; z_J3wL{Pgv9iMoIP4lmHqKKURk`{aVf%UXPQD$O~1-~hyAr;QBKJAS{=bpCziCr_*5 zHlDSCA9>c>)g)GYe<|(!^iD6&uBcf&7yrraFf}$Xfapm&r2g~obN#lyOm2y7+tiJh z{Ejl@_)uVU!)NEQgf(i13l`{iKRo!in&!l@CA9-+!>}W6>tVJ10dF zA3RJ+evtC#_=mSZ*Vq65XZ+`Xzw%8(n7GbaYF^3^YA0v=Mp?2OC*%O{E*mk+T5r> zMJFku?wRD_KNiYub39*5D*d@rAdS#9+sE?eO$o0{Ns@cCo*P{`vdiGkOYXFU{@=_m9Gdm&LM6>c#9n`r-9= zc{WSULbh`DY&K`z&>XdQMbpzu*f&eUQjyY(iw+JQ^ZOMQuS}O%x&j`;N~f44A~t23 zAO5SZFF9jIfb!R?v&(trm8J2>l|5S_1y6-ar<&~R{~N8jyKnl#BTub)JXgNdD4K6y zpB7-EibAiJq_D{8D_CY)$fPOhv)7tm-zSRXLI6#&9$ty&t^h!&3Vq-85Lyz|8P)mUv*wjo3br OKRsRjT-G@yGywo9NAn5* literal 0 HcmV?d00001 diff --git a/Resources/Mass Preview.png b/Resources/Mass Preview.png new file mode 100644 index 0000000000000000000000000000000000000000..dff4df688d267d71b8b64c7117eb971d42d0171d GIT binary patch literal 1049 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjoCO|{#S9G0-5|_ZdRqK9ka616 z#WBRAGiiZlLP7#i5ySugNiN$Hj_>`yjpqyx*OQ1p|Md^|i}&!%78aGPZ(x;>0GSI? zYuS^f`um3Npa>PZVr*x~t7t>IQ88biZmVAo3`jLkZoI7*iLF(G$ALc~1KYaWBKhG{Fdx^4lH%}Yne#~lHVqnjvtsMJ? z&A`9_;^sq{2OnM*mrT=-KX0&EqvhcJsP=>TKegKq&);vD;aOm~NA!7Ogz)PF1>X-U zw{5w1l}CKt-INnuoCi%>;I_Zq&wSk9SY^j-gC9|u&NZLEncpbL<;-LAE%a;a-!CC? z#^i}ann;^Lj&%XkZbcp*9+=gRVKEYi8@2r&v5=|-nc*{esUZFAZC4P*9xZg7n9nbA0R z?%an@UvKAGvqp#K+_f|wyK~!k=Df){q4ut5dU^@_W=U9lDb46Q^JVLSAJ5m{=Q$s@ zFY(8>$L!5ZW*9UJ*vl)f1-cXFQYEdKO$^r3+RcmBsBAo?2#=;kxo*j@B%*YSU13AY z<-E4v{&7YIh6|@nTz_v*@`o+P$saZtyI(zU-~hzeN~fCa>;D_Axw~)r!y`|vc|2FX z)F_&7U!N9XRL|Gky_IvB8yg!ai2@UpQ$)ht_4f=i*X>r2H$VJ(yL^C1?TFQt5JuGhep`sKUe0DdNN2pR<>=yr`D+G%T3q&X#Xqld_}uJKtfTpA2|@{P?JR z__X+W$&#y64dU3psjUkw>^P>I813MH4o}64a+ku*UZe}x$;_~j@k5-pUA#Id OJUw0gT-G@yGywoOeZ4FI literal 0 HcmV?d00001 diff --git a/Resources/POI Heat Map.png b/Resources/POI Heat Map.png new file mode 100644 index 0000000000000000000000000000000000000000..0cb51ac374d9b78f2a92363d3fd043bf91646237 GIT binary patch literal 1481 zcmYjRX;4#F6b{BFR$s;il=l>yG*Y2PNJ3O-5ik%7SOFKR*dhsm1gQwLlrf6t5uSv` zqJcso0VLLTM8y$YrfLzgA(S1fb!fE{QVA$qq7e*ac@3q|{?#+w_-4F-jxz~^q8EJlb4Tv_UvcYk4K`2Q2Ycz_@S5=zV;gX|8BAv$*YlF*+P0E22#+CM zrWiG{VVMj?l@t0uYZizR*Q2hFI#jCJR858`Otb)xA6Y3CcttPA5-v(%In+J&bBk%9 z_cH2HsH_&AFyGD9o0=y806^=9Q|3z0tYLW!KMq95QHIT3ZZgn;CI%cEARxH`AxP>a zXkA?)s8hr!@*E#mxY_n(8~7a8pmx*rA8a=)2+nBWtW{`3^ctL`u|D+!nC{7zLDIca@`^^sY&v{!Lu2eiT~W*2k(I zvv>5Itz*L!J2mMzqJMDtu#+khcg}r=dby*A1as^?HP&H7b-)dOWHjnT!PO z?fpjR4ya_rQQ+idTtN@1*;K55{Gt*a*X2wYbjA<^KnzL4SE}bE=c-fHb&A^wjY&K` zii(+%H(pr91_pAfpDM=ILl9;vA|$@z1`YEdOfsUOT?|h@y3UM zkYJd%%gxf>?>UvP--HdEeA+dqiPN|+k;82muc5J$U89ME*EhnOa>lNK|EJEYXyLWVveM{9n>Q7%>(RKz> z2Jw`kqaTT_QVUoXKEJ*=`IUUu!n-#C zxPDbuRk9^(XtUO6HA3l4dfuU;vs{@aa|ygxZ;94p9)}#Or_uX{@a8Y;qsq9`>th{`O|{mMK%moB1$g~f3cYd+qsQz8mj|um zl5=s{jJYu&$N!+tJ<`+=;Gg9GM5n9Rx)YWM`(1}mPE>Aw-cwy26fiMAGUT;S2JbNX k3|`2|@I~{t|NC39m;|57o>wtxWiw($ZjWYN3+3ef4JFyVy#N3J literal 0 HcmV?d00001 diff --git a/Resources/Plugin Icon.png b/Resources/Plugin Icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d84f8af937a55868735fbb151ef8349b0313dfd2 GIT binary patch literal 1508 zcmYk5dsLEl7{_ra-cU<7h3qKmsVr1pc(=SJK~Ax?Y_{X&*p$pmE1lToXr&PsnU_ku zBv{^#QMTqLE!%0$3rG$~&8?estdKlQ(-g!Titr9IU4J~k=bz{HeV)&+Xy4ulJDUwQ zFc{1(k`fke@~CCALYUs6oEVqm~f=Kq@2zK*U`O@OF10pTPp3~Ig4hHDh z*?D=hxfcZIeOL`#KmtJ!TA@&&&gMZ6HFJGOIZdT*1Yz+uplwl8ppv?Wb4rzTkkTWE z4(j?d9*9IVCWFB+doP2TfbsEc?3T%Tbu-VMI8jNRpaOjpUudl*;AOi-I~K+Va6q3} zF30#{E&qbhD3n_$T|ygw1xKW!@rdkirXb{b17!BWcVihbf-9f_rv^|Q4hXxdc;A}!}G3oN){XR z)J3(j6B$(>LMqeGt8w0wrUk4Lz)a9gOZx|8#R7rA!-mgChlPa!KHTzhCdbl?b=TZ; z(r7g3)#JQ=oOt8fQA5h{_UAC`L_u|Kwmw0D)m9K>`?D(!7{MT}7M-6^v~D2;Ck7hY zy6@j8zWKU+SrtW_;W!5u1ucbUFoGO9<_ON1ek)tzhl)z(gEC7xsa}Oqoufoo+wle zG2lq8mixlEXh^4^yB~C6db{V;vkp~PGTO*F;*Y?Rij%fK3s$=kWiRhQqhxn~OGHds zm`znxnc1Oz@#fp!aT(>U-uJhd*l$+0O+bT3dF`pc)ELiMn6ABo71Q#~z%JWRN`e0$ z%D~?z0$goxx7RQo!_AqGLcGgw6+(lpN2Zj#7Uf9shUd44-{%C`R{hVUTppE}q)t~1 z8qO%yNu`OMxuK6ifL&Hw3(v~dPWFw{U1R+6=V!z_vN)28sQhe2DNwNrJ(Gt(ayi#(7h>&e zb!D0nfF9>GYC1QaN{vp|%|mAJ@lFRMQdtLVjMKndLf80g^i5m+OK_Oyvl`@n*_Mvw OB}9I?H|$q3mH8ioi?+f5 literal 0 HcmV?d00001 diff --git a/Resources/Plugin Version.png b/Resources/Plugin Version.png new file mode 100644 index 0000000000000000000000000000000000000000..df11f0a18f6270100039d653b33769e8796860c4 GIT binary patch literal 1461 zcmYk63s4hB7{?C}LWKkdn}Lhif>Z>J$_Z4cXhI?nX;m0e9)rpm0*nOnT=%r)mP+POJkqt|Y?&;4a@K_2MoR?S;7&O;>zTo{m);D%011ays;z@SP`-%RHDF?_dAi&#tu;)kEihg zL4}>rjo}XGWMTZ$QiH?CuokTfusU4nrGmcRcDG$L{@jJMJ&7iuIPD=15udzg-pn{V zqSbIWl-QY?nLm43Oe`_nO?@&s>5V-P_4x!^sx^G>1b@_-05wmFZ7^|_LlBh9l08j5 zwfxHC!u|NgABuPD2BIl3MedQt5o)>{j0r9*<=~z3Q`$(JzcVwsBh5UE8@xr&B!;=IbG$Atm{y zF@Ey>tczkMkO{S;i#?Vxj=!p{H&xkF_TNbeds^7wbiE=tXly)@!{r*4|2sP8;0x?p z(Lwtsal;uCzq9+TGD}ugNWS~lFgu~$$x_hz+hDERk zENX$XIk6n|8-%0g?B}SBy;7-ctXP9PtRy*SGf0tP4AK)-{hGA2ra3VDaF`p<48-krFA(}u8H%1Sze)oe+L*wWaIfpp#=YC07xhaEc@e(tjSV5? zHpf-MNb{dVw`mO^0sB&C5h=1-lQit^EbxLtDQUBAOT}ow_OxERi zxvt02x#5wcGu=A;!vs^&s{LD%!W%@hXOZ;eIK0?g`vJwKMzV$__wUo{Hd%&!$`t#( zEShva<6Li*N}SSJSX$5}sIIOK+_h78wx(=pb0hy$PVTKWAl+Vwm}!p->{_4T$1)9% zf&~&hes*T!c9BNv8B%Zx_>3x2lfygMCmrV0LtUy$R`ca+KE2=X z4B6N~K?n?%Lvwv(Wg;9N@+E!xWxh^$@)W*;ul%Whem>Vf{Of7Aq{P2Jb3P}AMryg_ zGO?>q|B~#cwv7M&Hj~wd&cXxb(A=&CZN@vM&iJ4HGH!s=7dibnqd+&{!*?zV4pS3Da?phmI|Nr0bV+TGYa>ppbV`9qzqsWe_?mH$= zoN3uL-M_&*GPs@b=2wLe|LvKZ73}qyyQhd9p6|cjXXeizdUvY-Ccki?eq3r}jE0?(b>p>JRte(N`B2KmBj* zYe^lMyAn^Pgaq*X|31I*;mvT4--qSH+U);JO4i-AJa%AR&bb3hi%*~V@i&;Eds67H z_`F138{Qlm5&|GPrqfe03;ji-bjZH7? zXPiBC=E#ACSw{~jDV_iD{An(mTbLi4S*d$le)=_!4WBs9{5*SL0XxLV-w*cN{N5sO z|MPyVW%a39{sBMs&zx(#x?uvxwH@`pp4uN?zhB_n?)Cd6>i+&be&EPSAXYu`;rmb1 zHv8{=wf}!V&OWvO?%YUVbpB@qo7lv1v6=n9#Jl+xU;X{+Pwl>*e?xDMP129w*Yn*x zB`wpQaIm%h-K;Ngz4^dxkg+xYk9~N3O|fnM^|Jpz|9^IVJU`$6j|88OJ-5-E#>Pg7 zp@-&8&gE9Qxx>OrQbMvhcaE)PiLcHKAds;8laf&JK`_Yb&+p&u56?W@%VYm;-jCyF z4(?uyh?^;Y$e{?&wm-+cxEZQwi9MEQsKqSaO`wg MAJOR_VERSION + "." + MINOR_VERSION + "." + PATCH_VERSION; + public static int MAJOR_VERSION = 0; + public static int MINOR_VERSION = 1; + public static int PATCH_VERSION = 0; + } +} diff --git a/Utils/TabProperties.cs b/Utils/TabProperties.cs new file mode 100644 index 0000000..96b437d --- /dev/null +++ b/Utils/TabProperties.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Grasshopper; +using Grasshopper.Kernel; + +namespace CapableArchiTool.Utils +{ + public class TabProperties : GH_AssemblyPriority + { + public override GH_LoadingInstruction PriorityLoad() + { + Instances.ComponentServer.AddCategoryIcon("Capable Archi Tool", Properties.Resources.Plugin_Icon); + Instances.ComponentServer.AddCategoryShortName("Capable Archi Tool", "CAT"); + Instances.ComponentServer.AddCategorySymbolName("Capable Archi Tool", 'C'); + return GH_LoadingInstruction.Proceed; + } + + } +} \ No newline at end of file