Beispiel #1
0
 /// <summary>
 /// Write mesh data to mesh file
 /// </summary>
 public static void Write(this MeshData meshData, string filename)
 {
     meshData.ToMeshFile().Write(filename);
 }
Beispiel #2
0
        /// <summary>
        /// Build list of face boundaries of <paramref name="mesh"/>
        /// </summary>
        public static List <MeshBoundary> BuildBoundaryList(MeshData mesh)
        {
            if (mesh.Faces == null)
            {
                mesh.BuildDerivedData();
            }

            // Sort all faces on boundary code
            Dictionary <int, List <MeshFace> > bcs = new Dictionary <int, List <MeshFace> >();

            for (int i = 0; i < mesh.Faces.Count; i++)
            {
                MeshFace meshFace = mesh.Faces[i];
                if (meshFace.IsBoundaryFace())
                {
                    List <MeshFace> boundaryFaces;
                    if (!bcs.TryGetValue(meshFace.Code, out boundaryFaces))
                    {
                        boundaryFaces = new List <MeshFace>();
                        bcs.Add(meshFace.Code, boundaryFaces);
                    }
                    boundaryFaces.Add(meshFace);
                }
            }

            List <MeshBoundary> boundaries = new List <MeshBoundary>();

            // For each boundary code, find segments
            foreach (KeyValuePair <int, List <MeshFace> > bfkvp in bcs)
            {
                int             code  = bfkvp.Key;
                List <MeshFace> faces = bfkvp.Value;

                // Sort faces on FromNode index
                faces.Sort((f1, f2) => f1.FromNode.Index.CompareTo(f2.FromNode.Index));

                // Create searchable array of FromNode indices
                int[] fromNodes = faces.Select(f => f.FromNode.Index).ToArray();

                // Matching array telling which boundary segment a given face belongs to
                int[] faceSegmentIndex = new int[faces.Count];
                for (int ii = 0; ii < faceSegmentIndex.Length; ii++)
                {
                    faceSegmentIndex[ii] = -1;
                }

                // All segments with this boundary code
                List <LinkedList <int> > segments = new List <LinkedList <int> >();

                // Make sure to visit all faces
                for (int i = 0; i < faces.Count; i++)
                {
                    // Check if this face has already been visited.
                    if (faceSegmentIndex[i] >= 0)
                    {
                        continue;
                    }

                    // Start new boundary segment with face i
                    int currentSegmentIndex         = segments.Count;
                    int currentFaceIndex            = i;
                    LinkedList <int> currentSegment = new LinkedList <int>();
                    // Add current face to segment
                    currentSegment.AddLast(currentFaceIndex);
                    faceSegmentIndex[currentFaceIndex] = currentSegmentIndex;

                    while (true)
                    {
                        // Try find next face, which is the face with fromNode matching currentFace.ToNode
                        MeshFace currentFace   = faces[currentFaceIndex];
                        int      nextFaceIndex = Array.BinarySearch(fromNodes, currentFace.ToNode.Index);

                        if (nextFaceIndex < 0)
                        {
                            // No to-node, we are done with this segment
                            segments.Add(currentSegment);
                            break;
                        }

                        // Check if the next face is already part of a segment
                        if (faceSegmentIndex[nextFaceIndex] >= 0)
                        {
                            if (faceSegmentIndex[nextFaceIndex] == currentSegmentIndex)
                            {
                                // Circular boundary - we are done with this segment
                                segments.Add(currentSegment);
                                break;
                            }

                            // Now: nextSegment is not the same as the currentSection,
                            // but they should be - move entire current segment to the
                            // start of the nextFace segment

                            int nextFaceSegment = faceSegmentIndex[nextFaceIndex];
                            // Move all from current segment to
                            LinkedListNode <int> thisSegmentListNode = currentSegment.Last;
                            while (thisSegmentListNode != null)
                            {
                                int faceToMoveIndex = thisSegmentListNode.Value;
                                segments[nextFaceSegment].AddFirst(faceToMoveIndex);
                                faceSegmentIndex[faceToMoveIndex] = nextFaceSegment;
                                thisSegmentListNode = thisSegmentListNode.Previous;
                            }
                            break; // Break out of while (true) loop
                        }

                        // Make nextFace to currentFace - add it to the list of current segments.
                        currentFaceIndex = nextFaceIndex;
                        currentSegment.AddLast(currentFaceIndex);
                        faceSegmentIndex[currentFaceIndex] = currentSegmentIndex;
                    }
                }

                MeshBoundary meshBoundary = new MeshBoundary()
                {
                    Code = code
                };
                foreach (LinkedList <int> segment in segments)
                {
                    if (segment == null)
                    {
                        continue;
                    }
                    List <MeshFace> segmentFaces = new List <MeshFace>(segment.Count);
                    foreach (int currentFace in segment)
                    {
                        segmentFaces.Add(faces[currentFace]);
                    }
                    meshBoundary.Segments.Add(segmentFaces);
                }

                boundaries.Add(meshBoundary);
            }

            boundaries.Sort((mb1, mb2) => mb1.Code.CompareTo(mb2.Code));
            return(boundaries);
        }
 /// <summary>
 /// Convert a <see cref="MeshFile"/> class into a <see cref="MeshData"/> class.
 /// </summary>
 public static MeshData ToMeshData(this MeshFile file)
 {
     return(MeshData.CreateMesh(file.Projection, file.NodeIds, file.X, file.Y, file.Z, file.Code, file.ElementIds, file.ElementType, file.ElementTable, file.ZUnit));
 }