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() { 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 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 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 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 string ToString() { StringBuilder ret = new StringBuilder(""); string connectstyle = ""; if (SubPolyIndex != -1) { OutputError("Reject region"); return(""); } 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"); } if (Layer != "Edge.Cuts") { List <string> Layers = Brd.GetLayers(Layer); foreach (var L in Layers) { ret.Append($" (zone (net {Net_no}) (net_name {Net_name}) (layer {L}) (hatch edge 0.508)"); ret.Append($" (priority 100)\n"); ret.Append($" (connect_pads {connectstyle} (clearance {clearance}))\n"); // TODO sort out these numbers properly ret.Append($" (min_thickness 0.2)\n"); if (Keepout) { ret.Append("(keepout(copperpour not_allowed))\n"); } else if (PolygonCutout) { ret.Append("(keepout (tracks not_allowed) (vias allowed) (copperpour not_allowed))"); } string fill = (Layer == "Edge.Cuts") ? "no" : "yes"; ret.Append($" (fill {fill} (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()); } ret.Append("\n )\n )\n )\n"); } } else { Point Start = new Point(0, 0); Start = Points[0]; int i; for (i = 0; i < Points.Count - 1; i++) { ret.Append($" (gr_line (start {Points[i].X} {-Points[i].Y}) (end {Points[i + 1].X} {-Points[i + 1].Y}) (layer Edge.Cuts) (width 0.1))\n"); } ret.Append($" (gr_line (start {Points[i].X} {-Points[i].Y}) (end {Start.X} {-Start.Y}) (layer Edge.Cuts) (width 0.1))\n"); } return(ret.ToString()); }
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); }