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; }
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); }
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)); } } } }