diff --git a/Components/API/GH_HTTPGetRequestAsync.cs b/Components/API/GH_HTTPGetRequestAsync.cs
new file mode 100644
index 0000000..cc5797f
--- /dev/null
+++ b/Components/API/GH_HTTPGetRequestAsync.cs
@@ -0,0 +1,143 @@
+using System;
+using System.Collections.Generic;
+
+using Grasshopper.Kernel;
+using Rhino.Geometry;
+using System.IO;
+using System.Net;
+using System.Threading.Tasks;
+using Formicae.Helpers.API;
+using Formicae.Templates;
+
+namespace Formicae.Components.API
+{
+ public class MyComponent1 : GH_Component_HTTPAsync
+ {
+ ///
+ /// Initializes a new instance of the MyComponent1 class.
+ ///
+ public MyComponent1()
+ : base("HTTP GET (Async)", "GET Async",
+ "A generic HTTP GET request (asynchronous)",
+ Config.FormicaeTab, Config.Tabs.API)
+ {
+ }
+
+ ///
+ /// Registers all the input parameters for this component.
+ ///
+ protected override void RegisterInputParams(GH_InputParamManager pManager)
+ {// active
+ pManager.AddBooleanParameter("Send", "S", "Perform the request?", GH_ParamAccess.item, false);
+ // url (endpoint)
+ pManager.AddTextParameter("Url", "U", "Url for the request", GH_ParamAccess.item);
+
+ // custom headers (future)
+ // custom headers would be nice here: how to handle key-value pairs in GH? takes in a tree?
+
+ // auth
+ int authId = pManager.AddTextParameter("Authorization", "A", "If this request requires authorization, input your formatted token as an Auth string, e.g. \"Bearer h1g23g1fdg3d1\"", GH_ParamAccess.item);
+ // timeout
+ pManager.AddIntegerParameter("Timeout", "T", "Timeout for the request in ms. If the request takes longer that this, it will fail.", GH_ParamAccess.item, 10000);
+
+ pManager[authId].Optional = true;
+ }
+
+ ///
+ /// Registers all the output parameters for this component.
+ ///
+ protected override void RegisterOutputParams(GH_OutputParamManager pManager)
+ {
+ pManager.AddTextParameter("Response", "R", "Request response", 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)
+ {
+ if (_shouldExpire)
+ {
+ switch (_currentState)
+ {
+ case RequestState.Off:
+ Message = "Inactive";
+ _currentState = RequestState.Idle;
+ break;
+
+ case RequestState.Error:
+ Message = "ERROR";
+ AddRuntimeMessage(GH_RuntimeMessageLevel.Error, _response);
+ _currentState = RequestState.Idle;
+ break;
+
+ case RequestState.Done:
+ Message = "Complete!";
+ _currentState = RequestState.Idle;
+ break;
+ }
+ // Output...
+ DA.SetData(0, _response);
+ _shouldExpire = false;
+ return;
+ }
+
+ bool active = false;
+ string url = "";
+ string authToken = "";
+ int timeout = 0;
+
+ DA.GetData("Send", ref active);
+ if (!active)
+ {
+ _currentState = RequestState.Off;
+ _shouldExpire = true;
+ _response = "";
+ ExpireSolution(true);
+ return;
+ }
+
+ if (!DA.GetData("Url", ref url)) return;
+ DA.GetData("Authorization", ref authToken);
+ if (!DA.GetData("Timeout", ref timeout)) return;
+
+ // Validity checks
+ if (url == null || url.Length == 0)
+ {
+ _response = "Empty URL";
+ _currentState = RequestState.Error;
+ _shouldExpire = true;
+ ExpireSolution(true);
+ return;
+ }
+
+ _currentState = RequestState.Requesting;
+ Message = "Requesting...";
+
+ GETAsync(url, authToken, timeout);
+ }
+
+
+ ///
+ /// Provides an Icon for the component.
+ ///
+ protected override System.Drawing.Bitmap Icon
+ {
+ get
+ {
+ //You can add image files to your project resources and access them like this:
+ // return Resources.IconForThisComponent;
+ return null;
+ }
+ }
+
+ ///
+ /// Gets the unique ID for this component. Do not change this ID after release.
+ ///
+ public override Guid ComponentGuid
+ {
+ get { return new Guid("5FAB55FB-06C1-4F8D-AC13-4A95BC79727F"); }
+ }
+ }
+}
\ No newline at end of file
diff --git a/api/auth.cs b/Components/API/GH_auth.cs
similarity index 84%
rename from api/auth.cs
rename to Components/API/GH_auth.cs
index c5c88cf..cf13fb3 100644
--- a/api/auth.cs
+++ b/Components/API/GH_auth.cs
@@ -3,29 +3,30 @@
using Newtonsoft.Json.Linq;
using Grasshopper.Kernel;
using System.Threading.Tasks;
-namespace Formicae.api
+using Formicae.Helpers.API;
+namespace Formicae.Components.API
{
- public class auth : GH_Component
+ public class GH_auth : GH_Component
{
///
/// Initializes a new instance of the MyComponent1 class.
///
- public auth()
+ public GH_auth()
: base("auth", "auth",
"auth",
- "Formicae", "api")
+ Config.FormicaeTab, Config.Tabs.API)
{
}
///
/// Registers all the input parameters for this component.
///
- protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
+ protected override void RegisterInputParams(GH_InputParamManager pManager)
{
pManager.AddBooleanParameter("Trigger", "T", "Set to true to start the authentication process.", GH_ParamAccess.item);
}
- protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
+ protected override void RegisterOutputParams(GH_OutputParamManager pManager)
{
pManager.AddTextParameter("AccessToken", "Token", "The OAuth access token.", GH_ParamAccess.item);
}
@@ -58,7 +59,7 @@ protected override void SolveInstance(IGH_DataAccess DA)
{
Rhino.RhinoApp.InvokeOnUiThread((Action)(() =>
{
- this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Error during authentication: " + ex.Message);
+ AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Error during authentication: " + ex.Message);
}));
}
});
diff --git a/Components/DataVisualization/showWindRose.cs b/Components/DataVisualization/showWindRose.cs
new file mode 100644
index 0000000..bcc7186
--- /dev/null
+++ b/Components/DataVisualization/showWindRose.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+
+using Grasshopper.Kernel;
+using Rhino.Geometry;
+
+using System.Drawing;
+using Newtonsoft.Json;
+namespace Formicae.Components.DataVisualization
+{
+ public class showWindRose : GH_Component
+ {
+ public override Guid ComponentGuid => new Guid("A45FC4A2-0E1C-415C-86D7-D29D21AD74E1");
+ protected override Bitmap Icon => null;
+ public showWindRose()
+ : base("showWindRose", "showWindRose",
+ "showWindRose",
+ Config.FormicaeTab, Config.Tabs.Show)
+ {
+ }
+
+ ///
+ /// 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)
+ {
+ }
+
+ ///
+ /// 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)
+ {
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Components/GH_CreateHeightMaps.cs b/Components/GH_CreateHeightMaps.cs
deleted file mode 100644
index e6fb25b..0000000
--- a/Components/GH_CreateHeightMaps.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Formicae.Types;
-using Grasshopper.Kernel;
-using Rhino.Geometry;
-
-namespace Formicae.Components
-{
- public class GH_CreateHeightMaps : GH_Component
- {
- ///
- /// Initializes a new instance of the GH_CreateHeightMaps class.
- ///
- public GH_CreateHeightMaps()
- : base("GH_CreateHeightMaps", "Nickname",
- "Description",
- "Formicae", "Setup")
-
- {
- }
-
- ///
- /// Registers all the input parameters for this component.
- ///
- protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
- {
- pManager.AddGenericParameter("WindSimModel", "WindSimModel", "WindSimModel", GH_ParamAccess.item);
- }
-
- ///
- /// Registers all the output parameters for this component.
- ///
- protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
- {
- pManager.AddNumberParameter("HeightsMapWithoutBuildings", "HeightsMapWithoutBuildings", "HeightsMapWithoutBuildings", GH_ParamAccess.list);
- pManager.AddNumberParameter("HeightsMapWithBuildings", "HeightsMapWithBuildings", "HeightsMapWithBuildings", GH_ParamAccess.list);
- }
-
- ///
- /// 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)
- {
- WindSimulationModel windSimModel = new WindSimulationModel();
- DA.GetData(0,ref windSimModel);
-
- HeightMap heightMap = new HeightMap(windSimModel);
-
- //var mappedWithoutBuildings = HeightMap.MapToDomain(heightMap.HeightMapWithoutBuildings(), 0, 255);
- //var mappedWithBuildings = HeightMap.MapToDomain(heightMap.HeightMapWithBuildings(), 0, 255);
-
- var mappedWithoutBuildings = heightMap.HeightMapWithoutBuildings();
- var mappedWithBuildings = heightMap.HeightMapWithBuildings();
-
- //DA.SetDataList(0,heightMap.HeightMapWithoutBuildings());
- //DA.SetDataList(1,heightMap.HeightMapWithBuildings());
-
-
- DA.SetDataList(0, mappedWithoutBuildings);
- DA.SetDataList(1, mappedWithBuildings);
-
- }
-
- ///
- /// Provides an Icon for the component.
- ///
- protected override System.Drawing.Bitmap Icon
- {
- get
- {
- //You can add image files to your project resources and access them like this:
- // return Resources.IconForThisComponent;
- return null;
- }
- }
-
- ///
- /// Gets the unique ID for this component. Do not change this ID after release.
- ///
- public override Guid ComponentGuid
- {
- get { return new Guid("0B9A9778-22FA-49AA-9C3E-730022BB56AD"); }
- }
- }
-}
\ No newline at end of file
diff --git a/Components/GH_CreateSimulationBox.cs b/Components/GH_CreateSimulationBox.cs
deleted file mode 100644
index bbb9b79..0000000
--- a/Components/GH_CreateSimulationBox.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Formicae.Types;
-using Grasshopper.Kernel;
-using Rhino.Geometry;
-
-namespace Formicae.Components
-{
- public class GH_CreateSimulationBox : GH_Component
- {
- ///
- /// Initializes a new instance of the GH_CreateSimulationBox class.
- ///
- public GH_CreateSimulationBox()
- : base("Create Simulation Box ", "Nickname",
- "Description",
- "Formicae", "Setup")
- {
- }
-
- ///
- /// Registers all the input parameters for this component.
- ///
- protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
- {
- pManager.AddBrepParameter("Box", "box", "500X500 box to make the simulaiton Grids", GH_ParamAccess.item);
- }
-
- ///
- /// Registers all the output parameters for this component.
- ///
- protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
- {
- // pManager.AddMeshParameter("SimulaitonMeshGrid", "SMG", "A grid to simulate on", GH_ParamAccess.item);
- pManager.AddPointParameter("SimulationPoints", "Simpts", "A grid of points to get the height maps", GH_ParamAccess.list);
- pManager.AddMeshParameter("ResultMeshGrid", "RMG", "A grid to viz the results",GH_ParamAccess.item);
- pManager.AddGenericParameter("SimulationBox", "simBox", "Simulation box object", 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)
- {
- Brep box = new Brep();
- DA.GetData(0, ref box);
-
- SimulationBox simbox = new SimulationBox(box);
- //var simMesh = simbox.GetSimulationMesh();
- //var simPts = simbox.GetSimulationPoints();
- //var ResultMesh = simbox.GetResultMeshGrid();
-
- var simPts = simbox.LiftedPts;
- var ResultMesh = simbox.LiftedResultMesh;
- DA.SetDataList(0, simPts);
- DA.SetData(1, ResultMesh);
- DA.SetData(2, simbox);
-
- }
-
- ///
- /// Provides an Icon for the component.
- ///
- protected override System.Drawing.Bitmap Icon
- {
- get
- {
- //You can add image files to your project resources and access them like this:
- // return Resources.IconForThisComponent;
- return null;
- }
- }
-
- ///
- /// Gets the unique ID for this component. Do not change this ID after release.
- ///
- public override Guid ComponentGuid
- {
- get { return new Guid("1F1E5EE5-6DD9-436C-9C7B-4D51AD92B912"); }
- }
- }
-}
\ No newline at end of file
diff --git a/Components/GH_CreateWindSimulationModel.cs b/Components/GH_CreateWindSimulationModel.cs
deleted file mode 100644
index 069f760..0000000
--- a/Components/GH_CreateWindSimulationModel.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Formicae.Types;
-using Grasshopper.Kernel;
-using Rhino.Geometry;
-
-namespace Formicae.Components
-{
- public class GH_CreateWindSimulationModel : GH_Component
- {
- ///
- /// Initializes a new instance of the GH_CreateWindSimulationModel class.
- ///
- public GH_CreateWindSimulationModel()
- : base("GH_CreateWindSimulationModel", "Nickname",
- "Description",
- "Formicae", "Setup")
- {
- }
-
- ///
- /// Registers all the input parameters for this component.
- ///
- protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
- {
- pManager.AddMeshParameter("TerrainMesh", "TM", "Mesh used to represent the terrain", GH_ParamAccess.item);
- pManager.AddBrepParameter("Buildings Breps", "BB", "Buildings as Breps (Kepp at volumetric level and simple boxes)", GH_ParamAccess.list);
- pManager.AddGenericParameter("Simulation Box", "SimBox", "Simulation Box Object", GH_ParamAccess.item);
-
- }
-
- ///
- /// Registers all the output parameters for this component.
- ///
- protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
- {
- pManager.AddGenericParameter("WindSimModel", "WindSimModel", "WindSimModel",GH_ParamAccess.item);
- // pManager.AddGenericParameter("Debug", "Debug", "Debug", 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)
- {
- Mesh tMesh = new Mesh();
- DA.GetData(0, ref tMesh);
- Terrain terrain = new Terrain(tMesh);
-
- List blgsBrep = new List();
- DA.GetDataList(1, blgsBrep);
- Buildings bldgs = new Buildings(blgsBrep);
-
- SimulationBox simBox = new SimulationBox();
- DA.GetData(2, ref simBox);
-
- WindSimulationModel windSimModel = new WindSimulationModel(bldgs, terrain, simBox);
-
- DA.SetData(0, windSimModel);
- //DA.SetData(1, simBox);
-
- }
-
- ///
- /// Provides an Icon for the component.
- ///
- protected override System.Drawing.Bitmap Icon
- {
- get
- {
- //You can add image files to your project resources and access them like this:
- // return Resources.IconForThisComponent;
- return null;
- }
- }
-
- ///
- /// Gets the unique ID for this component. Do not change this ID after release.
- ///
- public override Guid ComponentGuid
- {
- get { return new Guid("7C2E1E1E-CAB8-47B0-956B-9351A3BDB8BD"); }
- }
- }
-}
\ No newline at end of file
diff --git a/Components/GH_postArray.cs b/Components/GH_postArray.cs
new file mode 100644
index 0000000..69cba6c
--- /dev/null
+++ b/Components/GH_postArray.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+
+using Grasshopper.Kernel;
+using Rhino.Geometry;
+using System.Drawing;
+using Newtonsoft.Json;
+
+namespace Formicae.Components
+{
+
+ public class GH_postArray : GH_Component
+ {
+ public override Guid ComponentGuid => new Guid("05AACC05-6188-4760-BB01-796D6DF98607");
+ protected override Bitmap Icon => null;
+
+ public GH_postArray()
+ : base("GH_postArray", "GH_postArray",
+ "GH_postArray",
+ Config.FormicaeTab, Config.Tabs.API)
+ {
+ }
+
+ protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
+ {
+ pManager.AddTextParameter("HeightArray", "HeightArr", "HeightArr", GH_ParamAccess.item);
+ pManager.AddTextParameter("Wind Parameters", "WindPar", "WindPar", GH_ParamAccess.item);
+ pManager.AddTextParameter("WindcomfortClass", "WClass", "WClass", GH_ParamAccess.item);
+
+ }
+
+ protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
+ {
+
+ pManager.AddTextParameter("PostArray", "PostArr", "PostArr", GH_ParamAccess.item);
+ }
+
+
+ protected override void SolveInstance(IGH_DataAccess DA)
+ {
+
+ string heightArrayJson = string.Empty;
+ string windParamsJson = string.Empty;
+ string windClass = "lawson_2001";
+ if (!DA.GetData(0, ref heightArrayJson)) return;
+ if (!DA.GetData(1, ref windParamsJson)) return;
+ if (!DA.GetData(2, ref windClass)) return;
+
+
+
+ var windParams = JsonConvert.DeserializeObject>(windParamsJson);
+ object roughness = windParams.TryGetValue("roughness", out roughness) ? roughness : 0;
+ windParams.Remove("roughness");
+ var heightMaps = JsonConvert.DeserializeObject>(heightArrayJson);
+
+ var body = new Dictionary
+ {
+ {"heightMaps", heightMaps},
+ {"windRose", windParams},
+ {"type", "comfort"},
+ {"roughness", roughness},
+ {"comfortScale", windClass}
+ };
+ string bodyJson = JsonConvert.SerializeObject(body);
+ DA.SetData(0, bodyJson);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Components/GH_terrainArrays.cs b/Components/GH_terrainArrays.cs
new file mode 100644
index 0000000..d446450
--- /dev/null
+++ b/Components/GH_terrainArrays.cs
@@ -0,0 +1,129 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+using Grasshopper.Kernel;
+
+using Grasshopper.Kernel.Types;
+using Newtonsoft.Json;
+using static Formicae.Helpers.RayTracing;
+using static Formicae.Helpers.MeshHelper;
+
+using System.Drawing;
+using System.IO.Compression;
+using System.IO;
+using System.Text;
+namespace Formicae.Components
+{
+ public class GH_terrainArrays : GH_Component
+ {
+ public override Guid ComponentGuid => new Guid("792CBE8E-4903-4F5F-A408-8087DC7FA6CB");
+
+ protected override Bitmap Icon => null;
+
+ public IGH_GeometricGoo terrain;
+
+ public GH_terrainArrays()
+ : base("GH_terrainArrays", "FG_TA",
+ "GH_terrainArrays",
+ Config.FormicaeTab, Config.Tabs.Geometry)
+ {
+ }
+
+ protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
+ {
+ pManager.AddGeometryParameter("Terrain", "T", "", GH_ParamAccess.item);
+ pManager.AddGeometryParameter("Terrain + Building", "T+B", "", GH_ParamAccess.item);
+ }
+
+ protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
+ {
+ pManager.AddTextParameter("Height Dictionary", "HeightDict", "HeightDict", GH_ParamAccess.item);
+ pManager.AddMeshParameter("Analysis Mesh", "AnalysisMesh", "AnalysisMesh", GH_ParamAccess.item);
+ }
+
+
+ protected override void SolveInstance(IGH_DataAccess DA)
+ {
+ Rhino.Geometry.Mesh terrainAndBuildings = new Rhino.Geometry.Mesh();
+ DA.GetData(0, ref terrain);
+ DA.GetData(1, ref terrainAndBuildings);
+
+ var terrainToMesh = Remesh(terrain);
+ var terrainAndBuildingsToMesh = terrainAndBuildings;
+
+ var rectTerrain = GetBase(terrainToMesh);
+
+ var gridPoints = GetPoints(rectTerrain);
+ var analysisPoints = GetPointsAnalysis(rectTerrain);
+
+ var rayTerrain = HitPointsHeight(gridPoints, terrainToMesh);
+ Rhino.Geometry.Mesh ProbMesh = CreateMeshFromGridPoints(HitPoints(analysisPoints, terrainToMesh),201,201);
+
+ var rayTerrainAndBuilding = HitPointsHeight(gridPoints, terrainAndBuildingsToMesh);
+
+ double apiMin = rayTerrainAndBuilding.Min();
+ double apiMax = rayTerrain.Max();
+
+ int[] apiBuildingParallel = new int[rayTerrainAndBuilding.Length];
+ int[] apiTerrainParallel = new int[rayTerrain.Length];
+
+
+ if (apiMax != apiMin)
+ {
+ for (int index = 0; index < rayTerrainAndBuilding.Length; index++)
+ {
+ var value = rayTerrainAndBuilding[index];
+ var normalizedValue = (value - apiMin) / (apiMax - apiMin) * 255;
+ apiBuildingParallel[index] = (int)Math.Round(normalizedValue);
+ }
+
+ for (int index = 0; index < rayTerrain.Length; index++)
+ {
+ var value = rayTerrain[index];
+ var normalizedValue = (value - apiMin) / (apiMax - apiMin) * 255;
+ apiTerrainParallel[index] = (int)Math.Round(normalizedValue);
+ }
+ }
+
+ List apiBuilding = new List(apiBuildingParallel);
+ List apiTerrain = new List(apiTerrainParallel);
+
+ var heightMaps = new Dictionary
+ {
+ {"terrainHeightArray", apiTerrain},
+ {"minHeight", apiMin},
+ {"maxHeight", apiMax},
+ {"buildingAndTerrainHeightArray", apiBuilding}
+ };
+
+ string jsonString = JsonConvert.SerializeObject(heightMaps,Formatting.None);
+
+ DA.SetData(0, jsonString);
+ DA.SetData(1, ProbMesh);
+
+
+ }
+
+ public static byte[] CompressString(string str)
+ {
+ byte[] uncompressedBytes = Encoding.UTF8.GetBytes(str);
+
+ using (var memoryStream = new MemoryStream())
+ {
+ using (var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress))
+ {
+ gzipStream.Write(uncompressedBytes, 0, uncompressedBytes.Length);
+ }
+
+ return memoryStream.ToArray();
+ }
+ }
+
+ public static string ToBase64String(byte[] bytes)
+ {
+ return Convert.ToBase64String(bytes);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Config.cs b/Config.cs
new file mode 100644
index 0000000..40079c2
--- /dev/null
+++ b/Config.cs
@@ -0,0 +1,26 @@
+namespace Formicae
+{
+ static class Config
+ {
+ public enum FormicaeSubTab
+ {
+ Geometry,
+ API,
+ Show,
+ }
+
+ //Name for the GH tab
+ public static string FormicaeTab { get => " Formicae"; }
+ public static string Suffix { get => " Formicae"; }
+
+ public static class Tabs
+ {
+ public static string Geometry { get => $"{(FormicaeSubTab)0}"; }
+ public static string API { get => $"{(FormicaeSubTab)1}"; }
+ public static string Show { get => $"{(FormicaeSubTab)2}"; }
+
+
+
+ }
+ }
+}
diff --git a/Dependencies/DHARTAPI.dll b/Dependencies/DHARTAPI.dll
new file mode 100644
index 0000000..9dfcf75
Binary files /dev/null and b/Dependencies/DHARTAPI.dll differ
diff --git a/Dependencies/DHARTAPICSharp.dll b/Dependencies/DHARTAPICSharp.dll
new file mode 100644
index 0000000..0231dc1
Binary files /dev/null and b/Dependencies/DHARTAPICSharp.dll differ
diff --git a/Dependencies/embree3.dll b/Dependencies/embree3.dll
new file mode 100644
index 0000000..3d34380
Binary files /dev/null and b/Dependencies/embree3.dll differ
diff --git a/Dependencies/tbb.dll b/Dependencies/tbb.dll
new file mode 100644
index 0000000..e4aae8e
Binary files /dev/null and b/Dependencies/tbb.dll differ
diff --git a/Formicae.csproj b/Formicae.csproj
index 403356f..0c8f937 100644
--- a/Formicae.csproj
+++ b/Formicae.csproj
@@ -13,5 +13,11 @@
+
+
+
+ Assemblies\DHARTAPICSharp.dll
+
+
\ No newline at end of file
diff --git a/Formicae.gha b/Formicae.gha
deleted file mode 100644
index 71b314f..0000000
Binary files a/Formicae.gha and /dev/null differ
diff --git a/FormicaeComponent.cs b/FormicaeComponent.cs
deleted file mode 100644
index 27ec889..0000000
--- a/FormicaeComponent.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using Grasshopper;
-using Grasshopper.Kernel;
-using Rhino.Geometry;
-using System;
-using System.Collections.Generic;
-
-namespace Formicae
-{
- public class FormicaeComponent : GH_Component
- {
- ///
- /// Each implementation of GH_Component must provide a public
- /// constructor without any arguments.
- /// Category represents the Tab in which the component will appear,
- /// Subcategory the panel. If you use non-existing tab or panel names,
- /// new tabs/panels will automatically be created.
- ///
- public FormicaeComponent()
- : base("FormicaeComponent", "Nickname",
- "Description",
- "Category", "Subcategory")
- {
- }
-
- ///
- /// 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)
- {
- }
-
- ///
- /// This is the method that actually does the work.
- ///
- /// The DA object can be used to retrieve data from input parameters and
- /// to store data in output parameters.
- protected override void SolveInstance(IGH_DataAccess DA)
- {
- }
-
- ///
- /// Provides an Icon for every component that will be visible in the User Interface.
- /// Icons need to be 24x24 pixels.
- /// You can add image files to your project resources and access them like this:
- /// return Resources.IconForThisComponent;
- ///
- protected override System.Drawing.Bitmap Icon => null;
-
- ///
- /// Each component must have a unique Guid to identify it.
- /// It is vital this Guid doesn't change otherwise old ghx files
- /// that use the old ID will partially fail during loading.
- ///
- public override Guid ComponentGuid => new Guid("fff4de67-6264-4ddd-af2c-e75df0fe636f");
- }
-}
\ No newline at end of file
diff --git a/Helpers/API/GH_Component_HTTPAsync.cs b/Helpers/API/GH_Component_HTTPAsync.cs
new file mode 100644
index 0000000..24beb0b
--- /dev/null
+++ b/Helpers/API/GH_Component_HTTPAsync.cs
@@ -0,0 +1,143 @@
+using Formicae.Templates;
+using Grasshopper.Kernel;
+using Rhino;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+namespace Formicae.Helpers.API
+{
+ public abstract class GH_Component_HTTPAsync : GH_Component
+ {
+ protected string _response = "";
+ protected bool _shouldExpire = false;
+ protected RequestState _currentState = RequestState.Off;
+
+ public GH_Component_HTTPAsync(string name, string nickname, string description, string category, string subcategory)
+ : base(name, nickname, description, category, subcategory)
+ {
+ }
+
+ protected override void ExpireDownStreamObjects()
+ {
+ if (_shouldExpire)
+ {
+ base.ExpireDownStreamObjects();
+ }
+ }
+
+ protected void POSTAsync(
+ string url,
+ string body,
+ string contentType,
+ string authorization,
+ int timeout)
+ {
+ Task.Run(() =>
+ {
+ try
+ {
+ // Compose the request
+ byte[] data = Encoding.ASCII.GetBytes(body);
+
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
+ request.Method = "POST";
+ request.ContentType = contentType;
+ request.ContentLength = data.Length;
+ request.Timeout = timeout;
+
+ // Handle authorization
+ if (authorization != null && authorization.Length > 0)
+ {
+ ServicePointManager.Expect100Continue = true;
+ ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; //the auth type
+
+ request.PreAuthenticate = true;
+ request.Headers.Add("Authorization", authorization);
+ }
+ else
+ {
+ request.Credentials = CredentialCache.DefaultCredentials;
+ }
+
+ using (var stream = request.GetRequestStream())
+ {
+ stream.Write(data, 0, data.Length);
+ }
+ var res = request.GetResponse();
+ _response = new StreamReader(res.GetResponseStream()).ReadToEnd();
+
+ _currentState = RequestState.Done;
+
+ _shouldExpire = true;
+ RhinoApp.InvokeOnUiThread((Action)delegate { ExpireSolution(true); });
+ }
+ catch (Exception ex)
+ {
+ _response = ex.Message;
+
+ _currentState = RequestState.Error;
+
+ _shouldExpire = true;
+ RhinoApp.InvokeOnUiThread((Action)delegate { ExpireSolution(true); });
+
+ return;
+ }
+ });
+ }
+
+
+ protected void GETAsync(
+ string url,
+ string authorization,
+ int timeout)
+ {
+ Task.Run(() =>
+ {
+ try
+ {
+ // Compose the request
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
+ request.Method = "GET";
+ request.Timeout = timeout;
+
+ // Handle authorization
+ if (authorization != null && authorization.Length > 0)
+ {
+ ServicePointManager.Expect100Continue = true;
+ ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; //the auth type
+
+ request.PreAuthenticate = true;
+ request.Headers.Add("Authorization", authorization);
+ }
+ else
+ {
+ request.Credentials = CredentialCache.DefaultCredentials;
+ }
+
+ var res = request.GetResponse();
+ _response = new StreamReader(res.GetResponseStream()).ReadToEnd();
+
+ _currentState = RequestState.Done;
+
+ _shouldExpire = true;
+ RhinoApp.InvokeOnUiThread((Action)delegate { ExpireSolution(true); });
+ }
+ catch (Exception ex)
+ {
+ _response = ex.Message;
+
+ _currentState = RequestState.Error;
+
+ _shouldExpire = true;
+ RhinoApp.InvokeOnUiThread((Action)delegate { ExpireSolution(true); });
+
+ return;
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/Helpers/API/GH_Component_HTTPSync.cs b/Helpers/API/GH_Component_HTTPSync.cs
new file mode 100644
index 0000000..49533fc
--- /dev/null
+++ b/Helpers/API/GH_Component_HTTPSync.cs
@@ -0,0 +1,105 @@
+using Formicae.Templates;
+using Grasshopper.Kernel;
+using Rhino;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+namespace Formicae.Helpers.API
+{
+ public abstract class GH_Component_HTTPSync : GH_Component
+ {
+ public GH_Component_HTTPSync(string name, string nickname, string description, string category, string subcategory)
+ : base(name, nickname, description, category, subcategory)
+ {
+ }
+
+ protected string POST(
+ string url,
+ string body,
+ string contentType,
+ string authorization,
+ int timeout)
+ {
+ try
+ {
+ // Compose the request
+ byte[] data = Encoding.ASCII.GetBytes(body);
+
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
+ request.Method = "POST";
+ request.ContentType = contentType;
+ request.ContentLength = data.Length;
+ request.Timeout = timeout;
+
+ // Handle authorization
+ if (authorization != null && authorization.Length > 0)
+ {
+ System.Net.ServicePointManager.Expect100Continue = true;
+ System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; //the auth type
+
+ request.PreAuthenticate = true;
+ request.Headers.Add("Authorization", authorization);
+ }
+ else
+ {
+ request.Credentials = CredentialCache.DefaultCredentials;
+ }
+
+ using (var stream = request.GetRequestStream())
+ {
+ stream.Write(data, 0, data.Length);
+ }
+ var res = request.GetResponse();
+ var response = new StreamReader(res.GetResponseStream()).ReadToEnd();
+ return response;
+ }
+ catch (Exception ex)
+ {
+ AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Something went wrong: " + ex.Message);
+ return "";
+ }
+ }
+
+ protected string GET(
+ string url,
+ string authorization,
+ int timeout)
+ {
+ try
+ {
+ // Compose the request
+ HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
+ request.Method = "GET";
+ request.Timeout = timeout;
+
+ // Handle authorization
+ if (authorization != null && authorization.Length > 0)
+ {
+ System.Net.ServicePointManager.Expect100Continue = true;
+ System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; //the auth type
+
+ request.PreAuthenticate = true;
+ request.Headers.Add("Authorization", authorization);
+ }
+ else
+ {
+ request.Credentials = CredentialCache.DefaultCredentials;
+ }
+
+ var res = request.GetResponse();
+ var response = new StreamReader(res.GetResponseStream()).ReadToEnd();
+
+ return response;
+ }
+ catch (Exception ex)
+ {
+ AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Something went wrong: " + ex.Message);
+ return "";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/api/OAuthHandler.cs b/Helpers/API/OAuthHandler.cs
similarity index 98%
rename from api/OAuthHandler.cs
rename to Helpers/API/OAuthHandler.cs
index acc2f8f..e7891e2 100644
--- a/api/OAuthHandler.cs
+++ b/Helpers/API/OAuthHandler.cs
@@ -12,7 +12,7 @@
using System.Net.Http;
using System.Threading;
-namespace Formicae.api
+namespace Formicae.Helpers.API
{
@@ -100,7 +100,7 @@ public static async Task GetAccessToken()
// You had commented out the state encryption check, ensuring it's intentional.
// var incoming = context.Request.QueryString.Get("state");
- var buffer = System.Text.Encoding.UTF8.GetBytes("success!");
+ var buffer = Encoding.UTF8.GetBytes("success!");
response.ContentLength64 = buffer.Length;
response.OutputStream.WriteAsync(buffer, 0, buffer.Length).ContinueWith((task) =>
{
diff --git a/Helpers/API/RequestStateEnum.cs b/Helpers/API/RequestStateEnum.cs
new file mode 100644
index 0000000..5923ad9
--- /dev/null
+++ b/Helpers/API/RequestStateEnum.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Formicae.Templates
+{
+ public enum RequestState
+ {
+ Off,
+ Idle,
+ Requesting,
+ Done,
+ Error
+ };
+}
\ No newline at end of file
diff --git a/Helpers/MeshHelper.cs b/Helpers/MeshHelper.cs
index e15d422..b0a774e 100644
--- a/Helpers/MeshHelper.cs
+++ b/Helpers/MeshHelper.cs
@@ -4,7 +4,8 @@
using System.Text;
using System.Threading.Tasks;
using Rhino.Geometry;
-using Grasshopper;
+using Rhino.DocObjects;
+
using Grasshopper.Kernel;
using Grasshopper.Kernel.Types;
using GH_IO.Serialization;
@@ -13,186 +14,139 @@
using Rhino.Geometry.Intersect;
using System.Drawing.Printing;
using System.Security.Policy;
+using System.Collections.Concurrent;
namespace Formicae.Helpers
{
- public static class MeshHelper
+ public class MeshHelper
{
- ///
- /// Creates a single face with squared offset (read vertically)
- ///
- /// Bot left
- ///
- ///
- public static Mesh GetSingleMeshForResult(Plane plane)
+ public static Rhino.Geometry.Mesh Remesh(IGH_GeometricGoo goo)
{
- // 1 meter
- double offset = 1;
- Mesh m = new Mesh();
- m.Vertices.Add(plane.Origin);
- m.Vertices.Add(plane.Origin + plane.YAxis * offset);
- m.Vertices.Add(plane.Origin + plane.YAxis * offset + plane.XAxis * offset);
- m.Vertices.Add(plane.Origin + plane.XAxis * offset);
- m.Faces.AddFace(0, 1, 2, 3);
- return m;
- }
+ Guid id = goo.ReferenceID;
+ var rhinoObj = new RhinoObject[] { RhinoDoc.ActiveDoc.Objects.Find(id) };
+ if (rhinoObj == null) return null;
- ///
- /// Create a mesh grid (Read vertically)
- ///
- /// Result Plane
- /// 200 X 200 300 X 300 Grid etc..
- public static Mesh GetGridMeshForResult(Plane originPlane, double gridTotalDistance , double gridresolution)
- {
- Mesh resultGrid = new Mesh();
- for (int i = 0; i < gridTotalDistance; i++)
- {
- //Create plane in x direction
- Plane offsetedPlane = originPlane;
- offsetedPlane.Translate(originPlane.XAxis * i);
- Mesh OffsetMeshinX = GetSingleMeshForResult(offsetedPlane);
+ ObjRef[] getMesh = Rhino.DocObjects.RhinoObject.GetRenderMeshesWithUpdatedTCs(rhinoObj, false, false, false, false); //hidden objects won't be ignored
+ if (getMesh.Length == 0) return null;
- for (int j = 0; j < gridTotalDistance; j++)
- {
- //Translate in y direction
- Mesh tempMesh = OffsetMeshinX.DuplicateMesh();
- tempMesh.Translate(originPlane.YAxis * j);
- resultGrid.Append(tempMesh);
- }
- }
- return resultGrid;
+ return getMesh[0].Mesh();
}
- ///
- /// Create a mesh grid (Read vertically)
- ///
- /// Top left corner
- ///
- public static Mesh GetPlaneForMeshSimulation(Plane plane)
- {
- double offset = 1.5;
- Mesh m = new Mesh();
- m.Vertices.Add(plane.Origin);
- m.Vertices.Add(plane.Origin - plane.YAxis * offset);
- m.Vertices.Add(plane.Origin - (plane.YAxis * offset) + (plane.XAxis * offset));
- m.Vertices.Add(plane.Origin + plane.XAxis * offset);
- m.Faces.AddFace(0, 1, 2, 3);
- return m;
+ public static Rectangle3d GetBase(Rhino.Geometry.Mesh mesh)
+ {
+ BoundingBox box = mesh.GetBoundingBox(false);
+
+ double zOffset = 100;
+ Point3d center = new Point3d((box.Min.X + box.Max.X) / 2, (box.Min.Y + box.Max.Y) / 2, box.Max.Z + zOffset);
+ double length = 500;
+ double width = 500;
+ Point3d rectStart = new Point3d(center.X - length / 2, center.Y - width / 2, center.Z);
+ Point3d rectEnd = new Point3d(center.X + length / 2, center.Y + width / 2, center.Z);
+ Rectangle3d rect = new Rectangle3d(new Plane(center, Vector3d.ZAxis), rectStart, rectEnd);
+
+ return rect;
}
- [Obsolete]
- public static Mesh GetGridMeshForSimulation(Plane OriginPlane, double GridtTotalDistance)
+ public static Point3d[] GetPoints(Rectangle3d rect)
{
- //Too slow
- Mesh resultGrid = new Mesh();
-
- for (int i = 0; i < GridtTotalDistance; i++)
+ int divisions = (int)Math.Sqrt(250000) - 1;
+ double width = rect.Width;
+ double height = rect.Height;
+ double spacingX = width / divisions;
+ double spacingY = height / divisions;
+
+ int arrayLength = (divisions + 1) * (divisions + 1);
+ Point3d[] points = new Point3d[arrayLength];
+ for (int i = 0; i <= divisions; i++)
{
- //Create plane in Y direction
- Plane offsetedPlane = OriginPlane;
- offsetedPlane.Translate(OriginPlane.XAxis * i);
- Mesh OffsetMeshinY = GetPlaneForMeshSimulation(offsetedPlane);
-
- for (int j = 0; j < GridtTotalDistance; j++)
+ for (int j = 0; j <= divisions; j++)
{
- //Translate in X direction
- Mesh tempMesh = OffsetMeshinY.DuplicateMesh();
- tempMesh.Translate(OriginPlane.XAxis * j);
- resultGrid.Append(tempMesh);
+
+ double x = rect.Corner(0).X + (j * spacingX);
+ double y = rect.Corner(0).Y + (i * spacingY);
+ Point3d pt = new Point3d(x, y, rect.Corner(0).Z);
+ int index = (i * (divisions + 1)) + j;
+ points[index] = pt;
}
}
- return resultGrid;
+
+ return points;
}
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public static List GetGridPointsForSimulation(Plane OriginPlane, double GridtTotalDistance , double gridResolution)
- {
- var pts = new List();
- for (int i = 0; i < GridtTotalDistance; i++)
+ public static Point3d[] GetPointsAnalysis(Rectangle3d rect)
+ {
+
+ Point3d center = new Point3d(
+ (rect.Corner(0).X + rect.Corner(2).X) / 2,
+ (rect.Corner(0).Y + rect.Corner(2).Y) / 2,
+ rect.Corner(0).Z);
+
+ double desiredLength = 200;
+ double desiredWidth = 200;
+
+ Point3d newRectStart = new Point3d(center.X - desiredLength / 2, center.Y - desiredWidth / 2, center.Z);
+ Point3d newRectEnd = new Point3d(center.X + desiredLength / 2, center.Y + desiredWidth / 2, center.Z);
+ Rectangle3d newRect = new Rectangle3d(new Plane(center, Vector3d.ZAxis), newRectStart, newRectEnd);
+ int divisions = (int)Math.Sqrt(40000);
+ double width = newRect.Width;
+ double height = newRect.Height;
+ double spacingX = width / divisions;
+ double spacingY = height / divisions;
+
+ Point3d[] points = new Point3d[(divisions + 1) * (divisions + 1)]; // Adjust for one extra in each dimension
+
+ for (int i = 0; i <= divisions; i++)
{
-
- //Create plane in Y direction
- Plane offsetedPlane = OriginPlane;
- offsetedPlane.Translate(OriginPlane.YAxis * -i * gridResolution);
- Point3d pointToOffset = offsetedPlane.Origin - OriginPlane.YAxis * gridResolution / 2;
- //Create plane in Y direction
- //Point3d pointToOffset = OriginPlane.Origin - (OriginPlane.YAxis) * gridResolution / 2*i;
-
- for (int j = 0; j < GridtTotalDistance; j++)
+ for (int j = 0; j <= divisions; j++)
{
- //Translate in X direction
- Point3d tempPt = new Point3d(pointToOffset) + (OriginPlane.XAxis) * gridResolution / 2; // move the point to the right
- tempPt = tempPt + OriginPlane.XAxis * gridResolution * j; // move the point with the array
- //Point3d tempPt = new Point3d(pointToOffset) + OriginPlane.XAxis * gridResolution * j ;
- pts.Add(tempPt);
+ double x = newRect.Corner(0).X + (j * spacingX);
+ double y = newRect.Corner(0).Y + (i * spacingY);
+ points[i * (divisions + 1) + j] = new Point3d(x, y, newRect.Corner(0).Z); // Assuming flat Z
}
}
- return pts;
+ return points;
}
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public static Mesh GetResultMeshRowMajor(Plane OriginPlane, double GridFaceCount, double gridResolution)
+
+
+
+ public static Mesh CreateMeshFromGridPoints(Point3d[] points, int gridWidth, int gridHeight)
{
+ if (points == null || points.Length == 0)
+ throw new ArgumentException("Points array is null or empty", nameof(points));
+ if (points.Length != gridWidth * gridHeight)
+ throw new ArgumentException("Points array size does not match grid dimensions", nameof(points));
+
Mesh mesh = new Mesh();
- for (int i = 0; i < GridFaceCount; i++)
+ foreach (Point3d point in points)
{
+ mesh.Vertices.Add(point);
+ }
- //Create plane in Y direction
- Plane offsetedPlane = OriginPlane;
- offsetedPlane.Translate(OriginPlane.YAxis * -i * gridResolution);
- Mesh OffsetMeshinY = GetPlaneForMeshSimulation(offsetedPlane);
-
-
- for (int j = 0; j < GridFaceCount; j++)
+ // Create faces
+ for (int y = 0; y < gridHeight - 1; y++)
+ {
+ for (int x = 0; x < gridWidth - 1; x++)
{
- //Translate in X direction
- Mesh tempMesh = OffsetMeshinY.DuplicateMesh();
- tempMesh.Translate(OriginPlane.XAxis * j * gridResolution);
- mesh.Append(tempMesh);
+ int lowerLeft = y * gridWidth + x;
+ int lowerRight = y * gridWidth + x + 1;
+ int upperLeft = (y + 1) * gridWidth + x;
+ int upperRight = (y + 1) * gridWidth + x + 1;
+
+ mesh.Faces.AddFace(lowerLeft, lowerRight, upperRight, upperLeft);
}
}
+ mesh.Normals.ComputeNormals();
+ mesh.Compact();
+
return mesh;
}
- public static List ProjectPointsDownardOnMesh(IEnumerable pts, Mesh mesh)
- {
- Mesh[] meshArray = new Mesh[1];
- meshArray[0] = mesh;
- var projectedPts = Intersection.ProjectPointsToMeshes(meshArray, pts, Vector3d.ZAxis * -1, RhinoDoc.ActiveDoc.ModelAbsoluteTolerance).ToList();
- return projectedPts;
- }
- ///
- /// Drapes a mesh onto anthor assuming its higher
- ///
- ///
- ///
- ///
- public static Mesh DrapeMesh(Mesh MeshToDrape, Mesh TargetMesh)
- {
- var pointsToProject = MeshToDrape.Vertices.ToPoint3dArray();
- var projectdPts = ProjectPointsDownardOnMesh(pointsToProject, TargetMesh);
- Mesh drappedMesh = new Mesh();
- drappedMesh.Vertices.AddVertices(projectdPts);
- drappedMesh.Faces.AddFaces(MeshToDrape.Faces);
- return drappedMesh;
- }
}
}
diff --git a/Helpers/RayTracing.cs b/Helpers/RayTracing.cs
new file mode 100644
index 0000000..7bf748b
--- /dev/null
+++ b/Helpers/RayTracing.cs
@@ -0,0 +1,75 @@
+
+using Rhino.Geometry;
+using DHARTAPI.Geometry;
+using DHARTAPI.RayTracing;
+using System.Diagnostics;
+using System.Threading.Tasks;
+
+
+namespace Formicae.Helpers
+{
+ public class RayTracing
+ {
+ public static Point3d[] HitPoints(Point3d[] points, Rhino.Geometry.Mesh contextMesh)
+ {
+ Point3d[] points_ = new Point3d[points.Length];
+ MeshInfo _contextMesh = new MeshInfo(contextMesh.Faces.ToIntArray(true), contextMesh.Vertices.ToFloatArray());
+ EmbreeBVH bvh = new EmbreeBVH(_contextMesh);
+
+ var analysisPoints = new DHARTAPI.Vector3D[points.Length];
+ for (int i = 0; i < points.Length; i++)
+ analysisPoints[i] = new DHARTAPI.Vector3D((float)points[i].X, (float)points[i].Y, (float)points[i].Z);
+
+
+ var direction_vector = new DHARTAPI.Vector3D(0, 0, -1);
+
+
+ DHARTAPI.Vector3D[] hitPoints = new DHARTAPI.Vector3D[points.Length];
+
+ Parallel.For(0, points.Length, i =>
+ {
+ hitPoints[i] = EmbreeRaytracer.IntersectForPoint(bvh, analysisPoints[i], direction_vector);
+ points_[i] = new Point3d(hitPoints[i].x, hitPoints[i].y, hitPoints[i].z); ;
+ });
+
+ return points_;
+ }
+
+
+ public static double[] HitPointsHeight(Point3d[] points, Rhino.Geometry.Mesh contextMesh)
+ {
+ Point3d[] points_ = new Point3d[points.Length];
+ double[] height_ = new double[points.Length];
+
+ MeshInfo _contextMesh = new MeshInfo(contextMesh.Faces.ToIntArray(true), contextMesh.Vertices.ToFloatArray());
+ EmbreeBVH bvh = new EmbreeBVH(_contextMesh);
+
+
+ var analysisPoints = new DHARTAPI.Vector3D[points.Length];
+ for (int i = 0; i < points.Length; i++)
+ analysisPoints[i] = new DHARTAPI.Vector3D((float)points[i].X, (float)points[i].Y, (float)points[i].Z);
+
+
+ var direction_vector = new DHARTAPI.Vector3D(0, 0, -1);
+ DHARTAPI.Vector3D[] hitPoints = new DHARTAPI.Vector3D[points.Length];
+ Parallel.For(0, points.Length, i =>
+ {
+
+ hitPoints[i] = EmbreeRaytracer.IntersectForPoint(bvh, analysisPoints[i], direction_vector);
+ points_[i] = new Point3d(hitPoints[i].x, hitPoints[i].y, hitPoints[i].z);
+ height_[i] = hitPoints[i].z;
+ });
+
+ return height_;
+ }
+
+
+ public static void LogTime(ref Stopwatch sw, string text)
+ {
+ sw.Stop();
+ Rhino.RhinoApp.WriteLine($"{text}: {sw.ElapsedMilliseconds} ms");
+ sw.Restart();
+ }
+
+ }
+}
diff --git a/Supporting Grasshopper Scripts/forma-api.gh b/Supporting Grasshopper Scripts/forma-api.gh
index 6e82870..4f1aee3 100644
Binary files a/Supporting Grasshopper Scripts/forma-api.gh and b/Supporting Grasshopper Scripts/forma-api.gh differ
diff --git a/Supporting Grasshopper Scripts/rhino/sample.3dm b/Supporting Grasshopper Scripts/rhino/sample.3dm
index 2bd61c5..641bb20 100644
Binary files a/Supporting Grasshopper Scripts/rhino/sample.3dm and b/Supporting Grasshopper Scripts/rhino/sample.3dm differ
diff --git a/Supporting Grasshopper Scripts/rhino/sample.3dm.rhl b/Supporting Grasshopper Scripts/rhino/sample.3dm.rhl
deleted file mode 100644
index 834a06e..0000000
--- a/Supporting Grasshopper Scripts/rhino/sample.3dm.rhl
+++ /dev/null
@@ -1,3 +0,0 @@
-mm1039
-MM-C0D1E-028
-Wednesday, February 14, 2024
\ No newline at end of file
diff --git a/Supporting Grasshopper Scripts/input.json b/Supporting Grasshopper Scripts/sample/input.json
similarity index 100%
rename from Supporting Grasshopper Scripts/input.json
rename to Supporting Grasshopper Scripts/sample/input.json
diff --git a/api/sample/input_without_grids - simplified.json b/Supporting Grasshopper Scripts/sample/input_without_grids - simplified.json
similarity index 100%
rename from api/sample/input_without_grids - simplified.json
rename to Supporting Grasshopper Scripts/sample/input_without_grids - simplified.json
diff --git a/Types/Buildings.cs b/Types/Buildings.cs
deleted file mode 100644
index c829921..0000000
--- a/Types/Buildings.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using Grasshopper.Kernel;
-using Rhino.Geometry;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Formicae.Types
-{
- public class Buildings
- {
- public Brep buildingBreps;
-
- public List buildings;
-
- public Buildings() { }
-
- public Mesh previewMesh => GetBuildingsPreviewMesh();
-
- public Buildings(Brep brep)
- {
- buildingBreps = brep;
- }
-
- public Buildings(Listbreps)
- {
- Brep brep = new Brep();
- //foreach(var b in breps)
- //{
- // brep.Append(b);
- //}
- //buildingBreps = brep;
-
- this.buildings = breps;
- }
-
- public Mesh GetBuildingsPreviewMesh()
- {
- //Mesh mesh = new Mesh();
- //Mesh[] meshes = Mesh.CreateFromBrep(this.buildingBreps, MeshingParameters.FastRenderMesh);
- //foreach (var m in meshes)
- //{
- // mesh.Append(m);
- //}
- //return mesh;
-
- Mesh mesh = new Mesh();
- foreach ( var bldg in buildings )
- {
- mesh.Append(Mesh.CreateFromBrep(bldg, MeshingParameters.FastRenderMesh));
- }
-
- return mesh;
- }
-
-
- }
-}
diff --git a/Types/HeightMap.cs b/Types/HeightMap.cs
deleted file mode 100644
index e476bd2..0000000
--- a/Types/HeightMap.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using Grasshopper.Kernel;
-using Rhino.Geometry;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Rhino.Geometry.Intersect;
-using Formicae.Helpers;
-using System.Diagnostics;
-
-namespace Formicae.Types
-{
- public class HeightMap
- {
- public WindSimulationModel Model { get; set; }
-
- public HeightMap() { }
-
- public HeightMap(WindSimulationModel model)
- {
- this.Model = model;
- }
-
- public List HeightMapWithoutBuildings()
- {
- List heights = new List();
- List projectedPts = MeshHelper.ProjectPointsDownardOnMesh(Model.SimulationBox.LiftedPts, Model.GetModelMeshWithoutBuildings());
- foreach (Point3d p in projectedPts)
- {
- heights.Add(p.Z);
- }
- return heights;
- }
-
- public List HeightMapWithBuildings()
- {
- List heights = new List();
- List projectedPts = MeshHelper.ProjectPointsDownardOnMesh(Model.SimulationBox.LiftedPts, Model.GetModelMeshWithBuildings());
- foreach (Point3d p in projectedPts)
- {
- heights.Add(p.Z);
- }
- return heights;
- }
-
- public static List MapToDomain(List values, double domainMin, double domainMax)
- {
- List mappedValues = new List();
- double range = domainMax - domainMin;
-
- Stopwatch stopwatch = new Stopwatch();
- stopwatch.Start();
- foreach (var value in values)
- {
-
- double mappedValue = ((value - values.Min()) / (values.Max() - values.Min())) * range + domainMin;
- mappedValues.Add(mappedValue);
- }
-
- stopwatch.Stop();
- var profileSpan = stopwatch.Elapsed;
- Rhino.RhinoApp.WriteLine(profileSpan.ToString());
-
- return mappedValues;
- }
- }
-}
diff --git a/Types/SimulationBox.cs b/Types/SimulationBox.cs
deleted file mode 100644
index 22045bb..0000000
--- a/Types/SimulationBox.cs
+++ /dev/null
@@ -1,399 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Rhino.Geometry;
-using Grasshopper;
-using Grasshopper.Kernel;
-using Grasshopper.Kernel.Types;
-using GH_IO.Serialization;
-using Rhino;
-using System.Runtime.InteropServices.WindowsRuntime;
-using Formicae.Helpers;
-
-
-
-
-namespace Formicae.Types
-{
- ///
- /// A box that is used to orient and simulate the geometry
- ///
- public class SimulationBox : IGH_Goo,IGH_GeometricGoo,IGH_PreviewData
- {
-
- #region Properties
- public BoundingBox BoundingBox { get; set; }
- public Brep BoundingBoxBrep { get; set; }
-
-
- public bool IsValid => this.IsABox();
-
- public string IsValidWhyNot => throw new NotImplementedException();
-
- public string TypeName => "SimulationBox";
-
- public string TypeDescription => "A bounding box used to extract the simulation grid for wind analysis from Forma.";
-
- public BoundingBox Boundingbox => throw new NotImplementedException();
-
- public Guid ReferenceID { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
-
- public bool IsReferencedGeometry => this.BoundingBoxBrep != null;
-
- public bool IsGeometryLoaded => this.BoundingBoxBrep != null;
-
- public BoundingBox ClippingBox => BoundingBoxBrep?.GetBoundingBox(false) ?? BoundingBox.Unset;
-
- public double ResultMeshFaceCount = 200; // 300 in meters
-
- public double SimulationGridFaceCount = 500; // 750 in meters
-
- public double SimulationGridResolution = 1.5;
-
- public double BoxHeight => GetBoxHeight();
-
- public double SimulationGridDistance = 750;
-
- public double ResultGridDistance = 300;
-
- ///
- /// Points that can be used to calculate height always heigher than the Simulation Box Brep
- ///
- public List LiftedPts => GetSimulationPointsUp();
-
- ///
- /// Result mesh that is heigher than the Simulation Box, Can be used to drape
- ///
- public Mesh LiftedResultMesh => GetResultMeshUp();
-
-
- #endregion
-
- #region constructors
-
- public SimulationBox()
- {
-
- }
-
- ///
- /// Create a simulation bounding box based on BB.
- ///
- ///
- public SimulationBox(BoundingBox box)
- {
- this.BoundingBox = box;
- this.BoundingBoxBrep = box.ToBrep();
-
- }
-
- ///
- /// Createa a simulation bounding box based on a brep
- ///
- ///
- public SimulationBox (Brep box )
- {
- this.BoundingBoxBrep = box;
- }
-
- #endregion
-
- #region IGH_Goo
-
- public IGH_Goo Duplicate()
- {
- throw new NotImplementedException();
- }
-
- public IGH_GooProxy EmitProxy()
- {
- throw new NotImplementedException();
- }
-
- public bool CastFrom(object source)
- {
- throw new NotImplementedException();
- }
-
- public bool CastTo(out T target)
- {
- throw new NotImplementedException();
- }
-
- public object ScriptVariable()
- {
- throw new NotImplementedException();
- }
-
- public bool Write(GH_IWriter writer)
- {
- throw new NotImplementedException();
- }
-
- public bool Read(GH_IReader reader)
- {
- throw new NotImplementedException();
-
- }
-
- #endregion
-
- #region IGH_GeometricGoo
-
- public IGH_GeometricGoo DuplicateGeometry()
- {
- return this;
- }
-
- public BoundingBox GetBoundingBox(Transform xform)
- {
- throw new NotImplementedException();
- }
-
- public IGH_GeometricGoo Transform(Transform xform)
- {
- throw new NotImplementedException();
- }
-
- public IGH_GeometricGoo Morph(SpaceMorph xmorph)
- {
- throw new NotImplementedException();
- }
-
- public bool LoadGeometry()
- {
- throw new NotImplementedException();
- }
-
- public bool LoadGeometry(RhinoDoc doc)
- {
- throw new NotImplementedException();
- }
-
- public void ClearCaches()
- {
- throw new NotImplementedException();
- }
-
-
- #endregion
-
- #region IGH_PreviewData
-
- public void DrawViewportWires(GH_PreviewWireArgs args)
- {
- args.Pipeline.DrawDottedPolyline(GetResultMeshOutline(), System.Drawing.Color.Magenta,true);
- args.Pipeline.Draw3dText("Interest Area", System.Drawing.Color.Black, this.GetTopCenterPlane(), 3, "Arial");
-
- }
-
- public void DrawViewportMeshes(GH_PreviewMeshArgs args)
- {
- // throw new NotImplementedException();
- args.Pipeline.DrawDottedPolyline(GetResultMeshOutline(), System.Drawing.Color.Magenta, true);
- args.Pipeline.Draw3dText("Interest Area", System.Drawing.Color.Black, this.GetTopCenterPlane(), 3, "Arial");
- }
-
- #endregion
-
- #region Simulation grid
-
- ///
- /// Checks if the brep is a box based on the number of points
- ///
- /// True if the brep has only 8 points
- public bool IsABox()
- {
- return this.BoundingBoxBrep.Vertices.Count == 8;
- }
-
-
- ///
- /// Get an oriented plane at the lowest point of the bounding box
- ///
- ///
- public Plane GetGridPlaneForBotLeftCorner()
- {
- var Brepvertices = this.BoundingBoxBrep.Vertices;
- var BrepPts = Brepvertices.Select(a => a.Location).ToList();
- var LowestX = Brepvertices.Select(a => a.Location).Select(b => b.X).Min();
- var LowestY = Brepvertices.Select(a => a.Location).Select(b => b.Y).Min();
- var LowestZ = Brepvertices.Select(a => a.Location).Select(b => b.Z).Min();
- var MaxX = Brepvertices.Select(a => a.Location).Select(b => b.X).Max();
- var MaxY = Brepvertices.Select(a => a.Location).Select(b => b.Y).Max();
-
- Point3d Pa = new Point3d();
- Point3d Pb = new Point3d();
- Point3d Pc = new Point3d();
-
- foreach (var pt in BrepPts)
- {
- if (pt.X == LowestX && pt.Y == LowestY && pt.Z == LowestZ)
- {
- Pa = pt;
- }
- if (pt.X == MaxX && pt.Y == LowestY && pt.Z == LowestZ)
- {
- Pb = pt;
- }
- if (pt.X == LowestX && pt.Y == MaxY && pt.Z == LowestZ)
- {
- Pc = pt;
- }
- }
-
- Vector3d u = Pb - Pa;
- u.Unitize();
- Vector3d v = Pc - Pa;
- v.Unitize();
- Point3d origin = Pa;
-
- Plane plane = new Plane(origin, u, v);
- return plane;
-
- }
-
-
- ///
- /// Get the result plane to generate the grid for the result grid
- ///
- ///
- public Plane GetResultPlane()
- {
- var botleftcorner = GetGridPlaneForBotLeftCorner();
- //double leftoverspace = (this.SimulationGridFaceCount - this.ResultGridDistance) / 2;
- botleftcorner.Translate(botleftcorner.XAxis * 225);
- botleftcorner.Translate(botleftcorner.YAxis * 525);
- return botleftcorner;
- }
-
- ///
- /// Gets the simulation Plane to generate the simulaiton grid
- ///
- ///
- public Plane GetSimulationPlane()
- {
- var botleftcorner = GetGridPlaneForBotLeftCorner();
- botleftcorner.Translate(botleftcorner.YAxis * this.SimulationGridDistance);
- return botleftcorner;
- }
-
- /////
- ///// Gets the grid for the result to be colored
- /////
- /////
- //public Mesh GetResultMeshGrid ()
- //{
- // return MeshHelper.GetGridMeshForResult(GetResultPlane(), this.ResultGridDistance,1.5);
- //}
-
-
-
- ///
- /// Gets the grid for the result to be colored
- ///
- ///
- public Mesh GetResultMeshGrid()
- {
- return MeshHelper.GetResultMeshRowMajor(GetResultPlane(), this.ResultMeshFaceCount, this.SimulationGridResolution); //Same resolution
- }
-
- [Obsolete]
- ///
- /// TOO SLOW!! Get the grid for the simulation to calcualte height maps
- ///
- ///
- public Mesh GetSimulationMesh()
- {
- return MeshHelper.GetGridMeshForSimulation(GetSimulationPlane(), this.SimulationGridFaceCount);
- }
-
-
-
-
- public List GetSimulationPoints()
- {
- return MeshHelper.GetGridPointsForSimulation(GetSimulationPlane(),this.SimulationGridFaceCount, this.SimulationGridResolution);
- }
-
-
-
- #endregion
-
- #region Methods
-
- public override string ToString()
- {
- return $"A {TypeName} with a simulation grid of size {this.SimulationGridFaceCount} * {this.SimulationGridFaceCount} of resolution {this.SimulationGridResolution} (Distance between points)" +
- $"\nAt the center of which an interest area grid (resultGrid) of size {this.ResultMeshFaceCount} * {this.ResultMeshFaceCount} of resolution {this.SimulationGridResolution} ";
- }
-
- ///
- /// Gets the center point in the middle of the top Surface
- ///
- ///
- public Point3d GetTopCenterPoint()
- {
- return this.BoundingBox.GetCorners()[4] + this.BoundingBox.GetCorners()[7] / 2;
- }
-
- ///
- /// Gets the result mesh outline for Viz
- ///
- ///
- public Polyline GetResultMeshOutline()
- {
- var plane = GetGridPlaneForBotLeftCorner();
- plane.Origin = GetTopCenterPoint();
- Rectangle3d rect = new Rectangle3d(plane, this.ResultMeshFaceCount, this.ResultMeshFaceCount);
- return rect.ToPolyline();
- }
-
- ///
- /// Gets a plane in the center of the top surface
- ///
- ///
- public Plane GetTopCenterPlane()
- {
- var plane = GetGridPlaneForBotLeftCorner();
- plane.Origin = GetTopCenterPoint();
- return plane;
- }
-
- public double GetBoxHeight()
- {
- // return this.BoundingBox.GetCorners()[7].Z - this.BoundingBox.GetCorners()[0].Z;
- var Brepvertices = this.BoundingBoxBrep.Vertices;
- var LowestZ = Brepvertices.Select(a => a.Location).Select(b => b.Z).Min();
- var MaxZ = Brepvertices.Select(a => a.Location).Select(b => b.Z).Max();
- return MaxZ - LowestZ;
- }
-
-
- public List GetSimulationPointsUp()
- {
- var lowSimPts = GetSimulationPoints();
- List LiftedSimPts = new List();
- foreach (var simPt in lowSimPts)
- {
- LiftedSimPts.Add(simPt + Vector3d.ZAxis * this.BoxHeight * 1.1);
- }
- return LiftedSimPts;
- }
-
- ///
- /// Put the result mesh heigher than the Simulation Box
- ///
- ///
- public Mesh GetResultMeshUp()
- {
- Mesh mesh = GetResultMeshGrid();
- mesh.Translate(Vector3d.ZAxis * this.BoxHeight * 1.1);
- return mesh;
- }
-
- #endregion
- }
-}
diff --git a/Types/Terrain.cs b/Types/Terrain.cs
deleted file mode 100644
index 4407f17..0000000
--- a/Types/Terrain.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using Rhino.Geometry;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Formicae.Types
-{
- public class Terrain
- {
- public Mesh terrainMesh;
- public Terrain() { }
- public Terrain(Mesh mesh)
- {
- terrainMesh = mesh;
- }
-
- }
-}
diff --git a/Types/WindSimulationModel.cs b/Types/WindSimulationModel.cs
deleted file mode 100644
index a06553b..0000000
--- a/Types/WindSimulationModel.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-using Formicae.Helpers;
-using Rhino.Geometry;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Formicae.Types
-{
- public class WindSimulationModel
- {
- public WindSimulationModel() { }
-
- public Buildings Buildings { get; set; }
- public Terrain Terrain { get; set; }
- public SimulationBox SimulationBox { get; set; }
-
- public Mesh ModelWithBuildings => GetModelMeshWithBuildings();
- public Mesh ModelwithoutBuildings => GetModelMeshWithoutBuildings();
-
- public Mesh DrapedResultMesh => GetResultMeshDraped();
-
- public WindSimulationModel(Buildings blgs , Terrain terrain, SimulationBox simBox)
- {
- this.Buildings = blgs;
- this.Terrain = terrain;
- this.SimulationBox = simBox;
- }
-
- public Mesh GetModelMeshWithBuildings()
- {
- Mesh mesh = new Mesh();
- mesh.Append(Buildings.previewMesh);
- mesh.Append(Terrain.terrainMesh);
- return mesh;
- }
-
- public Mesh GetModelMeshWithoutBuildings()
- {
- Mesh mesh = new Mesh();
- mesh.Append(Terrain.terrainMesh);
- return mesh;
- }
-
- public Mesh GetResultMeshDraped()
- {
- return MeshHelper.DrapeMesh(this.SimulationBox.LiftedResultMesh, this.Terrain.terrainMesh);
- }
-
-
- }
-}