Exemple #1
0
        /***************************************************/
        /**** 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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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));
        }
Exemple #4
0
        /***************************************************/
        /**** 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());
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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);
        }
Exemple #8
0
        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);
        }
Exemple #9
0
        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);
        }
Exemple #10
0
        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());
        }
Exemple #11
0
        /***************************************************/

        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);
        }
Exemple #12
0
 public static Basis LocalOrientation(this FEMeshFace face, FEMesh mesh)
 {
     return(face.IsNull(mesh) ? null : LocalOrientation(face.Normal(mesh), face.OrientationAngle));
 }
Exemple #13
0
        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);
        }