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); } } }
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); } }
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]; }
//////////////////////////////////////////////// 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(); }
//////////////////////////////////////////////// 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; }
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; }
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); } }
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; }
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); } }
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)); } }
//------------------------------------------------------------------------------ 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(); }
//--------------------------------------------------------------------------- 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; }
//--------------------------------------------------------------------- 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(); }
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()]); }
public void AddPolygons(Polygons poly) { if (poly.Count == 0) return; PolyInfo pi = new PolyInfo(); pi.polygons = poly; pi.si = style.Clone(); PolyInfoList.Add(pi); }
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(); } } }