private static PcbGraphics PolylineHelper(PcbUnits coordinateUnits,Piece item) { PcbGraphicsLayer l = PcbGraphicsLayer.TopSilk; PcbLineType t = PcbLineType.Solid; if (Piece.GraphicsLayerMapping.ContainsKey(item.CurrentLayer)) { l = Piece.GraphicsLayerMapping[item.CurrentLayer]; } else { WarningListener.AddFormat(new NotImplementedException(), "Default graphics layer used instead of #{0}",item.CurrentLayer); } if (Piece.LineTypeMapping.ContainsKey(item.CurrentLineType)) { t = Piece.LineTypeMapping[item.CurrentLineType]; } else { WarningListener.AddFormat(new NotImplementedException(), "Default line type used instead of {0}",Enum.GetName(typeof(Piece.LineType),item.CurrentLineType)); } PcbGraphics g = new PcbGraphics(coordinateUnits,coordinateUnits,l,item.XY.Count - 1); for (int i = 1; i < item.XY.Count; i++) { g.Lines.Add(new PcbSilkLine(item.XY[i - 1],item.XY[i],coordinateUnits,coordinateUnits,item.Width,t)); } return(g); }
private static void ProcessDecalPieces(PcbDesign res,PcbUnits coordinateUnits,Partdecal decal) { //Pieces are graphics and traces res.Traces.Capacity += decal.Pieces.Count(x => x.CurrentType == Piece.PieceType.Copper); res.Graphics.Capacity += decal.Pieces.Count(x => x.CurrentType != Piece.PieceType.Copper); foreach (var item in decal.Pieces) { switch (item.CurrentType) { case Piece.PieceType.Open: res.Graphics.Add(PolylineHelper(coordinateUnits,item)); break; case Piece.PieceType.Closed: res.Graphics.Add(PolylineHelper(coordinateUnits,item)); break; case Piece.PieceType.Copper: //Should move it to LINES instead of PARTDECAL res.Traces.Add( new PcbTrace(item.CurrentLayer == Piece.LayerAllNumber ? PcbLayer.All : (PcbLayer)item.CurrentLayer, item.Width,coordinateUnits,coordinateUnits,item.XY)); break; default: WarningListener.AddFormat(new NotImplementedException(), "Decal type {0} ignored.",Enum.GetName(typeof(Piece.PieceType),item.CurrentType)); break; } } }
public PcbGraphics(PcbUnits units, PcbUnits coordinateUnits, PcbGraphicsLayer layer, int capacity = 4) { Lines = new List <PcbSilkLine>(capacity); Units = units; CoordinateUnits = coordinateUnits; Layer = layer; }
public void SetUnits(PcbUnits units) { double mult = PcbDesign.GetUnitConversionMultiplier(Units) / PcbDesign.GetUnitConversionMultiplier(units); Thickness *= mult; Units = units; }
/// <summary> /// For easy modification inside foreach /// </summary> /// <param name="units">Target units</param> public void SetCoordinateUnits(PcbUnits units) { double mult = PcbDesign.GetUnitConversionMultiplier(CoordinateUnits) / PcbDesign.GetUnitConversionMultiplier(units); XY = XY.Select(x => new Point(x.X * mult, x.Y * mult)).ToList(); CoordinateUnits = units; }
public PcbPadStyle(PcbPadShape shape, PcbUnits units, double dim1, double dim2, double drill = 0) { Shape = shape; Units = units; Dimension1 = dim1; Dimension2 = dim2; Drill = drill; }
public PcbTrace(PcbLayer layer, double thickness, PcbUnits units, PcbUnits coordinateUnits, List <Point> points) { XY = points; Layer = layer; Units = units; CoordinateUnits = coordinateUnits; Thickness = thickness; }
public void SetCoordinateUnits(PcbUnits units) { double mult = PcbDesign.GetUnitConversionMultiplier(CoordinateUnits) / PcbDesign.GetUnitConversionMultiplier(units); Start = new Point(Start.X * mult, Start.Y * mult); End = new Point(End.X * mult, End.Y * mult); CoordinateUnits = units; }
/// <summary> /// For easy modification inside foreach /// </summary> /// <param name="units">Target units</param> public void SetCoordinateUnits(PcbUnits units) { double mult = PcbDesign.GetUnitConversionMultiplier(CoordinateUnits) / PcbDesign.GetUnitConversionMultiplier(units); X *= mult; Y *= mult; CoordinateUnits = units; }
public void SetUnits(PcbUnits units) { double mult = PcbDesign.GetUnitConversionMultiplier(Units) / PcbDesign.GetUnitConversionMultiplier(units); Dimension1 *= mult; Dimension2 *= mult; Drill *= mult; Units = units; }
public PcbSilkLine(Point start, Point end, PcbUnits units, PcbUnits coordinateUnits, double thickness, PcbLineType type = PcbLineType.Solid) { Start = start; End = end; Units = units; CoordinateUnits = coordinateUnits; Thickness = thickness; Type = type; }
public void SynchronizeUnits(PcbUnits units) { foreach (var item in Lines) { if (item.Units != units) { item.SetUnits(units); } } Units = units; }
public void SynchronizeCoordinateUnits(PcbUnits units) { foreach (var item in Lines) { if (item.CoordinateUnits != units) { item.SetCoordinateUnits(units); } } CoordinateUnits = units; }
public PcbPad(string number, PcbUnits coordinateUnits, double x, double y, PcbLayer layer, PcbPadStyle style, string flags = null) { Number = number; CoordinateUnits = coordinateUnits; X = x; Y = y; Layer = layer; Style = style; Flags = flags; }
public static PcbDesign Parse(string contents) { //Parse units from the header int i = contents.IndexOf(FileHeaderDesignator,1); int j = contents.LastIndexOf(FileHeaderSeparator,i) + 1; string temp = contents.Substring(j,i - j); PcbUnits coordinateUnits = HeaderUnits.First(x => x.Value == temp).Key; //Get section boundaries i = contents.IndexOf(LineSeparator,i) + 1; Dictionary <ControlStatement,int> sections = new Dictionary <ControlStatement,int>(ControlStatements.Length); for (int k = 0; k < ControlStatements.Length; k++) { j = contents.IndexOf(ControlStatements[k],i); if (j > -1) { j = contents.IndexOf(LineSeparator,j) + 1; if (j < contents.Length) { if (contents[j] == LineSeparator) { j++; } if (contents[j] == CaretReset) { j += 2; } } sections.Add((ControlStatement)k,j); } } //Parse partdecal int currentSectionStart = sections[ControlStatement.PARTDECAL]; int currentSectionEnd = FindSectionEnd(sections,ControlStatement.PARTDECAL); int currentSectionLength = currentSectionEnd - currentSectionStart; Partdecal decal = null; try { decal = Partdecal.Parse(contents.Substring(currentSectionStart,currentSectionLength)); } catch (Exception e) { WarningListener.Add(e); } //Others are not needed yet return(PADSToPcbDesign(coordinateUnits,decal)); }
public void SynchronizeUnits(PcbUnits units) { foreach (var item in Pads) { if (item.Units != units) { item.SetUnits(units); } } foreach (var item in Traces) { if (item.Units != units) { item.SetUnits(units); } } foreach (var item in Graphics) { item.SynchronizeUnits(units); } }
/// <summary> /// Converts CoordinateUnits of objects to the units of the design. /// </summary> public void SynchronizeCoordinateUnits(PcbUnits units) { foreach (var item in Pads) { if (item.CoordinateUnits != units) { item.SetCoordinateUnits(units); } } foreach (var item in Traces) { if (item.CoordinateUnits != units) { item.SetCoordinateUnits(units); } } foreach (var item in Graphics) { item.SynchronizeCoordinateUnits(units); } CoordinateUnits = units; }
private static PcbPadStyle DeterminePadStyle(PadStack.StackLine line,PcbUnits coordinateUnits) { PcbPadStyle style; bool drilled = line.Arguments[(int)PadStack.StackLine.DependentArguments.DrillSize].Present; switch (line.CurrentShape) { case PadStack.Shape.Round: //"Round" pads with drill argument are used for drilled pads (not annular pads!) style = new PcbPadStyle(drilled ? PcbPadShape.CircularTH : PcbPadShape.CircularSMT, coordinateUnits,line.Size,0, drilled ? (double)line.Arguments[(int)PadStack.StackLine.DependentArguments.DrillSize].Value : 0); break; case PadStack.Shape.Square: style = new PcbPadStyle(drilled ? PcbPadShape.RectangularTH : PcbPadShape.RectangularSMT, coordinateUnits,line.Size,line.Size, drilled ? (double)line.Arguments[(int)PadStack.StackLine.DependentArguments.DrillSize].Value : 0); break; case PadStack.Shape.Annular: style = new PcbPadStyle(drilled ? PcbPadShape.CircularTH : PcbPadShape.CircularSMT, coordinateUnits,line.Size, (double)line.Arguments[(int)PadStack.StackLine.DependentArguments.InternalDiameter].Value, drilled ? (double)line.Arguments[(int)PadStack.StackLine.DependentArguments.DrillSize].Value : 0); break; case PadStack.Shape.RectangularFinger: style = new PcbPadStyle(PcbPadShape.RectangularSMT,coordinateUnits,line.Size, (double)line.Arguments[(int)PadStack.StackLine.DependentArguments.FingerLength].Value); WarningListener.Add(new NotImplementedException("Only Length argument is supported for RectangularFinger pad style!")); break; default: throw new NotImplementedException(string.Format( "Pad shape {0} ignored.",Enum.GetName(typeof(PadStack.Shape),line.CurrentShape))); } return(style); }
/// <summary> /// Get PCB (coordinate) units name /// </summary> /// <param name="units">Supported: Thou, Millimeter, TenNanometers, Inch</param> /// <returns>Name string</returns> public string this[PcbUnits units] { get { switch (units) { case PcbUnits.Thou: return("1th"); case PcbUnits.Millimeter: return("1mm"); case PcbUnits.TenNanometers: return("10nm"); case PcbUnits.Inch: return("1in"); default: throw new ArgumentException("Bad units."); } } }
/// <summary> /// Intended only for internal use /// </summary> /// <param name="from">Coordinate units</param> /// <returns>Multiplier that converts specified unit into 0.1nm-s (angstroms)</returns> public static double GetUnitConversionMultiplier(PcbUnits from) { switch (from) { case PcbUnits.Thou: return(254000); case PcbUnits.Millimeter: return(10000000); case PcbUnits.TenNanometers: return(100); case PcbUnits.Inch: return(254000000); case PcbUnits.TwoThirdsOfNanometer: return(20 / 3); default: throw new ArgumentException("Bad coordinate units."); } }
private static PcbDesign PADSToPcbDesign(PcbUnits coordinateUnits,Partdecal decal) { PcbDesign res = new PcbDesign(); //Partdecal try { if (decal != null) { ProcessDecalPieces(res,coordinateUnits,decal); ProcessDecalPads(res,coordinateUnits,decal); } } catch (Exception e) { WarningListener.Add(e); } //Others are not implemented yet //Header info res.SynchronizeCoordinateUnits(coordinateUnits); return(res); }
private static void ProcessDecalPads(PcbDesign res,PcbUnits coordinateUnits,Partdecal decal) { //Terminals + padstacks = pads PadStack defaultStack = decal.PadStacks.FirstOrDefault(x => x.PinDesignator == PadStack.AllTerminalsDesignator); res.Pads.Capacity += decal.Terminals.Count; foreach (var item in decal.Terminals) { var padstack = FindSuitablePadstack(decal,item,defaultStack); if (padstack == null) { WarningListener.Add(new ArgumentException(),"Can't find a suitable padstack for the terminal #" + item.PinDesignator); continue; } var drillLine = padstack.StackLines.FirstOrDefault(x => x.Arguments[(int)PadStack.StackLine.DependentArguments.DrillSize].Present); if (drillLine != null) { //Detect drill-only holes double d = (double)drillLine.Arguments[(int)PadStack.StackLine.DependentArguments.DrillSize].Value; if (d >= drillLine.Size) { res.Pads.Add(new PcbPad(item.PinDesignator,coordinateUnits,item.X,item.Y,PcbLayer.Drill, new PcbPadStyle(PcbPadShape.CircularTH,coordinateUnits,d,0,d))); continue; } } List <PadStack.StackLine> usefulLines = padstack.StackLines.Where(x => (x.Size != 0 || x.Arguments.Any(y => y.Present))).ToList(); if (usefulLines.Count == 3) //Recognize layer "ALL" { //PADS requires minimum of 3 layers specified, 0x0 size indicates that the pad is not actually present //If some stacklines have 0 size and no useful arguments (shape does not count), then we effectively have less stacklines if (usefulLines.Select(x => x.Layer).Union(PadStack.AllLayerPattern).Count() == 3) { //Find layer that contains the most arguments (drill for example appears only for component-side layer) int maxArgs = 0; for (int i = 1; i < usefulLines.Count; i++) { if (usefulLines[maxArgs].Arguments.Count(x => x.Present) < usefulLines[i].Arguments.Count(x => x.Present)) { maxArgs = i; } } res.Pads.Add(new PcbPad(item.PinDesignator,coordinateUnits,item.X,item.Y,PcbLayer.All, DeterminePadStyle(usefulLines[maxArgs],coordinateUnits))); continue; } } //If this is not a special case, parse stacklines one-by-one foreach (var line in usefulLines) { PcbPadStyle style = DeterminePadStyle(line,coordinateUnits); PcbLayer layer = DeterminePcbLayer(line); res.Pads.Add(new PcbPad(item.PinDesignator,coordinateUnits,item.X,item.Y,layer,style)); //-1 stands for both "Internal layers", but we can return only a single layer, so fix it afterwards if (layer == PcbLayer.InternalBottom) { res.Pads.Add(new PcbPad(item.PinDesignator,coordinateUnits,item.X,item.Y, PcbLayer.InternalTop,style)); } } } }
public PcbTrace(PcbLayer layer, double thickness, PcbUnits units, PcbUnits coordinateUnits, int capacity = 4) : this(layer, thickness, units, coordinateUnits, new List <Point>(capacity)) { }
private Partdecal(int pieces,int terminals,int stacks,string name,PcbUnits units) : this(pieces,terminals,stacks) { Name = name; Units = units; }
/// <summary> /// Affects dimensions inside PcbPadStyle /// </summary> /// <param name="units">Target units</param> public void SetUnits(PcbUnits units) { Style.SetUnits(units); }