internal void SetLineSegment(PointD A, PointD B, double Width, double Rotation) { var Dir = B - A; Dir.Normalize(); var N = Dir.Rotate(90) * Width * 0.5; Shape.Vertices.Clear(); Shape.Add(A.X - N.X, A.Y - N.Y); Shape.Add(A.X + N.X, A.Y + N.Y); Shape.Add(B.X + N.X, B.Y + N.Y); Shape.Add(B.X - N.X, B.Y - N.Y); Shape.Close(); Shape.RotateDegrees(Rotation); }
public string BuildGerber(GerberNumberFormat format, string MacroNameSuffix = "", double RotationAngle = 0) { string res = String.Format("%ADD{0}", ID.ToString("D2")); int parmcount = 0; switch (ShapeType) { case GerberApertureShape.Macro: res += MacroName + MacroNameSuffix; if (MacroParamList.Count > 0) { res += ","; } foreach (var a in MacroParamList) { parmcount++; if (parmcount >= 2) { res += "X"; } res += Gerber.ToFloatingPointString(format._ScaleMMToFile(a)).Replace(',', '.'); } break; case GerberApertureShape.Circle: { if (CircleRadius > 3) { //Console.WriteLine("test"); } res += "C," + Gerber.ToFloatingPointString(format._ScaleMMToFile(CircleRadius * 2)).Replace(',', '.'); } break; case GerberApertureShape.Rectangle: if (RotationAngle == 0 || (int)RotationAngle == 180) { res += "R," + Gerber.ToFloatingPointString(format._ScaleMMToFile(RectWidth)).Replace(',', '.') + "X" + Gerber.ToFloatingPointString(format._ScaleMMToFile(RectHeight)).Replace(',', '.'); } else { if ((int)RotationAngle == 90 || (int)RotationAngle == (-90) || (int)RotationAngle == (270)) { res += "R," + Gerber.ToFloatingPointString(format._ScaleMMToFile(RectHeight)).Replace(',', '.') + "X" + Gerber.ToFloatingPointString(format._ScaleMMToFile(RectWidth)).Replace(',', '.'); } else { string macroname = "REC" + (MacroPostFix++).ToString(); PolyLine Rect = new PolyLine(PolyLine.PolyIDs.Temp); Rect.MakeRectangle(RectWidth, RectHeight); Rect.RotateDegrees(RotationAngle); res = Gerber.BuildOutlineApertureMacro(macroname, Rect.Vertices, format) + res; res += macroname; if (Gerber.ShowProgress) { Console.WriteLine("generated rotated rect: "); } if (Gerber.ShowProgress) { Console.WriteLine(res); } } } break; case GerberApertureShape.Polygon: if (RotationAngle == 0) { res += "P," + Gerber.ToFloatingPointString(format._ScaleMMToFile(NGonRadius * 2)).Replace(',', '.') + "X" + NGonSides.ToString() + "X" + Gerber.ToFloatingPointString(NGonRotation).Replace(',', '.'); } else { double newangle = NGonRotation + RotationAngle; while (newangle < 0) { newangle += 360; } while (newangle > 360) { newangle -= 360; } res += "P," + Gerber.ToFloatingPointString(format._ScaleMMToFile(NGonRadius * 2)).Replace(',', '.') + "X" + NGonSides.ToString() + "X" + Gerber.ToFloatingPointString(newangle).Replace(',', '.'); if (Gerber.ShowProgress) { Console.WriteLine("generated rotated NGon: "); } if (Gerber.ShowProgress) { Console.WriteLine(res); } } break; case GerberApertureShape.OBround: if (RotationAngle == 0 || Math.Abs(Math.Abs(RotationAngle) - 180) < 0.01) { res += "O," + Gerber.ToFloatingPointString(format._ScaleMMToFile(RectWidth)).Replace(',', '.') + "X" + Gerber.ToFloatingPointString(format._ScaleMMToFile(RectHeight)).Replace(',', '.'); } else { if (Math.Abs(Math.Abs(RotationAngle) - 90) < 0.01) { res += "O," + Gerber.ToFloatingPointString(format._ScaleMMToFile(RectHeight)).Replace(',', '.') + "X" + Gerber.ToFloatingPointString(format._ScaleMMToFile(RectWidth)).Replace(',', '.'); } else { string macroname = "OBR" + (MacroPostFix++).ToString(); PolyLine Obround = new PolyLine(PolyLine.PolyIDs.Temp); Obround.SetObround(RectWidth, RectHeight); Obround.RotateDegrees(RotationAngle); res = Gerber.BuildOutlineApertureMacro(macroname, Obround.Vertices, format) + res; res += macroname; if (Gerber.ShowProgress) { Console.WriteLine("generated rotated obround: "); } if (Gerber.ShowProgress) { Console.WriteLine(res); } } } break; case GerberApertureShape.Compound: { string macroname = "COMP" + (MacroPostFix++).ToString() + MacroNameSuffix; string macrores = Gerber.WriteMacroStart(macroname); foreach (var P in Parts) { PolyLine Comp = new PolyLine(PolyLine.PolyIDs.Temp); foreach (var a in P.Shape.Vertices) { Comp.Add(a.X, a.Y); } Comp.Close(); Comp.RotateDegrees(RotationAngle); macrores += Gerber.WriteMacroPartVertices(Comp.Vertices, format); } macrores += Gerber.WriteMacroEnd(); res = macrores + res; res += macroname; if (Parts.Count > 1) { Console.WriteLine("Number of parts: {0} but only 1 written", Parts.Count); Console.WriteLine(res); } // res += MacroName; if (MacroParamList.Count > 0) { res += ","; } foreach (var a in MacroParamList) { parmcount++; if (parmcount >= 2) { res += "X"; } res += Gerber.ToFloatingPointString(a).Replace(',', '.'); } if (Gerber.ShowProgress) { Console.WriteLine("generated rotated compound macro shape: "); } if (Gerber.ShowProgress) { Console.WriteLine(res); } } break; default: Console.WriteLine("I don't know how to generate the source for this aperture yet."); break; } res += "*%"; return(res); }
public List <PolyLine> CreatePolyLineSet(double X, double Y, int ShapeID, double rotation, double scale, GerberParserState.MirrorMode mirrored) { List <PolyLine> Res = new List <PolyLine>(); if (Parts.Count > 0) { List <PolyLine> ResPre = new List <PolyLine>(); List <PolyLine> ResPreNeg = new List <PolyLine>(); foreach (var a in Parts.Where(x => x.Polarity == true)) { ResPre.AddRange(a.CreatePolyLineSet(0, 0, ShapeID, 0, 1, GerberParserState.MirrorMode.NoMirror)); } foreach (var a in Parts.Where(x => x.Polarity == false)) { ResPreNeg.AddRange(a.CreatePolyLineSet(0, 0, ShapeID, 0, 1, GerberParserState.MirrorMode.NoMirror)); } Polygons Combined = new Polygons(); Polygons Solution = new Polygons(); Polygons clips = new Polygons(); if (ResPreNeg.Count == 0) { foreach (var c in ResPre) { // c.CheckIfHole(); //clips.Add(c.toPolygon()); //cp.AddPolygons(clips, PolyType.ptClip); //cp.Execute(ClipType.ctUnion, Combined, PolyFillType.pftNonZero, PolyFillType.pftEvenOdd); Solution.Add(c.toPolygon()); } foreach (var p in Solution) { PolyLine PL = new PolyLine(ShapeID); PL.fromPolygon(p); Res.Add(PL); } } else { foreach (var c in ResPreNeg) { // c.CheckIfHole(); //clips.Add(c.toPolygon()); //cp.AddPolygons(clips, PolyType.ptClip); //cp.Execute(ClipType.ctUnion, Combined, PolyFillType.pftNonZero, PolyFillType.pftEvenOdd); clips.Add(c.toPolygon()); } foreach (var c in ResPre) { // c.CheckIfHole(); //clips.Add(c.toPolygon()); //cp.AddPolygons(clips, PolyType.ptClip); //cp.Execute(ClipType.ctUnion, Combined, PolyFillType.pftNonZero, PolyFillType.pftEvenOdd); Combined.Add(c.toPolygon()); } Clipper cp = new Clipper(); cp.AddPolygons(Combined, PolyType.ptClip); cp.AddPolygons(clips, PolyType.ptSubject); cp.Execute(ClipType.ctDifference, Solution, PolyFillType.pftNonZero, PolyFillType.pftNonZero); foreach (var p in Solution) { PolyLine PL = new PolyLine(ShapeID); PL.fromPolygon(p); Res.Add(PL); } } } else { if (Shape.Count() > 0) { var PL = new PolyLine(ShapeID); for (int i = 0; i < Shape.Count(); i++) { PL.Add(Shape.Vertices[i].X, Shape.Vertices[i].Y); } PL.Add(Shape.Vertices[0].X, Shape.Vertices[0].Y); PL.Close(); Res.Add(PL); } else { if (Gerber.ShowProgress) { Console.WriteLine("creating empty shape?? {0} {1}", MacroName, ShapeType); } } } if (rotation != 0 || scale != 1 || mirrored != GerberParserState.MirrorMode.NoMirror) { double CA = Math.Cos((rotation * Math.PI * 2) / 360.0); double SA = Math.Sin((rotation * Math.PI * 2) / 360.0); double xscale = scale; double yscale = scale; switch (mirrored) { case GerberParserState.MirrorMode.X: xscale = -xscale; break; case GerberParserState.MirrorMode.XY: xscale = -xscale; yscale = -yscale; break; case GerberParserState.MirrorMode.Y: yscale = -yscale; break; } foreach (var a in Res) { foreach (var p in a.Vertices) { double Xin = p.X; double Yin = p.Y; double nX = Xin * CA - Yin * SA; double nY = Xin * SA + Yin * CA; p.X = nX * xscale; p.Y = nY * yscale; } } } foreach (var a in Res) { foreach (var p in a.Vertices) { p.X += X; p.Y += Y; } } return(Res); }
public List <PolyLine> CreatePolyLineSet(double X, double Y, int ShapeID) { List <PolyLine> Res = new List <PolyLine>(); if (Parts.Count > 0) { List <PolyLine> ResPre = new List <PolyLine>(); foreach (var a in Parts) { ResPre.AddRange(a.CreatePolyLineSet(X, Y, ShapeID)); } Polygons Combined = new Polygons(); Polygons clips = new Polygons(); foreach (var c in ResPre) { // c.CheckIfHole(); //Clipper cp = new Clipper(); //cp.AddPolygons(Combined, PolyType.ptSubject); //clips.Add(c.toPolygon()); //cp.AddPolygons(clips, PolyType.ptClip); //cp.Execute(ClipType.ctUnion, Combined, PolyFillType.pftNonZero, PolyFillType.pftEvenOdd); Combined.Add(c.toPolygon()); } foreach (var p in Combined) { PolyLine PL = new PolyLine(ShapeID); PL.fromPolygon(p); Res.Add(PL); } } else { if (Shape.Count() > 0) { var PL = new PolyLine(ShapeID); for (int i = 0; i < Shape.Count(); i++) { PL.Add(X + Shape.Vertices[i].X, Y + Shape.Vertices[i].Y); } PL.Add(X + Shape.Vertices[0].X, Y + Shape.Vertices[0].Y); PL.Close(); Res.Add(PL); } else { if (Gerber.ShowProgress) { Console.WriteLine("creating empty shape?? {0} {1}", MacroName, ShapeType); } } } return(Res); }