public bool RequiresSupport() { bool supportInScene = scene.VisibleMeshes().Any(i => i.WorldOutputType() == PrintOutputTypes.Support); if (!supportInScene) { // there is no support in the scene check if there are faces that require support var supportCandidates = scene.VisibleMeshes().Where(i => i.OutputType != PrintOutputTypes.Support); // find all the faces that are candidates for support foreach (var item in supportCandidates) { var matrix = item.WorldMatrix(scene); for (int faceIndex = 0; faceIndex < item.Mesh.Faces.Count; faceIndex++) { bool aboveBed = false; var face = item.Mesh.Faces[faceIndex]; var verts = new int[] { face.v0, face.v1, face.v2 }; foreach (var vertex in verts) { if (item.Mesh.Vertices[vertex].Transform(matrix).Z > .01) { aboveBed = true; break; } } if (aboveBed) { var face0Normal = item.Mesh.Faces[faceIndex].normal.TransformNormal(matrix).GetNormal(); var angle = MathHelper.RadiansToDegrees(Math.Acos(face0Normal.Dot(-Vector3Float.UnitZ))); if (angle < MaxOverHangAngle) { // TODO: consider how much area all supported polygons represent return(true); } } } } } return(false); }