public static Polygons ConvertToLines(Polygons polygons, bool closedLoop) { Polygons linePolygons = new Polygons(); foreach (Polygon polygon in polygons) { if (polygon.Count > 2) { int endIndex = closedLoop ? polygon.Count : polygon.Count - 1; for (int vertexIndex = 0; vertexIndex < endIndex; vertexIndex++) { linePolygons.Add(new Polygon() { polygon[vertexIndex], polygon[(vertexIndex + 1) % polygon.Count] }); } } else { linePolygons.Add(polygon); } } return(linePolygons); }
public void GenerateBase(Polygons polygonShape, double bottomWithoutBase) { if (polygonShape != null && polygonShape.Select(p => p.Count).Sum() > 3) { Polygons polysToOffset = new Polygons(); switch (BaseType) { case BaseTypes.Rectangle: polysToOffset.Add(GetBoundingPolygon(polygonShape)); break; case BaseTypes.Circle: polysToOffset.Add(GetBoundingCircle(polygonShape)); break; case BaseTypes.Outline: PolyTree polyTreeForBase = GetPolyTree(polygonShape); foreach (PolyNode polyToOffset in polyTreeForBase.Childs) { polysToOffset.Add(polyToOffset.Contour); } break; } if (polysToOffset.Count > 0) { Polygons basePolygons; if (BaseType == BaseTypes.Outline && InfillAmount > 0) { basePolygons = Offset(polysToOffset, (BaseSize + InfillAmount) * scalingForClipper); basePolygons = Offset(basePolygons, -InfillAmount * scalingForClipper); } else { basePolygons = Offset(polysToOffset, BaseSize * scalingForClipper); } basePolygons = ClipperLib.Clipper.CleanPolygons(basePolygons, 10); VertexStorage rawVectorShape = basePolygons.PolygonToPathStorage(); var vectorShape = new VertexSourceApplyTransform(rawVectorShape, Affine.NewScaling(1.0 / scalingForClipper)); var baseObject = new Object3D() { Mesh = VertexSourceToMesh.Extrude(vectorShape, zHeight: ExtrusionHeight) }; Children.Add(baseObject); baseObject.Mesh.Translate(new Vector3(0, 0, -ExtrusionHeight + bottomWithoutBase)); } else { // clear the mesh Mesh = null; } } }
void GenerateAustPlusRandomEllipses(int count) { subjects.Clear(); //load map of Australia from resource ... System.IO.Stream polyStream = Alt.IO.VirtualFile.OpenRead("AltData/Clipper/aust.bin"); int len = (int)polyStream.Length; byte[] b = new byte[len]; polyStream.Read(b, 0, len); int polyCnt = BitConverter.ToInt32(b, 0); int k = 4; for (int i = 0; i < polyCnt; ++i) { int vertCnt = BitConverter.ToInt32(b, k); k += 4; Polygon pg = new Polygon(vertCnt); for (int j = 0; j < vertCnt; ++j) { float x = BitConverter.ToSingle(b, k) * scale; float y = BitConverter.ToSingle(b, k + 4) * scale; k += 8; pg.Add(new IntPoint((int)x, (int)y)); } subjects.Add(pg); } clips.Clear(); Random rand = new Random(); GraphicsPath path = new GraphicsPath(); PointI pt = new PointI(); const int ellipse_size = 100, margin = 10; for (int i = 0; i < count; ++i) { int w = WorkArea.Width - ellipse_size - margin * 2; int h = WorkArea.Height - ellipse_size - margin * 2; pt.X = rand.Next(w) + margin; pt.Y = rand.Next(h) + margin; int size = rand.Next(ellipse_size - 20) + 20; path.Reset(); path.AddEllipse(pt.X, pt.Y, size, size); path.Flatten(); Polygon clip = new Polygon(path.PathPoints.Length);//Count()); foreach (Point p in path.PathPoints) { clip.Add(new IntPoint((int)(p.X * scale), (int)(p.Y * scale))); } clips.Add(clip); } }
public Form1(IOperation IOperation) //Dependency Injection { _IOperation = IOperation; InitializeComponent(); polygons = new Polygons(); //Create initial instances of two polygons polygons.Add(Factory.Factory.Instance()); polygons.Add(Factory.Factory.Instance()); }
//--------------------------------------------------------------------- private void GenerateAustPlusRandomEllipses(int count) { subjects.Clear(); //load map of Australia from resource ... _assembly = Assembly.GetExecutingAssembly(); polyStream = _assembly.GetManifestResourceStream("GuiDemo.aust.bin"); int len = (int)polyStream.Length; byte[] b = new byte[len]; polyStream.Read(b, 0, len); int polyCnt = BitConverter.ToInt32(b, 0); int k = 4; for (int i = 0; i < polyCnt; ++i) { int vertCnt = BitConverter.ToInt32(b, k); k += 4; Polygon pg = new Polygon(vertCnt); for (int j = 0; j < vertCnt; ++j) { float x = BitConverter.ToSingle(b, k) * scale; float y = BitConverter.ToSingle(b, k + 4) * scale; k += 8; pg.Add(new IntPoint((int)x, (int)y)); } subjects.Add(pg); } clips.Clear(); Random rand = new Random(); GraphicsPath path = new GraphicsPath(); Point pt = new Point(); const int ellipse_size = 100, margin = 10; for (int i = 0; i < count; ++i) { int w = pictureBox1.ClientRectangle.Width - ellipse_size - margin * 2; int h = pictureBox1.ClientRectangle.Height - ellipse_size - margin * 2 - statusStrip1.Height; pt.X = rand.Next(w) + margin; pt.Y = rand.Next(h) + margin; int size = rand.Next(ellipse_size - 20) + 20; path.Reset(); path.AddEllipse(pt.X, pt.Y, size, size); path.Flatten(); Polygon clip = new Polygon(path.PathPoints.Count()); foreach (PointF p in path.PathPoints) { clip.Add(new IntPoint((int)(p.X * scale), (int)(p.Y * scale))); } clips.Add(clip); } }
//////////////////////////////////////////////// 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 static void ProcessPolyTreeNodeIntoSeparateIslands(this Polygons polygonsIn, PolyNode node, List <Polygons> ret) { for (int n = 0; n < node.ChildCount; n++) { PolyNode child = node.Childs[n]; Polygons polygons = new Polygons(); polygons.Add(child.Contour); for (int i = 0; i < child.ChildCount; i++) { polygons.Add(child.Childs[i].Contour); polygonsIn.ProcessPolyTreeNodeIntoSeparateIslands(child.Childs[i], ret); } ret.Add(polygons); } }
//--------------------------------------------------------------------- private void GenerateAustPlusRandomEllipses(int count) { subjects.Clear(); //load map of Australia from resource ... Assembly _assembly = Assembly.GetExecutingAssembly(); using (BinaryReader polyStream = new BinaryReader(_assembly.GetManifestResourceStream("GuiDemo.aust.bin"))) { int polyCnt = polyStream.ReadInt32(); for (int i = 0; i < polyCnt; ++i) { int vertCnt = polyStream.ReadInt32(); Polygon pg = new Polygon(vertCnt); for (int j = 0; j < vertCnt; ++j) { float x = polyStream.ReadSingle() * scale; float y = polyStream.ReadSingle() * scale; pg.Add(new IntPoint((int)x, (int)y)); } subjects.Add(pg); } } clips.Clear(); Random rand = new Random(); using (GraphicsPath path = new GraphicsPath()) { const int ellipse_size = 100, margin = 10; for (int i = 0; i < count; ++i) { int w = pictureBox1.ClientRectangle.Width - ellipse_size - margin * 2; int h = pictureBox1.ClientRectangle.Height - ellipse_size - margin * 2 - statusStrip1.Height; int x = rand.Next(w) + margin; int y = rand.Next(h) + margin; int size = rand.Next(ellipse_size - 20) + 20; path.Reset(); path.AddEllipse(x, y, size, size); path.Flatten(); Polygon clip = new Polygon(path.PathPoints.Count()); foreach (PointF p in path.PathPoints) { clip.Add(new IntPoint((int)(p.X * scale), (int)(p.Y * scale))); } clips.Add(clip); } } }
public static Polygons CreateFromString(string polygonsPackedString, double scale = 1) { Polygon SinglePolygon(string polygonString) { var poly = new Polygon(); string[] intPointData = polygonString.Split(','); int increment = 2; for (int i = 0; i < intPointData.Length - 1; i += increment) { string elementX = intPointData[i]; string elementY = intPointData[i + 1]; var nextIntPoint = new IntPoint(double.Parse(elementX) * scale, double.Parse(elementY) * scale); poly.Add(nextIntPoint); } return(poly); } Polygons output = new Polygons(); string[] polygons = polygonsPackedString.Split('|'); foreach (string polygonString in polygons) { Polygon nextPoly = SinglePolygon(polygonString); if (nextPoly.Count > 0) { output.Add(nextPoly); } } return(output); }
private void SetPolygons() { var zc = ZoneContract; Polygons.Clear(); if (zc == null) { return; } Polygon poly = new Polygon() { //FillColor = Color.FromHex(zc.ARGBFill), //StrokeColor = Color.FromHex(zc.ARGBFill), FillColor = Color.FromHex(Constants.CardinalRed50ARGB), StrokeColor = Color.FromHex(Constants.CardinalRed50ARGB), StrokeWidth = 1.0f, Tag = new PolygonTag() { PolygonTagType = PolygonTagType.Zone, Tag = zc.Description } }; foreach (var shape in zc.ZoneShapes.Where(z => z.Order > 0).OrderBy(z => z.Order)) { poly.Positions.Add(new Position(shape.Latitude, shape.Longitude)); //TODO: add code to display negative space } Polygons.Add(poly); }
public void AddPolygon() { Polygon p = new Polygon(); Polygons.Add(p); Polygon = p; }
/// \brief Constructs a new Polygon. /// \return Newly created Polygon without any connections. public Polygon MakePolygon() { Polygon polygon = new Polygon(); Polygons.Add(polygon); return(polygon); }
/// <summary> /// Load existing collision /// </summary> /// <param name="buffer"></param> public void Load(byte[] buffer) { try { using (BinaryReader b = new BinaryReader(new MemoryStream(buffer))) { var polygonCount = b.ReadInt32(); for (int i = 0; i < polygonCount; i++) { var polygon = new Polygon2(); var pointNum = b.ReadInt32(); for (int p = 0; p < pointNum; p++) { var point = new K2DPosition(); point.X = b.ReadInt32(); point.Y = b.ReadInt32(); polygon.Points.Add(point); } Polygons.Add(polygon); } } XLog.WriteLine(Levels.Good, "Ok"); } catch (Exception exception) { Blank(); XLog.WriteLine(Levels.Error, "Failed"); XLog.WriteLine(Levels.Fatal, "NfaManager::Load<Exception> -> {0}", exception); } }
private void StartAnimation(object sender, EventArgs e) { _continueAnimation = true; LockButtons(Grafika002.Form1.ActionType.animation); animationPolygon = Polygon.RandomPolygon(_drawing); animationPolygon.FinnishDrawing(); animationPolygon.FillEnabled = true; Polygons.Add(animationPolygon); int maxRight = 0; while (_continueAnimation && maxRight < mainPictureBox.Width) { lock (this.mainPictureBox.Image) { _drawing.ClearBitmap(); Polygons.ForEach(x => x.DrawPolygon()); maxRight = animationPolygon.MoveRigth(); IntersectAllPolygonsWithAnimationPolygon(); this.mainPictureBox.Image = directBitmap.Bitmap; mainPictureBox.Update(); mainPictureBox.Refresh(); Application.DoEvents(); } } Polygons.Remove(animationPolygon); _drawing.ClearBitmap(); Polygons.ForEach(x => x.DrawPolygon()); this.mainPictureBox.Image = directBitmap.Bitmap; LockButtons(Grafika002.Form1.ActionType.animation, true); }
public void AddPolygon(Polygon p2) { if (!Polygons.Contains(p2)) { Polygons.Add(p2); } }
public static void AddAll(this Polygons polygons, Polygons other) { for (int n = 0; n < other.Count; n++) { polygons.Add(other[n]); } }
private void StopDrawingClick(object sender, EventArgs e) { polygon?.FinnishDrawing(); polygon = new Polygon(_drawing); Polygons.Add(polygon); RedrawPolygons(); }
private void ClipPolygons() { if (Polygons.Count != 2) { throw new InvalidOperationException("Clipping is only possible for two and exactly two polygons"); } if (Clipper == null) { throw new InvalidOperationException("No polygon clipper set"); } var resultPolygon = Clipper.GetIntersectedPolygon(Polygons[0].Points, Polygons[1].Points); if (resultPolygon.IsEmpty) { DialogHandler?.ShowMessageBox("No overlap"); } else { Polygons.Clear(); var color = GenerateRandomColor(); Polygons.Add(new Polygon { Description = "Clipped Polygon", Points = resultPolygon, StrokeColor = color, FillColor = Color.FromArgb(128, color) }); } }
//Calculate Poly's from Points private Polygons GenerateRandomCubes(int countObs) { int scale = trackBar1.Value; Polygons obs = new Polygons(); int height = rand.Next(0, pictureBox1.Width * scale / 10); int width = rand.Next(0, pictureBox1.Width * scale / 10); int x; int y; for (int i = 0; i < countObs; i++) { Polygon cube = new Polygon(); x = rand.Next(0, pictureBox1.Width * scale); y = rand.Next(0, pictureBox1.Height * scale); cube.Add(GeneratePoint(x, y)); x = x + rand.Next(0, pictureBox1.Width * scale / 10); cube.Add(GeneratePoint(x, y)); y = y + rand.Next(0, pictureBox1.Width * scale / 10); cube.Add(GeneratePoint(x, y)); x = x - rand.Next(0, pictureBox1.Width * scale / 10); cube.Add(GeneratePoint(x, y)); obs.Add(cube); } return(obs); }
private void GenerateRandomPolygon(int count) { int Q = 10; Random rand = new Random(); int l = 10; int t = 10; int r = (pictureBox1.ClientRectangle.Width - 20) / Q * Q; int b = (pictureBox1.ClientRectangle.Height - 20) / Q * Q; subjects.Clear(); clips.Clear(); Polygon subj = new Polygon(count); for (int i = 0; i < count; ++i) { subj.Add(GenerateRandomPoint(l, t, r, b, rand)); } subjects.Add(subj); Polygon clip = new Polygon(count); for (int i = 0; i < count; ++i) { clip.Add(GenerateRandomPoint(l, t, r, b, rand)); } clips.Add(clip); }
/// <summary> /// Add the 2D projection of the given arc /// to the current element outline union /// </summary> static public bool AddToUnion( Polygons union, VertexLookup vl, Clipper c, Arc arc) { IList <XYZ> pts = arc.Tessellate(); int n = pts.Count; Polygons faces = new Polygons(1); Polygon face2d = new Polygon(n); IntPoint a = vl.GetOrAdd(pts[0]); face2d.Add(a); for (int i = 1; i < n; ++i) { IntPoint b = vl.GetOrAdd(pts[i]); if (b != a) { face2d.Add(b); a = b; } } faces.Add(face2d); return(c.AddPaths(faces, PolyType.ptSubject, true)); }
public static void GenerateConcentricInfill(ConfigSettings config, Polygons partOutline, ref 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 static Polygons CreatePolygons(this IVertexSource sourcePath, double scaling = 1000) { var allPolys = new Polygons(); Polygon currentPoly = null; foreach (VertexData vertexData in sourcePath.Vertices()) { if (vertexData.command == ShapePath.FlagsAndCommand.MoveTo || vertexData.IsLineTo) { // MoveTo always creates a new polygon if (vertexData.command == ShapePath.FlagsAndCommand.MoveTo) { currentPoly = null; } // Construct current polygon if unset if (currentPoly == null) { currentPoly = new Polygon(); allPolys.Add(currentPoly); } // Add polygon point for LineTo or MoveTo command currentPoly.Add(new IntPoint(vertexData.position.X * scaling, vertexData.position.Y * scaling)); } else if (vertexData.command != ShapePath.FlagsAndCommand.FlagNone) { // Clear active, reconstructed on first valid point currentPoly = null; } } return(allPolys); }
private void AddPaddingTraectory() { //long scale = 1000; List <IntPoint> lpoint = new Polygon(); //lpoint.Add(new IntPoint(10 * scale, 10 * scale)); //lpoint.Add(new IntPoint(10 * scale, 20 * scale)); //lpoint.Add(new IntPoint(20 * scale, 20 * scale)); //lpoint.Add(new IntPoint(20 * scale, 10 * scale)); //lpoint.Add(new IntPoint(16 * scale, 10 * scale)); //lpoint.Add(new IntPoint(16 * scale, 15 * scale)); //lpoint.Add(new IntPoint(14 * scale, 15 * scale)); //lpoint.Add(new IntPoint(14 * scale, 10 * scale)); Polygons pSource = new Polygons(); Polygons pDestin = new Polygons(); pSource.Add(lpoint); pDestin = GetOffsetPolugon(pSource, (double)numericDiff.Value * 10000); ////отобразим результат //Bitmap mybitmap = new Bitmap(pictureBox1.ClientRectangle.Width, pictureBox1.ClientRectangle.Height, PixelFormat.Format32bppArgb); //using (Graphics newgraphic = Graphics.FromImage(mybitmap)) //{ // newgraphic.SmoothingMode = SmoothingMode.AntiAlias; // newgraphic.Clear(Color.White); // GraphicsPath path1 = new GraphicsPath(); // path1.FillMode = FillMode.Winding; // GraphicsPath path2 = new GraphicsPath(); // path2.FillMode = FillMode.Winding; // foreach (Polygon pg in pSource) // { // PointF[] pts = PolygonToPointFArray(pg, scale / 10); // path1.AddPolygon(pts); // pts = null; // } // foreach (Polygon pg in pDestin) // { // PointF[] pts = PolygonToPointFArray(pg, scale / 10); // path2.AddPolygon(pts); // pts = null; // } // newgraphic.DrawPath(new Pen(Color.Blue, 1.0f), path1); // newgraphic.DrawPath(new Pen(Color.Red, 1.0f), path2); //} //pictureBox1.Image = mybitmap; }
private static InfillGrid generateRaftGrid(Polygons raftOutline, float density) { //Start by calculating the endpoints of the raft long raftMinX = Global.Values.modelMinX - Global.Values.raftDistance * 2; long raftMaxX = Global.Values.modelMaxX + Global.Values.raftDistance * 2; long raftMinY = Global.Values.modelMinY - Global.Values.raftDistance * 2; long raftMaxY = Global.Values.modelMaxY + Global.Values.raftDistance * 2; Polygons rightList = new Polygons(); Polygons leftList = new Polygons(); uint spacing = caluclateNeededSpacing(density, Global.Values.nozzleWidth); uint divider = (uint)(Global.Values.nozzleWidth + spacing); uint amountOfLines = 0; //2 points of line segments IntPoint p1 = new IntPoint(); IntPoint p2 = new IntPoint(); //We need to start creating diagonal lines before the min x sothat there are lines over every part of the model long xOffset = (long)((raftMaxY - raftMinY) / Math.Tan(MathUtils.MathHelper.ToRadians(45))); raftMinX -= xOffset; amountOfLines = (uint)((raftMaxX - raftMinX) / divider); //Calculate the right and left line simeltaniously for (uint i = 0; i < amountOfLines; i++) { //First the right angled line p1.X = raftMinX + i * divider + (Global.Values.nozzleWidth / 2); p1.Y = raftMinY; p2.X = p1.X;// +xOffset; p2.Y = raftMaxY; Polygon line = new Polygon(); line.Add(p1); line.Add(p2); rightList.Add(line); } amountOfLines = (uint)((raftMaxY - raftMinY) / divider); //Calculate the right and left line simeltaniously for (uint i = 0; i < amountOfLines; i++) { p1.Y = raftMinY + i * divider + (Global.Values.nozzleWidth / 2); p1.X = raftMinX; p2.Y = p1.Y;// +xOffset; p2.X = raftMaxX; Polygon line = new Polygon(); line.Add(p1); line.Add(p2); leftList.Add(line); } return(new InfillGrid(rightList, leftList)); }
public static Polygons GetExtrusionPolygons(string[] gcode, ref MovementInfo movementInfo) { Polygons foundPolygons = new Polygons(); bool extruding = false; // check that all moves are on the outside of the cylinder (not crossing to a new point) int movementCount = 0; foreach (MovementInfo movement in TestUtlities.Movements(gcode, movementInfo)) { bool isExtrude = movement.extrusion != movementInfo.extrusion; if (extruding) { if (isExtrude) { // add to the extrusion foundPolygons[foundPolygons.Count - 1].Add(new IntPoint( (long)(movement.position.x * 1000), (long)(movement.position.y * 1000), (long)(movement.position.z * 1000))); } else { extruding = false; } } else // not extruding { if (isExtrude) { // starting a new extrusion foundPolygons.Add(new Polygon()); foundPolygons[foundPolygons.Count - 1].Add(new IntPoint( (long)(movement.position.x * 1000), (long)(movement.position.y * 1000), (long)(movement.position.z * 1000))); extruding = true; } else // do nothing waiting for extrude { int stop = 0; } } movementInfo = movement; movementCount++; } for (int i = foundPolygons.Count - 1; i >= 0; i--) { if (foundPolygons[i].Count == 1) { foundPolygons.RemoveAt(i); } } return(foundPolygons); }
/// <summary> /// Add new collision /// </summary> /// <param name="location"></param> public void Add(PointF[] points) { var polygon = _2DUtils.PointToPolygon(points); Polygons.Add(polygon); Added?.Invoke(this, polygon); }
public void AddPoly(Polygon p) { if (p.Name == string.Empty) { p.Name = nextPathName; } Polygons.Add(p); UpdateExtent(p); }
private void MovePolygonToTop(Polygon p) { if (p == null) { return; } Polygons.Remove(p); Polygons.Add(p); }
private void testpoly() { Polygons subj = new Polygons(2); subj.Add(new Polygon(4)); subj[0].Add(new IntPoint(180, 200)); subj[0].Add(new IntPoint(260, 200)); subj[0].Add(new IntPoint(260, 150)); subj[0].Add(new IntPoint(180, 150)); }
public static void GenerateLinePaths(Polygons polygonToInfill, ref Polygons infillLinesToPrint, int lineSpacing, int infillExtendIntoPerimeter_um, double rotation, long rotationOffset = 0) { if (polygonToInfill.Count > 0) { Polygons outlines = polygonToInfill.Offset(infillExtendIntoPerimeter_um); if (outlines.Count > 0) { PointMatrix matrix = new PointMatrix(-(rotation + 90)); // we are rotating the part so we rotate by the negative so the lines go the way we expect outlines.ApplyMatrix(matrix); Aabb boundary = new Aabb(outlines); boundary.min.X = ((boundary.min.X / lineSpacing) - 1) * lineSpacing - rotationOffset; int xLineCount = (int)((boundary.max.X - boundary.min.X + (lineSpacing - 1)) / lineSpacing); Polygons unclipedPatern = new Polygons(); long firstX = boundary.min.X / lineSpacing * lineSpacing; for (int lineIndex = 0; lineIndex < xLineCount; lineIndex++) { Polygon line = new Polygon(); line.Add(new IntPoint(firstX + lineIndex * lineSpacing, boundary.min.Y)); line.Add(new IntPoint(firstX + lineIndex * lineSpacing, boundary.max.Y)); unclipedPatern.Add(line); } PolyTree ret = new PolyTree(); Clipper clipper = new Clipper(); clipper.AddPaths(unclipedPatern, PolyType.ptSubject, false); clipper.AddPaths(outlines, PolyType.ptClip, true); clipper.Execute(ClipType.ctIntersection, ret, PolyFillType.pftPositive, PolyFillType.pftEvenOdd); Polygons newSegments = Clipper.OpenPathsFromPolyTree(ret); PointMatrix inversematrix = new PointMatrix((rotation + 90)); newSegments.ApplyMatrix(inversematrix); infillLinesToPrint.AddRange(newSegments); } } }
//------------------------------------------------------------------------------ public static void AddPolyNodeToPolygons(PolyNode polynode, Polygons polygons) { if (polynode.Contour.Count > 0) polygons.Add(polynode.Contour); foreach (PolyNode pn in polynode.Childs) AddPolyNodeToPolygons(pn, polygons); }
//------------------------------------------------------------------------------ private void BuildResult(Polygons polyg) { polyg.Clear(); polyg.Capacity = m_PolyOuts.Count; for (int i = 0; i < m_PolyOuts.Count; i++) { OutRec outRec = m_PolyOuts[i]; 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.prev; } polyg.Add(pg); } }
public Polygons CreateLineLoops(int pixelsToIntPointsScale, int maxLineLoopsToAdd = int.MaxValue) { Polygons LineLoops = new Polygons(); bool[] hasBeenAddedList = new bool[LineSegments.Count]; for (int segmentToAddIndex = 0; segmentToAddIndex < LineSegments.Count; segmentToAddIndex++) { if (!hasBeenAddedList[segmentToAddIndex]) { // now find all the connected segments until we get back to this one Polygon loopToAdd = new Polygon(); // walk the loop int currentSegmentIndex = segmentToAddIndex; LineSegment currentSegment = LineSegments[currentSegmentIndex]; Vector2 connectionVertex = currentSegment.end; loopToAdd.Add(new IntPoint((long)(connectionVertex.x * pixelsToIntPointsScale), (long)(connectionVertex.y * pixelsToIntPointsScale))); hasBeenAddedList[currentSegmentIndex] = true; bool addedToLoop = false; do { bool foundNextSegment = false; addedToLoop = false; for (int segmentToCheckIndex = 0; segmentToCheckIndex < LineSegments.Count; segmentToCheckIndex++) { LineSegment segmentToCheck = LineSegments[segmentToCheckIndex]; if (!hasBeenAddedList[segmentToCheckIndex]) { if (connectionVertex == segmentToCheck.start) { connectionVertex = segmentToCheck.end; foundNextSegment = true; } else if (connectionVertex == segmentToCheck.end) { connectionVertex = segmentToCheck.start; foundNextSegment = true; } else { int i = 0; } if (foundNextSegment) { hasBeenAddedList[segmentToCheckIndex] = true; currentSegmentIndex = segmentToCheckIndex; currentSegment = segmentToCheck; loopToAdd.Add(new IntPoint((long)(connectionVertex.x * pixelsToIntPointsScale), (long)(connectionVertex.y * pixelsToIntPointsScale))); addedToLoop = true; break; } } } } while (addedToLoop); LineLoops.Add(loopToAdd); if (LineLoops.Count > maxLineLoopsToAdd) { break; } } } return LineLoops; }
public static void GenerateHexLinePaths(Polygons in_outline, ref Polygons result, int lineSpacing, int infillExtendIntoPerimeter_um, double rotationDegrees, int layerIndex) { int extraRotationAngle = 0; if (in_outline.Count > 0) { Polygons outlines = in_outline.Offset(infillExtendIntoPerimeter_um); if (outlines.Count > 0) { int perIncrementOffset = (int)(lineSpacing * Math.Sqrt(3) / 2 + .5); PointMatrix matrix = new PointMatrix(-(rotationDegrees + extraRotationAngle)); // we are rotating the part so we rotate by the negative so the lines go the way we expect outlines.ApplyMatrix(matrix); Aabb boundary = new Aabb(outlines); boundary.min.X = ((boundary.min.X / lineSpacing) - 1) * lineSpacing; boundary.min.Y = ((boundary.min.Y / perIncrementOffset) - 2) * perIncrementOffset; boundary.max.X += lineSpacing; boundary.max.Y += perIncrementOffset; Polygons unclipedPatern = new Polygons(); foreach (IntPoint startPoint in StartPositionIterator(boundary, lineSpacing, layerIndex)) { Polygon attachedLine = new Polygon(); foreach (IntPoint center in IncrementPositionIterator(startPoint, boundary, lineSpacing, layerIndex)) { // what we are adding are the little plusses that define the points // | top // | // /\ center // left/ \ right // IntPoint left = center + new IntPoint(-lineSpacing / 2, -perIncrementOffset / 3); IntPoint right = center + new IntPoint(lineSpacing / 2, -perIncrementOffset / 3); IntPoint top = center + new IntPoint(0, perIncrementOffset * 2 / 3); switch (layerIndex % 3) { case 0: // left to right attachedLine.Add(left); attachedLine.Add(center); attachedLine.Add(center); attachedLine.Add(right); unclipedPatern.Add(new Polygon() { top, center }); break; case 1: // left to top attachedLine.Add(left); attachedLine.Add(center); attachedLine.Add(center); attachedLine.Add(top); unclipedPatern.Add(new Polygon() { center, right }); break; case 2: // top to right attachedLine.Add(top); attachedLine.Add(center); attachedLine.Add(center); attachedLine.Add(right); unclipedPatern.Add(new Polygon() { left, center }); break; } } if (attachedLine.Count > 0) { unclipedPatern.Add(attachedLine); } } PolyTree ret = new PolyTree(); Clipper clipper = new Clipper(); clipper.AddPaths(unclipedPatern, PolyType.ptSubject, false); clipper.AddPaths(outlines, PolyType.ptClip, true); clipper.Execute(ClipType.ctIntersection, ret, PolyFillType.pftPositive, PolyFillType.pftEvenOdd); Polygons newSegments = Clipper.OpenPathsFromPolyTree(ret); PointMatrix inversematrix = new PointMatrix((rotationDegrees + extraRotationAngle)); newSegments.ApplyMatrix(inversematrix); result.AddRange(newSegments); } } }
public Polygons GetPathsWithOverlapsRemoved(Polygon perimeter, int overlapMergeAmount_um) { // make a copy that has every point duplicatiod (so that we have them as segments). Polygon polySegments = new Polygon(perimeter.Count * 2); for (int i = 0; i < perimeter.Count - 1; i++) { IntPoint point = perimeter[i]; IntPoint nextPoint = perimeter[i + 1]; polySegments.Add(point); polySegments.Add(nextPoint); } Altered[] markedAltered = new Altered[polySegments.Count/2]; int segmentCount = polySegments.Count / 2; // now walk every segment and check if there is another segment that is similar enough to merge them together for (int firstSegmentIndex = 0; firstSegmentIndex < segmentCount; firstSegmentIndex++) { int firstPointIndex = firstSegmentIndex * 2; for (int checkSegmentIndex = firstSegmentIndex + 1; checkSegmentIndex < segmentCount; checkSegmentIndex++) { int checkPointIndex = checkSegmentIndex * 2; // The first point of start and the last point of check (the path will be coming back on itself). long startDelta = (polySegments[firstPointIndex] - polySegments[checkPointIndex + 1]).Length(); // if the segmets are similar enough if (startDelta < overlapMergeAmount_um) { // The last point of start and the first point of check (the path will be coming back on itself). long endDelta = (polySegments[firstPointIndex + 1] - polySegments[checkPointIndex]).Length(); if (endDelta < overlapMergeAmount_um) { // move the first segments points to the average of the merge positions polySegments[firstPointIndex] = (polySegments[firstPointIndex] + polySegments[checkPointIndex + 1]) / 2; // the start polySegments[firstPointIndex + 1] = (polySegments[firstPointIndex + 1] + polySegments[checkPointIndex]) / 2; // the end markedAltered[firstSegmentIndex] = Altered.merged; // mark this segment for removal markedAltered[checkSegmentIndex] = Altered.remove; // We only expect to find one match for each segment, so move on to the next segment break; } } } } // Check for perimeter edeges that need to be removed that are the u turns of sectons that go back on themselves. // __________ // |__________| -> |--------| the 2 vertical sections should be removed for (int segmentIndex = 0; segmentIndex < segmentCount; segmentIndex++) { int prevSegmentIndex = (int)((uint)(segmentIndex - 1) % (uint)segmentCount); int nextSegmentIndex = (segmentIndex + 1) % segmentCount; if ((markedAltered[nextSegmentIndex] == Altered.merged && markedAltered[prevSegmentIndex] == Altered.remove) || (markedAltered[nextSegmentIndex] == Altered.remove && markedAltered[prevSegmentIndex] == Altered.merged)) { markedAltered[segmentIndex] = Altered.remove; } } // remove the marked segments for (int segmentIndex = segmentCount - 1; segmentIndex >= 0; segmentIndex--) { int pointIndex = segmentIndex * 2; if (markedAltered[segmentIndex] == Altered.remove) { polySegments.RemoveRange(pointIndex, 2); } } // go through the polySegmets and create a new polygon for every connected set of segmets Polygons separatedPolygons = new Polygons(); Polygon currentPolygon = new Polygon(); separatedPolygons.Add(currentPolygon); // put in the first point for (int segmentIndex = 0; segmentIndex < polySegments.Count; segmentIndex += 2) { // add the start point currentPolygon.Add(polySegments[segmentIndex]); // if the next segment is not connected to this one if (segmentIndex < polySegments.Count - 2 && polySegments[segmentIndex + 1] != polySegments[segmentIndex + 2]) { // add the end point currentPolygon.Add(polySegments[segmentIndex + 1]); // create a new polygon currentPolygon = new Polygon(); separatedPolygons.Add(currentPolygon); } } // add the end point currentPolygon.Add(polySegments[polySegments.Count - 1]); return separatedPolygons; }
public static Polygons CreateFromString(string polygonsPackedString) { Polygons output = new Polygons(); string[] polygons = polygonsPackedString.Split('|'); foreach (string polygonString in polygons) { Polygon nextPoly = PolygonHelper.CreateFromString(polygonString); if (nextPoly.Count > 0) { output.Add(nextPoly); } } return output; }
private static void ProcessPolyTreeNodeIntoSeparatIslands(this Polygons polygonsIn, PolyNode node, List<Polygons> ret) { for (int n = 0; n < node.ChildCount; n++) { PolyNode child = node.Childs[n]; Polygons polygons = new Polygons(); polygons.Add(child.Contour); for (int i = 0; i < child.ChildCount; i++) { polygons.Add(child.Childs[i].Contour); polygonsIn.ProcessPolyTreeNodeIntoSeparatIslands(child.Childs[i], ret); } ret.Add(polygons); } }
public static Polygons DeepCopy(this Polygons polygons) { Polygons deepCopy = new Polygons(); foreach (Polygon poly in polygons) { deepCopy.Add(new Polygon(poly)); } return deepCopy; }
public bool BridgeAngle(Polygons areaAboveToFill, out double bridgeAngle, string debugName = "") { SliceLayer layerToRestOn = this; bridgeAngle = -1; Aabb boundaryBox = new Aabb(areaAboveToFill); //To detect if we have a bridge, first calculate the intersection of the current layer with the previous layer. // This gives us the islands that the layer rests on. Polygons islandsToRestOn = new Polygons(); foreach (LayerIsland islandToRestOn in layerToRestOn.Islands) { if (!boundaryBox.Hit(islandToRestOn.BoundingBox)) { continue; } islandsToRestOn.AddRange(areaAboveToFill.CreateIntersection(islandToRestOn.IslandOutline)); } if (OUTPUT_DEBUG_DATA) { string outlineString = areaAboveToFill.WriteToString(); string islandOutlineString = ""; foreach (LayerIsland prevLayerIsland in layerToRestOn.Islands) { foreach (Polygon islandOutline in prevLayerIsland.IslandOutline) { islandOutlineString += islandOutline.WriteToString(); } islandOutlineString += "|"; } string islandsString = islandsToRestOn.WriteToString(); } Polygons islandConvexHuls = new Polygons(); foreach(Polygon poly in islandsToRestOn) { islandConvexHuls.Add(poly.CreateConvexHull()); } if (islandsToRestOn.Count > 5 || islandsToRestOn.Count < 1) { return false; } if (islandsToRestOn.Count == 1) { return GetSingleIslandAngle(areaAboveToFill, islandsToRestOn[0], out bridgeAngle, debugName); } // Find the 2 largest islands that we rest on. double biggestArea = 0; double nextBiggestArea = 0; int indexOfBiggest = -1; int indexOfNextBigest = -1; for (int islandIndex = 0; islandIndex < islandsToRestOn.Count; islandIndex++) { //Skip internal holes if (!islandsToRestOn[islandIndex].Orientation()) { continue; } double area = Math.Abs(islandConvexHuls[islandIndex].Area()); if (area > biggestArea) { if (biggestArea > nextBiggestArea) { nextBiggestArea = biggestArea; indexOfNextBigest = indexOfBiggest; } biggestArea = area; indexOfBiggest = islandIndex; } else if (area > nextBiggestArea) { nextBiggestArea = area; indexOfNextBigest = islandIndex; } } if (indexOfBiggest < 0 || indexOfNextBigest < 0) { return false; } Polygons big1 = new Polygons() { islandConvexHuls[indexOfBiggest] }; Polygons big2 = new Polygons() { islandConvexHuls[indexOfNextBigest] }; Polygons intersection = big1.CreateIntersection(big2); if(intersection.Count > 0) { return GetSingleIslandAngle(areaAboveToFill, islandsToRestOn[indexOfBiggest], out bridgeAngle, debugName); } IntPoint center1 = islandsToRestOn[indexOfBiggest].CenterOfMass(); IntPoint center2 = islandsToRestOn[indexOfNextBigest].CenterOfMass(); bridgeAngle = Math.Atan2(center2.Y - center1.Y, center2.X - center1.X) / Math.PI * 180; Range0To360(ref bridgeAngle); if (OUTPUT_DEBUG_DATA) { islandsToRestOn.SaveToGCode("{0} - angle {1:0.}.gcode".FormatWith(debugName, bridgeAngle)); } return true; }
public static Polygons ConvertToLines(Polygons polygons) { Polygons linePolygons = new Polygons(); foreach(Polygon polygon in polygons) { if (polygon.Count > 2) { for (int vertexIndex = 0; vertexIndex < polygon.Count; vertexIndex++) { linePolygons.Add(new Polygon() { polygon[vertexIndex], polygon[(vertexIndex + 1) % polygon.Count] }); } } else { linePolygons.Add(polygon); } } return linePolygons; }
//--------------------------------------------------------------------- bool LoadFromFile(string filename, Polygons ppg, double scale = 0, int xOffset = 0, int yOffset = 0) { double scaling = Math.Pow(10, scale); 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); 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((int)Math.Round(x), (int)Math.Round(y))); } } return true; }
static private void GetAreasRecursive(PolyNode polyTreeForPlate, Polygons discreteAreas) { if (!polyTreeForPlate.IsHole) { discreteAreas.Add(polyTreeForPlate.Contour); } foreach (PolyNode child in polyTreeForPlate.Childs) { GetAreasRecursive(child, discreteAreas); } }
public void GenerateSkirt(int distance, int extrusionWidth_um, int numberOfLoops, int minLength, int initialLayerHeight, ConfigSettings config) { LayerDataStorage storage = this; bool externalOnly = (distance > 0); for (int skirtLoop = 0; skirtLoop < numberOfLoops; skirtLoop++) { int offsetDistance = distance + extrusionWidth_um * skirtLoop + extrusionWidth_um / 2; Polygons skirtPolygons = new Polygons(storage.wipeTower.Offset(offsetDistance)); for (int extrudeIndex = 0; extrudeIndex < storage.Extruders.Count; extrudeIndex++) { if (config.continuousSpiralOuterPerimeter && extrudeIndex > 0) { continue; } if (storage.Extruders[extrudeIndex].Layers.Count < 1) { continue; } SliceLayer layer = storage.Extruders[extrudeIndex].Layers[0]; for (int partIndex = 0; partIndex < layer.Islands.Count; partIndex++) { if (config.continuousSpiralOuterPerimeter && partIndex > 0) { continue; } if (externalOnly) { Polygons p = new Polygons(); p.Add(layer.Islands[partIndex].IslandOutline[0]); //p.Add(IntPointHelper.CreateConvexHull(layer.parts[partIndex].outline[0])); skirtPolygons = skirtPolygons.CreateUnion(p.Offset(offsetDistance)); } else { skirtPolygons = skirtPolygons.CreateUnion(layer.Islands[partIndex].IslandOutline.Offset(offsetDistance)); } } } if (storage.support != null) { skirtPolygons = skirtPolygons.CreateUnion(storage.support.GetBedOutlines().Offset(offsetDistance)); } //Remove small inner skirt holes. Holes have a negative area, remove anything smaller then 100x extrusion "area" for (int n = 0; n < skirtPolygons.Count; n++) { double area = skirtPolygons[n].Area(); if (area < 0 && area > -extrusionWidth_um * extrusionWidth_um * 100) { skirtPolygons.RemoveAt(n--); } } storage.skirt.AddAll(skirtPolygons); int lenght = (int)storage.skirt.PolygonLength(); if (skirtLoop + 1 >= numberOfLoops && lenght > 0 && lenght < minLength) { // add more loops for as long as we have not extruded enough length numberOfLoops++; } } }