Beispiel #1
0
        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));
        }