public Population(int populationSize, Boolean initialise, Paths pgs, IntPoint m_startPoint,Tour greedtour)
        {
            this.oripaths = pgs;   //保存传入的路劲集合,用来计算适应度,及距离
            this.startPoint = m_startPoint;

            tours = new Tour[populationSize];        //种群路劲集合

            int greedseedsize = 15;
            // If we need to initialise a population of tours do so
            if (initialise)
            {
                for (int j = 0; j < greedseedsize; j++)
                {
                    saveTour(j, greedtour);
                }

                // Loop and create individuals
                for (int i = greedseedsize; i < populationSize; i++)
                {
                    Tour newTour = new Tour(pgs.Count);
                    newTour.generateIndividual();
                    saveTour(i, newTour);
                }
            }
        }
Example #2
0
        public static void FlattenPolyNode(List<PolyNode> nodes, List<Polygons>polys)
        {
            // Must pass in something that contains outer polygons (first childs of a polytree)
            foreach (PolyNode node in nodes)
            {
                // First level children are all outer polgons
                Polygons polygons = new Polygons();
                polygons.Add(node.Contour);
                if (node.IsHole)
                {
                    // Got a problem here...
                }

                // And the polygon can have many holes
                foreach (PolyNode hole in node.Childs)
                {
                    if (!hole.IsHole)
                    {
                        // Got a problem here...
                    }
                    polygons.Add(hole.Contour);
                    // If the holes have children, they will be outer polygons
                    FlattenPolyNode(hole.Childs, polys);
                }
                polys.Add(polygons);
            }
        }
Example #3
0
        public static void GenerateConcentricInfill(ConfigSettings config, Polygons partOutline, Polygons fillPolygons, long extrusionWidthOverride_um = 0)
        {
            if (extrusionWidthOverride_um == 0)
            {
                extrusionWidthOverride_um = config.ExtrusionWidth_um;
            }

            Polygons outlineCopy = new Polygons(partOutline);
            foreach (Polygon outline in outlineCopy)
            {
                if (outline.Count > 0)
                {
                    outline.Add(outline[0]);
                }
            }
            int linespacing_um = (int)(extrusionWidthOverride_um / (config.InfillPercent / 100));
            while (outlineCopy.Count > 0)
            {
                for (int outlineIndex = 0; outlineIndex < outlineCopy.Count; outlineIndex++)
                {
                    Polygon r = outlineCopy[outlineIndex];
                    fillPolygons.Add(r);
                }
                outlineCopy = outlineCopy.Offset(-linespacing_um);
                foreach (Polygon outline in outlineCopy)
                {
                    if (outline.Count > 0)
                    {
                        outline.Add(outline[0]);
                    }
                }
            }
        }
 //插入路径或多边形集合
 public void AddPathsOrPologons(Paths inpaths, bool pathtype)
 {
     foreach (Path tempths in inpaths)
     {
         mOriginalPathsSet.Add(tempths);
         mPathTypestates.Add(pathtype);
     }
 }
 public AvoidCrossingPerimeters(Polygons boundaryPolygons)
 {
     this.boundaryPolygons = boundaryPolygons;
     minXPosition = new long[boundaryPolygons.Count];
     maxXPosition = new long[boundaryPolygons.Count];
     indexOfMinX = new int[boundaryPolygons.Count];
     indexOfMaxX = new int[boundaryPolygons.Count];
 }
Example #6
0
 ////////////////////////////////////////////////
 static Polygons ExPolygons2Polygons(ExPolygons epgs)
 {
     Polygons result = new Polygons();
     foreach (ExPolygon epg in epgs)
     {
         result.Add(epg.outer);
         foreach (Polygon hole in epg.holes)
             result.Add(hole);
     }
     return result;
 }
        private ClipperPolygons CombineLineSegments(ClipperPolygons lines)
        {
            PolylineReduction reduction = new PolylineReduction();

            foreach (var points in lines)
            {
                reduction.AddLine(points);
            }

            return reduction.Reduce();
        }
Example #8
0
        ////////////////////////////////////////////////
        static bool LoadFromFile(string filename, Polygons ppg, int dec_places, int xOffset = 0, int yOffset = 0)
        {
            double scaling;
            scaling = Math.Pow(10, dec_places);

            ppg.Clear();
            if (!File.Exists(filename)) return false;
            StreamReader sr = new StreamReader(filename);
            if (sr == null) return false;
            string line;
            if ((line = sr.ReadLine()) == null) return false;
            int polyCnt, vertCnt;
            if (!Int32.TryParse(line, out polyCnt) || polyCnt < 0) return false;
            ppg.Capacity = polyCnt;
            for (int i = 0; i < polyCnt; i++)
            {
                if ((line = sr.ReadLine()) == null) return false;
                if (!Int32.TryParse(line, out vertCnt) || vertCnt < 0) return false;
                Polygon pg = new Polygon(vertCnt);
                ppg.Add(pg);
                if (scaling > 0.999 & scaling < 1.001)
                    for (int j = 0; j < vertCnt; j++)
                    {
                        Int64 x, y;
                        if ((line = sr.ReadLine()) == null) return false;
                        char[] delimiters = new char[] { ',', ' ' };
                        string[] vals = line.Split(delimiters);
                        if (vals.Length < 2) return false;
                        if (!Int64.TryParse(vals[0], out x)) return false;
                        if (!Int64.TryParse(vals[1], out y))
                            if (vals.Length < 2 || !Int64.TryParse(vals[2], out y)) return false;
                        x = x + xOffset;
                        y = y + yOffset;
                        pg.Add(new IntPoint(x, y));
                    }
                else
                    for (int j = 0; j < vertCnt; j++)
                    {
                        double x, y;
                        if ((line = sr.ReadLine()) == null) return false;
                        char[] delimiters = new char[] { ',', ' ' };
                        string[] vals = line.Split(delimiters);
                        if (vals.Length < 2) return false;
                        if (!double.TryParse(vals[0], out x)) return false;
                        if (!double.TryParse(vals[1], out y))
                            if (vals.Length < 2 || !double.TryParse(vals[2], out y)) return false;
                        x = x * scaling + xOffset;
                        y = y * scaling + yOffset;
                        pg.Add(new IntPoint((Int64)Math.Round(x), (Int64)Math.Round(y)));
                    }
            }
            return true;
        }
Example #9
0
        public static bool GetPoint(Vector2[] quad, bool outter, out List<Vector2> list, bool isClose=true)
        {
            List<IntPoint> quadLines = new List<IntPoint>();
            for(int i=0; i < quad.Length; i++){
                Vector3 from = quad[i];
                IntPoint to = new IntPoint(from.x * DrawHelper.ClipScalling, from.y * DrawHelper.ClipScalling);
                quadLines.Add(to);

                //				IntPoint to = quad[i+1];
                //				to = new IntPoint(to.X * scale.X * scalling, to.Y * scale.Y * scalling);
                //				quadLines.Add(to);
            }

            EndType endType = EndType.etOpenButt;
            if(isClose){
                endType = EndType.etClosedPolygon;
            }

            //Debug.Log("endType: " + endType);

            ClipperOffset co = new ClipperOffset();
            co.AddPath(quadLines, JoinType.jtMiter, endType);
            Paths solution = new Paths();
            double delta = -DrawHelper.WallThick/2 * DrawHelper.ClipScalling;
            if(outter){
                delta = -delta;
            }

            co.MiterLimit = 8;
            co.Execute(ref solution, delta);

            list = new List<Vector2>();

            if(solution.Count > 0){
                foreach(IntPoint p in solution[0]){
                    Vector3 re = new Vector3(p.X * 1.0f/DrawHelper.ClipScalling, p.Y * 1.0f/DrawHelper.ClipScalling, 0f);

                    if(!isClose){
                        //Debug.Log("result: " + re);
                    }

                    list.Add(re);
                }
                list.Add(list[0]);
                return Clipper.Orientation(solution[0]);
            }
            else{
                Debug.LogError("no solution..");
            }

            return true;
        }
Example #10
0
 public void Calculate(Polygons polys)
 {
     min = new IntPoint(long.MaxValue, long.MaxValue);
     max = new IntPoint(long.MinValue, long.MinValue);
     for (int i = 0; i < polys.Count; i++)
     {
         for (int j = 0; j < polys[i].Count; j++)
         {
             if (min.X > polys[i][j].X) min.X = polys[i][j].X;
             if (min.Y > polys[i][j].Y) min.Y = polys[i][j].Y;
             if (max.X < polys[i][j].X) max.X = polys[i][j].X;
             if (max.Y < polys[i][j].Y) max.Y = polys[i][j].Y;
         }
     }
 }
        private void AddPolygonCollider2DElements(ClipperPolygons polygons, List<XElement> xmlList)
        {
            if (polygons.Count == 0)
                return;

            // Add just one polygon collider that has all paths in it.
            List<XElement> pathElements = new List<XElement>();
            foreach (var path in polygons)
            {
                string data = String.Join(" ", path.Select(pt => String.Format("{0},{1}", pt.X * Program.Scale, pt.Y * Program.Scale)));
                XElement pathElement = new XElement("Path", data);
                pathElements.Add(pathElement);
            }

            XElement polyColliderElement = new XElement("PolygonCollider2D", pathElements);
            xmlList.Add(polyColliderElement);
        }
        private void AddEdgeCollider2DElements(ClipperPolygons lines, List<XElement> xmlList)
        {
            if (lines.Count == 0)
                return;

            // Add one edge collider for every polyline
            // Clipper does not combine line segments for us
            var combined = CombineLineSegments(lines);
            foreach (var points in combined)
            {
                string data = String.Join(" ", points.Select(pt => String.Format("{0},{1}", pt.X * Program.Scale, pt.Y * Program.Scale)));
                XElement edgeCollider =
                    new XElement("EdgeCollider2D",
                        new XElement("Points", data));

                xmlList.Add(edgeCollider);
            }
        }
Example #13
0
        public static void GenerateGridInfill(ConfigSettings config, Polygons partOutline, Polygons fillPolygons, double fillAngle, int linespacing_um = 0)
        {
            if (linespacing_um == 0)
            {
                if (config.InfillPercent <= 0)
                {
                    throw new Exception("infillPercent must be greater than 0.");
                }
                linespacing_um = (int)(config.ExtrusionWidth_um / (config.InfillPercent / 100) * 2);
            }

            Infill.GenerateLinePaths(partOutline, fillPolygons, linespacing_um, config.InfillExtendIntoPerimeter_um, fillAngle);

            fillAngle += 90;
            if (fillAngle > 360)
            {
                fillAngle -= 360;
            }

            Infill.GenerateLinePaths(partOutline, fillPolygons, linespacing_um, config.InfillExtendIntoPerimeter_um, fillAngle);
        }
        public void CreateWipeShield(int totalLayers, ConfigSettings config)
        {
            if (config.WipeShieldDistanceFromShapes_um <= 0)
            {
                return;
            }

            for (int layerIndex = 0; layerIndex < totalLayers; layerIndex++)
            {
                Polygons wipeShield = new Polygons();
                for (int extruderIndex = 0; extruderIndex < this.Extruders.Count; extruderIndex++)
                {
                    for (int islandIndex = 0; islandIndex < this.Extruders[extruderIndex].Layers[layerIndex].Islands.Count; islandIndex++)
                    {
                        wipeShield = wipeShield.CreateUnion(this.Extruders[extruderIndex].Layers[layerIndex].Islands[islandIndex].IslandOutline.Offset(config.WipeShieldDistanceFromShapes_um));
                    }
                }
                this.wipeShield.Add(wipeShield);
            }

            for (int layerIndex = 0; layerIndex < totalLayers; layerIndex++)
            {
                this.wipeShield[layerIndex] = this.wipeShield[layerIndex].Offset(-1000).Offset(1000);
            }

            int offsetAngle = (int)Math.Tan(60.0 * Math.PI / 180) * config.LayerThickness_um;//Allow for a 60deg angle in the wipeShield.
            for (int layerIndex = 1; layerIndex < totalLayers; layerIndex++)
            {
                this.wipeShield[layerIndex] = this.wipeShield[layerIndex].CreateUnion(this.wipeShield[layerIndex - 1].Offset(-offsetAngle));
            }

            for (int layerIndex = totalLayers - 1; layerIndex > 0; layerIndex--)
            {
                this.wipeShield[layerIndex - 1] = this.wipeShield[layerIndex - 1].CreateUnion(this.wipeShield[layerIndex].Offset(-offsetAngle));
            }
        }
 //------------------------------------------------------------------------------
 private void BuildResult(Polygons polyg)
 {
     polyg.Clear();
     polyg.Capacity = m_PolyOuts.Count;
     foreach (OutRec outRec in m_PolyOuts)
     {
         if (outRec.pts == null) continue;
         OutPt p = outRec.pts;
         int cnt = PointCount(p);
         if (cnt < 3) continue;
         Polygon pg = new Polygon(cnt);
         for (int j = 0; j < cnt; j++)
         {
             pg.Add(p.pt);
             p = p.next;
         }
         polyg.Add(pg);
     }
 }
 //------------------------------------------------------------------------------
 public bool Execute(ClipType clipType, Polygons solution)
 {
     return Execute(clipType, solution,
         PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd);
 }
 //------------------------------------------------------------------------------
 public bool AddPolygons(Polygons ppg, PolyType polyType)
 {
     bool result = false;
     for (int i = 0; i < ppg.Count; ++i)
         if (AddPolygon(ppg[i], polyType)) result = true;
     return result;
 }
 //------------------------------------------------------------------------------
 public bool Execute(ClipType clipType, Polygons solution,
     PolyFillType subjFillType, PolyFillType clipFillType)
 {
     if (m_ExecuteLocked) return false;
     m_ExecuteLocked = true;
     solution.Clear();
     m_SubjFillType = subjFillType;
     m_ClipFillType = clipFillType;
     m_ClipType = clipType;
     bool succeeded = ExecuteInternal(false);
     //build the return polygons ...
     if (succeeded) BuildResult(solution);
     m_ExecuteLocked = false;
     return succeeded;
 }
 //------------------------------------------------------------------------------
 public static Polygons SimplifyPolygons(Polygons polys)
 {
     Polygons result = new Polygons();
     Clipper c = new Clipper();
     c.AddPolygons(polys, PolyType.ptSubject);
     c.Execute(ClipType.ctUnion, result);
     return result;
 }
            public PolyOffsetBuilder(Polygons pts, Polygons solution, double delta, JoinType jointype, double MiterLimit = 2)
            {
                //precondtion: solution != pts

                if (delta == 0)
                {
                    solution = pts;
                    return;
                }

                this.pts = pts;
                this.delta = delta;
                if (MiterLimit <= 1) MiterLimit = 1;
                double RMin = 2/(MiterLimit*MiterLimit);

                normals = new List<DoublePoint>();

                double deltaSq = delta*delta;
                solution.Clear();
                solution.Capacity = pts.Count;
                for (m_i = 0; m_i < pts.Count; m_i++)
                {
                    int len = pts[m_i].Count;
                    if (len > 1 && pts[m_i][0].X == pts[m_i][len - 1].X &&
                        pts[m_i][0].Y == pts[m_i][len - 1].Y) len--;

                    if (len == 0 || (len < 3 && delta <= 0))
                        continue;
                    else if (len == 1)
                    {
                        Polygon arc;
                        arc = BuildArc(pts[m_i][len - 1], 0, 2 * Math.PI, delta);
                        solution.Add(arc);
                        continue;
                    }

                    //build normals ...
                    normals.Clear();
                    normals.Capacity = len;
                    for (int j = 0; j < len -1; ++j)
                        normals.Add(GetUnitNormal(pts[m_i][j], pts[m_i][j+1]));
                    normals.Add(GetUnitNormal(pts[m_i][len - 1], pts[m_i][0]));

                    currentPoly = new Polygon();
                    m_k = len - 1;
                    for (m_j = 0; m_j < len; ++m_j)
                    {
                        switch (jointype)
                        {
                            case JoinType.jtMiter:
                            {
                                m_R = 1 + (normals[m_j].X*normals[m_k].X +
                                    normals[m_j].Y*normals[m_k].Y);
                                if (m_R >= RMin) DoMiter(); else DoSquare(MiterLimit);
                                break;
                            }
                            case JoinType.jtRound:
                                DoRound();
                                break;
                            case JoinType.jtSquare:
                                DoSquare(1);
                                break;
                        }
                        m_k = m_j;
                    }
                    solution.Add(currentPoly);
                }

                //finally, clean up untidy corners ...
                Clipper clpr = new Clipper();
                clpr.AddPolygons(solution, PolyType.ptSubject);
                if (delta > 0)
                {
                    clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftPositive, PolyFillType.pftPositive);
                }
                else
                {
                    IntRect r = clpr.GetBounds();
                    Polygon outer = new Polygon(4);

                    outer.Add(new IntPoint(r.left - 10, r.bottom + 10));
                    outer.Add(new IntPoint(r.right + 10, r.bottom + 10));
                    outer.Add(new IntPoint(r.right + 10, r.top - 10));
                    outer.Add(new IntPoint(r.left - 10, r.top - 10));

                    clpr.AddPolygon(outer, PolyType.ptSubject);
                    clpr.Execute(ClipType.ctUnion, solution, PolyFillType.pftNegative, PolyFillType.pftNegative);
                    if (solution.Count > 0)
                    {
                        solution.RemoveAt(0);
                        for (int i = 0; i < solution.Count; i++)
                            solution[i].Reverse();
                    }
                }
            }
 //------------------------------------------------------------------------------
 public static Polygons OffsetPolygons(Polygons poly, double delta)
 {
     Polygons result = new Polygons(poly.Count);
     new PolyOffsetBuilder(poly, result, delta, JoinType.jtSquare, 2.0);
     return result;
 }
 //------------------------------------------------------------------------------
 public static Polygons OffsetPolygons(Polygons poly, double delta,
     JoinType jointype, double MiterLimit)
 {
     Polygons result = new Polygons(poly.Count);
     new PolyOffsetBuilder(poly, result, delta, jointype, MiterLimit);
     return result;
 }
Example #23
0
        private void WriteSupportPolygons(SliceDataStorage storage, GCodePlanner gcodeLayer, int layerIndex, ConfigSettings config, Polygons supportPolygons, SupportType interfaceLayer)
        {
            for (int volumeIndex = 0; volumeIndex < storage.volumes.Count; volumeIndex++)
            {
                SliceLayer layer = storage.volumes[volumeIndex].layers[layerIndex];
                for (int partIndex = 0; partIndex < layer.parts.Count; partIndex++)
                {
                    supportPolygons = supportPolygons.CreateDifference(layer.parts[partIndex].TotalOutline.Offset(config.supportXYDistance_um));
                }
            }

            //Contract and expand the support polygons so small sections are removed and the final polygon is smoothed a bit.
            supportPolygons = supportPolygons.Offset(-config.extrusionWidth_um * 1);
            supportPolygons = supportPolygons.Offset(config.extrusionWidth_um * 1);

            List<Polygons> supportIslands = supportPolygons.CreateLayerOutlines(PolygonsHelper.LayerOpperation.EvenOdd);
            PathOrderOptimizer islandOrderOptimizer = new PathOrderOptimizer(gcode.GetPositionXY());

            for (int islandIndex = 0; islandIndex < supportIslands.Count; islandIndex++)
            {
                islandOrderOptimizer.AddPolygon(supportIslands[islandIndex][0]);
            }
            islandOrderOptimizer.Optimize();

            for (int islandIndex = 0; islandIndex < supportIslands.Count; islandIndex++)
            {
                Polygons island = supportIslands[islandOrderOptimizer.bestPolygonOrderIndex[islandIndex]];
                Polygons supportLines = new Polygons();
                if (config.supportLineSpacing_um > 0)
                {
                    switch (interfaceLayer)
                    {
                        case SupportType.Interface:
                            Infill.GenerateLineInfill(config, island, ref supportLines, config.supportInfillStartingAngle + 90, config.extrusionWidth_um);
                            break;

                        case SupportType.General:
                            switch (config.supportType)
                            {
                                case ConfigConstants.SUPPORT_TYPE.GRID:
                                    Infill.GenerateGridInfill(config, island, ref supportLines, config.supportInfillStartingAngle, config.supportLineSpacing_um);
                                    break;

                                case ConfigConstants.SUPPORT_TYPE.LINES:
                                    Infill.GenerateLineInfill(config, island, ref supportLines, config.supportInfillStartingAngle, config.supportLineSpacing_um);
                                    break;
                            }
                            break;

                        default:
                            throw new NotImplementedException();
                    }
                }

                if (config.avoidCrossingPerimeters)
                {
                    gcodeLayer.SetOuterPerimetersToAvoidCrossing(island);
                }

                switch (interfaceLayer)
                {
                    case SupportType.Interface:
                        gcodeLayer.WritePolygonsByOptimizer(supportLines, supportInterfaceConfig);
                        break;

                    case SupportType.General:
                        if (config.supportType == ConfigConstants.SUPPORT_TYPE.GRID)
                        {
                            gcodeLayer.WritePolygonsByOptimizer(island, supportNormalConfig);
                        }
                        gcodeLayer.WritePolygonsByOptimizer(supportLines, supportNormalConfig);
                        break;

                    default:
                        throw new NotImplementedException();
                }

                gcodeLayer.SetOuterPerimetersToAvoidCrossing(null);
            }
        }
Example #24
0
        private void CreateWipeShields(SliceDataStorage storage, int totalLayers)
        {
            for (int layerNr = 0; layerNr < totalLayers; layerNr++)
            {
                Polygons wipeShield = new Polygons();
                for (int volumeIdx = 0; volumeIdx < storage.volumes.Count; volumeIdx++)
                {
                    for (int partNr = 0; partNr < storage.volumes[volumeIdx].layers[layerNr].parts.Count; partNr++)
                    {
                        wipeShield = wipeShield.CreateUnion(storage.volumes[volumeIdx].layers[layerNr].parts[partNr].TotalOutline.Offset(config.wipeShieldDistanceFromShapes_um));
                    }
                }
                storage.wipeShield.Add(wipeShield);
            }

            for (int layerIndex = 0; layerIndex < totalLayers; layerIndex++)
            {
                storage.wipeShield[layerIndex] = storage.wipeShield[layerIndex].Offset(-1000).Offset(1000);
            }

            int offsetAngle = (int)Math.Tan(60.0 * Math.PI / 180) * config.layerThickness_um;//Allow for a 60deg angle in the wipeShield.
            for (int layerNr = 1; layerNr < totalLayers; layerNr++)
            {
                storage.wipeShield[layerNr] = storage.wipeShield[layerNr].CreateUnion(storage.wipeShield[layerNr - 1].Offset(-offsetAngle));
            }

            for (int layerNr = totalLayers - 1; layerNr > 0; layerNr--)
            {
                storage.wipeShield[layerNr - 1] = storage.wipeShield[layerNr - 1].CreateUnion(storage.wipeShield[layerNr].Offset(-offsetAngle));
            }
        }
Example #25
0
 //------------------------------------------------------------------------------
 void SaveToFile(string filename, Polygons ppg, int scale = 0)
 {
     double scaling = Math.Pow(10, scale);
     StreamWriter writer = new StreamWriter(filename);
     if (writer == null) return;
     writer.Write("{0}\n", ppg.Count);
     foreach (Polygon pg in ppg)
     {
         writer.Write("{0}\n", pg.Count);
         foreach (IntPoint ip in pg)
             writer.Write("{0:0.0000}, {1:0.0000}\n",
                 (double)ip.X/scaling, (double)ip.Y/scaling);
     }
     writer.Close();
 }
Example #26
0
        //---------------------------------------------------------------------------
        private void DrawBitmap(bool justClip = false)
        {
            if (!justClip)
            {
                if (rbTest2.Checked)
                    GenerateAustPlusRandomEllipses((int)nudCount.Value);
                else
                    GenerateRandomPolygon((int)nudCount.Value);
            }

            Cursor.Current = Cursors.WaitCursor;
            Graphics newgraphic;
            newgraphic = Graphics.FromImage(mybitmap);
            newgraphic.SmoothingMode = SmoothingMode.AntiAlias;
            newgraphic.Clear(Color.White);

            GraphicsPath path = new GraphicsPath();
            if (rbNonZero.Checked) path.FillMode = FillMode.Winding;

            //draw subjects ...
            foreach (Polygon pg in subjects)
            {
                PointF[] pts = PolygonToPointFArray(pg, scale);
                path.AddPolygon(pts);
                pts = null;
            }
            Pen myPen = new Pen(Color.FromArgb(196, 0xC3, 0xC9, 0xCF), (float)0.6);
            SolidBrush myBrush = new SolidBrush(Color.FromArgb(127, 0xDD, 0xDD, 0xF0));
            newgraphic.FillPath(myBrush, path);
            newgraphic.DrawPath(myPen, path);
            path.Reset();

            //draw clips ...
            if (rbNonZero.Checked) path.FillMode = FillMode.Winding;
            foreach (Polygon pg in clips)
            {
                PointF[] pts = PolygonToPointFArray(pg, scale);
                path.AddPolygon(pts);
                pts = null;
            }
            myPen.Color = Color.FromArgb(196, 0xF9, 0xBE, 0xA6);
            myBrush.Color = Color.FromArgb(127, 0xFF, 0xE0, 0xE0);
            newgraphic.FillPath(myBrush, path);
            newgraphic.DrawPath(myPen, path);

            //do the clipping ...
            if ((clips.Count > 0 || subjects.Count > 0) && !rbNone.Checked)
            {
                Polygons solution2 = new Polygons();
                Clipper c = new Clipper();
                c.AddPolygons(subjects, PolyType.ptSubject);
                c.AddPolygons(clips, PolyType.ptClip);
                exSolution.Clear();
                solution.Clear();
                bool succeeded = c.Execute(GetClipType(), solution, GetPolyFillType(), GetPolyFillType());
                if (succeeded)
                {
                    myBrush.Color = Color.Black;
                    path.Reset();

                    //It really shouldn't matter what FillMode is used for solution
                    //polygons because none of the solution polygons overlap.
                    //However, FillMode.Winding will show any orientation errors where
                    //holes will be stroked (outlined) correctly but filled incorrectly  ...
                    path.FillMode = FillMode.Winding;

                    //or for something fancy ...
                    if (nudOffset.Value != 0)
                        solution2 = Clipper.OffsetPolygons(solution, (double)nudOffset.Value * scale, JoinType.jtMiter);
                    else
                        solution2 = new Polygons(solution);
                    foreach (Polygon pg in solution2)
                    {
                        PointF[] pts = PolygonToPointFArray(pg, scale);
                        if (pts.Count() > 2)
                            path.AddPolygon(pts);
                        pts = null;
                    }
                    myBrush.Color = Color.FromArgb(127, 0x66, 0xEF, 0x7F);
                    myPen.Color = Color.FromArgb(255, 0, 0x33, 0);
                    myPen.Width = 1.0f;
                    newgraphic.FillPath(myBrush, path);
                    newgraphic.DrawPath(myPen, path);

                    //now do some fancy testing ...
                    Font f = new Font("Arial", 8);
                    SolidBrush b = new SolidBrush(Color.Navy);
                    double subj_area = 0, clip_area = 0, int_area = 0, union_area = 0;
                    c.Clear();
                    c.AddPolygons(subjects, PolyType.ptSubject);
                    c.Execute(ClipType.ctUnion, solution2, GetPolyFillType(), GetPolyFillType());
                    foreach (Polygon pg in solution2) subj_area += Clipper.Area(pg);
                    c.Clear();
                    c.AddPolygons(clips, PolyType.ptClip);
                    c.Execute(ClipType.ctUnion, solution2, GetPolyFillType(), GetPolyFillType());
                    foreach (Polygon pg in solution2) clip_area += Clipper.Area(pg);
                    c.AddPolygons(subjects, PolyType.ptSubject);
                    c.Execute(ClipType.ctIntersection, solution2, GetPolyFillType(), GetPolyFillType());
                    foreach (Polygon pg in solution2) int_area += Clipper.Area(pg);
                    c.Execute(ClipType.ctUnion, solution2, GetPolyFillType(), GetPolyFillType());
                    foreach (Polygon pg in solution2) union_area += Clipper.Area(pg);

                    StringFormat lftStringFormat = new StringFormat();
                    lftStringFormat.Alignment = StringAlignment.Near;
                    lftStringFormat.LineAlignment = StringAlignment.Near;
                    StringFormat rtStringFormat = new StringFormat();
                    rtStringFormat.Alignment = StringAlignment.Far;
                    rtStringFormat.LineAlignment = StringAlignment.Near;
                    Rectangle rec = new Rectangle(pictureBox1.ClientSize.Width - 108,
                        pictureBox1.ClientSize.Height - 116, 104, 106);
                    newgraphic.FillRectangle(new SolidBrush(Color.FromArgb(196, Color.WhiteSmoke)), rec);
                    newgraphic.DrawRectangle(myPen, rec);
                    rec.Inflate(new Size(-2, 0));
                    newgraphic.DrawString("Areas", f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 14));
                    newgraphic.DrawString("subj: ", f, b, rec, lftStringFormat);
                    newgraphic.DrawString((subj_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 12));
                    newgraphic.DrawString("clip: ", f, b, rec, lftStringFormat);
                    newgraphic.DrawString((clip_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 12));
                    newgraphic.DrawString("intersect: ", f, b, rec, lftStringFormat);
                    newgraphic.DrawString((int_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 12));
                    newgraphic.DrawString("---------", f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 10));
                    newgraphic.DrawString("s + c - i: ", f, b, rec, lftStringFormat);
                    newgraphic.DrawString(((subj_area + clip_area - int_area) / 100000).ToString("0,0"), f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 10));
                    newgraphic.DrawString("---------", f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 10));
                    newgraphic.DrawString("union: ", f, b, rec, lftStringFormat);
                    newgraphic.DrawString((union_area / 100000).ToString("0,0"), f, b, rec, rtStringFormat);
                    rec.Offset(new Point(0, 10));
                    newgraphic.DrawString("---------", f, b, rec, rtStringFormat);
                } //end if succeeded
            } //end if something to clip

            pictureBox1.Image = mybitmap;
            newgraphic.Dispose();
            Cursor.Current = Cursors.Default;
        }
Example #27
0
        //---------------------------------------------------------------------
        private void Form1_Load(object sender, EventArgs e)
        {
            mybitmap = new Bitmap(
                pictureBox1.ClientRectangle.Width,
                pictureBox1.ClientRectangle.Height,
                PixelFormat.Format32bppArgb);

            subjects = new Polygons();
            clips = new Polygons();
            solution = new Polygons();
            exSolution = new ExPolygons();

            toolStripStatusLabel1.Text =
                "Tip: Use the mouse-wheel (or +,-,0) to adjust the offset of the solution polygons.";
            DrawBitmap();
        }
Example #28
0
        private void addWipeTower(SliceDataStorage storage, GCodePlanner gcodeLayer, int layerNr, int prevExtruder, int extrusionWidth_um)
        {
            if (config.wipeTowerSize_um < 1)
            {
                return;
            }

            //If we changed extruder, print the wipe/prime tower for this nozzle;
            gcodeLayer.WritePolygonsByOptimizer(storage.wipeTower, supportInterfaceConfig);
            Polygons fillPolygons = new Polygons();
            Infill.GenerateLinePaths(storage.wipeTower, ref fillPolygons, extrusionWidth_um, config.infillExtendIntoPerimeter_um, 45 + 90 * (layerNr % 2));
            gcodeLayer.WritePolygonsByOptimizer(fillPolygons, supportInterfaceConfig);

            //Make sure we wipe the old extruder on the wipe tower.
            gcodeLayer.WriteTravel(storage.wipePoint - config.extruderOffsets[prevExtruder] + config.extruderOffsets[gcodeLayer.getExtruder()]);
        }
Example #29
0
 public void AddPolygons(Polygons poly)
 {
     if (poly.Count == 0) return;
     PolyInfo pi = new PolyInfo();
     pi.polygons = poly;
     pi.si = style.Clone();
     PolyInfoList.Add(pi);
 }
Example #30
0
        private void CalculateInfillData(SliceDataStorage storage, int volumeIndex, int layerIndex, SliceLayerPart part, ref Polygons fillPolygons, ref Polygons bridgePolygons)
        {
            // generate infill the bottom layers including bridging
            foreach (Polygons outline in part.SolidBottomOutlines.CreateLayerOutlines(PolygonsHelper.LayerOpperation.EvenOdd))
            {
                if (layerIndex > 0)
                {
                    double bridgeAngle;
                    if (Bridge.BridgeAngle(outline, storage.volumes[volumeIndex].layers[layerIndex - 1], out bridgeAngle))
                    {
                        Infill.GenerateLinePaths(outline, ref bridgePolygons, config.extrusionWidth_um, config.infillExtendIntoPerimeter_um, bridgeAngle);
                    }
                    else
                    {
                        Infill.GenerateLinePaths(outline, ref fillPolygons, config.extrusionWidth_um, config.infillExtendIntoPerimeter_um, config.infillStartingAngle);
                    }
                }
                else
                {
                    Infill.GenerateLinePaths(outline, ref fillPolygons, config.firstLayerExtrusionWidth_um, config.infillExtendIntoPerimeter_um, config.infillStartingAngle);
                }
            }

            // generate infill for the top layers
            foreach (Polygons outline in part.SolidTopOutlines.CreateLayerOutlines(PolygonsHelper.LayerOpperation.EvenOdd))
            {
                Infill.GenerateLinePaths(outline, ref fillPolygons, config.extrusionWidth_um, config.infillExtendIntoPerimeter_um, config.infillStartingAngle);
            }

            // generate infill intermediate layers
            foreach (Polygons outline in part.SolidInfillOutlines.CreateLayerOutlines(PolygonsHelper.LayerOpperation.EvenOdd))
            {
                if (true) // use the old infill method
                {
                    Infill.GenerateLinePaths(outline, ref fillPolygons, config.extrusionWidth_um, config.infillExtendIntoPerimeter_um, config.infillStartingAngle + 90 * (layerIndex % 2));
                }
                else // use the new concentric infill (not tested enough yet) have to handle some bad casses better
                {
                    double oldInfillPercent = config.infillPercent;
                    config.infillPercent = 100;
                    Infill.GenerateConcentricInfill(config, outline, ref fillPolygons);
                    config.infillPercent = oldInfillPercent;
                }
            }

            double fillAngle = config.infillStartingAngle;

            // generate the infill for this part on this layer
            if (config.infillPercent > 0)
            {
                switch (config.infillType)
                {
                    case ConfigConstants.INFILL_TYPE.LINES:
                        if ((layerIndex & 1) == 1)
                        {
                            fillAngle += 90;
                        }
                        Infill.GenerateLineInfill(config, part.InfillOutlines, ref fillPolygons, fillAngle);
                        break;

                    case ConfigConstants.INFILL_TYPE.GRID:
                        Infill.GenerateGridInfill(config, part.InfillOutlines, ref fillPolygons, fillAngle);
                        break;

                    case ConfigConstants.INFILL_TYPE.TRIANGLES:
                        Infill.GenerateTriangleInfill(config, part.InfillOutlines, ref fillPolygons, fillAngle);
                        break;

                    case ConfigConstants.INFILL_TYPE.HEXAGON:
                        Infill.GenerateHexagonInfill(config, part.InfillOutlines, ref fillPolygons, fillAngle, layerIndex);
                        break;

                    case ConfigConstants.INFILL_TYPE.CONCENTRIC:
                        Infill.GenerateConcentricInfill(config, part.InfillOutlines, ref fillPolygons);
                        break;

                    default:
                        throw new NotImplementedException();
                }
            }
        }