private static Polygon BuildSubMeshBoundaryGeometry(CMeshData mesh, BoundarySegmentsBuilder bsb, List <CMeshFace> boundaryFaces) { // Find connected segments List <LinkedList <int> > segments = bsb.BuildBoundarySegments(boundaryFaces); if (segments == null) { return(null); } LinearRing shell = null; List <LinearRing> holes = new List <LinearRing>(); // Create mesh boundary with segments for (int isegment = 0; isegment < segments.Count; isegment++) { LinkedList <int> segment = segments[isegment]; CMeshFace first = boundaryFaces[segment.First.Value]; CMeshFace last = boundaryFaces[segment.Last.Value]; if (!NodeEquals(first.FromNode, last.ToNode)) { Console.Out.WriteLine("Skipping: {0,4} {1,8} {2,8} {3,8}", isegment, segment.Count, first.FromNode, last.ToNode); continue; } Coordinate[] coords = new Coordinate[segment.Count + 1]; int i = 0; foreach (int iFace in segment) { CMeshFace face = boundaryFaces[iFace]; coords[i++] = new Coordinate(face.FromNode.X, face.FromNode.Y); } coords[segment.Count] = new Coordinate(last.ToNode.X, last.ToNode.Y); LinearRing ring = new LinearRing(coords); if (ring.IsCCW) { if (shell != null) { throw new Exception("Finding two shells of a connected sub-mesh"); } shell = ring; } else { holes.Add(ring); } } Polygon p; if (holes.Count > 0) { p = new Polygon(shell, holes.ToArray()); } else { p = new Polygon(shell); } return(p); }
/// <summary> /// Build list of <see cref="CMeshBoundary"/>, one for each boundary code, based on the <paramref name="meshFaces"/> /// <para> /// The <paramref name="meshFaces"/> need only contain boundary faces. Internal faces are ignored. /// </para> /// </summary> private static List <CMeshBoundary> BuildBoundaryList(CMeshData mesh, List <CMeshFace> meshFaces) { // Sort all faces on boundary code, assuming code numbers does not grow very big. List <List <CMeshFace> > bcs = new List <List <CMeshFace> >(); for (int i = 0; i < meshFaces.Count; i++) { CMeshFace meshFace = meshFaces[i]; if (meshFace.IsBoundaryFace()) { while (meshFace.Code + 1 > bcs.Count) { List <CMeshFace> boundaryFaces = new List <CMeshFace>(); bcs.Add(boundaryFaces); } bcs[meshFace.Code].Add(meshFace); } } List <CMeshBoundary> boundaries = new List <CMeshBoundary>(); BoundarySegmentsBuilder bsb = new BoundarySegmentsBuilder(mesh); // For each boundary code, find segments for (int ic = 0; ic < bcs.Count; ic++) { int code = ic; List <CMeshFace> faces = bcs[ic]; List <LinkedList <int> > segments = bsb.BuildBoundarySegments(faces); if (segments == null) { continue; } // Create mesh boundary with segments CMeshBoundary meshBoundary = new CMeshBoundary() { Code = code }; foreach (LinkedList <int> segment in segments) { if (segment == null) { continue; } List <CMeshFace> segmentFaces = new List <CMeshFace>(segment.Count); foreach (int currentFace in segment) { segmentFaces.Add(faces[currentFace]); } meshBoundary.Segments.Add(segmentFaces); } boundaries.Add(meshBoundary); } //// Sort on boundary codes - well, they are created in code-order //boundaries.Sort((mb1, mb2) => mb1.Code.CompareTo(mb2.Code)); return(boundaries); }