/// <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);
        }
示例#10
0
        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));
                    }
                }
            }
        }