diff --git a/SAP2000_Adapter/CRUD/Read/Mesh.cs b/SAP2000_Adapter/CRUD/Read/Mesh.cs new file mode 100644 index 00000000..4d3f43b8 --- /dev/null +++ b/SAP2000_Adapter/CRUD/Read/Mesh.cs @@ -0,0 +1,147 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2026, 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.Elements; +using BH.oM.Adapters.SAP2000; +using BH.oM.Geometry; +using BH.oM.Structure.Elements; +using BH.oM.Structure.SurfaceProperties; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BH.Engine.Structure; + +namespace BH.Adapter.SAP2000 +{ + public partial class SAP2000Adapter + { + /***************************************************/ + + private List ReadMesh(List ids = null) + { + int nameCount = 0; + string[] nameArr = { }; + m_model.AreaObj.GetNameList(ref nameCount, ref nameArr); + + ids = FilterIds(ids, nameArr); + + List meshes = new List(); + Dictionary nodes = GetCachedOrReadAsDictionary(); + Dictionary surfaceProps = GetCachedOrReadAsDictionary(); + + foreach (string id in ids) + { + FEMesh mesh = new FEMesh(); + + SAP2000Id sap2000id = new SAP2000Id(); + sap2000id.Id = id; + + List meshNodeIds = new List(); + + //Get out the "Element" ids, i.e. the mesh faces + int nbELem = 0; + string[] elemNames = new string[0]; + m_model.AreaObj.GetElm(id, ref nbELem, ref elemNames); + + for (int j = 0; j < nbELem; j++) + { + //Get out the name of the points for each face + int nbPts = 0; + string[] ptsNames = new string[0]; + m_model.AreaElm.GetPoints(elemNames[j], ref nbPts, ref ptsNames); + + FEMeshFace face = new FEMeshFace(); + + for (int k = 0; k < nbPts; k++) + { + string nodeId = ptsNames[k]; + Node node; + + //Check if node already has been pulled + if (!nodes.TryGetValue(nodeId, out node)) + { + double x = 0, y = 0, z = 0; + m_model.PointElm.GetCoordCartesian(nodeId, ref x, ref y, ref z); + node = new Node() { Position = new Point { X = x, Y = y, Z = z } }; + SetAdapterId(node, nodeId); + nodes[ptsNames[k]] = node; + } + + //Check if node already has been added to the mesh + if (!meshNodeIds.Contains(nodeId)) + meshNodeIds.Add(nodeId); + + //Get corresponding node index + face.NodeListIndices.Add(meshNodeIds.IndexOf(nodeId)); + } + + //Add face to list + SetAdapterId(face, elemNames[j]); + mesh.Faces.Add(face); + + } + + //Set mesh nodes - if there are no nodes, don't create the mesh. + if (nodes.Count != 0 && mesh.Faces.Count != 0) + { + mesh.Nodes = meshNodeIds.Select(x => nodes[x]).ToList(); + + string propertyName = ""; + + m_model.AreaObj.GetProperty(id, ref propertyName); + + if (propertyName != "None") + { + mesh.Property = surfaceProps[propertyName]; + } + + //Get local x-axis + double orientation = 0; + bool advanced = false; + m_model.AreaObj.GetLocalAxes(id, ref orientation, ref advanced); + + Vector normal = mesh.Faces.First().Normal(mesh); //Assuming flat mesh, all normals equal + Vector localX = Convert.ToPanelLocalXAxis(normal, orientation); + mesh = mesh.SetLocalOrientations(localX); + + // Get guid + string guid = null; + m_model.AreaObj.GetGUID(id, ref guid); + sap2000id.PersistentId = guid; + + SetAdapterId(mesh, sap2000id); + meshes.Add(mesh); + } + else + { + BH.Engine.Base.Compute.RecordWarning("Mesh " + id.ToString() + " could not be pulled, because it contains no nodes"); + } + } + BH.Engine.Base.Compute.RecordWarning("Meshes - Only one face normal vector is pulled from every mesh and it is applied to all the faces of the mesh."); + return meshes; + } + + /***************************************************/ + } +} diff --git a/SAP2000_Adapter/CRUD/Read/_IRead.cs b/SAP2000_Adapter/CRUD/Read/_IRead.cs index f11fe08b..fbb39b48 100644 --- a/SAP2000_Adapter/CRUD/Read/_IRead.cs +++ b/SAP2000_Adapter/CRUD/Read/_IRead.cs @@ -63,6 +63,8 @@ protected override IEnumerable IRead(Type type, IList ids, ActionCo return ReadMaterial(listIds); else if (type == typeof(Panel)) return ReadPanel(listIds); + else if (type == typeof(FEMesh)) + return ReadMesh(listIds); else if (type == typeof(ISurfaceProperty) || type.GetInterfaces().Contains(typeof(ISurfaceProperty))) return ReadSurfaceProperty(listIds); else if (type == typeof(LoadCombination)) diff --git a/SAP2000_Adapter/Convert/ToBHoM/Panel.cs b/SAP2000_Adapter/Convert/ToBHoM/Panel.cs new file mode 100644 index 00000000..7583c799 --- /dev/null +++ b/SAP2000_Adapter/Convert/ToBHoM/Panel.cs @@ -0,0 +1,69 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2026, 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; +using BH.Engine.Geometry; +using BH.oM.Geometry; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BH.Adapter.SAP2000 +{ + public static partial class Convert + { + /***************************************************/ + /**** Public Methods ****/ + /***************************************************/ + + public static Vector ToPanelLocalXAxis(Vector normal, double orientationAngle) + { + Vector locYref; + + if (Query.IsParallel(normal, Vector.ZAxis)!=0) + { + //Vector is paralell to z-axis + locYref = Vector.YAxis; + } + else + { + //Vector is not paralell to z-axis + locYref = Vector.ZAxis.Project(new Plane { Normal = normal }); + } + + Vector localXref = locYref.CrossProduct(normal); + + return localXref.Rotate(BH.Engine.Units.Convert.FromDegree(orientationAngle), normal); + } + + /***************************************************/ + + } +} + + + + + + diff --git a/SAP2000_Adapter/SAP2000_Adapter.csproj b/SAP2000_Adapter/SAP2000_Adapter.csproj index ff0c8937..70b55301 100644 --- a/SAP2000_Adapter/SAP2000_Adapter.csproj +++ b/SAP2000_Adapter/SAP2000_Adapter.csproj @@ -182,6 +182,11 @@ + + $(ProgramData)\BHoM\Assemblies\Units_Engine.dll + False + False + @@ -191,6 +196,7 @@ + @@ -221,6 +227,7 @@ + @@ -269,4 +276,4 @@ --> - \ No newline at end of file + diff --git a/dependencies.txt b/dependencies.txt index c859174b..f9af9c0d 100644 --- a/dependencies.txt +++ b/dependencies.txt @@ -1,3 +1,4 @@ BHoM/BHoM BHoM/BHoM_Engine -BHoM/BHoM_Adapter \ No newline at end of file +BHoM/BHoM_Adapter +BHoM/Localisation_Toolkit \ No newline at end of file