public string ToString(double x, double y) { Int32 SA = Convert.ToInt32(StartAngle * 100); Int32 EA = Convert.ToInt32(EndAngle * 100); if (Math.Abs(EA - SA) == 36000) { // it's a circle return($" (fp_circle (center {Math.Round(X1 - x, Precision)} {Math.Round(-(Y1 - y), Precision)}) (end {Math.Round(X1+Radius - x, Precision)} {Math.Round(-(Y1 - y), Precision)}) (layer {Layer}) (width {Width}))\n"); } else { double Xs, Ys, Xe, Ye; Xs = Math.Round((X1 - x) + Radius * Math.Cos(Radians(StartAngle)), Precision); Ys = Math.Round((Y1 - y) + Radius * Math.Sin(Radians(StartAngle)), Precision); Xe = Math.Round((X1 - x) + Radius * Math.Cos(Radians(EndAngle)), Precision); Ye = Math.Round((Y1 - y) + Radius * Math.Sin(Radians(EndAngle)), Precision); Width = Math.Round(Width, Precision); CheckMinMax(Xs, Ys); CheckMinMax(Xe, Xe); var arc = new StringBuilder(""); string n = (net == -1) ? "" : $"net {net}"; List <string> Layers = Brd.GetLayers(Brd.GetLayer(Layer)); foreach (var L in Layers) { arc.Append($" (arc (start {Xs} {-Ys}) (end {Xe} {Ye}) (angle {Math.Round(EndAngle-StartAngle, Precision)}) (layer {L}) (width {Width}))\n"); } return(arc.ToString()); } }
public override string ToString() { string StartL = Brd.GetLayer(StartLayer); string EndL = Brd.GetLayer(EndLayer); string blind = ((StartL != "F.Cu") || (EndL != "B.Cu")) ? "blind" : ""; return($" (via {blind} (at {Math.Round(X, Precision)} {Math.Round(-Y, Precision)}) (size {Size}) (drill {Drill}) (layers {StartL} {EndL}) (net {Net}))\n"); }
public override string ToString() { var ret = new StringBuilder(""); string connectstyle = ""; double clearance = GetRuleValue(this, "Clearance", "PolygonClearance"); if (Layer.Substring(0, 2) == "In") { // this is an inner layer so use plane clearance clearance = GetRuleValue(this, "PlaneClearance", "PlaneClearance"); } List <string> Layers = Brd.GetLayers(Brd.GetLayer(Layer)); foreach (var L in Layers) { ret.Append($" (zone (net {NetNo}) (net_name {NetName}) (layer {L}) (hatch edge 0.508)"); ret.Append($" (priority {GetPriority(PourIndex)})\n"); ret.Append($" (connect_pads {connectstyle} (clearance {clearance}))\n"); // TODO sort out these numbers properly ret.Append($" (min_thickness {NeckWidthThreshold})\n"); ret.Append(" (fill yes (arc_segments 16) (thermal_gap 0.2) (thermal_bridge_width 0.3))\n"); var i = 0; ret.Append(" (polygon (pts\n "); foreach (var Point in Points) { i++; if ((i % 5) == 0) { ret.Append("\n "); } ret.Append(Point.ToString()); CheckMinMax(Point.X, Point.Y); } ret.Append("\n )\n )\n )\n"); if (IsSplitPlane) { ret.Append("# Split Plane\n"); } } return(ret.ToString()); }
public override string ToString(double x, double y, double ModuleRotation) { Point2D p1 = new Point2D(X1 - x, Y1 - y); double X2 = (X1 - x) + Radius * Math.Cos(Radians(StartAngle)); double Y2 = (Y1 - y) + Radius * Math.Sin(Radians(StartAngle)); Point2D p2 = new Point2D(X2, Y2); p1.Rotate(ModuleRotation); p2.Rotate(ModuleRotation); Int32 SA = Convert.ToInt32(StartAngle * 100); Int32 EA = Convert.ToInt32(EndAngle * 100); if (Math.Abs(EA - SA) == 36000) { // it's a circle StringBuilder circle = new StringBuilder(""); List <string> Layers = Brd.GetLayers(Brd.GetLayer(Layer)); foreach (var L in Layers) { circle.Append($" (fp_circle (center {p1.X} {-p1.Y}) (end {p2.X} {-p2.Y}) (layer {L}) (width {Width}))\n"); } return(circle.ToString()); } else { StringBuilder arc = new StringBuilder(""); List <string> Layers = Brd.GetLayers(Brd.GetLayer(Layer)); foreach (var L in Layers) { arc.Append($" (fp_arc (start {Math.Round(p1.X, Precision)} {Math.Round(-p1.Y, Precision)}) (end {Math.Round(p2.X, Precision)} {Math.Round(-p2.Y, Precision)}) (angle {Math.Round(-(EndAngle - StartAngle), Precision)}) (layer {L}) (width {Width}))\n"); } return(arc.ToString());; } }
public Polygon(string line) // string Layer, int net) { string param; ObjectType = PCBObjectType.Polygon; Int32 net = 0; if ((param = GetString(line, "|NET=")) != "") { net = Convert.ToInt32(param) + 1; } string Net = GetNetName(net); if ((param = GetString(line, "|COMPONENT=")) != "") { Component = Convert.ToInt32(param); InComponent = true; } if ((param = GetString(line, "|LAYER=")) != "") { Layer = Brd.GetLayer(param); } IsSplitPlane = ((param = GetString(line, "|POLYGONTYPE=")) == "Split Plane"); if (!IsSplitPlane && (param = GetString(line, "|TRACKWIDTH=")) != "") { TrackWidth = Convert.ToDouble(GetNumberInMM(param)); } else { TrackWidth = 0.1; // maybe should be smaller for split plane NeckWidthThreshold = 0.1; } if ((param = GetString(line, "|POURINDEX=")) != "") { PourIndex = Convert.ToInt16(param); if (PourIndex > Brd.MaxPourIndex) { Brd.MaxPourIndex = PourIndex; } } if ((param = GetString(line, "|NECKWIDTHTHRESHOLD=")) != "") { NeckWidthThreshold = GetNumberInMM(param.Trim(charsToTrim)); } NetNo = net; NetName = GetNetName(NetNo); Points = new List <Point>(); string[] coords = line.Split('|'); // now add all the vertices for (var j = 0; j < coords.Length; j++) { if (coords[j].StartsWith("KIND")) { var start = coords[j].IndexOf('=') + 1; string type = coords[j].Substring(start); j++; start = coords[j].IndexOf('=') + 1; string coord = coords[j].Substring(start); // get start X double VX = GetCoordinateX(coord.Trim(charsToTrim)); j++; start = coords[j].IndexOf('=') + 1; coord = coords[j].Substring(start); // get start Y double VY = GetCoordinateY(coord.Trim(charsToTrim)); j++; start = coords[j].IndexOf('=') + 1; coord = coords[j].Substring(start); // get centre X double CX = GetCoordinateX(coord.Trim(charsToTrim)); j++; start = coords[j].IndexOf('=') + 1; coord = coords[j].Substring(start); // get centre Y double CY = GetCoordinateY(coord.Trim(charsToTrim)); j++; start = coords[j].IndexOf('=') + 1; coord = coords[j].Substring(start); // get start angle double SA = GetDouble(coord.Trim(charsToTrim)); j++; start = coords[j].IndexOf('=') + 1; coord = coords[j].Substring(start); // get end angle double EA = GetDouble(coord.Trim(charsToTrim)); j++; start = coords[j].IndexOf('=') + 1; coord = coords[j].Substring(start); // get radius double R = GetNumberInMM(coord.Trim(charsToTrim)); if (type == "0") { // straight line AddPoint(Math.Round(VX, Precision), Math.Round(VY, Precision)); } else { // this is an arc so have to simulate arc with a number of line segments // first normalise it so that the centre is at 0,0 // save the centre point double XC = CX; double YC = CY; double X = VX - XC; double Y = VY - YC; // generate arc segments at 5° increments if (EA < SA) { EA += 360; } // start point of arc X = R * Math.Cos(Arc.Radians(SA)); Y = R * Math.Sin(Arc.Radians(SA)); // end point of arc double X2 = R * Math.Cos(Arc.Radians(EA)); double Y2 = R * Math.Sin(Arc.Radians(EA)); bool clockwise = true; double l1 = Math.Sqrt((VX - (X + XC)) * (VX - (X + XC)) + (VY - (Y + YC)) * (VY - (Y + YC))); double l2 = Math.Sqrt((VX - (X2 + XC)) * (VX - (X2 + XC)) + (VY - (Y2 + YC)) * (VY - (Y2 + YC))); if (l1 < l2) { clockwise = false; } // need to determine if this is clockwise or anticlockwise as the // start and end angles are back to front if (!clockwise) { // anticlockwise for (double angle = SA; angle < EA; angle += 5) { double X1 = R * Math.Cos(Arc.Radians(angle)); double Y1 = R * Math.Sin(Arc.Radians(angle)); AddPoint(X + XC, Y + YC); X = X1; Y = Y1; } // do last segment if (X != X2 || Y != Y2) { AddPoint(X2 + XC, Y2 + YC); } } else { // clockwise // start point of arc X = R * Math.Cos(Arc.Radians(EA)); Y = R * Math.Sin(Arc.Radians(EA)); // end point of arc X2 = R * Math.Cos(Arc.Radians(SA)); Y2 = R * Math.Sin(Arc.Radians(SA)); for (double angle = EA; angle > SA; angle -= 5) { double X1 = R * Math.Cos(Arc.Radians(angle)); double Y1 = R * Math.Sin(Arc.Radians(angle)); AddPoint(X + XC, Y + YC); X = X1; Y = Y1; } // do last segment if (X != X2 || Y != Y2) { AddPoint(X2 + XC, Y2 + YC); } } } } } }
public override bool ProcessLine(byte[] record) { base.ProcessLine(); using (MemoryStream ms = new MemoryStream(record)) { // Use the memory stream in a binary reader. using (BinaryReader br = new BinaryReader(ms)) { ms.Seek(0, SeekOrigin.Begin); Layer = (Layers)br.ReadByte(); // line offset 0 Locked = br.ReadByte(); // line offset 1 Keepout = (int)br.ReadByte(); // line offset 2 ms.Seek(3, SeekOrigin.Begin); Net = br.ReadInt16(); Net += 1; NetName = $"\"{NetsL[Net].Name}\""; ms.Seek(7, SeekOrigin.Begin); Component = br.ReadInt16(); InComponent = (Component != -1); ms.Seek(13, SeekOrigin.Begin); X1 = Math.Round(Bytes2mm(br.ReadBytes(4)) - originX, Precision); ms.Seek(17, SeekOrigin.Begin); Y1 = Math.Round(Bytes2mm(br.ReadBytes(4)) - originY, Precision); ms.Seek(21, SeekOrigin.Begin); X2 = Math.Round(Bytes2mm(br.ReadBytes(4)) - originX, Precision); ms.Seek(25, SeekOrigin.Begin); Y2 = Math.Round(Bytes2mm(br.ReadBytes(4)) - originY, Precision); ms.Seek(29, SeekOrigin.Begin); Rotation = br.ReadDouble(); CheckMinMax(X1, Y1); CheckMinMax(X2, Y2); } if (Keepout == 2) { Point2D p1 = new Point2D(X1, Y1); Point2D p2 = new Point2D(X2, Y2); Point2D c = new Point2D(X1 + (X2 - X1) / 2, Y1 + (Y2 - Y1) / 2); if (InComponent) { // need to factor in component's rotation if (Component < ModulesL.Count) { try { double rot = ModulesL[Component].Rotation; p1 = p1.Rotate(c, rot); p2 = p2.Rotate(c, rot); } catch (Exception Ex) { CheckThreadAbort(Ex); } } } string layer = ""; if (Layer == Layers.Keepout_Layer) { layer = "*.Cu"; } else { layer = Brd.GetLayer(Layer); } List <string> layers = Brd.GetLayers(layer); foreach (var L in layers) { // generate a keepout keepouts.Append( $@" (zone(net 0)(net_name """")(layers {L})(tstamp 0)(hatch edge 0.508) (connect_pads(clearance 0.508)) (min_thickness 0.254) (keepout(tracks not_allowed)(vias not_allowed)(copperpour not_allowed)) (fill(arc_segments 32)(thermal_gap 0.508)(thermal_bridge_width 0.508)) (polygon (pts (xy {p1.X} {-p1.Y})(xy {p2.X} {-p1.Y})(xy {p2.X} {-p2.Y})(xy {p1.X} {-p2.Y}) ) ) ) "); } } else if (!InComponent) // keepouts not allowed in components (yet) { List <string> Layers = Brd.GetLayers(Brd.GetLayer(Layer)); foreach (var L in Layers) { fills.Append($" (gr_poly (pts (xy {X1} {-(Y1)}) (xy {X1} {-(Y2)}) (xy {X2} {-(Y2)}) (xy {X2} {-(Y1)})) (layer {L}) (width 0))\n"); } } else { Fill Fill = new Fill(X1, Y1, X2, Y2, Brd.GetLayer(Layer), GetNetName(Net)); if (Component < ModulesL.Count && Component != -1) { ModulesL[Component].Fills.Add(Fill); } } return(true); } }
public override string ToString() { // for some reason the arc in version 5.99 needs start middle end // rather than start end angle like for fp_arc ... go figure // X1, Y1 = centre double Xs, Ys, Xm, Ym, Xe, Ye; Xs = Math.Round(X1 + Radius * Math.Cos(Radians(StartAngle)), Precision); Ys = Math.Round(Y1 + Radius * Math.Sin(Radians(StartAngle)), Precision); Xm = Math.Round(X1 + Radius * Math.Cos(Radians(StartAngle + (EndAngle - StartAngle) / 2)), Precision); Ym = Math.Round(Y1 + Radius * Math.Sin(Radians(StartAngle + (EndAngle - StartAngle) / 2)), Precision); Xe = Math.Round(X1 + Radius * Math.Cos(Radians(EndAngle)), Precision); Ye = Math.Round(Y1 + Radius * Math.Sin(Radians(EndAngle)), Precision); string netstr = (net == -1) ? "" : $"(net {net})"; if (Brd.IsCopperLayer(Layer)) { return($" (arc (start {Xs} {-Ys}) (mid {Xm} {-Ym}) (end {Xe} {-Ye}) (layer {Brd.GetLayer(Layer)}) {netstr} (width {Width}))\n"); } else { return($" (gr_arc (start {Math.Round(X1, Precision)} {Math.Round(-Y1, Precision)}) (end {Math.Round(Xs, Precision)} {Math.Round(-Ys, Precision)}) (angle {Math.Round(-(EndAngle - StartAngle), Precision)}) (layer {Brd.GetLayer(Layer)}) (width {Width}))\n"); } }
public override bool ProcessLine(byte[] line) { double StartAngle, EndAngle, Radius, Width; Layers Layer; double X1, Y1; Int16 Component; Int16 net; base.ProcessLine(); ArcStruct a = ByteArrayToStructure <ArcStruct>(line); Layer = (Layers)a.Layer; net = a.net; net++; Component = a.Component; X1 = Math.Round((double)a.X1 * 25.4 / 10000000 - originX, Precision); Y1 = Math.Round((double)a.Y1 * 25.4 / 10000000 - originY, Precision); Radius = Math.Round((double)a.Radius * 25.4 / 10000000, Precision); StartAngle = a.StartAngle; EndAngle = a.EndAngle; Width = (double)a.Width * 25.4 / 10000000; bool InComponent = Component != -1; double Angle; if (EndAngle < StartAngle) { EndAngle += 360; } Angle = (EndAngle - StartAngle); double X = X1 + Radius * Math.Cos(StartAngle * Math.PI / 180); double Y = Y1 + Radius * Math.Sin(StartAngle * Math.PI / 180); string layer = Brd.GetLayer(Layer); if (!InComponent) { if (net > 0 && Brd.IsCopperLayer(Layer)) { if (!Globals.PcbnewVersion) { // arcs with nets on copper layers allowed in 5.99 Arc Arc = new Arc(X1, Y1, StartAngle, EndAngle, Radius, Layer, Width, net); ArcsL.Add(Arc); } else { //arcs.Append($" (arc (start {Math.Round(X1, Precision)} {Math.Round(-Y1, Precision)}) (end {Math.Round(X, Precision)} {Math.Round(-Y, Precision)}) (angle {Math.Round(Angle, Precision)}) (layer {L}) (net {Net}) (width {Width}))\n"); // we have an arc/track on a copper layer and it has a net // these aren't supported by KiCad yet so generate a curve out of track segments // first normalise it so that the centre is at 0,0 // save the centre point double XC = X1; double YC = Y1; X = X - XC; Y = Y - YC; double radius = Math.Sqrt(X * X + Y * Y); // start angle in radians double start_angle = Arc.Radians(StartAngle); double end_angle = Arc.Radians(EndAngle); double X2 = Radius * Math.Cos(end_angle); double Y2 = Radius * Math.Sin(end_angle); X = Radius * Math.Cos(start_angle); Y = Radius * Math.Sin(start_angle); // generate arc segments at 5° increments for (double angle = start_angle; angle < end_angle; angle += 2 * Math.PI / 72) { X1 = Radius * Math.Cos(angle); Y1 = Radius * Math.Sin(angle); Line Line = new Line(XC + X, YC + Y, XC + X1, YC + Y1, layer, Width, net); LinesL.Add(Line); X = X1; Y = Y1; } // do last segment if (X != X2 || Y != Y2) { Line Line = new Line(X + XC, Y + YC, X2 + XC, Y2 + YC, layer, Width, net); LinesL.Add(Line); } } } else { // only add if not part of board outline if ((layer != "Edge.Cuts") || !Brd.CheckExistingArc(X1, Y1, X, Y, Angle)) { List <string> Layers = Brd.GetLayers(layer); foreach (var L in Layers) { Arc Arc = new Arc(X1, Y1, StartAngle, EndAngle, Radius, Brd.GetAltiumLayer(L), Width); ArcsL.Add(Arc); } } } } else { Arc Arc = new Arc(X1, Y1, StartAngle, EndAngle, Radius, Layer, Width); ModulesL[Component].Arcs.Add(Arc); } return(true); }
public Module(string line) { string param; ObjectType = PCBObjectType.Module; Designator = ""; Comment = ""; Name = GetString(line, "|PATTERN="); ComponentKind = GetString(line, "|COMPONENTKIND="); if (Name.Contains("\\")) { Name = Name.Replace("\\", "_"); // TODO check this out } if (Name.Contains("\"")) { Name = Name.Replace("\"", "_"); } if ((param = GetString(line, "|X=").Trim(charsToTrim)) != "") { X = GetCoordinateX(param); } if ((param = GetString(line, "|Y=").Trim(charsToTrim)) != "") { Y = GetCoordinateY(param); } Layer = ""; if ((param = GetString(line, "|LAYER=")) != "") { Layer = Brd.GetLayer(param); } DesignatorOn = true; if ((param = GetString(line, "|NAMEON=")) != "") { DesignatorOn = param == "TRUE"; } CommentOn = true; if ((param = GetString(line, "|COMMENTON=")) != "") { CommentOn = param == "TRUE"; } Locked = false; if ((param = GetString(line, "|LOCKED=")) != "") { Locked = param == "TRUE"; } PrimitiveLock = false; if ((param = GetString(line, "|PRIMITIVELOCK=")) != "") { PrimitiveLock = param == "TRUE"; } Rotation = 0; if ((param = GetString(line, "|ROTATION=").Trim(charsToTrim)) != "") { Rotation = Convert.ToDouble(param); if (Rotation == 360) { Rotation = 0; } } if (Layer == "F.Cu" || Layer == "B.Cu") { Attr = "smd"; } else { Attr = ""; } if (ComponentKind == "1" || ComponentKind == "2" || ComponentKind == "4") { Attr = "virtual"; } Tedit = "(tedit 0)"; Tstamp = "(tstamp 0)"; // create the object lists for this component Lines = new ObjectList <Line>(); Pads = new ObjectList <Pad>(); Strings = new ObjectList <String>(); ViasL = new ObjectList <Via>(); Arcs = new ObjectList <Arc>(); Fills = new ObjectList <Fill>(); Polygons = new ObjectList <Polygon>(); Regions = new ObjectList <Region>(); ComponentBodies = new ObjectList <ComponentBody>(); ShapeBasedModels = new ObjectList <ShapeBasedModel>(); ID++; // update for next Module }
public Dimension(string line) { string[] words = line.Split('|'); string param; ObjectType = PCBObjectType.Dimension; if ((param = GetString(line, "|X1=").Trim(charsToTrim)) != "") { X1 = GetCoordinateX(param); } if ((param = GetString(line, "|Y1=").Trim(charsToTrim)) != "") { Y1 = GetCoordinateY(param); } if ((param = GetString(line, "|X2=").Trim(charsToTrim)) != "") { X2 = GetCoordinateX(param); } if ((param = GetString(line, "|Y2=").Trim(charsToTrim)) != "") { Y2 = GetCoordinateY(param); } if ((param = GetString(line, "|DIMENSIONKIND=")) != "") { DIMENSIONKIND = Convert.ToInt16(param); } if ((param = GetString(line, "|DIMENSIONLAYER=")) != "") { layer = Brd.GetLayer(param); } if ((param = GetString(line, "|LX=").Trim(charsToTrim)) != "") { LX = GetCoordinateX(param); } if ((param = GetString(line, "|LY=").Trim(charsToTrim)) != "") { LY = GetCoordinateY(param); } if ((param = GetString(line, "|HX=").Trim(charsToTrim)) != "") { HX = GetCoordinateX(param); } if ((param = GetString(line, "|HY=").Trim(charsToTrim)) != "") { HY = GetCoordinateY(param); } if ((param = GetString(line, "|REFERENCE0POINTX=").Trim(charsToTrim)) != "") { REFERENCE0POINTX = GetCoordinateX(param); } if ((param = GetString(line, "|REFERENCE0POINTY=").Trim(charsToTrim)) != "") { REFERENCE0POINTY = GetCoordinateY(param); } if ((param = GetString(line, "|REFERENCE1POINTX=").Trim(charsToTrim)) != "") { REFERENCE1POINTX = GetCoordinateX(param); } if ((param = GetString(line, "|REFERENCE1POINTY=").Trim(charsToTrim)) != "") { REFERENCE1POINTY = GetCoordinateY(param); } if ((param = GetString(line, "|TEXTPOSITION=")) != "") { TextPosition = param; } if ((param = GetString(line, "|ANGLE=").Trim(charsToTrim)) != "") { ANGLE = Math.Round(Convert.ToDouble(param), Precision); if (ANGLE == 180 || ANGLE == 360) { ANGLE = 0; } if (ANGLE == 270) { ANGLE = 90; } } if ((param = GetString(line, "|ARROWSIZE=").Trim(charsToTrim)) != "") { ARROWSIZE = GetNumberInMM(param); } if ((param = GetString(line, "|ARROWLINEWIDTH=").Trim(charsToTrim)) != "") { ARROWLINEWIDTH = GetNumberInMM(param); } if ((param = GetString(line, "|ARROWLENGTH=").Trim(charsToTrim)) != "") { ARROWLENGTH = GetNumberInMM(param); } if ((param = GetString(line, "|LINEWIDTH=").Trim(charsToTrim)) != "") { LINEWIDTH = GetNumberInMM(param); } if ((param = GetString(line, "|TEXTHEIGHT=").Trim(charsToTrim)) != "") { TEXTHEIGHT = GetNumberInMM(param); } if ((param = GetString(line, "|TEXTWIDTH=").Trim(charsToTrim)) != "") { TEXTWIDTH = GetNumberInMM(param); } if ((param = GetString(line, "|TEXTHEIGHT=").Trim(charsToTrim)) != "") { TEXTHEIGHT = GetNumberInMM(param); } if ((param = GetString(line, "|TEXTX=").Trim(charsToTrim)) != "") { TEXTX = GetCoordinateX(param); } if ((param = GetString(line, "|TEXTY=").Trim(charsToTrim)) != "") { TEXTY = GetCoordinateY(param); } if ((param = GetString(line, "|TEXT1X=").Trim(charsToTrim)) != "") { TEXT1X = GetCoordinateX(param); } if ((param = GetString(line, "|TEXT1Y=").Trim(charsToTrim)) != "") { TEXT1Y = GetCoordinateY(param); } if ((param = GetString(line, "|TEXTPRECISION=").Trim(charsToTrim)) != "") { TEXTPRECISION = Convert.ToInt32(param); } if ((param = GetString(line, "|TEXTFORMAT=").Trim(charsToTrim)) != "") { TextFormat = Convert.ToInt32(param); } if ((param = GetString(line, "|TEXTDIMENSIONUNIT=").Trim(charsToTrim)) != "") { DimensionUnit = param; } // translate to fit in worksheet Point2D R0 = new Point2D(REFERENCE0POINTX, REFERENCE0POINTY); Point2D R1 = new Point2D(REFERENCE1POINTX, REFERENCE1POINTY); Point2D centre = new Point2D(X1, Y1); // rotate the two reference points to make horizontal dimension R0 = R0.Rotate(centre, -ANGLE); R1 = R1.Rotate(centre, -ANGLE); Point2D end = new Point2D(R1.X, Y1); Point2D a1a = new Point2D(X1 + ARROWSIZE, Y1 + ARROWSIZE / 3); Point2D a1b = new Point2D(X1 + ARROWSIZE, Y1 - ARROWSIZE / 3); Point2D a2a = new Point2D(end.X - ARROWSIZE, end.Y + ARROWSIZE / 3); Point2D a2b = new Point2D(end.X - ARROWSIZE, end.Y - ARROWSIZE / 3); CheckMinMax(X1, Y1); CheckMinMax(end.X, end.Y); CheckMinMax(a1a.X, a1a.Y); CheckMinMax(a1b.X, a1b.Y); CheckMinMax(a2a.X, a2a.Y); CheckMinMax(a2b.X, a2b.Y); }
public override string ToString() { if (DIMENSIONKIND != 1) // TODO fix this - filter out radial dimensions { OutputError($"Unsupported Dimension kind ({DIMENSIONKIND}) at {X1},{Y1}"); return(""); } // translate to fit in worksheet Point2D R0 = new Point2D(REFERENCE0POINTX, REFERENCE0POINTY); Point2D R1 = new Point2D(REFERENCE1POINTX, REFERENCE1POINTY); Point2D centre = new Point2D(X1, Y1); // rotate the two reference points to make horizontal dimension R0 = R0.Rotate(centre, -ANGLE); R1 = R1.Rotate(centre, -ANGLE); Point2D end = new Point2D(R1.X, Y1); // calculate the length of the crossbar length = R1.X - X1; // length in mm // calculate the end points of the arrow features Point2D a1a = new Point2D(X1 + ARROWSIZE, Y1 + ARROWSIZE / 3); Point2D a1b = new Point2D(X1 + ARROWSIZE, Y1 - ARROWSIZE / 3); Point2D a2a = new Point2D(end.X - ARROWSIZE, end.Y + ARROWSIZE / 3); Point2D a2b = new Point2D(end.X - ARROWSIZE, end.Y - ARROWSIZE / 3); if (length < 0) { // there must be a better way to do this but hey ho length = -length; // calculate the end points of the arrow features a1a = new Point2D(X1 - ARROWSIZE, Y1 + ARROWSIZE / 3); a1b = new Point2D(X1 - ARROWSIZE, Y1 - ARROWSIZE / 3); a2a = new Point2D(end.X + ARROWSIZE, end.Y + ARROWSIZE / 3); a2b = new Point2D(end.X + ARROWSIZE, end.Y - ARROWSIZE / 3); } string units; int UnitsIndex = 0; int Ilength; int Dlength; // convert length to string based on Units and precision switch (DimensionUnit) { case "Mils": length = length / 25.4 * 1000; units = "mil"; UnitsIndex = 1; break; case "Millimeters": units = "mm"; UnitsIndex = 2; break; case "Inches": length = length / 25.4; units = "in"; UnitsIndex = 0; break; case "Centimeters": length = length / 10; units = "cm"; UnitsIndex = 2; // no CM in Pcbnew (yet) break; default: // mm units = "mm"; UnitsIndex = 2; break; } length = Math.Round(length, TEXTPRECISION); Int32 MP = Convert.ToInt32(Math.Pow(10, TEXTPRECISION)); Int32 FP = Convert.ToInt32(length * Math.Pow(10, TEXTPRECISION)); Ilength = FP / MP; Dlength = FP - Ilength * MP; string Decimal = Dlength.ToString("D" + TEXTPRECISION); if (TEXTPRECISION == 0) { text = $"{Ilength}{units}"; } else { text = $"{Ilength}.{Decimal}{units}"; } // rotate all the points back a1a = a1a.Rotate(centre, ANGLE); a1b = a1b.Rotate(centre, ANGLE); a2a = a2a.Rotate(centre, ANGLE); a2b = a2b.Rotate(centre, ANGLE); R0 = R0.Rotate(centre, ANGLE); R1 = R1.Rotate(centre, ANGLE); end = end.Rotate(centre, ANGLE); var string1 = new StringBuilder(""); var Layers = Brd.GetLayers(Brd.GetLayer(layer)); string Justify = ""; switch (TextPosition) { case "Auto": break; // just do centre case "Center": break; // just do centre case "Top": break; // just do centre case "Bottom": break; // just do centre case "Right": Justify = "(justify right)"; break; case "Left": Justify = "(justify left)"; break; case "InsideRight": Justify = "(justify right)"; break; case "InsideLeft": Justify = "(justify left)"; break; case "UniDirectional": break; // just do centre case "Manual": break; // just do centre } foreach (var L in Layers) { string1.Append($@" (dimension 176 (width {LINEWIDTH}) (layer {L}) (gr_text {text} (at {TEXT1X} {-TEXT1Y} {ANGLE}) (layer {L.ToString()}) (effects (font (size {Math.Round(TEXTHEIGHT, Precision)} {Math.Round(TEXTHEIGHT, Precision)}) (thickness {Math.Round(LINEWIDTH, Precision)})) {Justify}) ) (format (units {UnitsIndex}) (units_format {1}) (precision {TEXTPRECISION})) (style (thickness {TEXTWIDTH}) (arrow_length {ARROWLENGTH}) (text_position_mode {1}) (extension_height {1}) (extension_offset 0) keep_text_aligned ) (feature1 (pts (xy {end.X} {-end.Y}) (xy {R1.X} {-R1.Y}) )) (feature2 (pts (xy {X1} {-Y1}) (xy {R0.X} {-R0.Y}))) (crossbar (pts (xy {X1} {-Y1}) (xy {end.X} {-end.Y}))) (arrow1a (pts (xy {X1} {-Y1}) (xy {a1a.X} {-a1a.Y}))) (arrow1b (pts (xy {X1} {-Y1}) (xy {a1b.X} {-a1b.Y}))) (arrow2a (pts (xy {end.X} {-end.Y}) (xy {a2a.X} {-a2a.Y}))) (arrow2b (pts (xy {end.X} {-end.Y}) (xy {a2b.X} {-a2b.Y}))) )"); } return(string1.ToString()); }
public override bool ProcessBinaryFile(byte[] data) { StartTimer(); if (Binary_size == 0) { return(false); } long p = 0; Int32 len; string str = ""; try { using (MemoryStream ms = new MemoryStream(data)) { long size = ms.Length; if (size == 0) { return(true); } BinaryReader br = new BinaryReader(ms, System.Text.Encoding.UTF8); while (p < size) { base.ProcessLine(); // keep count byte record_type = br.ReadByte(); if (record_type != 5) { break; } len = br.ReadInt32(); byte[] bytes = br.ReadBytes(len); // 0xEC); // read the number of bytes up to actual text // map text structure to the bytes Text text = ByteArrayToStructure <Text>(bytes); Layers Layer = (Layers)text.Layer; Int16 Component = text.Component; bool InComponent = Component != -1; double X = Math.Round(ToMM(text.X) - originX, Precision); double Y = Math.Round(ToMM(text.Y) - originY, Precision); double Height = Math.Round(ToMM(text.Height), Precision); double Width = Math.Round(ToMM(text.Height), Precision); double Rotation = text.Rotation % 360; // altium seem to store 0 as 360 quite a lot! bool Mirror = text.Mirror != 0; double Thickness = ToMM(text.Thickness); bool IsComment = text.IsComment != 0; bool IsDesignator = text.IsDesignator != 0; bool TrueType = text.TrueType != 0; UInt32 TextLen = br.ReadUInt32(); bool Italic = text.Italic != 0; bool Bold = text.Bold != 0; byte strlen = br.ReadByte(); byte[] textbytes = br.ReadBytes(strlen); p = ms.Position; // now at end of record str = Encoding.UTF8.GetString(textbytes, 0, strlen); string layer = Brd.GetLayer(Layer); str = ConvertSpecialStrings(str, Component, layer); if (TrueType) { //string Font = text.FontName; StringBuilder SB = new StringBuilder(""); unsafe { for (int i = 0; i < 32; i++) { if (text.FontName[i] == 0) { break; } char c = (char)text.FontName[i]; SB.Append(c); } } string Font = SB.ToString(); TTFont F; FontFamily fontFamily = null; try { fontFamily = new FontFamily(Font); // check if font is on font list if ((F = FindFont(Font, Bold, Italic, Height)) == null) { // get metrics for font and bung it onto font list FontStyle Style = ((Bold) ? FontStyle.Bold : 0) | ((Italic) ? FontStyle.Italic : 0); Font font = new Font(fontFamily, 100, Style, GraphicsUnit.Pixel); float Ascent = font.FontFamily.GetCellAscent(Style); float Descent = font.FontFamily.GetCellDescent(Style); float EmHeight = font.FontFamily.GetEmHeight(Style); float TotalHeight = Ascent + Descent; float InternalLeading = TotalHeight - EmHeight; double TTHeight = (float)(Ascent - InternalLeading); F = new TTFont { FontName = Font, Italic = Italic, Bold = Bold, TotalHeight = TotalHeight, TTHeight = TTHeight, Height = Height }; Height = Height / F.TotalHeight * F.TTHeight; Height = Height - Height / 5; F.TTHeight = Height; Size CharWidth = TextRenderer.MeasureText("A", font); F.CharWidth = Height * ((float)CharWidth.Height / (float)CharWidth.Width); Fonts.Add(F); } Height = F.TTHeight; Thickness = Height / (Bold ? 5 : 10); Width = F.CharWidth; } catch (ArgumentException) { OutputError($"Font {Font} does not exist on this computer"); // couldn't find font so estimate size Height = Height / 2; Width = Height; } } str = str.Replace("\r", ""); str = str.Replace("\n", "\\n"); if (!InComponent) { double Angle = (90 - Rotation) * Math.PI / 180; double X1 = Height / 2 * Math.Cos(Angle); double Y1 = Height / 2 * Math.Sin(Angle); List <string> Layers = Brd.GetLayers(layer); foreach (var L in Layers) { string It = Italic ? "italic" : ""; texts.Append($" (gr_text \"{ToLiteral(str)}\" (at {Math.Round(X - X1, Precision)} {-Math.Round(Y + Y1, Precision)} {Math.Round(Rotation, Precision)}) (layer {L}) (effects (font (size {Height} {Width}) (thickness {Thickness}) {It}) (justify left {(Mirror ? "mirror" : "")})))\n"); } } else { Module Mod = ModulesL[Component]; string Hide = ""; string type = ""; if (IsDesignator) { type = "reference"; Hide = Mod.DesignatorOn ? "" : "hide"; if (Brd.DesignatorDisplayMode && str.Contains("_")) { // This is a virtual designator // Pcbnew doesn't have anything like this so // set the designator onto the Dwgs.User layer // and put a copy minus the channel designator on the // top/bottom overlay layer // str = str.Substring(0, str.IndexOf('_')); } Mod.Designator = str; } else if (IsComment) { type = "value"; Hide = Mod.CommentOn ? "" : "hide"; if (layer == "F.Cu") { layer = "F.Fab"; } else if (layer == "B.Cu") { layer = "B.Fab"; } /*if (Brd.DesignatorDisplayMode) * { * // should get the seperator from the project file (.PrjPCB) * // under ChannelRoomLevelSeperator * // can't find it in board data assume it's '_' * str = str.Substring(0, str.IndexOf('_')); * }*/ Mod.Comment = ToLiteral(str); } else { type = "user"; if (str == Mod.Comment) { str = "%V"; } if (str == Mod.Designator) { str = "%R"; } } if (Hide == "") { GetBoundingBox(str, X, Y, Rotation, Height, Width); } if (Brd.DesignatorDisplayMode && str.Contains("_")) { // put designator on Dwgs.User and virtual designator on silkscreen String S1 = new String(type, str, X, Y, Rotation, "Dwgs.User", Height, Width, Thickness, Hide, Mirror, Italic); ModulesL[Component].Strings.Add(S1); str = str.Substring(0, str.IndexOf('_')); String S2 = new String("user", str, X, Y, Rotation, layer, Height, Width, Thickness, Hide, Mirror, Italic); ModulesL[Component].Strings.Add(S2); } else { String String = new String(type, str, X, Y, Rotation, layer, Height, Width, Thickness, Hide, Mirror, Italic); ModulesL[Component].Strings.Add(String); } } } } } catch (Exception Ex) { CheckThreadAbort(Ex); } return(true); }
public override bool ProcessLine(byte[] record) { Layers Layer; Int16 Component; bool InComponent; base.ProcessLine(); using (MemoryStream ms = new MemoryStream(record)) { // Use the memory stream in a binary reader. using (BinaryReader br = new BinaryReader(ms)) { try { ms.Seek(0, SeekOrigin.Begin); Layer = (Layers)br.ReadByte(); ms.Seek(1, SeekOrigin.Begin); short Flags = (short)br.ReadInt16(); ms.Seek(3, SeekOrigin.Begin); int net = (int)br.ReadInt16() + 1; ms.Seek(7, SeekOrigin.Begin); Component = br.ReadInt16(); InComponent = Component != -1; ms.Seek(0x12, SeekOrigin.Begin); int strlen = br.ReadInt32(); ms.Seek(0x16, SeekOrigin.Begin); byte[] bytes = br.ReadBytes(strlen); string str = ConvertToString(bytes); ms.Seek(0x16 + strlen, SeekOrigin.Begin); Int32 DataLen = br.ReadInt32(); string l = Brd.GetLayer((Layers)Layer); Region r = new Region(l, net, Flags, str); if (r.SubPolyIndex > 0) { // Rejected region return(true); } while (DataLen-- > 0) { double X = Math.Round(ToMM(br.ReadDouble()) - originX, Precision); double Y = Math.Round(ToMM(br.ReadDouble()) - originY, Precision); r.AddPoint(X, Y); } if (!InComponent) { RegionsL.Add(r); } else { if (!r.Keepout && !r.PolygonCutout) { ModulesL[Component].Regions.Add(r); } else { // until keepouts are allowed in components // just add as a board region RegionsL.Add(r); } } } catch (Exception Ex) { CheckThreadAbort(Ex); } } } return(true); }
public Dimension(string line) { string param; if ((param = GetString(line, "|X1=").Trim(charsToTrim)) != "") { X1 = GetCoordinateX(param); } if ((param = GetString(line, "|Y1=").Trim(charsToTrim)) != "") { Y1 = GetCoordinateY(param); } if ((param = GetString(line, "|X2=").Trim(charsToTrim)) != "") { X2 = GetCoordinateX(param); } if ((param = GetString(line, "|Y2=").Trim(charsToTrim)) != "") { Y2 = GetCoordinateY(param); } if ((param = GetString(line, "|DIMENSIONKIND=")) != "") { DIMENSIONKIND = Convert.ToInt16(param); } if ((param = GetString(line, "|DIMENSIONLAYER=")) != "") { layer = Brd.GetLayer(param); } if ((param = GetString(line, "|LX=").Trim(charsToTrim)) != "") { LX = GetCoordinateX(param); } if ((param = GetString(line, "|LY=").Trim(charsToTrim)) != "") { LY = GetCoordinateY(param); } if ((param = GetString(line, "|HX=").Trim(charsToTrim)) != "") { HX = GetCoordinateX(param); } if ((param = GetString(line, "|HY=").Trim(charsToTrim)) != "") { HY = GetCoordinateY(param); } if ((param = GetString(line, "|REFERENCE0POINTX=").Trim(charsToTrim)) != "") { REFERENCE0POINTX = GetCoordinateX(param); } if ((param = GetString(line, "|REFERENCE0POINTY=").Trim(charsToTrim)) != "") { REFERENCE0POINTY = GetCoordinateY(param); } if ((param = GetString(line, "|REFERENCE1POINTX=").Trim(charsToTrim)) != "") { REFERENCE1POINTX = GetCoordinateX(param); } if ((param = GetString(line, "|REFERENCE1POINTY=").Trim(charsToTrim)) != "") { REFERENCE1POINTY = GetCoordinateY(param); } if ((param = GetString(line, "|ANGLE=").Trim(charsToTrim)) != "") { ANGLE = Math.Round(Convert.ToDouble(param), Precision); if (ANGLE == 180 || ANGLE == 360) { ANGLE = 0; } if (ANGLE == 270) { ANGLE = 90; } } if ((param = GetString(line, "|ARROWSIZE=").Trim(charsToTrim)) != "") { ARROWSIZE = GetNumberInMM(param); } if ((param = GetString(line, "|ARROWLINEWIDTH=").Trim(charsToTrim)) != "") { ARROWLINEWIDTH = GetNumberInMM(param); } if ((param = GetString(line, "|ARROWLENGTH=").Trim(charsToTrim)) != "") { ARROWLENGTH = GetNumberInMM(param); } if ((param = GetString(line, "|LINEWIDTH=").Trim(charsToTrim)) != "") { LINEWIDTH = GetNumberInMM(param); } if ((param = GetString(line, "|TEXTHEIGHT=").Trim(charsToTrim)) != "") { TEXTHEIGHT = GetNumberInMM(param); } if ((param = GetString(line, "|TEXTWIDTH=").Trim(charsToTrim)) != "") { TEXTWIDTH = GetNumberInMM(param); } if ((param = GetString(line, "|TEXTHEIGHT=").Trim(charsToTrim)) != "") { TEXTHEIGHT = GetNumberInMM(param); } if ((param = GetString(line, "|TEXTX=").Trim(charsToTrim)) != "") { TEXTX = GetCoordinateX(param); } if ((param = GetString(line, "|TEXTY=").Trim(charsToTrim)) != "") { TEXTY = GetCoordinateY(param); } if ((param = GetString(line, "|TEXT1X=").Trim(charsToTrim)) != "") { TEXT1X = GetCoordinateX(param); } if ((param = GetString(line, "|TEXT1Y=").Trim(charsToTrim)) != "") { TEXT1Y = GetCoordinateY(param); } if ((param = GetString(line, "|TEXTPRECISION=").Trim(charsToTrim)) != "") { TEXTPRECISION = Convert.ToInt32(param); } if ((param = GetString(line, "|TEXTDIMENSIONUNIT=").Trim(charsToTrim)) != "") { DimensionUnit = param; } }
public override bool ProcessLine(byte[] line) { double X1, Y1, X2, Y2, width; int net; Layers layer; bool InComponent = false; Int16 component = 0; base.ProcessLine(); net = B2UInt16(line, 3 + 5); if (net == 0x0000FFFF) { net = 0; } else { net++; } component = B2Int16(line, 7 + 5); InComponent = (component != -1); X1 = Math.Round(ToMM(line, 13 + 5) - originX, Precision); Y1 = Math.Round(ToMM(line, 17 + 5) - originY, Precision); X2 = Math.Round(ToMM(line, 21 + 5) - originX, Precision); Y2 = Math.Round(ToMM(line, 25 + 5) - originY, Precision); CheckMinMax(X1 + originX, Y1 + originY); CheckMinMax(X2 + originX, Y2 + originY); width = Math.Round(ToMM(line, 29 + 5), Precision); layer = (Layers)line[5]; string Layer = Brd.GetLayer(layer); int ComponentNumber = 0; if (InComponent) { // belongs to a component definition ComponentNumber = component; } // check for and reject very short tracks if (Length(X1, Y1, X2, Y2) <= 0.001) { OutputError($"Zero length track rejected at X1={X1} Y1={-Y1} X2={X2} y2={-Y2} "); return(true); } if (!InComponent) { if (net == 0) { if (!Brd.OnInnerLayer(layer)) { if ((Layer != "Edge.Cuts") || !Brd.CheckExistingLine(X1, -Y1, X2, -Y2)) { List <string> Layers = Brd.GetLayers(Layer); foreach (var L in Layers) { Line Line = new Line(X1, Y1, X2, Y2, L, width, net); LinesL.Add(Line); } } } } else { Line Line = new Line(X1, Y1, X2, Y2, Brd.GetLayer(layer), width, net); LinesL.Add(Line); //tracks.Append($" (segment (start {X1} {-Y1}) (end {X2} {-Y2}) (width {width}) (layer {Layer}) (net {net}))\n"); //track_count++; } } else { Line Line = new Line(X1, Y1, X2, Y2, Brd.GetLayer(layer), width); ModulesL[ComponentNumber].Lines.Add(Line); } return(true); }
public override bool ProcessBinaryFile(byte[] data) { bool GenerateTxtFile = true; // set to true to generate text version of the file FileStream TextFile = null; StartTimer(); if (Binary_size == 0) { return(false); } if (GenerateTxtFile) { if (ExtractFiles) { TextFile = File.Open("Data.txt", FileMode.OpenOrCreate); } } try { using (MemoryStream ms = new MemoryStream(data)) { UInt32 pos = 0; uint size = (uint)ms.Length; BinaryReader br = new BinaryReader(ms, System.Text.Encoding.UTF8); ms.Seek(pos, SeekOrigin.Begin); List <UInt32> Starts = new List <UInt32>(); // look for record starts { Stopwatch timer = new Stopwatch(); timer.Start(); // signature is // byte 02 // int32 length // byte strlen = length - 1 // string strlen ascci chars // bytes 01 00 00 00 while (pos < size) { ms.Seek(pos, SeekOrigin.Begin); byte recordtype = br.ReadByte(); // should be 2 if (recordtype == 2) { // possible start UInt32 nextnamelength = br.ReadUInt32(); if (nextnamelength < 256) { uint l = br.ReadByte(); // string length if (l == nextnamelength - 1) { // everything ok so far // now check bytes in string are ASCII bool found = true; for (int i = 0; i < l; i++) { byte c = br.ReadByte(); if (c < 0x20 || c > 0x7F) { found = false; } } if (br.ReadByte() != 1) { found = false; } if (br.ReadByte() != 0) { found = false; } if (br.ReadByte() != 0) { found = false; } if (br.ReadByte() != 0) { found = false; } if (br.ReadByte() != 0) { found = false; } if (found) { // OutputString($"Found header at {pos:x08}"); Starts.Add(pos); } } } } pos = pos + 1; } } pos = 0; int index = -1; Int16 Component; byte[] r = br.ReadBytes(2); try { UInt32 Longest = 0; UInt32 len; // find the length of the logest pad record foreach (var p in Starts) { index++; if (index < Starts.Count - 1) { len = Starts[index + 1] - Starts[index]; } else { len = size - Starts[index]; } if (len > Longest) { Longest = len; } } index = -1; if (GenerateTxtFile && ExtractFiles) { AddText(TextFile, $"Altium Version {VersionString}\n"); // generate headers for .txt file string Header1 = "Pos "; for (int i = 0; i < Longest; i++) { Header1 += $"{(i / 100),-3:D2}"; } string Header2 = " "; for (int i = 0; i < Longest; i++) { Header2 += $"{(i % 100),-3:D2}"; } string Header3 = "--------------------"; for (int i = 0; i < Longest; i++) { Header3 += $"---"; } if (ExtractFiles) { AddText(TextFile, Header1 + "\n"); AddText(TextFile, Header2 + "\n"); AddText(TextFile, Header3 + "\n"); } } foreach (var p in Starts) { pos = p; //OutputString($"Processing pad record at {pos:x08}"); index++; base.ProcessLine(); ms.Seek(p, SeekOrigin.Begin); byte recordtype = br.ReadByte(); // should be 2 UInt32 next = br.ReadUInt32(); uint l = br.ReadByte(); // string length //pos = (uint)ms.Position; string name; if (l != 0) { name = new string(br.ReadChars((int)l)); } else { name = ""; } pos = (uint)ms.Position; // find out how many bytes to read if (index < Starts.Count - 1) { len = Starts[index + 1] - Starts[index]; } else { len = size - Starts[index]; } // we are now pointing to the pad record // Layers Layer; byte shape; bool plated; double X, Y, XSize, YSize, HoleSize; //, MIDXSize, MIDYSize, BottomXSize, BottomYSize; double Rotation = 0; double RRatio = 0; Int16 Net; Int16 JumperID; byte[] bytes = br.ReadBytes((int)len - 6); // get record after header stuff if (GenerateTxtFile) { if (p == 0) { r = bytes; // get reference bytes } StringBuilder text = new StringBuilder(""); int count = 0; int CompareLimit = Math.Min(r.Length, bytes.Length); foreach (var c in bytes) { if (count < CompareLimit && r[count] != bytes[count]) { text.Append($"|{c:X2}"); } else { text.Append($" {c:X2}"); } count++; } if (ExtractFiles) { AddText(TextFile, $"{pos:X8} " + $"{len - name.Length,4} {name,4} {text.ToString()}\n"); } } PadStruct pad = ByteArrayToStructure <PadStruct>(bytes); ms.Seek(pos + pad.Offset, SeekOrigin.Begin); int LayersSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(PadLayers)); byte[] layerbytes = br.ReadBytes(LayersSize); // get layers data PadLayers PadLayers = ByteArrayToStructure <PadLayers>(layerbytes); Layer = (Layers)pad.Layer; Net = pad.Net; Net++; string n = NetsL[Net].Name; Component = pad.Component; if (Component != -1 && Component != 0) { X = 0; } X = ToMM(pad.X) - originX; Y = ToMM(pad.Y) - originY; XSize = ToMM(pad.XSize); YSize = ToMM(pad.YSize); HoleSize = ToMM(pad.HoleSize); unsafe { shape = pad.TopShape; if (len > 160 && shape == 1) // TODO this can't be right { shape = PadLayers.PadShapes[0]; RRatio = (double)PadLayers.RRatios[0] / 200; } else { RRatio = 0; } } if (shape > 5) { shape = 5; } string[] shapes = { "circle", "circle", "rect", "octagonal", "oval", "roundrect" }; if (shapes[shape] == "circle" && XSize != YSize) { shape = 4; // oval pad } Rotation = pad.Rotation; plated = pad.Plated != 0; JumperID = pad.JumperID; bool InComponent = Component != -1; string type; if (Layer == Layers.Multi_Layer) { if (plated) { type = "thru_hole"; } else { type = "np_thru_hole"; // name = "\"\""; } if (HoleSize < 0.01) { OutputError($"Zero size hole through hole pad at {X} {Y}"); } } else { type = "smd"; } string layer = Brd.GetLayer(Layer); if (!Brd.IsCopperLayer(Layer)) { OutputError($"Pad on non copper layer = {Layer} at {X} {-Y}"); // TODO generate circular polygon instead continue; } if (layer == "Margin") // TODO sort this keepout layer malarky { layer = "Dwgs.User"; } if (type == "smd") { layer += layer == "F.Cu" ? " F.Mask F.Paste" : (layer == "B.Cu") ? " B.Mask B.Paste" : ""; } else { layer += " *.Mask"; } if (XSize < HoleSize | YSize < HoleSize) { XSize = YSize = HoleSize; } Pad Pad = new Pad(name, type, shapes[shape], X, Y, Rotation, XSize, YSize, HoleSize, layer, Net, RRatio) { Component = Component }; if (pad.UsePasteMaskRules == 1) { Pad.PasteMaskExpansion = GetRuleValue(Pad, "PasteMaskExpansion", "PasteMaskExpansion"); } else { Pad.PasteMaskExpansion = ToMM(pad.PasteMaskExpansion); } if (pad.UseSolderMaskRules == 1) { Pad.SolderMaskExpansion = GetRuleValue(Pad, "SolderMaskExpansion", "SolderMaskExpansion"); } else { Pad.SolderMaskExpansion = ToMM(pad.SolderMaskExpansion); } if (!InComponent) { PadsL.Add(Pad); // free pads not allowed (at present) in PcbNew so generate a single pad module Module M = new Module($"FreePad{ModulesL.Count}", X, Y, XSize, YSize, Pad); ModulesL.Add(M); } else { try { ModulesL[Component].Pads.Add(Pad); } catch (Exception Ex) { CheckThreadAbort(Ex, $"At position {pos} in Pads file"); } } } } catch (Exception Ex) { CheckThreadAbort(Ex); } if (GenerateTxtFile && TextFile != null) { TextFile.Close(); } } } catch (Exception Ex) { CheckThreadAbort(Ex); } return(true); }