diff --git a/Robot_Adapter/CRUD/Create/Elements/Panels.cs b/Robot_Adapter/CRUD/Create/Elements/Panels.cs index 4a0d5690..b279d21e 100644 --- a/Robot_Adapter/CRUD/Create/Elements/Panels.cs +++ b/Robot_Adapter/CRUD/Create/Elements/Panels.cs @@ -29,6 +29,9 @@ using BHEG = BH.Engine.Geometry; using BH.oM.Structure.Constraints; using BH.Engine.Robot; +using BH.Engine.Spatial; +using BH.Engine.Geometry; +using System; namespace BH.Adapter.Robot { @@ -63,6 +66,27 @@ private bool CreateCollection(IEnumerable panels) robotPanel.SetLabel(IRobotLabelType.I_LT_PANEL_THICKNESS, panel.Property.Name); RobotSelection rPanelOpenings = m_RobotApplication.Project.Structure.Selections.Create(IRobotObjectType.I_OT_OBJECT); + + Vector bhNormal = panel.Normal(); + + //Tolerance is lower than any geometry tolerance used in the BHoM, hence defined here + double tolerance = 1e-16; + if (Math.Abs(bhNormal.Z) > tolerance) + { + if (bhNormal.Z < 0) + robotPanel.Main.Attribs.DirZ = 1; + } + else if (Math.Abs(bhNormal.X) > tolerance) + { + if (bhNormal.X < 0) + robotPanel.Main.Attribs.DirZ = 1; + } + else + { + if (bhNormal.Y < 0) + robotPanel.Main.Attribs.DirZ = 1; + } + foreach (Opening opening in panel.Openings) { List openingSubEdges = new List(); diff --git a/Robot_Adapter/CRUD/Read/Elements/Panels.cs b/Robot_Adapter/CRUD/Read/Elements/Panels.cs index 48376ad9..c1ceca18 100644 --- a/Robot_Adapter/CRUD/Read/Elements/Panels.cs +++ b/Robot_Adapter/CRUD/Read/Elements/Panels.cs @@ -20,6 +20,7 @@ * along with this code. If not, see . */ +using System; using System.Collections.Generic; using System.Linq; using BH.oM.Structure.Elements; @@ -29,6 +30,8 @@ using BH.oM.Geometry; using System.Collections; using BH.oM.Structure.MaterialFragments; +using BH.Engine.Spatial; +using BH.Engine.Geometry; namespace BH.Adapter.Robot { @@ -104,18 +107,37 @@ private List ReadPanels(IList ids = null) BH.oM.Geometry.Point coordPoint = BH.Engine.Geometry.Query.StartPoint(outline as dynamic); double x, y, z; robotPanel.Main.Attribs.GetDirX(out x, out y, out z); - BH.oM.Geometry.Vector coordXAxis = BH.Engine.Geometry.Create.Vector(x, y, z); - BH.oM.Geometry.Vector coordZAxis = BH.Engine.Geometry.Compute.FitPlane(outline as dynamic).Normal; - if (coordZAxis.Z == 0) + Vector coordXAxis = BH.Engine.Geometry.Create.Vector(x, y, z); + Vector coordZAxis = panel.Normal(); + + + bool flip = robotPanel.Main.Attribs.DirZ == 1; + double tolerance = 1e-16; + + if (Math.Abs(coordZAxis.Z) > tolerance) { - if ((coordZAxis.X > coordZAxis.Y && coordZAxis.X < 1) || (coordZAxis.Y > coordZAxis.X && coordZAxis.Y < 1)) - coordZAxis = BH.Engine.Geometry.Modify.Reverse(coordZAxis); + if (coordZAxis.Z < 0) + flip = !flip; + } + else if (Math.Abs(coordZAxis.X) > tolerance) + { + if (coordZAxis.X < 0) + flip = !flip; + } + else + { + if (coordZAxis.Y < 0) + flip = !flip; } - if (robotPanel.Main.Attribs.DirZ == 0) - coordZAxis = BH.Engine.Geometry.Modify.Reverse(coordZAxis); - BH.oM.Geometry.CoordinateSystem.Cartesian tempCoordSys = BH.Engine.Geometry.Create.CartesianCoordinateSystem(coordPoint, coordXAxis, coordZAxis); - BH.oM.Geometry.CoordinateSystem.Cartesian coordinateSystem = BH.Engine.Geometry.Create.CartesianCoordinateSystem(coordPoint, coordXAxis, tempCoordSys.Z); + if (flip) + { + coordZAxis = coordZAxis.Reverse(); + FlipOutline(panel); + } + + Vector coordYAxis = coordZAxis.CrossProduct(coordXAxis); + BH.oM.Geometry.CoordinateSystem.Cartesian coordinateSystem = BH.Engine.Geometry.Create.CartesianCoordinateSystem(coordPoint, coordXAxis, coordYAxis); panel.CustomData["CoordinateSystem"] = coordinateSystem; if (robotPanel.HasLabel(IRobotLabelType.I_LT_PANEL_THICKNESS) != 0) @@ -180,6 +202,18 @@ private List ReadPanels(IList ids = null) /***************************************************/ + //Method put here temporary until available in Spatial_Engine + private void FlipOutline(Panel panel) + { + foreach (Edge e in panel.ExternalEdges) + { + e.Curve = e.Curve.IFlip(); + } + panel.ExternalEdges.Reverse(); + } + + /***************************************************/ + //Method is stripped dpwn to only return data needed for extracting mesh results private List ReadPanelsLight(IList ids = null) { diff --git a/Robot_Adapter/CRUD/Read/Loads/AreaUniformlyDistributedLoad.cs b/Robot_Adapter/CRUD/Read/Loads/ControurLoads.cs similarity index 65% rename from Robot_Adapter/CRUD/Read/Loads/AreaUniformlyDistributedLoad.cs rename to Robot_Adapter/CRUD/Read/Loads/ControurLoads.cs index 8a370b45..b47a4263 100644 --- a/Robot_Adapter/CRUD/Read/Loads/AreaUniformlyDistributedLoad.cs +++ b/Robot_Adapter/CRUD/Read/Loads/ControurLoads.cs @@ -1,4 +1,4 @@ -/* +/* * This file is part of the Buildings and Habitats object Model (BHoM) * Copyright (c) 2015 - 2020, the respective contributors. All rights reserved. * @@ -29,6 +29,7 @@ using BH.oM.Base; using BH.oM.Structure.Loads; using BH.oM.Adapters.Robot; +using BH.Engine.Robot; namespace BH.Adapter.Robot @@ -39,19 +40,18 @@ public partial class RobotAdapter /**** Private Methods ****/ /***************************************************/ - private List ReadAreaUniformlyDistributedLoad(List ids = null) + private List ReadContourLoads(List ids = null) { + List bhomLoads = new List(); - Dictionary bhomPanel = ReadPanels().ToDictionary(x => System.Convert.ToInt32(x.CustomData[AdapterIdName])); Dictionary bhomLoadCases = new Dictionary(); List lCases = ReadLoadCase(); for (int i = 0; i < lCases.Count; i++) { - if (!bhomLoadCases.ContainsKey(lCases[i].Name)) + if (bhomLoadCases.ContainsKey(lCases[i].Name) == false) bhomLoadCases.Add(lCases[i].Name, lCases[i]); } - //Dictionary bhomLoadCases = ReadLoadCase().ToDictionary(x => x.Name); IRobotCaseCollection loadCollection = m_RobotApplication.Project.Structure.Cases.GetAll(); for (int i = 1; i <= loadCollection.Count; i++) @@ -65,33 +65,40 @@ private List ReadAreaUniformlyDistributedLoad(List ids = null) for (int j = 1; j <= sCase.Records.Count; j++) { IRobotLoadRecord loadRecord = sCase.Records.Get(j); - List elementIds = Convert.FromRobotSelectionString(loadRecord.Objects.ToText()); - List objects = new List(); - for (int k = 0; k < elementIds.Count; k++) - { - if (bhomPanel.ContainsKey(elementIds[k])) - objects.Add(bhomPanel[elementIds[k]]); - } switch (loadRecord.Type) { - case IRobotLoadRecordType.I_LRT_UNIFORM: - double fx = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_PX); - double fy = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_PY); - double fz = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_PZ); - double ls = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_LOCAL_SYSTEM); - double pj = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_PROJECTED); + case IRobotLoadRecordType.I_LRT_IN_CONTOUR: + double fx = loadRecord.GetValue((short)IRobotInContourRecordValues.I_ICRV_PX1); + double fy = loadRecord.GetValue((short)IRobotInContourRecordValues.I_ICRV_PY1); + double fz = loadRecord.GetValue((short)IRobotInContourRecordValues.I_ICRV_PZ1); + double nbPoints = loadRecord.GetValue((short)IRobotInContourRecordValues.I_ICRV_NPOINTS); + double localAxis = loadRecord.GetValue((short)IRobotInContourRecordValues.I_ICRV_LOCAL); + double projectedLoad = loadRecord.GetValue((short)IRobotInContourRecordValues.I_ICRV_PROJECTION); + RobotLoadRecordInContour contourRecord = loadRecord as RobotLoadRecordInContour; - AreaUniformlyDistributedLoad PanelPressure = new AreaUniformlyDistributedLoad + List contourPoints = new List(); + + for (int k = 0; k < nbPoints; k++) { - Pressure = new Vector { X = fx, Y = fy, Z = fz }, + double x, y, z; + + contourRecord.GetContourPoint(k + 1, out x, out y, out z); + contourPoints.Add(new Point { X = x, Y = y, Z = z }); + } + + contourPoints.Add(contourPoints.First()); + + oM.Structure.Loads.ContourLoad contourLoad = new oM.Structure.Loads.ContourLoad + { + Force = new Vector { X = fx, Y = fy, Z = fz }, + Contour = new Polyline { ControlPoints = contourPoints }, Loadcase = bhomLoadCases[sCase.Name], - Objects = new BHoMGroup() { Elements = objects.ToList() }, - Axis = ls == 0 ? LoadAxis.Global : LoadAxis.Local, - Projected = pj == 1 + Axis = localAxis == 1 ? LoadAxis.Local : LoadAxis.Global, + Projected = projectedLoad == 1 }; - bhomLoads.Add(PanelPressure); + bhomLoads.Add(contourLoad); break; } } @@ -101,6 +108,7 @@ private List ReadAreaUniformlyDistributedLoad(List ids = null) return bhomLoads; } + /***************************************************/ } diff --git a/Robot_Adapter/CRUD/Read/Loads/GeometricalLineLoads.cs b/Robot_Adapter/CRUD/Read/Loads/GeometricalLineLoads.cs new file mode 100644 index 00000000..a626b5bc --- /dev/null +++ b/Robot_Adapter/CRUD/Read/Loads/GeometricalLineLoads.cs @@ -0,0 +1,119 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2020, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using BH.oM.Structure.Elements; +using RobotOM; +using BH.oM.Geometry; +using BH.oM.Base; +using BH.oM.Structure.Loads; +using BH.oM.Adapters.Robot; +using BH.Engine.Robot; + + +namespace BH.Adapter.Robot +{ + public partial class RobotAdapter + { + /***************************************************/ + /**** Private Methods ****/ + /***************************************************/ + + private List ReadGeometricalLineLoads(List ids = null) + { + + List bhomLoads = new List(); + Dictionary bhomLoadCases = new Dictionary(); + List lCases = ReadLoadCase(); + for (int i = 0; i < lCases.Count; i++) + { + if (bhomLoadCases.ContainsKey(lCases[i].Name) == false) + bhomLoadCases.Add(lCases[i].Name, lCases[i]); + } + + IRobotCaseCollection loadCollection = m_RobotApplication.Project.Structure.Cases.GetAll(); + + for (int i = 1; i <= loadCollection.Count; i++) + { + IRobotCase lCase = loadCollection.Get(i) as IRobotCase; + if (lCase.Type == IRobotCaseType.I_CT_SIMPLE) + { + IRobotSimpleCase sCase = lCase as IRobotSimpleCase; + if (bhomLoadCases.ContainsKey(sCase.Name)) + { + for (int j = 1; j <= sCase.Records.Count; j++) + { + IRobotLoadRecord loadRecord = sCase.Records.Get(j); + + switch (loadRecord.Type) + { + case IRobotLoadRecordType.I_LRT_LINEAR_3D: + double fxa = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_PX1); + double fya = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_PY1); + double fza = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_PZ1); + double fxb = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_PX2); + double fyb = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_PY2); + double fzb = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_PZ2); + + double mxa = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MX1); + double mya = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MY1); + double mza = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MZ1); + double mxb = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MX2); + double myb = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MY2); + double mzb = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MZ2); + double local = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_LOCAL); + + IRobotLoadRecordLinear3D linRecord = loadRecord as IRobotLoadRecordLinear3D; + + double xa, ya, za, xb, yb, zb; + + linRecord.GetPoint(1, out xa, out ya, out za); + linRecord.GetPoint(2, out xb, out yb, out zb); + + oM.Structure.Loads.GeometricalLineLoad contourLoad = new oM.Structure.Loads.GeometricalLineLoad + { + ForceA = new Vector { X = fxa, Y = fya, Z = fza }, + ForceB = new Vector { X = fxb, Y = fyb, Z = fzb }, + MomentA = new Vector { X = mxa, Y = mya, Z = mza }, + MomentB = new Vector { X = mxb, Y = myb, Z = mzb }, + Location = new Line { Start = new Point { X = xa, Y = ya, Z = za }, End = new Point { X = xb, Y = yb, Z = zb } }, + Axis = local.FromRobotLoadAxis(), + Loadcase = bhomLoadCases[sCase.Name] + }; + bhomLoads.Add(contourLoad); + break; + } + } + } + } + } + return bhomLoads; + } + + + /***************************************************/ + + } + +} diff --git a/Robot_Adapter/CRUD/Read/Loads/Loads.cs b/Robot_Adapter/CRUD/Read/Loads/Loads.cs index 895b53ed..5dae7612 100644 --- a/Robot_Adapter/CRUD/Read/Loads/Loads.cs +++ b/Robot_Adapter/CRUD/Read/Loads/Loads.cs @@ -23,12 +23,15 @@ using System; using System.Collections.Generic; using System.Linq; +using System.ComponentModel; +using BH.oM.Reflection.Attributes; using BH.oM.Structure.Elements; using RobotOM; using BH.oM.Geometry; using BH.oM.Base; using BH.oM.Structure.Loads; using BH.oM.Adapters.Robot; +using BH.Engine.Robot; namespace BH.Adapter.Robot @@ -41,32 +44,78 @@ public partial class RobotAdapter private List ReadLoads(Type type, List ids = null) { - if (type == typeof(PointLoad)) - return ReadNodeLoads(ids); - else if (type == typeof(oM.Structure.Loads.ContourLoad) || type == typeof(oM.Adapters.Robot.ContourLoad)) - return ReadContourLoads(ids); - else if (type == typeof(oM.Structure.Loads.GeometricalLineLoad) || type == typeof(oM.Adapters.Robot.GeometricalLineLoad)) - return ReadGeometricalLineLoads(ids); - else if (type == typeof(oM.Structure.Loads.AreaUniformlyDistributedLoad)) - return ReadAreaUniformlyDistributedLoad(ids); - return new List(); + //Ensure previous object caches have been cleared + ClearLoadObjectCache(); + + List loads = new List(); + + //Element loads + if (type.IsAssignableFrom(typeof(AreaUniformlyDistributedLoad))) + loads.AddRange(ReadObjectLoads(record => record.FromRobotAreaUDL(), IRobotLoadRecordType.I_LRT_UNIFORM, ids)); + + if (type.IsAssignableFrom(typeof(AreaTemperatureLoad))) + loads.AddRange(ReadObjectLoads(record => record.FromRobotAreaTempLoad(), IRobotLoadRecordType.I_LRT_THERMAL_IN_3_POINTS, ids)); + + if (type.IsAssignableFrom(typeof(BarPointLoad))) + loads.AddRange(ReadObjectLoads(record => record.FromRobotBarPtLoad(), IRobotLoadRecordType.I_LRT_BAR_FORCE_CONCENTRATED, ids)); + + if (type.IsAssignableFrom(typeof(BarTemperatureLoad))) + loads.AddRange(ReadObjectLoads(record => record.FromRobotBarTempLoad(), IRobotLoadRecordType.I_LRT_BAR_THERMAL, ids)); + + if (type.IsAssignableFrom(typeof(BarUniformlyDistributedLoad))) + { + loads.AddRange(ReadObjectLoads(record => record.FromRobotBarUDLForce(), IRobotLoadRecordType.I_LRT_BAR_UNIFORM, ids)); + loads.AddRange(ReadObjectLoads(record => record.FromRobotBarUDLMoment(), IRobotLoadRecordType.I_LRT_BAR_MOMENT_DISTRIBUTED, ids)); + } + + if (type.IsAssignableFrom(typeof(BarVaryingDistributedLoad))) + { + var unFormatedBarVarLoads = ReadObjectLoads(record => record.FromRobotBarVarDistLoad(), IRobotLoadRecordType.I_LRT_BAR_TRAPEZOIDALE, ids); + //Fixes the issue with BarVaryingLoads having different definition in relation to DistanceFromB + loads.AddRange(unFormatedBarVarLoads.SelectMany(x => (x as BarVaryingDistributedLoad).FixVaryingLoadEndDistances())); + } + + if (type.IsAssignableFrom(typeof(GravityLoad))) + loads.AddRange(ReadObjectLoads(record => record.FromRobotGravityLoad(), IRobotLoadRecordType.I_LRT_DEAD, ids)); + + if (type.IsAssignableFrom(typeof(PointAcceleration))) + loads.AddRange(ReadObjectLoads(record => record.FromRobotPtAccel(), IRobotLoadRecordType.I_LRT_NODE_ACCELERATION, ids)); + + if (type.IsAssignableFrom(typeof(PointDisplacement))) + loads.AddRange(ReadObjectLoads(record => record.FromRobotPtDisp(), IRobotLoadRecordType.I_LRT_NODE_DISPLACEMENT, ids)); + + if (type.IsAssignableFrom(typeof(PointLoad))) + loads.AddRange(ReadObjectLoads(record => record.FromRobotPtLoad(), IRobotLoadRecordType.I_LRT_NODE_FORCE, ids)); + + if (type.IsAssignableFrom(typeof(PointVelocity))) + loads.AddRange(ReadObjectLoads(record => record.FromRobotPtVel(), IRobotLoadRecordType.I_LRT_NODE_VELOCITY, ids)); + + //Geometrical loads + if (type.IsAssignableFrom(typeof(oM.Structure.Loads.ContourLoad)) || type == typeof(oM.Adapters.Robot.ContourLoad)) + loads.AddRange(ReadContourLoads(ids)); + + if (type.IsAssignableFrom(typeof(oM.Structure.Loads.GeometricalLineLoad)) || type == typeof(oM.Adapters.Robot.GeometricalLineLoad)) + loads.AddRange(ReadGeometricalLineLoads(ids)); + + //Clean up the object cache + ClearLoadObjectCache(); + + return loads; } /***************************************************/ - private List ReadNodeLoads(List ids = null) + [Description("Reads load data for a particular type, filters out type based on the provided function and loadtype enum")] + [Input("convertMethod", "Method used for turning a load record into a BHoM load, setting all properties except for objects and case. For example `record => record.FromRobotAreaUDL()` for Areaload.")] + [Input("loadType","Robot loadtype enum corresponding to the type of load being pulled.")] + [Input("ids", "Not yet in use.")] + private List ReadObjectLoads(Func> convertMethod, IRobotLoadRecordType loadType, List ids = null) where T : IBHoMObject { + //Main method looping through all loadcases and extracting the picked up load type List bhomLoads = new List(); - Dictionary bhomNodes = ReadNodes().ToDictionary(x => System.Convert.ToInt32(x.CustomData[AdapterIdName])); - Dictionary bhomLoadCases = new Dictionary(); - List lCases = ReadLoadCase(); - for (int i = 0; i < lCases.Count; i++) - { - if (bhomLoadCases.ContainsKey(lCases[i].Name) == false) - bhomLoadCases.Add(lCases[i].Name, lCases[i]); - } + Dictionary loadObjects = ReadLoadCacheObjects().ToDictionary(x => System.Convert.ToInt32(x.CustomData[AdapterIdName])); + Dictionary bhomLoadCases = ReadLoadCase().ToDictionaryDistinctCheck(x => x.Name); - //Dictionary bhomLoadCases = ReadLoadCase().ToDictionary(x => x.Name); IRobotCaseCollection loadCollection = m_RobotApplication.Project.Structure.Cases.GetAll(); for (int i = 1; i <= loadCollection.Count; i++) @@ -80,32 +129,17 @@ private List ReadNodeLoads(List ids = null) for (int j = 1; j <= sCase.Records.Count; j++) { IRobotLoadRecord loadRecord = sCase.Records.Get(j); - List elementIds = Convert.FromRobotSelectionString(loadRecord.Objects.ToText()); - List objects = new List(); - for (int k = 0; k < elementIds.Count; k++) - { - if (bhomNodes.ContainsKey(elementIds[k])) - objects.Add(bhomNodes[elementIds[k]]); - } - switch (loadRecord.Type) + if (loadRecord.Type == loadType) { - case IRobotLoadRecordType.I_LRT_NODE_FORCE: - double fx = loadRecord.GetValue((short)IRobotNodeForceRecordValues.I_NFRV_FX); - double fy = loadRecord.GetValue((short)IRobotNodeForceRecordValues.I_NFRV_FY); - double fz = loadRecord.GetValue((short)IRobotNodeForceRecordValues.I_NFRV_FZ); - double mx = loadRecord.GetValue((short)IRobotNodeForceRecordValues.I_NFRV_CX); - double my = loadRecord.GetValue((short)IRobotNodeForceRecordValues.I_NFRV_CY); - double mz = loadRecord.GetValue((short)IRobotNodeForceRecordValues.I_NFRV_CZ); - PointLoad nodeForce = new PointLoad - { - Force = new Vector { X = fx, Y = fy, Z = fz }, - Moment = new Vector { X = mx, Y = my, Z = mz }, - Loadcase = bhomLoadCases[sCase.Name], - Objects = BH.Engine.Base.Create.BHoMGroup(objects) as BHoMGroup - }; - bhomLoads.Add(nodeForce); - break; + List objects = FilterLoadObjects(loadRecord, loadObjects); + Load load = convertMethod.Invoke(loadRecord); + if (load != null) + { + SetLoadGroup(load, objects.Cast()); + load.Loadcase = bhomLoadCases[sCase.Name]; + bhomLoads.Add(load); + } } } } @@ -116,152 +150,79 @@ private List ReadNodeLoads(List ids = null) /***************************************************/ - private List ReadContourLoads(List ids = null) + private static List FilterLoadObjects(IRobotLoadRecord loadRecord, Dictionary objects) { + //For case of entire structure, return all obejcts + if (loadRecord.Type == IRobotLoadRecordType.I_LRT_DEAD && loadRecord.GetValue((short)IRobotDeadRecordValues.I_DRV_ENTIRE_STRUCTURE) == 1) + { + return objects.Values.ToList(); + } - List bhomLoads = new List(); - Dictionary bhomLoadCases = new Dictionary(); - List lCases = ReadLoadCase(); - for (int i = 0; i < lCases.Count; i++) + List elementIds = Convert.FromRobotSelectionString(loadRecord.Objects.ToText()); + List loadObjects = new List(); + for (int k = 0; k < elementIds.Count; k++) { - if (bhomLoadCases.ContainsKey(lCases[i].Name) == false) - bhomLoadCases.Add(lCases[i].Name, lCases[i]); + if (objects.ContainsKey(elementIds[k])) + loadObjects.Add(objects[elementIds[k]]); } + return loadObjects; + } - IRobotCaseCollection loadCollection = m_RobotApplication.Project.Structure.Cases.GetAll(); + /***************************************************/ - for (int i = 1; i <= loadCollection.Count; i++) - { - IRobotCase lCase = loadCollection.Get(i) as IRobotCase; - if (lCase.Type == IRobotCaseType.I_CT_SIMPLE) - { - IRobotSimpleCase sCase = lCase as IRobotSimpleCase; - if (bhomLoadCases.ContainsKey(sCase.Name)) - { - for (int j = 1; j <= sCase.Records.Count; j++) - { - IRobotLoadRecord loadRecord = sCase.Records.Get(j); + private static void SetLoadGroup(Load load, IEnumerable objects) where T: IBHoMObject + { + BHoMGroup group = new BHoMGroup(); - switch (loadRecord.Type) - { - case IRobotLoadRecordType.I_LRT_IN_CONTOUR: - double fx = loadRecord.GetValue((short)IRobotInContourRecordValues.I_ICRV_PX1); - double fy = loadRecord.GetValue((short)IRobotInContourRecordValues.I_ICRV_PY1); - double fz = loadRecord.GetValue((short)IRobotInContourRecordValues.I_ICRV_PZ1); - double nbPoints = loadRecord.GetValue((short)IRobotInContourRecordValues.I_ICRV_NPOINTS); - double localAxis = loadRecord.GetValue((short)IRobotInContourRecordValues.I_ICRV_LOCAL); - double projectedLoad = loadRecord.GetValue((short)IRobotInContourRecordValues.I_ICRV_PROJECTION); - - RobotLoadRecordInContour contourRecord = loadRecord as RobotLoadRecordInContour; - - List contourPoints = new List(); - - for (int k = 0; k < nbPoints; k++) - { - double x, y, z; - - contourRecord.GetContourPoint(k + 1, out x, out y, out z); - contourPoints.Add(new Point { X = x, Y = y, Z = z }); - } - - contourPoints.Add(contourPoints.First()); - - oM.Structure.Loads.ContourLoad contourLoad = new oM.Structure.Loads.ContourLoad - { - Force = new Vector { X = fx, Y = fy, Z = fz }, - Contour = new Polyline { ControlPoints = contourPoints }, - Loadcase = bhomLoadCases[sCase.Name], - Axis = localAxis == 1 ? LoadAxis.Local : LoadAxis.Global, - Projected = projectedLoad == 1 - }; - bhomLoads.Add(contourLoad); - break; - } - } - } - } + foreach (IBHoMObject obj in objects) + { + if (obj is T) + group.Elements.Add((T)obj); } - return bhomLoads; + load.Objects = group; } - /***************************************************/ - - private List ReadGeometricalLineLoads(List ids = null) + private IEnumerable ReadLoadCacheObjects() { + //Reads elements of a particular type. - List bhomLoads = new List(); - Dictionary bhomLoadCases = new Dictionary(); - List lCases = ReadLoadCase(); - for (int i = 0; i < lCases.Count; i++) + Type type = typeof(T); + + if (type == typeof(BHoMObject)) { - if (bhomLoadCases.ContainsKey(lCases[i].Name) == false) - bhomLoadCases.Add(lCases[i].Name, lCases[i]); + var bars = ReadLoadCacheObjects(); + var panels = ReadLoadCacheObjects(); + return bars.Cast().Concat(panels.Cast()); } - IRobotCaseCollection loadCollection = m_RobotApplication.Project.Structure.Cases.GetAll(); + if (m_LoadObjectCache.ContainsKey(type)) + return m_LoadObjectCache[type].Cast(); - for (int i = 1; i <= loadCollection.Count; i++) - { - IRobotCase lCase = loadCollection.Get(i) as IRobotCase; - if (lCase.Type == IRobotCaseType.I_CT_SIMPLE) - { - IRobotSimpleCase sCase = lCase as IRobotSimpleCase; - if (bhomLoadCases.ContainsKey(sCase.Name)) - { - for (int j = 1; j <= sCase.Records.Count; j++) - { - IRobotLoadRecord loadRecord = sCase.Records.Get(j); + Type readType = type; + if (type == typeof(IAreaElement)) + readType = typeof(Panel); - switch (loadRecord.Type) - { - case IRobotLoadRecordType.I_LRT_LINEAR_3D: - double fxa = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_PX1); - double fya = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_PY1); - double fza = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_PZ1); - double fxb = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_PX2); - double fyb = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_PY2); - double fzb = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_PZ2); - - double mxa = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MX1); - double mya = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MY1); - double mza = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MZ1); - double mxb = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MX2); - double myb = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MY2); - double mzb = loadRecord.GetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MZ2); - - IRobotLoadRecordLinear3D linRecord = loadRecord as IRobotLoadRecordLinear3D; - - double xa, ya, za, xb, yb, zb; - - linRecord.GetPoint(1, out xa, out ya, out za); - linRecord.GetPoint(2, out xb, out yb, out zb); - - oM.Structure.Loads.GeometricalLineLoad contourLoad = new oM.Structure.Loads.GeometricalLineLoad - { - ForceA = new Vector { X = fxa, Y = fya, Z = fza }, - ForceB = new Vector { X = fxb, Y = fyb, Z = fzb }, - MomentA = new Vector { X = mxa, Y = mya, Z = mza }, - MomentB = new Vector { X = mxb, Y = myb, Z = mzb }, - Location = new Line { Start = new Point { X = xa, Y = ya, Z = za }, End = new Point { X = xb, Y = yb, Z = zb } }, - Loadcase = bhomLoadCases[sCase.Name] - }; - bhomLoads.Add(contourLoad); - break; - } - } - } - } - } - return bhomLoads; + IEnumerable readObjs = IRead(readType, null); + m_LoadObjectCache[type] = readObjs; + return readObjs.Cast(); } - /***************************************************/ + private void ClearLoadObjectCache() + { + m_LoadObjectCache = new Dictionary>(); + } + /***************************************************/ + /**** Private Fields ****/ + /***************************************************/ + private Dictionary> m_LoadObjectCache = new Dictionary>(); + + /***************************************************/ } } diff --git a/Robot_Adapter/Convert/FromRobot/Loads/AreaTemperatureLoad.cs b/Robot_Adapter/Convert/FromRobot/Loads/AreaTemperatureLoad.cs new file mode 100644 index 00000000..e7b0b333 --- /dev/null +++ b/Robot_Adapter/Convert/FromRobot/Loads/AreaTemperatureLoad.cs @@ -0,0 +1,62 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2020, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.Engine.Geometry; +using BH.oM.Structure.Loads; +using RobotOM; + +namespace BH.Adapter.Robot +{ + public static partial class Convert + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + public static AreaTemperatureLoad FromRobotAreaTempLoad(this IRobotLoadRecord loadRecord) + { + double t1 = loadRecord.GetValue((short)IRobotThermalIn3PointsRecordValues.I_3PRV_TX1); + double t2 = loadRecord.GetValue((short)IRobotThermalIn3PointsRecordValues.I_3PRV_TX2); + double t3 = loadRecord.GetValue((short)IRobotThermalIn3PointsRecordValues.I_3PRV_TX3); + + double g1 = loadRecord.GetValue((short)IRobotThermalIn3PointsRecordValues.I_3PRV_TZ1); + double g2 = loadRecord.GetValue((short)IRobotThermalIn3PointsRecordValues.I_3PRV_TZ2); + double g3 = loadRecord.GetValue((short)IRobotThermalIn3PointsRecordValues.I_3PRV_TZ3); + + if (t2 != 0 || t2 != 0 || t3 != 0 || g1 != 0 || g2 != 0 || g3 != 0) + { + Engine.Reflection.Compute.RecordWarning("The robot adapter currently only supports uniform temprature loads with no gradients. Area temprature load not pulled!"); + return null; + } + + return new AreaTemperatureLoad + { + TemperatureChange = t1, + }; + } + + /***************************************************/ + + + } +} + diff --git a/Robot_Adapter/Convert/FromRobot/Loads/AreaUniformlyDistributedLoad.cs b/Robot_Adapter/Convert/FromRobot/Loads/AreaUniformlyDistributedLoad.cs new file mode 100644 index 00000000..f53cbdde --- /dev/null +++ b/Robot_Adapter/Convert/FromRobot/Loads/AreaUniformlyDistributedLoad.cs @@ -0,0 +1,58 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2020, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Geometry; +using BH.oM.Structure.Loads; +using BH.oM.Structure.Elements; +using RobotOM; +using System.Collections.Generic; +using System.Linq; +using BH.oM.Base; + +namespace BH.Adapter.Robot +{ + public static partial class Convert + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + public static AreaUniformlyDistributedLoad FromRobotAreaUDL(this IRobotLoadRecord loadRecord) + { + double fx = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_PX); + double fy = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_PY); + double fz = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_PZ); + double local = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_LOCAL_SYSTEM); + double projected = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_PROJECTED); + + return new AreaUniformlyDistributedLoad + { + Pressure = new Vector { X = fx, Y = fy, Z = fz }, + Axis = local.FromRobotLoadAxis(), + Projected = projected.FromRobotProjected() + }; + } + + /***************************************************/ + } +} + diff --git a/Robot_Adapter/Convert/FromRobot/Loads/BarPointLoad.cs b/Robot_Adapter/Convert/FromRobot/Loads/BarPointLoad.cs new file mode 100644 index 00000000..347818ba --- /dev/null +++ b/Robot_Adapter/Convert/FromRobot/Loads/BarPointLoad.cs @@ -0,0 +1,65 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2020, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Geometry; +using BH.oM.Structure.Loads; +using RobotOM; + +namespace BH.Adapter.Robot +{ + public static partial class Convert + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + public static BarPointLoad FromRobotBarPtLoad(this IRobotLoadRecord loadRecord) + { + double fx = loadRecord.GetValue((short)IRobotBarForceConcentrateRecordValues.I_BFCRV_FX); + double fy = loadRecord.GetValue((short)IRobotBarForceConcentrateRecordValues.I_BFCRV_FY); + double fz = loadRecord.GetValue((short)IRobotBarForceConcentrateRecordValues.I_BFCRV_FZ); + double mx = loadRecord.GetValue((short)IRobotBarForceConcentrateRecordValues.I_BFCRV_CX); + double my = loadRecord.GetValue((short)IRobotBarForceConcentrateRecordValues.I_BFCRV_CY); + double mz = loadRecord.GetValue((short)IRobotBarForceConcentrateRecordValues.I_BFCRV_CZ); + double distA = loadRecord.GetValue((short)IRobotBarForceConcentrateRecordValues.I_BFCRV_X); + double rel = loadRecord.GetValue((short)IRobotBarForceConcentrateRecordValues.I_BFCRV_REL); + double local = loadRecord.GetValue((short)IRobotBarForceConcentrateRecordValues.I_BFCRV_LOC); + + if (rel != 0) + { + Engine.Reflection.Compute.RecordWarning("Currently no support for BarPointLoads with relative distance from ends"); + return null; + } + + return new BarPointLoad + { + Force = new Vector { X = fx, Y = fy, Z = fz }, + Moment = new Vector { X = mx, Y = my, Z = mz }, + DistanceFromA = distA, + Axis = local.FromRobotLoadAxis() + }; + } + + /***************************************************/ + } +} + diff --git a/Robot_Adapter/Convert/FromRobot/Loads/BarTemperatureLoad.cs b/Robot_Adapter/Convert/FromRobot/Loads/BarTemperatureLoad.cs new file mode 100644 index 00000000..ee4ff727 --- /dev/null +++ b/Robot_Adapter/Convert/FromRobot/Loads/BarTemperatureLoad.cs @@ -0,0 +1,55 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2020, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Structure.Loads; +using RobotOM; + +namespace BH.Adapter.Robot +{ + public static partial class Convert + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + public static BarTemperatureLoad FromRobotBarTempLoad(this IRobotLoadRecord loadRecord) + { + double t = loadRecord.GetValue((short)IRobotBarThermalRecordValues.I_BTRV_TX); + double ty = loadRecord.GetValue((short)IRobotBarThermalRecordValues.I_BTRV_TY); + double tz = loadRecord.GetValue((short)IRobotBarThermalRecordValues.I_BTRV_TZ); + + if (ty != 0 || tz != 0) + { + Engine.Reflection.Compute.RecordWarning("Temparature loads in Robot with non axial components found. BHoM Temprature loads only support uniform temprature change, only this value will be extracted."); + } + + return new BarTemperatureLoad + { + TemperatureChange = t + }; + + } + + /***************************************************/ + } +} + diff --git a/Robot_Adapter/Convert/FromRobot/Loads/BarUniformlyDistributedLoad.cs b/Robot_Adapter/Convert/FromRobot/Loads/BarUniformlyDistributedLoad.cs new file mode 100644 index 00000000..ce5099ba --- /dev/null +++ b/Robot_Adapter/Convert/FromRobot/Loads/BarUniformlyDistributedLoad.cs @@ -0,0 +1,72 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2020, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Geometry; +using BH.oM.Structure.Loads; +using RobotOM; + +namespace BH.Adapter.Robot +{ + public static partial class Convert + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + public static BarUniformlyDistributedLoad FromRobotBarUDLForce(this IRobotLoadRecord loadRecord) + { + double fx = loadRecord.GetValue((short)IRobotBarUniformRecordValues.I_BURV_PX); + double fy = loadRecord.GetValue((short)IRobotBarUniformRecordValues.I_BURV_PY); + double fz = loadRecord.GetValue((short)IRobotBarUniformRecordValues.I_BURV_PZ); + double local = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_LOCAL_SYSTEM); + double proj = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_PROJECTED); + + return new BarUniformlyDistributedLoad + { + Force = new Vector { X = fx, Y = fy, Z = fz }, + Projected = proj.FromRobotProjected(), + Axis = local.FromRobotLoadAxis() + }; + } + + /***************************************************/ + + public static BarUniformlyDistributedLoad FromRobotBarUDLMoment(this IRobotLoadRecord loadRecord) + { + double mx = loadRecord.GetValue((short)IRobotBarMomentDistributedRecordValues.I_BMDRV_MX); + double my = loadRecord.GetValue((short)IRobotBarMomentDistributedRecordValues.I_BMDRV_MY); + double mz = loadRecord.GetValue((short)IRobotBarMomentDistributedRecordValues.I_BMDRV_MZ); + double local = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_LOCAL_SYSTEM); + double proj = loadRecord.GetValue((short)IRobotUniformRecordValues.I_URV_PROJECTED); + + return new BarUniformlyDistributedLoad + { + Moment = new Vector { X = mx, Y = my, Z = mz }, + Projected = proj.FromRobotProjected(), + Axis = local.FromRobotLoadAxis() + }; + } + + /***************************************************/ + } +} + diff --git a/Robot_Adapter/Convert/FromRobot/Loads/BarVaryingDistributedLoad.cs b/Robot_Adapter/Convert/FromRobot/Loads/BarVaryingDistributedLoad.cs new file mode 100644 index 00000000..3ea9a0f5 --- /dev/null +++ b/Robot_Adapter/Convert/FromRobot/Loads/BarVaryingDistributedLoad.cs @@ -0,0 +1,99 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2020, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Geometry; +using BH.oM.Structure.Loads; +using System.Collections.Generic; +using BH.Engine.External.Robot; +using BH.oM.Base; +using BH.oM.Structure.Elements; +using System; +using System.Linq; +using RobotOM; + +namespace BH.Adapter.Robot +{ + public static partial class Convert + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + public static BarVaryingDistributedLoad FromRobotBarVarDistLoad(this IRobotLoadRecord loadRecord) + { + double fax = loadRecord.GetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PX1); + double fay = loadRecord.GetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PY1); + double faz = loadRecord.GetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PZ1); + double distA = loadRecord.GetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_X1); + double fbx = loadRecord.GetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PX2); + double fby = loadRecord.GetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PY2); + double fbz = loadRecord.GetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PZ2); + double distB = loadRecord.GetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_X2); + + double rel = loadRecord.GetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_RELATIVE); + double axis = loadRecord.GetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_LOCAL); + double proj = loadRecord.GetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PROJECTION); + + if (rel != 0) + { + Engine.Reflection.Compute.RecordWarning("Currently no support for BarVaryingDistributedLoad with relative distance from ends"); + return null; + } + + return new BarVaryingDistributedLoad + { + ForceA = new Vector { X = fax, Y = fay, Z = faz }, + ForceB = new Vector { X = fbx, Y = fby, Z = fbz }, + DistanceFromA = distA, + DistanceFromB = distB, + Axis = axis.FromRobotLoadAxis(), + Projected = proj.FromRobotProjected() + }; + } + + /***************************************************/ + + //Fixing the issue with Robot defining the second point in the BarVaryingLoad in relation to the start, while BHoM defines it in relation to the end + public static List FixVaryingLoadEndDistances(this BarVaryingDistributedLoad load) + { + List loads = new List(); + + int counter = 0; + foreach (var lengthGroup in load.Objects.Elements.GroupBarsByLength(0.001)) + { + BarVaryingDistributedLoad clone = load.GetShallowClone() as BarVaryingDistributedLoad; + clone.DistanceFromB = lengthGroup.Key - clone.DistanceFromB; //Set distance from B to be from end node instead of start + clone.Objects = new BHoMGroup() { Elements = lengthGroup.Value }; + loads.Add(clone); + counter++; + } + + if (counter > 1) + Engine.Reflection.Compute.RecordNote("Varying BarLoads in BHoM measures distance from start for the first point and from end for the second point, whilst Robot measures only from start node. To accommodate this, load pulled from Robot has been split up in multiple loads, grouped by the length of the Bars the load is applied to."); + + return loads; + } + + /***************************************************/ + } +} + diff --git a/Robot_oM/Enums/ObjectProperties.cs b/Robot_Adapter/Convert/FromRobot/Loads/GravityLoad.cs similarity index 58% rename from Robot_oM/Enums/ObjectProperties.cs rename to Robot_Adapter/Convert/FromRobot/Loads/GravityLoad.cs index 8e97ea0a..d183d3ef 100644 --- a/Robot_oM/Enums/ObjectProperties.cs +++ b/Robot_Adapter/Convert/FromRobot/Loads/GravityLoad.cs @@ -1,4 +1,4 @@ -/* +/* * This file is part of the Buildings and Habitats object Model (BHoM) * Copyright (c) 2015 - 2020, the respective contributors. All rights reserved. * @@ -20,19 +20,33 @@ * along with this code. If not, see . */ -namespace BH.oM.Adapters.Robot -{ - /***************************************************/ - /**** Public Enums ****/ - /***************************************************/ +using BH.oM.Geometry; +using BH.oM.Structure.Loads; +using RobotOM; - public enum ObjectProperties +namespace BH.Adapter.Robot +{ + public static partial class Convert { - Name, - Number - } + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + public static GravityLoad FromRobotGravityLoad(this IRobotLoadRecord loadRecord) + { + double dx = loadRecord.GetValue((short)IRobotDeadRecordValues.I_DRV_X); + double dy = loadRecord.GetValue((short)IRobotDeadRecordValues.I_DRV_Y); + double dz = loadRecord.GetValue((short)IRobotDeadRecordValues.I_DRV_Z); + double coef = loadRecord.GetValue((short)IRobotDeadRecordValues.I_DRV_COEFF); - /***************************************************/ - + return new GravityLoad + { + GravityDirection = new Vector { X = dx * coef, Y = dy * coef, Z = dz * coef } + }; + } + + /***************************************************/ + + } } diff --git a/Robot_Adapter/Convert/FromRobot/Loads/Load.cs b/Robot_Adapter/Convert/FromRobot/Loads/Load.cs index 94f428b9..c2633ac4 100644 --- a/Robot_Adapter/Convert/FromRobot/Loads/Load.cs +++ b/Robot_Adapter/Convert/FromRobot/Loads/Load.cs @@ -56,6 +56,21 @@ public static LoadNature FromRobot(IRobotCaseNature nature) return LoadNature.Other; } } + + /***************************************************/ + + public static LoadAxis FromRobotLoadAxis(this double axisValue) + { + return axisValue == 1 ? LoadAxis.Local : LoadAxis.Global; + } + + /***************************************************/ + + public static bool FromRobotProjected(this double isProjectedValue) + { + return isProjectedValue == 1; + } + /***************************************************/ } } diff --git a/Robot_oM/Enums/NodeProperties.cs b/Robot_Adapter/Convert/FromRobot/Loads/PointAcceleration.cs similarity index 60% rename from Robot_oM/Enums/NodeProperties.cs rename to Robot_Adapter/Convert/FromRobot/Loads/PointAcceleration.cs index 3d171cca..0d5b6c1c 100644 --- a/Robot_oM/Enums/NodeProperties.cs +++ b/Robot_Adapter/Convert/FromRobot/Loads/PointAcceleration.cs @@ -1,4 +1,4 @@ -/* +/* * This file is part of the Buildings and Habitats object Model (BHoM) * Copyright (c) 2015 - 2020, the respective contributors. All rights reserved. * @@ -20,18 +20,32 @@ * along with this code. If not, see . */ -namespace BH.oM.Adapters.Robot -{ - /***************************************************/ - /**** Public Enums ****/ - /***************************************************/ +using BH.oM.Geometry; +using BH.oM.Structure.Loads; +using RobotOM; - public enum NodeProperties +namespace BH.Adapter.Robot +{ + public static partial class Convert { - CoordinateSystem - } + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ - /***************************************************/ + public static PointAcceleration FromRobotPtAccel(this IRobotLoadRecord loadRecord) + { + double ax = loadRecord.GetValue((short)IRobotNodeAccelerationRecordValues.I_NACRV_UX); + double ay = loadRecord.GetValue((short)IRobotNodeAccelerationRecordValues.I_NACRV_UY); + double az = loadRecord.GetValue((short)IRobotNodeAccelerationRecordValues.I_NACRV_UZ); + return new PointAcceleration + { + TranslationalAcceleration = new Vector { X = ax, Y = ay, Z = az } + }; + + } + + /***************************************************/ + } } diff --git a/Robot_Adapter/Convert/FromRobot/Loads/PointDisplacement.cs b/Robot_Adapter/Convert/FromRobot/Loads/PointDisplacement.cs new file mode 100644 index 00000000..3ee9b3db --- /dev/null +++ b/Robot_Adapter/Convert/FromRobot/Loads/PointDisplacement.cs @@ -0,0 +1,54 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2020, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Geometry; +using BH.oM.Structure.Loads; +using RobotOM; + +namespace BH.Adapter.Robot +{ + public static partial class Convert + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + public static PointDisplacement FromRobotPtDisp(this IRobotLoadRecord loadRecord) + { + double ux = loadRecord.GetValue((short)IRobotNodeDisplacementRecordValues.I_NDRV_UX); + double uy = loadRecord.GetValue((short)IRobotNodeDisplacementRecordValues.I_NDRV_UY); + double uz = loadRecord.GetValue((short)IRobotNodeDisplacementRecordValues.I_NDRV_UZ); + double rx = loadRecord.GetValue((short)IRobotNodeDisplacementRecordValues.I_NDRV_RX); + double ry = loadRecord.GetValue((short)IRobotNodeDisplacementRecordValues.I_NDRV_RY); + double rz = loadRecord.GetValue((short)IRobotNodeDisplacementRecordValues.I_NDRV_RZ); + + return new PointDisplacement + { + Translation = new Vector { X = ux, Y = uy, Z = uz }, + Rotation = new Vector { X = rx, Y = ry, Z = rz } + }; + } + + /***************************************************/ + } +} + diff --git a/Robot_Adapter/Convert/FromRobot/Loads/PointLoad.cs b/Robot_Adapter/Convert/FromRobot/Loads/PointLoad.cs new file mode 100644 index 00000000..42d66771 --- /dev/null +++ b/Robot_Adapter/Convert/FromRobot/Loads/PointLoad.cs @@ -0,0 +1,54 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2020, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using BH.oM.Geometry; +using BH.oM.Structure.Loads; +using RobotOM; + +namespace BH.Adapter.Robot +{ + public static partial class Convert + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + public static PointLoad FromRobotPtLoad(this IRobotLoadRecord loadRecord) + { + double fx = loadRecord.GetValue((short)IRobotNodeForceRecordValues.I_NFRV_FX); + double fy = loadRecord.GetValue((short)IRobotNodeForceRecordValues.I_NFRV_FY); + double fz = loadRecord.GetValue((short)IRobotNodeForceRecordValues.I_NFRV_FZ); + double mx = loadRecord.GetValue((short)IRobotNodeForceRecordValues.I_NFRV_CX); + double my = loadRecord.GetValue((short)IRobotNodeForceRecordValues.I_NFRV_CY); + double mz = loadRecord.GetValue((short)IRobotNodeForceRecordValues.I_NFRV_CZ); + + return new PointLoad + { + Force = new Vector { X = fx, Y = fy, Z = fz }, + Moment = new Vector { X = mx, Y = my, Z = mz } + }; + } + + /***************************************************/ + } +} + diff --git a/Robot_oM/Enums/Commands.cs b/Robot_Adapter/Convert/FromRobot/Loads/PointVelocity.cs similarity index 61% rename from Robot_oM/Enums/Commands.cs rename to Robot_Adapter/Convert/FromRobot/Loads/PointVelocity.cs index 95040579..b7aaeaa5 100644 --- a/Robot_oM/Enums/Commands.cs +++ b/Robot_Adapter/Convert/FromRobot/Loads/PointVelocity.cs @@ -1,4 +1,4 @@ -/* +/* * This file is part of the Buildings and Habitats object Model (BHoM) * Copyright (c) 2015 - 2020, the respective contributors. All rights reserved. * @@ -20,18 +20,31 @@ * along with this code. If not, see . */ -namespace BH.oM.Adapters.Robot -{ - /***************************************************/ - /**** Public Enums ****/ - /***************************************************/ +using BH.oM.Geometry; +using BH.oM.Structure.Loads; +using RobotOM; - public enum Commands +namespace BH.Adapter.Robot +{ + public static partial class Convert { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ - } + public static PointVelocity FromRobotPtVel(this IRobotLoadRecord loadRecord) + { + double vx = loadRecord.GetValue((short)IRobotNodeVelocityRecordValues.I_NVRV_UX); + double vy = loadRecord.GetValue((short)IRobotNodeVelocityRecordValues.I_NVRV_UY); + double vz = loadRecord.GetValue((short)IRobotNodeVelocityRecordValues.I_NVRV_UZ); - /***************************************************/ + return new PointVelocity + { + TranslationalVelocity = new Vector { X = vx, Y = vy, Z = vz } + }; + } + /***************************************************/ + } } diff --git a/Robot_Adapter/Convert/ToRobot/Groups and Lists/Group.cs b/Robot_Adapter/Convert/ToRobot/Groups and Lists/Group.cs index 55c6bc50..cefe5d23 100644 --- a/Robot_Adapter/Convert/ToRobot/Groups and Lists/Group.cs +++ b/Robot_Adapter/Convert/ToRobot/Groups and Lists/Group.cs @@ -56,17 +56,25 @@ public static IRobotObjectType RobotObjectType(Type type) public static string CreateIdListOrGroupName(this Load load, RobotGroupServer rServer) where T : IBHoMObject { //For a named group, appy loads to the group name - if (!string.IsNullOrWhiteSpace(load.Objects.Name)) - { - IRobotObjectType rType = RobotObjectType(load.Objects.GetType()); - int gIndex = rServer.Find(rType, load.Objects.Name); - RobotGroup rGroup = rServer.Get(rType, gIndex); - return rGroup.SelList; - } + //Feature disabled until a more Robust group handling is in place in Robot_Toolkit + //if (!string.IsNullOrWhiteSpace(load.Objects.Name)) + //{ + // IRobotObjectType rType = RobotObjectType(load.Objects.GetType()); + // int gIndex = rServer.Find(rType, load.Objects.Name); + // RobotGroup rGroup = rServer.Get(rType, gIndex); + // return rGroup.SelList; + //} //Otherwise apply to the corresponding indecies - return load.Objects.Elements.Select(x => int.Parse(x.CustomData[AdapterID].ToString())).ToRobotSelectionString(); + return load.Objects.Elements.ToRobotSelectionString(); + + } + /***************************************************/ + + public static string ToRobotSelectionString(this IEnumerable objects) where T : IBHoMObject + { + return objects.Select(x => int.Parse(x.CustomData[AdapterID].ToString())).ToRobotSelectionString(); } /***************************************************/ diff --git a/Robot_oM/Enums/BarProperties.cs b/Robot_Adapter/Convert/ToRobot/Loads/AreaTemperatureLoad.cs similarity index 56% rename from Robot_oM/Enums/BarProperties.cs rename to Robot_Adapter/Convert/ToRobot/Loads/AreaTemperatureLoad.cs index 4a262fa8..1d9ffcc4 100644 --- a/Robot_oM/Enums/BarProperties.cs +++ b/Robot_Adapter/Convert/ToRobot/Loads/AreaTemperatureLoad.cs @@ -20,20 +20,32 @@ * along with this code. If not, see . */ -namespace BH.oM.Adapters.Robot +using BH.Engine.Geometry; +using BH.oM.Structure.Loads; +using RobotOM; + +namespace BH.Adapter.Robot { - /***************************************************/ - /**** Public Enums ****/ - /***************************************************/ - - public enum BarProperties + public static partial class Convert { - FramingElementDesignProperties, - StructureObjectType - } + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ - /***************************************************/ - + public static void ToRobot(this AreaTemperatureLoad load, RobotSimpleCase sCase, RobotGroupServer rGroupServer) + { + if (load.TemperatureChange == 0) + { + Engine.Reflection.Compute.RecordWarning("Zero temperature loads are not pushed to Robot"); + return; + } + IRobotLoadRecordThermalIn3Points loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_THERMAL_IN_3_POINTS) as IRobotLoadRecordThermalIn3Points; + loadRecord.Objects.FromText(load.CreateIdListOrGroupName(rGroupServer)); + loadRecord.SetValue((short)IRobotThermalIn3PointsRecordValues.I_3PRV_TX1, load.TemperatureChange); + + } + /***************************************************/ + } } diff --git a/Robot_Adapter/Convert/ToRobot/Loads/AreaUniformlyDistributedLoad.cs b/Robot_Adapter/Convert/ToRobot/Loads/AreaUniformlyDistributedLoad.cs index f0bb7f47..c7823486 100644 --- a/Robot_Adapter/Convert/ToRobot/Loads/AreaUniformlyDistributedLoad.cs +++ b/Robot_Adapter/Convert/ToRobot/Loads/AreaUniformlyDistributedLoad.cs @@ -36,7 +36,7 @@ public static void ToRobot(this AreaUniformlyDistributedLoad load, RobotSimpleCa { if (load.Pressure.Length() == 0) { - Engine.Reflection.Compute.RecordError("Zero pressures are not pushed to Robot"); + Engine.Reflection.Compute.RecordWarning("Zero pressures are not pushed to Robot"); return; } IRobotLoadRecord loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_UNIFORM); diff --git a/Robot_Adapter/Convert/ToRobot/Loads/BarPointLoad.cs b/Robot_Adapter/Convert/ToRobot/Loads/BarPointLoad.cs index caafd8ab..1bad31b5 100644 --- a/Robot_Adapter/Convert/ToRobot/Loads/BarPointLoad.cs +++ b/Robot_Adapter/Convert/ToRobot/Loads/BarPointLoad.cs @@ -36,7 +36,7 @@ public static void ToRobot(this BarPointLoad load, RobotSimpleCase sCase, RobotG { if (load.Force.Length() == 0 && load.Moment.Length() == 0) { - Engine.Reflection.Compute.RecordError("Zero forces and moments are not pushed to Robot"); + Engine.Reflection.Compute.RecordWarning("Zero forces and moments are not pushed to Robot"); return; } IRobotLoadRecord loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_BAR_FORCE_CONCENTRATED); @@ -49,6 +49,10 @@ public static void ToRobot(this BarPointLoad load, RobotSimpleCase sCase, RobotG loadRecord.SetValue((short)IRobotBarForceConcentrateRecordValues.I_BFCRV_CZ, load.Moment.Z); loadRecord.SetValue((short)IRobotBarForceConcentrateRecordValues.I_BFCRV_X, load.DistanceFromA); loadRecord.SetValue((short)IRobotBarForceConcentrateRecordValues.I_BFCRV_REL, 0); + + if (load.Axis == LoadAxis.Local) + loadRecord.SetValue((short)IRobotBarForceConcentrateRecordValues.I_BFCRV_LOC, 1); + } /***************************************************/ diff --git a/Robot_Adapter/Convert/ToRobot/Loads/BarTemperatureLoad.cs b/Robot_Adapter/Convert/ToRobot/Loads/BarTemperatureLoad.cs index b0ee9ed6..d716482a 100644 --- a/Robot_Adapter/Convert/ToRobot/Loads/BarTemperatureLoad.cs +++ b/Robot_Adapter/Convert/ToRobot/Loads/BarTemperatureLoad.cs @@ -35,7 +35,7 @@ public static void ToRobot(this BarTemperatureLoad load, RobotSimpleCase sCase, { if (load.TemperatureChange == 0) { - Engine.Reflection.Compute.RecordError("Zero thermal loads are not pushed to Robot"); + Engine.Reflection.Compute.RecordWarning("Zero thermal loads are not pushed to Robot"); return; } IRobotLoadRecord loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_BAR_THERMAL); diff --git a/Robot_Adapter/Convert/ToRobot/Loads/BarUniformlyDistributedLoad.cs b/Robot_Adapter/Convert/ToRobot/Loads/BarUniformlyDistributedLoad.cs index f77c0343..d606f1c4 100644 --- a/Robot_Adapter/Convert/ToRobot/Loads/BarUniformlyDistributedLoad.cs +++ b/Robot_Adapter/Convert/ToRobot/Loads/BarUniformlyDistributedLoad.cs @@ -36,7 +36,7 @@ public static void ToRobot(this BarUniformlyDistributedLoad load, RobotSimpleCas { if (load.Force.Length() == 0 && load.Moment.Length() == 0) { - Engine.Reflection.Compute.RecordError("Zero forces and moments are not pushed to Robot"); + Engine.Reflection.Compute.RecordWarning("Zero forces and moments are not pushed to Robot"); return; } diff --git a/Robot_Adapter/Convert/ToRobot/Loads/BarVaryingDistributedLoad.cs b/Robot_Adapter/Convert/ToRobot/Loads/BarVaryingDistributedLoad.cs index e921be45..60994d99 100644 --- a/Robot_Adapter/Convert/ToRobot/Loads/BarVaryingDistributedLoad.cs +++ b/Robot_Adapter/Convert/ToRobot/Loads/BarVaryingDistributedLoad.cs @@ -22,6 +22,7 @@ using BH.Engine.Geometry; using BH.oM.Structure.Loads; +using BH.Engine.External.Robot; using RobotOM; namespace BH.Adapter.Robot @@ -31,24 +32,50 @@ public static partial class Convert /***************************************************/ /**** Public Methods ****/ /***************************************************/ - + public static void ToRobot(this BarVaryingDistributedLoad load, RobotSimpleCase sCase, RobotGroupServer rGroupServer) { if (load.ForceA.Length() == 0 && load.ForceB.Length() == 0) { - Engine.Reflection.Compute.RecordError("Zero distributed forces are not pushed to Robot"); + Engine.Reflection.Compute.RecordWarning("Zero distributed forces are not pushed to Robot"); return; } - IRobotLoadRecord loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_BAR_TRAPEZOIDALE); - loadRecord.Objects.FromText(load.CreateIdListOrGroupName(rGroupServer)); - loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PX1, load.ForceA.X); - loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PY1, load.ForceA.Y); - loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PZ1, load.ForceA.Z); - loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_X1, load.DistanceFromA); - loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PX2, load.ForceB.X); - loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PY2, load.ForceB.Y); - loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PZ2, load.ForceB.Z); - loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_X2, load.DistanceFromB); + + if (load.MomentA.Length() != 0 && load.MomentB.Length() != 0) + { + Engine.Reflection.Compute.RecordError("Varying distributed moments are not supported in Robot."); + return; + } + + int counter = 0; + //Group bars by length within 1 mm. Robot applies loads differently from BHoM (both points referencing the start point while BHoM references the start for A and end for B) + foreach (var lengthGroupedBars in load.Objects.Elements.GroupBarsByLength(0.001)) + { + double dist2 = lengthGroupedBars.Key - load.DistanceFromB; + IRobotLoadRecord loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_BAR_TRAPEZOIDALE); + loadRecord.Objects.FromText(lengthGroupedBars.Value.ToRobotSelectionString()); + loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PX1, load.ForceA.X); + loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PY1, load.ForceA.Y); + loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PZ1, load.ForceA.Z); + loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_X1, load.DistanceFromA); + loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PX2, load.ForceB.X); + loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PY2, load.ForceB.Y); + loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PZ2, load.ForceB.Z); + loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_X2, dist2); + + if (load.Axis == LoadAxis.Local) + loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_LOCAL, 1); + + if (load.Projected) + loadRecord.SetValue((short)IRobotBarTrapezoidaleRecordValues.I_BTRV_PROJECTION, 1); + + counter++; + } + + if (counter > 1) + Engine.Reflection.Compute.RecordNote("Varying BarLoads in BHoM measures distance from start for the first point and from end for the second point, whilst Robot measures only from start node.To accommodate this, multiple loads have been generated in Robot, grouped by the length of the Bars the load is applied to."); + + } /***************************************************/ diff --git a/Robot_Adapter/Convert/ToRobot/Loads/ContourLoad.cs b/Robot_Adapter/Convert/ToRobot/Loads/ContourLoad.cs index fc86c81d..55fbdf6d 100644 --- a/Robot_Adapter/Convert/ToRobot/Loads/ContourLoad.cs +++ b/Robot_Adapter/Convert/ToRobot/Loads/ContourLoad.cs @@ -39,7 +39,7 @@ public static void ToRobot(this oM.Structure.Loads.ContourLoad load, RobotSimple { if (load.Force.Length() == 0) { - Engine.Reflection.Compute.RecordError("Zero contour forces are not pushed to Robot"); + Engine.Reflection.Compute.RecordWarning("Zero contour forces are not pushed to Robot"); return; } diff --git a/Robot_Adapter/Convert/ToRobot/Loads/GeometricalLineLoad.cs b/Robot_Adapter/Convert/ToRobot/Loads/GeometricalLineLoad.cs index fa1095ad..ec822563 100644 --- a/Robot_Adapter/Convert/ToRobot/Loads/GeometricalLineLoad.cs +++ b/Robot_Adapter/Convert/ToRobot/Loads/GeometricalLineLoad.cs @@ -35,7 +35,7 @@ public static void ToRobot(this oM.Structure.Loads.GeometricalLineLoad load, Rob { if (load.ForceA.Length() == 0 && load.ForceB.Length() == 0 && load.MomentA.Length() == 0 && load.MomentB.Length() == 0) { - Engine.Reflection.Compute.RecordError("Zero geometrical forces and moments are not pushed to Robot"); + Engine.Reflection.Compute.RecordWarning("Zero geometrical forces and moments are not pushed to Robot"); return; } IRobotLoadRecordLinear3D loadLin3D = sCase.Records.Create(IRobotLoadRecordType.I_LRT_LINEAR_3D) as IRobotLoadRecordLinear3D; @@ -56,6 +56,10 @@ public static void ToRobot(this oM.Structure.Loads.GeometricalLineLoad load, Rob loadLin3D.SetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MX2, load.MomentB.X); loadLin3D.SetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MY2, load.MomentB.Y); loadLin3D.SetValue((short)IRobotLinear3DRecordValues.I_L3DRV_MZ2, load.MomentB.Z); + + if(load.Axis == oM.Structure.Loads.LoadAxis.Local) + loadLin3D.SetValue((short)IRobotLinear3DRecordValues.I_L3DRV_LOCAL, 0); + } /***************************************************/ diff --git a/Robot_Adapter/Convert/ToRobot/Loads/GravityLoad.cs b/Robot_Adapter/Convert/ToRobot/Loads/GravityLoad.cs index bae342c8..6e8b7207 100644 --- a/Robot_Adapter/Convert/ToRobot/Loads/GravityLoad.cs +++ b/Robot_Adapter/Convert/ToRobot/Loads/GravityLoad.cs @@ -20,6 +20,7 @@ * along with this code. If not, see . */ +using System; using BH.oM.Structure.Loads; using RobotOM; @@ -33,12 +34,54 @@ public static partial class Convert public static void ToRobot(this GravityLoad load, RobotSimpleCase sCase, RobotGroupServer rGroupServer) { - IRobotLoadRecord loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_DEAD); - loadRecord.Objects.FromText(load.CreateIdListOrGroupName(rGroupServer)); - loadRecord.SetValue((short)IRobotDeadRecordValues.I_DRV_X, load.GravityDirection.X); - loadRecord.SetValue((short)IRobotDeadRecordValues.I_DRV_Y, load.GravityDirection.Y); - loadRecord.SetValue((short)IRobotDeadRecordValues.I_DRV_Z, load.GravityDirection.Z); - loadRecord.SetValue((short)IRobotDeadRecordValues.I_DRV_ENTIRE_STRUCTURE, 1); + int count = 0; + if (load.GravityDirection.X != 0) + { + count++; + IRobotLoadRecord loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_DEAD); + loadRecord.Objects.FromText(load.CreateIdListOrGroupName(rGroupServer)); + loadRecord.SetValue((short)IRobotDeadRecordValues.I_DRV_X, load.GravityDirection.X.Sign()); + loadRecord.SetValue((short)IRobotDeadRecordValues.I_DRV_COEFF, Math.Abs(load.GravityDirection.X)); + } + + if (load.GravityDirection.Y != 0) + { + count++; + IRobotLoadRecord loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_DEAD); + loadRecord.Objects.FromText(load.CreateIdListOrGroupName(rGroupServer)); + loadRecord.SetValue((short)IRobotDeadRecordValues.I_DRV_Y, load.GravityDirection.Y.Sign()); + loadRecord.SetValue((short)IRobotDeadRecordValues.I_DRV_COEFF, Math.Abs(load.GravityDirection.Y)); + } + + if (load.GravityDirection.Z != 0) + { + count++; + IRobotLoadRecord loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_DEAD); + loadRecord.Objects.FromText(load.CreateIdListOrGroupName(rGroupServer)); + loadRecord.SetValue((short)IRobotDeadRecordValues.I_DRV_Z, load.GravityDirection.Z.Sign()); + loadRecord.SetValue((short)IRobotDeadRecordValues.I_DRV_COEFF, Math.Abs(load.GravityDirection.Z)); + } + + if (count > 1) + { + Engine.Reflection.Compute.RecordNote("Gravity load split into its components resulting in more than one load record in Robot."); + } + else if (count == 0) + { + Engine.Reflection.Compute.RecordWarning("Gravity loads with no GravityDirection are not pushed to Robot."); + } + } + + /***************************************************/ + + private static int Sign(this double d) + { + if (d < 0) + return -1; + else if (d > 0) + return 1; + else + return 0; } /***************************************************/ diff --git a/Robot_Adapter/Convert/ToRobot/Loads/PointAcceleration.cs b/Robot_Adapter/Convert/ToRobot/Loads/PointAcceleration.cs index 99292ad6..25d09e94 100644 --- a/Robot_Adapter/Convert/ToRobot/Loads/PointAcceleration.cs +++ b/Robot_Adapter/Convert/ToRobot/Loads/PointAcceleration.cs @@ -36,7 +36,7 @@ public static void ToRobot(this PointAcceleration load, RobotSimpleCase sCase, R { if (load.TranslationalAcceleration.Length() == 0) { - Engine.Reflection.Compute.RecordError("Zero point accelerations are not pushed to Robot"); + Engine.Reflection.Compute.RecordWarning("Zero point accelerations are not pushed to Robot"); return; } IRobotLoadRecord loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_NODE_ACCELERATION); diff --git a/Robot_Adapter/Convert/ToRobot/Loads/PointDisplacement.cs b/Robot_Adapter/Convert/ToRobot/Loads/PointDisplacement.cs index f5d68deb..dccf7825 100644 --- a/Robot_Adapter/Convert/ToRobot/Loads/PointDisplacement.cs +++ b/Robot_Adapter/Convert/ToRobot/Loads/PointDisplacement.cs @@ -36,7 +36,7 @@ public static void ToRobot(this PointDisplacement load, RobotSimpleCase sCase, R { if (load.Translation.Length() == 0 && load.Rotation.Length() == 0) { - Engine.Reflection.Compute.RecordError("Zero point displacements are not pushed to Robot"); + Engine.Reflection.Compute.RecordWarning("Zero point displacements are not pushed to Robot"); return; } IRobotLoadRecord loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_NODE_DISPLACEMENT); diff --git a/Robot_Adapter/Convert/ToRobot/Loads/PointLoad.cs b/Robot_Adapter/Convert/ToRobot/Loads/PointLoad.cs index f44810a7..5725e04c 100644 --- a/Robot_Adapter/Convert/ToRobot/Loads/PointLoad.cs +++ b/Robot_Adapter/Convert/ToRobot/Loads/PointLoad.cs @@ -36,7 +36,7 @@ public static void ToRobot(this PointLoad load, RobotSimpleCase sCase, RobotGrou { if (load.Force.Length() == 0 && load.Moment.Length() == 0) { - Engine.Reflection.Compute.RecordError("Zero forces and moments are not pushed to Robot"); + Engine.Reflection.Compute.RecordWarning("Zero forces and moments are not pushed to Robot"); return; } IRobotLoadRecord loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_NODE_FORCE); diff --git a/Robot_Adapter/Convert/ToRobot/Loads/PointVelocity.cs b/Robot_Adapter/Convert/ToRobot/Loads/PointVelocity.cs index d7bbce21..8ec3cbdd 100644 --- a/Robot_Adapter/Convert/ToRobot/Loads/PointVelocity.cs +++ b/Robot_Adapter/Convert/ToRobot/Loads/PointVelocity.cs @@ -36,7 +36,7 @@ public static void ToRobot(this PointVelocity load, RobotSimpleCase sCase, Robot { if (load.TranslationalVelocity.Length() == 0) { - Engine.Reflection.Compute.RecordError("Zero point velocities are not pushed to Robot"); + Engine.Reflection.Compute.RecordWarning("Zero point velocities are not pushed to Robot"); return; } IRobotLoadRecord loadRecord = sCase.Records.Create(IRobotLoadRecordType.I_LRT_NODE_VELOCITY); diff --git a/Robot_Adapter/Robot_Adapter.csproj b/Robot_Adapter/Robot_Adapter.csproj index c301cc7c..3b0ff994 100644 --- a/Robot_Adapter/Robot_Adapter.csproj +++ b/Robot_Adapter/Robot_Adapter.csproj @@ -112,6 +112,10 @@ ..\..\BHoM_Engine\Build\Serialiser_Engine.dll False + + False + ..\..\BHoM_Engine\Build\Spatial_Engine.dll + ..\..\BHoM_Adapter\Build\Structure_AdapterModules.dll False @@ -145,10 +149,23 @@ + + + + + + + + + + + + + @@ -180,7 +197,6 @@ - @@ -211,8 +227,9 @@ + + - diff --git a/Robot_Engine/Compute/GroupBarsByLength.cs b/Robot_Engine/Compute/GroupBarsByLength.cs new file mode 100644 index 00000000..881b8b8f --- /dev/null +++ b/Robot_Engine/Compute/GroupBarsByLength.cs @@ -0,0 +1,55 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2019, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System; +using System.Linq; +using System.Collections.Generic; +using System.ComponentModel; +using BH.oM.Reflection.Attributes; +using BH.oM.Structure.Elements; +using BH.Engine.Structure; + +namespace BH.Engine.External.Robot +{ + public static partial class Compute + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + [Description("Groups bars by length, within a tolerance.")] + [Input("bars", "The bars to group.")] + [Input("tolerance", "Acceptable difference in length for each group")] + [Output("barGroup", "The bars grouped, as a dictionary, with the key being the length and the value being the corresponding bars.")] + public static Dictionary> GroupBarsByLength(this IEnumerable bars, double tolerance) + { + Dictionary> dict = new Dictionary>(); + foreach (var group in bars.GroupBy(x => (int)Math.Round(x.Length() / tolerance))) + { + dict[group.Key*tolerance] = group.ToList(); + } + return dict; + } + + /***************************************************/ + } +} diff --git a/Robot_Engine/Robot_Engine.csproj b/Robot_Engine/Robot_Engine.csproj index 0fe35b1b..0730e3d4 100644 --- a/Robot_Engine/Robot_Engine.csproj +++ b/Robot_Engine/Robot_Engine.csproj @@ -99,6 +99,7 @@ + diff --git a/Robot_oM/Robot_oM.csproj b/Robot_oM/Robot_oM.csproj index 6c3f710b..604ad30f 100644 --- a/Robot_oM/Robot_oM.csproj +++ b/Robot_oM/Robot_oM.csproj @@ -56,12 +56,8 @@ - - - -