private static PadStack FindSuitablePadstack(Partdecal decal,Terminal item,PadStack defaultStack) { PadStack padstack; if (PrioritizePadstackBindingByIndex) { string i = item.InternalIndex.ToString(); padstack = decal.PadStacks.FirstOrDefault(x => x.PinDesignator == i); } else { padstack = decal.PadStacks.FirstOrDefault(x => x.PinDesignator == item.PinDesignator); } if (padstack == null) { if (PrioritizePadstackBindingByIndex) { padstack = decal.PadStacks.FirstOrDefault(x => x.PinDesignator == item.PinDesignator); } else { string i = item.InternalIndex.ToString(); padstack = decal.PadStacks.FirstOrDefault(x => x.PinDesignator == i); } if (padstack == null) { padstack = defaultStack; } } return(padstack); }
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)); }
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); }
public static Partdecal Parse(string section) { if (section.Length == 0) { return(null); } TextReader reader = new StringReader(section); //StringBuilder temp = new StringBuilder(section.Length); //Header string[] split = reader.ReadLine().Split(' '); int pieces = int.Parse(split[(int)Header.Pieces]); int padstacks = int.Parse(split[(int)Header.Stacks]); int pinTerminals = int.Parse(split[(int)Header.Terminals]); Partdecal res = new Partdecal(pieces,pinTerminals,padstacks, split[(int)Header.Name],PartdecalUnits.First(x => x.Value == split[(int)Header.Units]).Key); int headerEnded = section.IndexOf(LineSeparator) + 1; int j; //Pieces foreach (var item in Piece.TypeString) { j = headerEnded; for (int i = 0; i < pieces; i++) { j = section.IndexOf(item.Value,j); if (j < 0) { break; } try { res.Pieces.Add(Piece.Parse(section.Substring(j),typeof(Piece.PartdecalHeader))); } catch (Exception e) { WarningListener.Add(e); } finally { j += item.Value.Length + 1; } } } //padstacks j = headerEnded; for (int i = 0; i < padstacks; i++) { j = section.IndexOf(PadStack.PadstackPrefix,j); if (j < 0) { break; } try { res.PadStacks.Add(PadStack.Parse(section.Substring(j))); } catch (Exception e) { WarningListener.Add(e); } finally { j += PadStack.PadstackPrefix.Length + 1; } } //terminals j = headerEnded; for (int i = 0; i < pinTerminals; i++) { j = section.IndexOf(Terminal.TerminalPrefix,j); if (j < 0) { break; } try { res.Terminals.Add(Terminal.Parse(section.Substring(j),i + 1)); } catch (Exception e) { WarningListener.Add(e); } finally { j += Terminal.TerminalPrefix.Length; } } 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)); } } } }
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; } } }