public Slice Slice(double slice_z_height, double perSlice) { var polies = new List <Polygon2D>(); var poliesInPlane = new List <Polygon2D>(); bool HasSurface = false; foreach (var p in Polygons) { var cut = p.CutAtZ(slice_z_height, slice_z_height + perSlice); if (cut != null && cut.GetType() == typeof(Line)) { // Got slice line var line = (Line)cut; if (polies.Count > 0) { // Try to add it to a Polygon already bool wasConnected = false; foreach (var po in polies) { var connectType = po.CanConnect(line); if (connectType != ConnectionType.NOT) { wasConnected = true; po.AddLine(line, connectType); break; } } if (!wasConnected) { polies.Add(new Polygon2D(line)); } } else { polies.Add(new Polygon2D(line)); } } else if (cut != null && cut.GetType() == typeof(Polygon2D)) { // Got polygon surface, so this _probably_ is a surface... Polygon2D polygon = (Polygon2D)cut; poliesInPlane.Add(polygon); HasSurface = true; //Fill in polygon } } List <Polygon2D> completePolygons = new List <Polygon2D>(); List <Polygon2D> needsConnections = new List <Polygon2D>(); for (int i = 0; i < polies.Count; i++) { var p = polies[i]; if (!p.IsComplete() && !p.WasTakenAway) { bool connectionFound = false; do { connectionFound = false; if (!p.IsComplete()) { // Find another poly that can connect to this one, // until it is closed. for (int j = 0; j < polies.Count; j++) { var p2 = polies[j]; if (i != j && !p2.WasTakenAway && p.AddPolygon(p2, p.CanConnect(p2))) { p2.WasTakenAway = true; connectionFound = true; break; } } } } while (connectionFound); if (p.IsComplete()) { // IsComplete => take away p.WasTakenAway = true; completePolygons.Add(p); } else { //p.WasTakenAway = true; //Line connect = new Line(p.LastPoint(), p.FirstPoint()); //p.AddLine(connect, ConnectionType.LAST); //foreach (var line in p.Lines) //{ // line.IsOpen = true; //} p.IsOpen = true; //completePolygons.Add(p); needsConnections.Add(p); } } else if (!p.WasTakenAway) { // IsComplete => take away p.WasTakenAway = true; completePolygons.Add(p); } } List <Polygon2D> stillNoConnection = new List <Polygon2D>(needsConnections); double factor = 10; while (stillNoConnection.Count > 0) { if (stillNoConnection.Count == 1) { Line line = new Line(stillNoConnection[0].Last().EndPoint, stillNoConnection[0].First().StartPoint); stillNoConnection[0].AddLine(line, ConnectionType.LAST); stillNoConnection[0].WasTakenAway = true; completePolygons.Add(stillNoConnection[0]); break; } for (int i = 0; i < stillNoConnection.Count; i++) { var p = stillNoConnection[i]; if (p.Lines.Count() == 1 && p.Lines.First().GetLength() < Point.EPSILON * factor) { p.WasTakenAway = true; break; } if (!p.IsComplete(Point.EPSILON * factor) && !p.WasTakenAway) { //Try connecting other polygons for (int j = 0; j < stillNoConnection.Count(); j++) { var p2 = stillNoConnection[j]; if (i != j) { if (!p2.WasTakenAway && !p2.IsComplete() && p.CanConnect(p2, Point.EPSILON * factor) != ConnectionType.NOT) { p.AddPolygon(p2, p.CanConnect(p2, Point.EPSILON * factor)); p2.WasTakenAway = true; } if (p.IsComplete()) { p.WasTakenAway = true; completePolygons.Add(p); break; } } } } if (p.IsComplete(Point.EPSILON * factor) && !p.WasTakenAway) { Line line = new Line(p.Last().EndPoint, p.First().StartPoint); p.AddLine(line, ConnectionType.LAST); p.WasTakenAway = true; p.IsOpen = false; completePolygons.Add(p); } } factor *= 10; stillNoConnection = stillNoConnection.Where(p => !p.IsComplete() && !p.WasTakenAway).ToList(); } //foreach (var p in needsConnections) //{ // Line line = new Line(p.Last().EndPoint, p.First().StartPoint); // p.AddLine(line, ConnectionType.LAST); //} //completePolygons.AddRange(needsConnections); // Simplify lines and reduce them to a minimum, and sort by area, largest first //foreach (var p in completePolygons) //{ // p.CleanLines(); //} List <Polygon2D> realCompletePolies = new List <Polygon2D>(); foreach (var p in completePolygons) { realCompletePolies.AddRange(p.CleanToPolygons()); } Polygon2D.DetermineHierachy(ref realCompletePolies, false); return(new Slice(realCompletePolies.Where(p => p.FilterShorts() && p.IsComplete()).ToList(), slice_z_height, HasSurface)); }