/// <summary> /// Write *.RGN file contents into a string /// </summary> /// <param name="design"></param> /// <returns>String ready to be written into a file</returns> public string Write(PcbDesign design) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; design.SynchronizeUnits(PcbUnits.Thou); design.SynchronizeCoordinateUnits(PcbUnits.TenNanometers); StringBuilder res = new StringBuilder(Signature); res.AppendFormat(Header, this[design.CoordinateUnits]); StringBuilder temp = new StringBuilder(); //Objects (pads and graphics) foreach (var item in design.Pads) { try { temp.AppendFormat(PadInObjects, item.Number, string.Format(this[item.Style.Shape], item.Style.Dimension1 + (item.Layer == PcbLayer.Drill ? 10 : 0), //10 thou ring for drill holes (ARES7 does not support Dim1=Dim2) item.Style.Drill > 0 ? item.Style.Drill : item.Style.Dimension2), this[item.Layer], item.X, item.Y, item.Flags ?? StandardPadFlags); } catch (NotImplementedException e) { WarningListener.Add(e); } } foreach (var item in design.Graphics) { foreach (var line in item.Lines) { try { temp.AppendFormat(GraphicsLineInObjects, this[item.Layer], line.Start.X, line.Start.Y, line.End.X, line.End.Y); } catch (NotImplementedException e) { WarningListener.Add(e); } } } res.AppendFormat(Objects, temp.ToString().TrimEnd(Environment.NewLine.ToCharArray())); temp.Clear(); //Vias res.AppendFormat(Vias, ""); //Layers and traces var layers = design.GetLayers(true); foreach (var item in layers) { var objects = design.GetObjectsFromLayer(item, true).Cast <PcbTrace>(); foreach (var trace in objects) { temp.AppendFormat(TraceInLayer, trace.Thickness, trace.Segments, string.Join(" ", trace.XY.ToList().Select(x => string.Format("{0} {1}", x.X, x.Y)))); } res.AppendFormat(Layer, this[item], temp.ToString().TrimEnd(Environment.NewLine.ToCharArray())); } return(res.ToString()); }
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 static string Convert(string original, EdaToolFormat source, EdaToolFormat destination) { PcbDesign des = null; string res = null; switch (source) { case EdaToolFormat.PADS_ASCII_PowerPcb: des = PADS.Parse(original); break; default: Console.WriteLine("Unsupported source EDA tool/format."); break; } if (des != null) { switch (destination) { case EdaToolFormat.RegionFile_ARES7: res = ARES7.Instance.Write(des); break; default: Console.WriteLine("Unsupported target EDA tool/format."); break; } } else { Console.WriteLine("PCB design wasn't parsed properly."); } return(res); }
/// <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 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); X *= mult; Y *= mult; CoordinateUnits = units; }
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; }
public void SetUnits(PcbUnits units) { double mult = PcbDesign.GetUnitConversionMultiplier(Units) / PcbDesign.GetUnitConversionMultiplier(units); Dimension1 *= mult; Dimension2 *= mult; Drill *= mult; Units = 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)); } } } }