/***************************************************/ /**** Public Methods ****/ /***************************************************/ public static FEMesh FEMesh(BH.oM.Geometry.Mesh mesh, ISurfaceProperty property = null, string name = null) { FEMesh feMesh = new FEMesh(); feMesh.Nodes = mesh.Vertices.Select(x => Node(x)).ToList(); foreach (Face face in mesh.Faces) { FEMeshFace feFace = new FEMeshFace(); feFace.NodeListIndices.Add(face.A); feFace.NodeListIndices.Add(face.B); feFace.NodeListIndices.Add(face.C); if (face.IsQuad()) { feFace.NodeListIndices.Add(face.D); } feMesh.MeshFaces.Add(feFace); } if (property != null) { feMesh.Property = property; } if (name != null) { feMesh.Name = name; } return(feMesh); }
public static Face Geometry(this FEMeshFace feFace) { if (feFace.NodeListIndices.Count < 3) { Reflection.Compute.RecordError("Insuffiecient node indices"); return(null); } if (feFace.NodeListIndices.Count > 4) { Reflection.Compute.RecordError("To high number of node indices. Can only handle triangular and quads"); return(null); } Face face = new Face(); face.A = feFace.NodeListIndices[0]; face.B = feFace.NodeListIndices[1]; face.C = feFace.NodeListIndices[2]; if (feFace.NodeListIndices.Count == 4) { face.D = feFace.NodeListIndices[3]; } return(face); }
public static FEMeshFace OrientTowards(this FEMeshFace face, FEMesh mesh, Point orientationPoint) { if (face.IsNull() || mesh.IsNull() || orientationPoint.IsNull()) { return(null); } Point centre = face.NodeListIndices.Select(i => mesh.Nodes[i].Position).Average(); Vector localX = (orientationPoint - centre).Normalise(); return(face.SetLocalOrientation(mesh, localX)); }
/***************************************************/ /**** Private methods ****/ /***************************************************/ //The List<string> in the methods below can be changed to a list of any type of identification more suitable for the toolkit //If no ids are provided, the convention is to return all elements of the type private List <FEMesh> ReadMesh(List <int> ids = null) { // Just reading mesh without properties. Use all nodes. int uID = 1; int err = 0; int numberPlateElements = 0; err = St7.St7GetTotal(uID, St7.tyPLATE, ref numberPlateElements); if (!St7ErrorCustom(err, "Could not get total number of plate elements.")) { return(null); } List <Node> nodes = ReadNodes(); List <ISurfaceProperty> plateProps = ReadSurfaceProperty(); if (ids == null || ids.Count == 0) { ids = Enumerable.Range(1, numberPlateElements).ToList(); } FEMesh[] meshes = new FEMesh[plateProps.Count]; Dictionary <int, int> platePropsNumbers = new Dictionary <int, int>(); for (int i = 0; i < plateProps.Count; i++) { platePropsNumbers.Add(GetAdapterId <int>(plateProps[i]), i); meshes[i] = new FEMesh(); meshes[i].Nodes = nodes; meshes[i].Property = plateProps[i]; meshes[i].Name = plateProps[i].Name; SetAdapterId(meshes[i], i); } foreach (int id in ids) { int platePropNum = 0; err = St7.St7GetElementProperty(uID, St7.ptPLATEPROP, id, ref platePropNum); int propIndex = platePropsNumbers[platePropNum]; FEMeshFace face = new FEMeshFace(); SetAdapterId(face, id); int[] plateConnection = new int[St7.kMaxElementNode + 1]; err = St7.St7GetElementConnection(uID, St7.tyPLATE, id, plateConnection); if (plateConnection[0] == 3 || plateConnection[0] == 6) // Plate elements Tri3 and Tri6. Firt index is a number of vertices { face.NodeListIndices = new int[] { plateConnection[1] - 1, plateConnection[2] - 1, plateConnection[3] - 1 }.ToList(); } else // All quad elements { face.NodeListIndices = new int[] { plateConnection[1] - 1, plateConnection[2] - 1, plateConnection[3] - 1, plateConnection[4] - 1 }.ToList(); } meshes[propIndex].Faces.Add(face); } return(meshes.ToList()); }
public static bool IsNull(this FEMeshFace face, FEMesh mesh, string msg = "", [CallerMemberName] string methodName = "Method") { // Check FEMeshFace and relevant nodes in FEMesh if (face.IsNull(msg, methodName)) { return(true); } else if (mesh.IsNull(false, true, face.NodeListIndices, msg, methodName)) { return(true); } return(false); }
public static FEMesh FEMesh(Mesh mesh, ISurfaceProperty property = null, Vector localX = null, string name = null) { if (mesh.IsNull()) { return(null); } FEMesh feMesh = new FEMesh(); feMesh.Nodes = mesh.Vertices.Select(x => Node(x)).ToList(); foreach (Face face in mesh.Faces) { FEMeshFace feFace = new FEMeshFace(); feFace.NodeListIndices.Add(face.A); feFace.NodeListIndices.Add(face.B); feFace.NodeListIndices.Add(face.C); if (face.IsQuad()) { feFace.NodeListIndices.Add(face.D); } feMesh.Faces.Add(feFace); } if (property != null) { feMesh.Property = property; } if (name != null) { feMesh.Name = name; } if (localX != null) { return(feMesh.SetLocalOrientations(localX)); } else { return(feMesh); } }
public static FEMeshFace SetLocalOrientation(this FEMeshFace face, FEMesh mesh, Vector localX) { if (face.IsNull() || mesh.IsNull() || localX.IsNull()) { return(null); } FEMeshFace clone = face.ShallowClone(); Vector normal = face.Normal(mesh); double orientationAngle = Compute.OrientationAngleAreaElement(normal, localX); if (!double.IsNaN(orientationAngle)) { clone.OrientationAngle = orientationAngle; } return(clone); }
public static List <Point> PointGrid(this FEMeshFace face, FEMesh mesh) { if (face.IsNull() || mesh.IsNull()) { return(null); } List <Point> pts = face.NodeListIndices.Select(i => mesh.Nodes[i].Position).ToList(); List <Point> temp = new List <Point>(); for (int i = 0; i < pts.Count; i++) { int next = (i + 1) % pts.Count; temp.Add((pts[i] + pts[next]) / 2); } pts.AddRange(temp); pts.Add(pts.Average()); return(pts); }
public static bool IsNull(this FEMeshFace face, string msg = "", [CallerMemberName] string methodName = "Method") { // Check FEMeshFace if (face == null) { ErrorMessage(methodName, "FEMeshFace", msg); return(true); } else if (face.NodeListIndices == null) { ErrorMessage(methodName, "FEMeshFace NodeListIndicies", msg); return(true); } else if (face.NodeListIndices.Count == 0) { Reflection.Compute.RecordError($"Cannot evaluate {methodName} because the Face NodeListIndicies count is 0. {msg}"); return(true); } return(false); }
public static Vector Normal(this FEMeshFace face, FEMesh mesh) { if (face.IsNull(mesh)) { return(null); } if (face.NodeListIndices.Count < 3) { Engine.Reflection.Compute.RecordError("Face has insufficient number of nodes to calculate normal."); return(null); } else if (face.NodeListIndices.Count > 4) { Engine.Reflection.Compute.RecordError("Can only determine normal from 3 or 4 sided faces."); return(null); } Point pA = mesh.Nodes[face.NodeListIndices[0]].Position; Point pB = mesh.Nodes[face.NodeListIndices[1]].Position; Point pC = mesh.Nodes[face.NodeListIndices[2]].Position; Vector normal; if (face.NodeListIndices.Count == 3) { normal = Engine.Geometry.Query.CrossProduct(pB - pA, pC - pB); } else { Point pD = mesh.Nodes[face.NodeListIndices[3]].Position; normal = (Engine.Geometry.Query.CrossProduct(pA - pD, pB - pA)) + (Engine.Geometry.Query.CrossProduct(pC - pB, pD - pC)); } return(normal.Normalise()); }
/***************************************************/ private List <FEMesh> ReadMesh(List <string> ids = null) { List <Panel> panelList = new List <Panel>(); int nameCount = 0; string[] nameArr = { }; m_model.AreaObj.GetNameList(ref nameCount, ref nameArr); ids = FilterIds(ids, nameArr); List <FEMesh> meshes = new List <FEMesh>(); Dictionary <string, Node> nodes = new Dictionary <string, Node>(); Dictionary <string, ISurfaceProperty> surfaceProps = ReadSurfaceProperty().ToDictionary(x => GetAdapterId <string>(x)); foreach (string id in ids) { FEMesh mesh = new FEMesh(); ETABSId etabsid = new ETABSId(); etabsid.Id = id; List <string> meshNodeIds = new List <string>(); //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 nodealready 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.FromCSILocalX(normal, orientation); mesh = mesh.SetLocalOrientations(localX); //Label and story string label = ""; string story = ""; if (m_model.AreaObj.GetLabelFromName(id, ref label, ref story) == 0) { etabsid.Label = label; etabsid.Story = story; } // Get guid string guid = null; m_model.AreaObj.GetGUID(id, ref guid); etabsid.PersistentId = guid; SetAdapterId(mesh, etabsid); meshes.Add(mesh); } else { BH.Engine.Base.Compute.RecordWarning("Mesh " + id.ToString() + " could not be pulled, because it contains no nodes"); } } return(meshes); }
public static Basis LocalOrientation(this FEMeshFace face, FEMesh mesh) { return(face.IsNull(mesh) ? null : LocalOrientation(face.Normal(mesh), face.OrientationAngle)); }
public static Cartesian CoordinateSystem(this FEMeshFace face, FEMesh mesh) { Basis orientation = face?.LocalOrientation(mesh); return(orientation != null ? new Cartesian(face.NodeListIndices.Select(i => mesh.Nodes[i].Position).Average(), orientation.X, orientation.Y, orientation.Z) : null); }