private IEnumerable<Solid> CreateSolids(DataStructures.MapObjects.Map map, List<Coordinate> points, IEnumerable<ObjFace> objFaces) { var faces = objFaces.Select(x => CreateFace(map, points, x)).ToList(); // See if the solid is valid var solid = new Solid(map.IDGenerator.GetNextObjectID()); solid.Colour = Colour.GetRandomBrushColour(); solid.Faces.AddRange(faces); faces.ForEach(x => x.Parent = solid); if (solid.IsValid()) { // Do an additional check to ensure that all edges are shared var edges = solid.Faces.SelectMany(x => x.GetEdges()).ToList(); if (edges.All(x => edges.Count(y => x.EquivalentTo(y)) == 2)) { // Valid! let's get out of here! yield return solid; yield break; } } // Not a valid solid, decompose into tetrahedrons/etc foreach (var face in faces) { var polygon = new Polygon(face.Vertices.Select(x => x.Location)); if (!polygon.IsValid() || !polygon.IsConvex()) { // tetrahedrons foreach (var triangle in face.GetTriangles()) { var tf = new Face(map.IDGenerator.GetNextFaceID()); tf.Plane = new Plane(triangle[0].Location, triangle[1].Location, triangle[2].Location); tf.Vertices.AddRange(triangle.Select(x => new Vertex(x.Location, tf))); tf.UpdateBoundingBox(); yield return SolidifyFace(map, tf); } } else { // cone/pyramid/whatever yield return SolidifyFace(map, face); } } }