Esempio n. 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sourcefile"></param>
        /// <param name="destfile"></param>
        /// <param name="DX">MM</param>
        /// <param name="DY">MM</param>
        /// <param name="Angle">Degrees</param>
        public static void Transform(string sourcefile, string destfile, double DX, double DY, double DXp, double DYp, double AngleInDeg = 0)
        {
            List <String> lines    = new List <string>();
            List <String> outlines = new List <string>();


            bool   WriteMove    = false;
            int    moveswritten = 0;
            double Angle        = AngleInDeg * (Math.PI * 2.0) / 360.0;
            double CA           = Math.Cos(Angle);
            double SA           = Math.Sin(Angle);

            using (StreamReader sr = new StreamReader(sourcefile))
            {
                while (sr.EndOfStream == false)
                {
                    String line = sr.ReadLine();
                    if (line.Length > 0)
                    {
                        lines.Add(line);
                    }
                }
            }
            lines = PolyLineSet.SanitizeInputLines(lines);

            if (Gerber.WriteSanitized)
            {
                Gerber.WriteAllLines(sourcefile + ".sanitized.txt", lines);
            }
            //   PolyLineSet Parsed = new PolyLineSet("parsed gerber");
            ParsedGerber Parsed = PolyLineSet.ParseGerber274x(lines, true, false, new GerberParserState()
            {
                GenerateGeometry = false
            });

            if (Gerber.ShowProgress)
            {
                Console.WriteLine("found apertures: ");
                foreach (var a in Parsed.State.Apertures)
                {
                    Console.WriteLine(a.Value.ToString());
                }
            }



            GerberNumberFormat CoordinateFormat = new GerberNumberFormat();

            CoordinateFormat.SetImperialMode();
            //   CoordinateFormat = Parsed.State.CoordinateFormat;

            int  cur          = 0;
            bool formatparsed = false;

            while (cur < lines.Count && formatparsed == false)
            {
                if (lines[cur].Length >= 2 && lines[cur].Substring(0, 2) == "%F")
                {
                    CoordinateFormat.Parse(lines[cur]);
                    formatparsed = true;
                }
                cur++;
            }

            //  double coordmultiplier = 1.0;
            double LastX = 0;
            double LastY = 0;

            for (int i = 0; i < lines.Count; i++)
            {
                GerberSplitter GS        = new GerberSplitter();
                string         FinalLine = lines[i].Replace("%", "").Replace("*", "").Trim();

                bool DumpToOutput = false;
                bool metaopen     = false;
                if (lines[i][0] == '%')
                {
                    DumpToOutput = true;
                    metaopen     = true;
                }
                else
                {
                    GS.Split(lines[i], CoordinateFormat);
                }


                switch (FinalLine)
                {
                case "G71": CoordinateFormat.SetMetricMode(); break;

                case "G70": CoordinateFormat.SetImperialMode(); break;

                case "MOIN":
                {
                    CoordinateFormat.SetImperialMode();
                    //CoordinateFormat.Multiplier  = 25.4f;
                }
                break;

                case "MOMM":
                {
                    CoordinateFormat.SetMetricMode();
                    //CoordinateFormat.Multiplier = 1.0f;
                }
                break;
                }
                if (lines[i].Length > 3 && lines[i].Substring(0, 3) == "%AM")
                {
                    string name = lines[i].Substring(3).Split('*')[0];

                    var M = Parsed.State.ApertureMacros[name];
                    M.Written = true;
                    var gerb = M.BuildGerber(CoordinateFormat, AngleInDeg).Split('\n');
                    foreach (var l in gerb)
                    {
                        if (l.Trim().Length > 0)
                        {
                            outlines.Add(l.Trim());
                        }
                    }
                    //    outlines.Add(lines[i]);
                    //  if (lines[i][lines[i].Length - 1] != '%')
                    ///  {
                    //   i++;
                    while (lines[i][lines[i].Length - 1] != '%')
                    {
                        //     outlines.Add(lines[i]);
                        i++;
                    }
//                       outlines.Add(lines[i]);
                    //     }
                }
                else

                if (lines[i].Length > 3 && lines[i].Substring(0, 3) == "%AD")
                {
                    GCodeCommand GCC = new GCodeCommand();
                    GCC.Decode(lines[i], CoordinateFormat);
                    if (GCC.numbercommands.Count < 1)
                    {
                        Console.WriteLine("Skipping bad aperture definition: {0}", lines[i]);
                    }
                    else
                    {
                        int ATID     = (int)GCC.numbercommands[0];
                        var Aperture = Parsed.State.Apertures[ATID];
                        if (Gerber.ShowProgress)
                        {
                            Console.WriteLine("found " + Aperture.ToString());
                        }
                        string gerb = Aperture.BuildGerber(CoordinateFormat, AngleInDeg);

                        if ((Aperture.ShapeType == GerberApertureShape.Compound || Aperture.ShapeType == GerberApertureShape.Macro) && Parsed.State.ApertureMacros[Aperture.MacroName].Written == false)
                        {
                            Console.WriteLine("Macro type defined - skipping");
                        }
                        else
                        {
                            outlines.Add(gerb);
                        }

                        //                   outlines.Add(lines[i]);
                        if (lines[i][lines[i].Length - 1] != '%')
                        {
                            i++;
                            while (lines[i] != "%")
                            {
                                //                         outlines.Add(lines[i]);
                                i++;
                            }
                            //                   outlines.Add(lines[i]);
                        }
                    }
                }
                else
                {
                    bool PureD = false;
                    if (GS.Has("G"))
                    {
                        int GCode = (int)GS.Get("G");
                        switch (GCode)
                        {
                        case 4: DumpToOutput = true; break;

                        case 90: CoordinateFormat.Relativemode = false; break;

                        case 91: CoordinateFormat.Relativemode = true; break;

                        case 71: CoordinateFormat.Multiplier = 1.0d; break;

                        case 70: CoordinateFormat.Multiplier = 25.4d; break;
                        }
                    }
                    if (DumpToOutput)
                    {
                        outlines.Add(lines[i]);
                        if (lines[i].Contains("LNData"))
                        {
                            Console.WriteLine(" heh");
                        }
                        if (lines[i][0] == '%')
                        {
                            int starti = i;
                            if (lines[i].Length == 1)
                            {
                                i++;
                            }
                            while (lines[i][lines[i].Length - 1] != '%')
                            {
                                if (i > starti)
                                {
                                    outlines.Add(lines[i]);
                                }
                                i++;
                            }
                            if (i > starti)
                            {
                                outlines.Add(lines[i]);
                            }
                        }
                    }
                    else
                    {
                        bool translate = true;
                        if (CoordinateFormat.Relativemode)
                        {
                            translate = false;
                        }
                        if (GS.Has("X") == false && GS.Has("Y") == false && (GS.Has("D") && GS.Get("D") < 10))
                        {
                            PureD = true;
                            int Dcode = (int)GS.Get("D");
                            if (Dcode == 1 || Dcode == 3)
                            {
                                if (moveswritten == 0)
                                {
                                    WriteMove = true;
                                }
                            }
                            moveswritten++;
                            Console.WriteLine(" Pure D Code: {0}", lines[i]);
                        }
                        else
                        if (GS.Has("X") || GS.Has("Y") || (GS.Has("D") && GS.Get("D") < 10))
                        {
                            int Dcode = (int)GS.Get("D");
                            if (Dcode == 1 || Dcode == 3)
                            {
                                if (moveswritten == 0)
                                {
                                    WriteMove = true;
                                }
                            }
                            moveswritten++;
                            double X = LastX;
                            if (GS.Has("X"))
                            {
                                X = GS.Get("X");
                            }
                            double Y = LastY;
                            if (GS.Has("Y"))
                            {
                                Y = GS.Get("Y");
                            }
                            LastX = X;
                            LastY = Y;
                            GetTransformedCoord(DX, DY, DXp, DYp, Angle, CA, SA, CoordinateFormat, translate, ref X, ref Y);
                            if ((GS.Has("I") || GS.Has("J")) && Angle != 0)
                            {
                                //   int g = (int)GS.Get("G");
                                //  if (g == 2 || g == 3)
                                {
                                    double I   = 0;
                                    double J   = 0;
                                    bool   arc = false;
                                    if (GS.Has("I"))
                                    {
                                        I = GS.Get("I"); arc = true;
                                    }
                                    ;
                                    if (GS.Has("J"))
                                    {
                                        J = GS.Get("J"); arc = true;
                                    }
                                    ;
                                    if (arc)
                                    {
                                        double nJ = J * CA + I * SA;
                                        double nI = -J * SA + I * CA;
                                        I = nI;
                                        J = nJ;
                                        //  GS.Set("I", Math.Abs(I));
                                        //  GS.Set("J", Math.Abs(J));
                                        GS.Set("I", I);
                                        GS.Set("J", J);
                                    }
                                }
                            }
                            GS.Set("X", X);
                            GS.Set("Y", Y);
                        }

                        if (WriteMove)
                        {
                            GerberSplitter GS2 = new GerberSplitter();
                            GS2.Set("D", 2);
                            double X0 = 0;
                            double Y0 = 0;
                            GetTransformedCoord(DX, DY, DXp, DYp, Angle, CA, SA, CoordinateFormat, translate, ref X0, ref Y0);
                            GS2.Set("X", X0);
                            GS2.Set("Y", Y0);
                            WriteMove = false;
                            outlines.Add(GS2.Rebuild(CoordinateFormat));
                        }
                        outlines.Add(GS.Rebuild(CoordinateFormat));
                        if (PureD)
                        {
                            Console.WriteLine("pureD");
                        }
                    }
                }
            }
            try
            {
                List <String> PostProcLines = new List <string>();
                foreach (var a in outlines)
                {
                    if (a == "%")
                    {
                        PostProcLines[PostProcLines.Count - 1] += "%";
                    }
                    else
                    {
                        PostProcLines.Add(a);
                    }
                }
                Gerber.WriteAllLines(destfile, PolyLineSet.SanitizeInputLines(PostProcLines));
            }
            catch (Exception E)
            {
                Console.WriteLine(E.Message);
            }
        }
Esempio n. 2
0
        private static Dictionary <string, Tuple <GerberApertureType, List <PointD> > > FillOverlapList(ProgressLog log, Dictionary <string, Tuple <GerberApertureType, List <PointD> > > overlapList, ParsedGerber subtr, string subtractfile)
        {
            log.PushActivity("Filling overlap list coords");
            List <String> lines    = new List <string>();
            List <String> outlines = new List <string>();

            int  CurrentAperture = 10;
            bool WriteMove       = false;
            int  moveswritten    = 0;

            using (StreamReader sr = new StreamReader(subtractfile))
            {
                while (sr.EndOfStream == false)
                {
                    String line = sr.ReadLine();
                    if (line.Length > 0)
                    {
                        lines.Add(line);
                    }
                }
            }
            lines = PolyLineSet.SanitizeInputLines(lines);

            //ParsedGerber Parsed = PolyLineSet.ParseGerber274x(log, lines, true, false, new GerberParserState() { GenerateGeometry = false });



            GerberNumberFormat CoordinateFormat = new GerberNumberFormat();

            CoordinateFormat.SetImperialMode();
            //   CoordinateFormat = Parsed.State.CoordinateFormat;

            int  cur          = 0;
            bool formatparsed = false;

            while (cur < lines.Count && formatparsed == false)
            {
                if (lines[cur].Length >= 2 && lines[cur].Substring(0, 2) == "%F")
                {
                    CoordinateFormat.Parse(lines[cur]);
                    formatparsed = true;
                }
                cur++;
            }

            //  double coordmultiplier = 1.0;
            double LastX = 0;
            double LastY = 0;

            for (int i = 0; i < lines.Count; i++)
            {
                GerberSplitter GS           = new GerberSplitter();
                string         FinalLine    = lines[i].Replace("%", "").Replace("*", "").Trim();
                bool           DumpToOutput = false;
                bool           metaopen     = false;
                if (lines[i][0] == '%')
                {
                    DumpToOutput = true;
                    metaopen     = true;
                }
                else
                {
                    GS.Split(lines[i], CoordinateFormat);
                }


                switch (FinalLine)
                {
                case "G71": CoordinateFormat.SetMetricMode(); break;

                case "G70": CoordinateFormat.SetImperialMode(); break;

                case "MOIN":
                {
                    CoordinateFormat.SetImperialMode();
                    //CoordinateFormat.Multiplier  = 25.4f;
                }
                break;

                case "MOMM":
                {
                    CoordinateFormat.SetMetricMode();
                    //CoordinateFormat.Multiplier = 1.0f;
                }
                break;
                }
                if (lines[i].Length > 3 && lines[i].Substring(0, 3) == "%AM")
                {
                    string name = lines[i].Substring(3).Split('*')[0];

                    var M = subtr.State.ApertureMacros[name];
                    M.Written = true;
                    var gerb = M.BuildGerber(CoordinateFormat, 0, "").Split('\n');
                    foreach (var l in gerb)
                    {
                        if (l.Trim().Length > 0)
                        {
                            outlines.Add(l.Trim());
                        }
                    }
                    //    outlines.Add(lines[i]);
                    //  if (lines[i][lines[i].Length - 1] != '%')
                    ///  {
                    //   i++;
                    while (lines[i][lines[i].Length - 1] != '%')
                    {
                        //     outlines.Add(lines[i]);
                        i++;
                    }
                    //                       outlines.Add(lines[i]);
                    //     }
                }
                else

                if (lines[i].Length > 3 && lines[i].Substring(0, 3) == "%AD")
                {
                    GCodeCommand GCC = new GCodeCommand();
                    GCC.Decode(lines[i], CoordinateFormat);
                    if (GCC.numbercommands.Count < 1)
                    {
                        log.AddString(String.Format("Skipping bad aperture definition: {0}", lines[i]));
                    }
                    else
                    {
                        int ATID     = (int)GCC.numbercommands[0];
                        var Aperture = subtr.State.Apertures[ATID];
                        if (Gerber.ShowProgress)
                        {
                            log.AddString(String.Format("found " + Aperture.ToString()));
                        }
                        string gerb = Aperture.BuildGerber(CoordinateFormat, "", 0);

                        if ((Aperture.ShapeType == GerberApertureShape.Compound || Aperture.ShapeType == GerberApertureShape.Macro) && subtr.State.ApertureMacros[Aperture.MacroName].Written == false)
                        {
                            log.AddString(String.Format("Macro type defined - skipping"));
                        }
                        else
                        {
                            outlines.Add(gerb);
                        }

                        //                   outlines.Add(lines[i]);
                        if (lines[i][lines[i].Length - 1] != '%')
                        {
                            i++;
                            while (lines[i] != "%")
                            {
                                //                         outlines.Add(lines[i]);
                                i++;
                            }
                            //                   outlines.Add(lines[i]);
                        }
                    }
                }
                else
                {
                    bool PureD = false;
                    if (GS.Has("G"))
                    {
                        int GCode = (int)GS.Get("G");
                        switch (GCode)
                        {
                        case 4: DumpToOutput = true; break;

                        case 90: CoordinateFormat.Relativemode = false; break;

                        case 91: CoordinateFormat.Relativemode = true; break;

                        case 71: CoordinateFormat.Multiplier = 1.0d; break;

                        case 70: CoordinateFormat.Multiplier = 25.4d; break;
                        }
                    }
                    if (DumpToOutput)
                    {
                        outlines.Add(lines[i]);
                        if (lines[i].Contains("LNData"))
                        {
                            log.AddString(String.Format(" heh"));
                        }
                        if (lines[i][0] == '%')
                        {
                            int starti = i;
                            if (lines[i].Length == 1)
                            {
                                i++;
                            }
                            while (lines[i][lines[i].Length - 1] != '%')
                            {
                                if (i > starti)
                                {
                                    outlines.Add(lines[i]);
                                }
                                i++;
                            }
                            if (i > starti)
                            {
                                outlines.Add(lines[i]);
                            }
                        }
                    }
                    else
                    {
                        bool translate = true;
                        if (CoordinateFormat.Relativemode)
                        {
                            translate = false;
                        }
                        if (GS.Has("X") == false && GS.Has("Y") == false && (GS.Has("D") && GS.Get("D") < 10))
                        {
                            PureD = true;
                            int Dcode = (int)GS.Get("D");
                            if (Dcode == 1 || Dcode == 3)
                            {
                                if (moveswritten == 0)
                                {
                                    WriteMove = true;
                                }
                            }
                            moveswritten++;
                            //log.AddString(String.Format("Pure D Code: {0}", lines[i]));
                        }
                        else
                        if (GS.Has("X") || GS.Has("Y") || (GS.Has("D") && GS.Get("D") < 10))
                        {
                            int Dcode = (int)GS.Get("D");
                            if (Dcode == 1 || Dcode == 3)
                            {
                                if (moveswritten == 0)
                                {
                                    WriteMove = true;
                                }
                            }
                            moveswritten++;
                            double X = LastX;
                            if (GS.Has("X"))
                            {
                                X = GS.Get("X");
                            }
                            double Y = LastY;
                            if (GS.Has("Y"))
                            {
                                Y = GS.Get("Y");
                            }
                            LastX = X;
                            LastY = Y;

                            GS.Set("X", X);
                            GS.Set("Y", Y);
                        }
                        if (GS.Get("D") >= 10)
                        {
                            CurrentAperture = (int)GS.Get("D");
                            // Select Aperture;
                        }
                        string hash = subtr.State.Apertures[CurrentAperture].GetApertureHash();
                        if (overlapList.ContainsKey(hash))
                        {
                            overlapList[hash].Item2.Add(new PointD(LastX, LastY));
                        }
                        if (WriteMove)
                        {
                            GerberSplitter GS2 = new GerberSplitter();
                            GS2.Set("D", 2);
                            double X0 = 0;
                            double Y0 = 0;
                            if (overlapList.ContainsKey(hash))
                            {
                                overlapList[hash].Item2.Add(new PointD(0, 0));
                            }
                            //GetTransformedCoord(DX, DY, DXp, DYp, Angle, CA, SA, CoordinateFormat, translate, ref X0, ref Y0);
                            GS2.Set("X", X0);
                            GS2.Set("Y", Y0);
                            WriteMove = false;
                            //                          outlines.Add(GS2.Rebuild(CoordinateFormat));
                        }
                        //                        outlines.Add(GS.Rebuild(CoordinateFormat));
                        if (PureD)
                        {
                            //log.AddString(String.Format("pureD"));
                        }
                    }
                }
            }
            try
            {
                //            List<String> PostProcLines = new List<string>();
                //              foreach (var a in outlines)
                //                {
                //  if (a == "%")
                //    {
                //          PostProcLines[PostProcLines.Count - 1] += "%";
                //        }
                //          else
                //            {
                //                  PostProcLines.Add(a);
                //                }
                //              }
                //                Gerber.WriteAllLines(outputfile, PolyLineSet.SanitizeInputLines(PostProcLines));
            }
            catch (Exception E)
            {
                log.AddString(String.Format(E.Message));
            }
            log.PopActivity();


            return(overlapList);
        }
Esempio n. 3
0
        bool ParseExcellon(List <string> lines, double drillscaler, ProgressLog log)
        {
            log.PushActivity("Parse Excellon");
            Tools.Clear();
            bool               headerdone  = false;
            int                currentline = 0;
            ExcellonTool       CurrentTool = null;
            GerberNumberFormat GNF         = new GerberNumberFormat();

            GNF.DigitsBefore = 3;
            GNF.DigitsAfter  = 3;
            GNF.OmitLeading  = true;
            double Scaler          = 1.0f;
            bool   FormatSpecified = false;
            bool   NumberSpecHad   = false;
            double LastX           = 0;
            double LastY           = 0;

            while (currentline < lines.Count)
            {
                switch (lines[currentline])
                {
                //  case "M70":  GNF.Multiplier = 25.4; break; // inch mode
                case "INCH":
                    if (Gerber.ExtremelyVerbose)
                    {
                        log.AddString("Out of header INCH found!");
                    }
                    GNF.SetImperialMode();

                    break;     // inch mode

                case "METRIC":
                    if (Gerber.ExtremelyVerbose)
                    {
                        log.AddString("Out of header METRIC found!");
                    }

                    GNF.SetMetricMode();
                    break;

                case "M72":
                    if (Gerber.ExtremelyVerbose)
                    {
                        log.AddString("Out of header M72 found!");
                    }
                    GNF.SetImperialMode();
                    break;     // inch mode

                case "M71":
                    if (Gerber.ExtremelyVerbose)
                    {
                        log.AddString("Out of header M71 found!");
                    }
                    GNF.SetMetricMode();
                    break;     // metric mode
                }
                if (lines[currentline] == "M48")
                {
                    //Console.WriteLine("Excellon header starts at line {0}", currentline);
                    currentline++;
                    while ((lines[currentline] != "%" && lines[currentline] != "M95"))
                    {
                        headerdone = true;
                        //double InchMult = 1;// 0.010;
                        switch (lines[currentline])
                        {
                        //  case "M70":  GNF.Multiplier = 25.4; break; // inch mode
                        case "INCH":
                            GNF.SetImperialMode();

                            //Scaler = 0.01;
                            break;     // inch mode

                        case "METRIC":
                            GNF.SetMetricMode();
                            break;

                        case "M72":
                            //GNF.Multiplier = 25.4 * InchMult;
                            GNF.SetImperialMode();
                            //  Scaler = 0.01;
                            break;     // inch mode

                        case "M71":
                            //GNF.Multiplier = 1.0;
                            GNF.SetMetricMode();
                            break;     // metric mode

                        default:
                        {
                            var S = lines[currentline].Split(',');
                            if (S[0].IndexOf("INCH") == 0 || S[0].IndexOf("METRIC") == 0)
                            {
                                if (S[0].IndexOf("INCH") == 0)
                                {
                                    GNF.SetImperialMode();
                                }
                                else
                                {
                                    GNF.SetMetricMode();
                                }
                                if (S.Count() > 1)
                                {
                                    for (int i = 1; i < S.Count(); i++)
                                    {
                                        if (S[i][0] == '0')
                                        {
                                            log.AddString(String.Format("Number spec reading!: {0}", S[i]));
                                            var A = S[i].Split('.');
                                            if (A.Length == 2)
                                            {
                                                GNF.DigitsBefore = A[0].Length;
                                                GNF.DigitsAfter  = A[1].Length;
                                                NumberSpecHad    = true;
                                            }
                                        }
                                        if (S[i] == "LZ")
                                        {
                                            GNF.OmitLeading = false;
                                        }
                                        if (S[i] == "TZ")
                                        {
                                            GNF.OmitLeading = true;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (lines[currentline][0] == ';')
                                {
                                    if (Gerber.ShowProgress)
                                    {
                                        log.AddString(lines[currentline]);
                                    }

                                    if (lines[currentline].Contains(";FILE_FORMAT="))
                                    {
                                        var N = lines[currentline].Substring(13).Split(':');
                                        GNF.DigitsBefore = int.Parse(N[0]);
                                        GNF.DigitsAfter  = int.Parse(N[1]);
                                        FormatSpecified  = true;
                                    }
                                }
                                else
                                {
                                    GCodeCommand GCC = new GCodeCommand();
                                    GCC.Decode(lines[currentline], GNF);
                                    if (GCC.charcommands.Count > 0)
                                    {
                                        switch (GCC.charcommands[0])
                                        {
                                        case 'T':
                                        {
                                            ExcellonTool ET = new ExcellonTool();


                                            ET.ID = (int)GCC.numbercommands[0];

                                            ET.Radius    = GNF.ScaleFileToMM(GCC.GetNumber('C')) / 2.0f;
                                            Tools[ET.ID] = ET;
                                        }
                                        break;
                                        }
                                    }
                                }
                            }
                        }
                        break;
                        }
                        currentline++;
                    }
                    //           Console.WriteLine("Excellon header stops at line {0}", currentline);
                    if (FormatSpecified == false && NumberSpecHad == false)
                    {
                        if (GNF.CurrentNumberScale == GerberNumberFormat.NumberScale.Imperial)
                        {
                            //  GNF.OmitLeading = true;
                            GNF.DigitsBefore = 2;
                            GNF.DigitsAfter  = 4;
                        }
                        else
                        {
                            GNF.DigitsAfter  = 3;
                            GNF.DigitsBefore = 3;
                        }
                    }
                }
                else
                {
                    if (headerdone)
                    {
                        GCodeCommand GCC = new GCodeCommand();
                        GCC.Decode(lines[currentline], GNF);
                        if (GCC.charcommands.Count > 0)
                        {
                            switch (GCC.charcommands[0])
                            {
                            case 'T':
                                if ((int)GCC.numbercommands[0] > 0)
                                {
                                    CurrentTool = Tools[(int)GCC.numbercommands[0]];
                                }
                                else
                                {
                                    CurrentTool = null;
                                }
                                break;

                            case 'M':

                            default:
                            {
                                GerberSplitter GS = new GerberSplitter();
                                GS.Split(GCC.originalline, GNF, true);
                                if (GS.Has("G") && GS.Get("G") == 85 && (GS.Has("X") || GS.Has("Y")))
                                {
                                    GerberListSplitter GLS = new GerberListSplitter();
                                    GLS.Split(GCC.originalline, GNF, true);

                                    double x1 = LastX;
                                    double y1 = LastY;

                                    if (GLS.HasBefore("G", "X"))
                                    {
                                        x1 = GNF.ScaleFileToMM(GLS.GetBefore("G", "X") * Scaler); LastX = x1;
                                    }
                                    if (GLS.HasBefore("G", "Y"))
                                    {
                                        y1 = GNF.ScaleFileToMM(GLS.GetBefore("G", "Y") * Scaler); LastY = y1;
                                    }


                                    double x2 = LastX;
                                    double y2 = LastY;

                                    if (GLS.HasAfter("G", "X"))
                                    {
                                        x2 = GNF.ScaleFileToMM(GLS.GetAfter("G", "X") * Scaler); LastX = x2;
                                    }
                                    if (GLS.HasAfter("G", "Y"))
                                    {
                                        y2 = GNF.ScaleFileToMM(GLS.GetAfter("G", "Y") * Scaler); LastY = y2;
                                    }

                                    CurrentTool.Slots.Add(new ExcellonTool.SlotInfo()
                                        {
                                            Start = new PointD(x1 * drillscaler, y1 * drillscaler), End = new PointD(x2 * drillscaler, y2 * drillscaler)
                                        });

                                    LastX = x2;
                                    LastY = y2;
                                }
                                else if (GS.Has("G") && GS.Get("G") == 00 && (GS.Has("X") || GS.Has("Y")))
                                {
                                    GerberListSplitter GLS = new GerberListSplitter();
                                    GLS.Split(GCC.originalline, GNF, true);

                                    double x1 = LastX;
                                    double y1 = LastY;

                                    if (GLS.HasAfter("G", "X"))
                                    {
                                        x1 = GNF.ScaleFileToMM(GLS.GetAfter("G", "X") * Scaler); LastX = x1;
                                    }
                                    if (GLS.HasAfter("G", "Y"))
                                    {
                                        y1 = GNF.ScaleFileToMM(GLS.GetAfter("G", "Y") * Scaler); LastY = y1;
                                    }
                                }
                                else if (GS.Has("G") && GS.Get("G") == 01 && (GS.Has("X") || GS.Has("Y")))
                                {
                                    GerberListSplitter GLS = new GerberListSplitter();
                                    GLS.Split(GCC.originalline, GNF, true);

                                    double x1 = LastX;
                                    double y1 = LastY;
                                    double x2 = LastX;
                                    double y2 = LastY;

                                    if (GLS.HasAfter("G", "X"))
                                    {
                                        x2 = GNF.ScaleFileToMM(GLS.GetAfter("G", "X") * Scaler); LastX = x2;
                                    }
                                    if (GLS.HasAfter("G", "Y"))
                                    {
                                        y2 = GNF.ScaleFileToMM(GLS.GetAfter("G", "Y") * Scaler); LastY = y2;
                                    }

                                    CurrentTool.Slots.Add(new ExcellonTool.SlotInfo()
                                        {
                                            Start = new PointD(x1 * drillscaler, y1 * drillscaler), End = new PointD(x2 * drillscaler, y2 * drillscaler)
                                        });

                                    LastX = x2;
                                    LastY = y2;
                                }
                                else
                                {
                                    if (GS.Has("X") || GS.Has("Y"))
                                    {
                                        double X = LastX;
                                        if (GS.Has("X"))
                                        {
                                            X = GNF.ScaleFileToMM(GS.Get("X") * Scaler);
                                        }
                                        double Y = LastY;
                                        if (GS.Has("Y"))
                                        {
                                            Y = GNF.ScaleFileToMM(GS.Get("Y") * Scaler);
                                        }
                                        CurrentTool.Drills.Add(new PointD(X * drillscaler, Y * drillscaler));
                                        LastX = X;
                                        LastY = Y;
                                    }
                                }
                            }
                            break;
                            }
                        }
                    }
                }
                currentline++;
            }
            log.PopActivity();
            return(headerdone);
        }
Esempio n. 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="lines"></param>
        /// <param name="drillscaler"></param>
        /// <param name="log"></param>
        /// <param name="radiusAdjust">半径修正系数,用于实现电镀孔厚度,单位mm</param>
        /// <returns></returns>
        bool ParseExcellon(List <string> lines, double drillscaler, ProgressLog log, double radiusScaler = 1.0f)
        {
            var LogID = log.PushActivity("Parse Excellon");

            Tools.Clear();
            bool               headerdone  = false;
            int                currentline = 0;
            ExcellonTool       CurrentTool = null;
            GerberNumberFormat GNF         = new GerberNumberFormat();

            GNF.DigitsBefore = 3;
            GNF.DigitsAfter  = 3;
            GNF.OmitLeading  = true;
            double             Scaler            = 1.0f;
            bool               FormatSpecified   = false;
            bool               NumberSpecHad     = false;
            double             LastX             = 0;
            double             LastY             = 0;
            CutterCompensation Compensation      = CutterCompensation.None;
            List <PointD>      PathCompensation  = new List <PointD>();
            bool               WarnIntersections = true;

            while (currentline < lines.Count)
            {
                switch (lines[currentline])
                {
                //  case "M70":  GNF.Multiplier = 25.4; break; // inch mode
                case "INCH":
                    if (Gerber.ExtremelyVerbose)
                    {
                        log.AddString("Out of header INCH found!");
                    }
                    GNF.SetImperialMode();

                    break;     // inch mode

                case "METRIC":
                    if (Gerber.ExtremelyVerbose)
                    {
                        log.AddString("Out of header METRIC found!");
                    }

                    GNF.SetMetricMode();
                    break;

                case "M72":
                    if (Gerber.ExtremelyVerbose)
                    {
                        log.AddString("Out of header M72 found!");
                    }
                    GNF.SetImperialMode();
                    break;     // inch mode

                case "M71":
                    if (Gerber.ExtremelyVerbose)
                    {
                        log.AddString("Out of header M71 found!");
                    }
                    GNF.SetMetricMode();
                    break;     // metric mode
                }
                if (lines[currentline] == "M48")
                {
                    //Console.WriteLine("Excellon header starts at line {0}", currentline);
                    currentline++;
                    while ((lines[currentline] != "%" && lines[currentline] != "M95"))
                    {
                        headerdone = true;
                        //double InchMult = 1;// 0.010;
                        switch (lines[currentline])
                        {
                        //  case "M70":  GNF.Multiplier = 25.4; break; // inch mode
                        case "INCH":
                            GNF.SetImperialMode();

                            //Scaler = 0.01;
                            break;     // inch mode

                        case "METRIC":
                            GNF.SetMetricMode();
                            break;

                        case "M72":
                            //GNF.Multiplier = 25.4 * InchMult;
                            GNF.SetImperialMode();
                            //  Scaler = 0.01;
                            break;     // inch mode

                        case "M71":
                            //GNF.Multiplier = 1.0;
                            GNF.SetMetricMode();
                            break;     // metric mode

                        default:
                        {
                            var S = lines[currentline].Split(',');
                            if (S[0].IndexOf("INCH") == 0 || S[0].IndexOf("METRIC") == 0)
                            {
                                if (S[0].IndexOf("INCH") == 0)
                                {
                                    GNF.SetImperialMode();
                                }
                                else
                                {
                                    GNF.SetMetricMode();
                                }
                                if (S.Count() > 1)
                                {
                                    for (int i = 1; i < S.Count(); i++)
                                    {
                                        if (S[i][0] == '0')
                                        {
                                            log.AddString(String.Format("Number spec reading!: {0}", S[i]));
                                            var A = S[i].Split('.');
                                            if (A.Length == 2)
                                            {
                                                GNF.DigitsBefore = A[0].Length;
                                                GNF.DigitsAfter  = A[1].Length;
                                                NumberSpecHad    = true;
                                            }
                                        }
                                        if (S[i] == "LZ")
                                        {
                                            GNF.OmitLeading = false;
                                        }
                                        if (S[i] == "TZ")
                                        {
                                            GNF.OmitLeading = true;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (lines[currentline][0] == ';')
                                {
                                    if (Gerber.ShowProgress)
                                    {
                                        log.AddString(lines[currentline]);
                                    }

                                    if (lines[currentline].Contains(";FILE_FORMAT="))
                                    {
                                        var N = lines[currentline].Substring(13).Split(':');
                                        GNF.DigitsBefore = int.Parse(N[0]);
                                        GNF.DigitsAfter  = int.Parse(N[1]);
                                        FormatSpecified  = true;
                                    }
                                }
                                else
                                {
                                    GCodeCommand GCC = new GCodeCommand();
                                    GCC.Decode(lines[currentline], GNF);
                                    if (GCC.charcommands.Count > 0)
                                    {
                                        switch (GCC.charcommands[0])
                                        {
                                        case 'T':
                                        {
                                            ExcellonTool ET = new ExcellonTool();


                                            ET.ID = (int)GCC.numbercommands[0];

                                            ET.Radius    = GNF.ScaleFileToMM(GCC.GetNumber('C')) / 2.0f * radiusScaler;
                                            Tools[ET.ID] = ET;
                                        }
                                        break;
                                        }
                                    }
                                }
                            }
                        }
                        break;
                        }
                        currentline++;
                    }
                    //           Console.WriteLine("Excellon header stops at line {0}", currentline);
                    if (FormatSpecified == false && NumberSpecHad == false)
                    {
                        if (GNF.CurrentNumberScale == GerberNumberFormat.NumberScale.Imperial)
                        {
                            //  GNF.OmitLeading = true;
                            GNF.DigitsBefore = 2;
                            GNF.DigitsAfter  = 4;
                        }
                        else
                        {
                            GNF.DigitsAfter  = 3;
                            GNF.DigitsBefore = 3;
                        }
                    }
                }
                else
                {
                    if (headerdone)
                    {
                        GCodeCommand GCC = new GCodeCommand();
                        GCC.Decode(lines[currentline], GNF);
                        if (GCC.charcommands.Count > 0)
                        {
                            switch (GCC.charcommands[0])
                            {
                            case 'T':
                                if ((int)GCC.numbercommands[0] > 0)
                                {
                                    CurrentTool = Tools[(int)GCC.numbercommands[0]];
                                }
                                else
                                {
                                    CurrentTool = null;
                                }
                                break;

                            case 'M':

                            default:
                            {
                                GerberSplitter GS = new GerberSplitter();
                                GS.Split(GCC.originalline, GNF, true);
                                if (GS.Has("G") && GS.Get("G") == 85 && (GS.Has("X") || GS.Has("Y")))
                                {
                                    GerberListSplitter GLS = new GerberListSplitter();
                                    GLS.Split(GCC.originalline, GNF, true);

                                    double x1 = LastX;
                                    double y1 = LastY;

                                    if (GLS.HasBefore("G", "X"))
                                    {
                                        x1 = GNF.ScaleFileToMM(GLS.GetBefore("G", "X") * Scaler); LastX = x1;
                                    }
                                    if (GLS.HasBefore("G", "Y"))
                                    {
                                        y1 = GNF.ScaleFileToMM(GLS.GetBefore("G", "Y") * Scaler); LastY = y1;
                                    }


                                    double x2 = LastX;
                                    double y2 = LastY;

                                    if (GLS.HasAfter("G", "X"))
                                    {
                                        x2 = GNF.ScaleFileToMM(GLS.GetAfter("G", "X") * Scaler); LastX = x2;
                                    }
                                    if (GLS.HasAfter("G", "Y"))
                                    {
                                        y2 = GNF.ScaleFileToMM(GLS.GetAfter("G", "Y") * Scaler); LastY = y2;
                                    }

                                    CurrentTool.Slots.Add(new ExcellonTool.SlotInfo()
                                        {
                                            Start = new PointD(x1 * drillscaler, y1 * drillscaler), End = new PointD(x2 * drillscaler, y2 * drillscaler)
                                        });

                                    LastX = x2;
                                    LastY = y2;
                                }
                                else if (GS.Has("G") && GS.Get("G") == 00 && (GS.Has("X") || GS.Has("Y")))
                                {
                                    GerberListSplitter GLS = new GerberListSplitter();
                                    GLS.Split(GCC.originalline, GNF, true);

                                    double x1 = LastX;
                                    double y1 = LastY;

                                    if (GLS.HasAfter("G", "X"))
                                    {
                                        x1 = GNF.ScaleFileToMM(GLS.GetAfter("G", "X") * Scaler); LastX = x1;
                                    }
                                    if (GLS.HasAfter("G", "Y"))
                                    {
                                        y1 = GNF.ScaleFileToMM(GLS.GetAfter("G", "Y") * Scaler); LastY = y1;
                                    }

                                    /* cancel cutter compensation */
                                    Compensation = CutterCompensation.None;
                                    PathCompensation.Clear();
                                }
                                else if (GS.Has("G") && GS.Get("G") == 01 && (GS.Has("X") || GS.Has("Y")))
                                {
                                    GerberListSplitter GLS = new GerberListSplitter();
                                    GLS.Split(GCC.originalline, GNF, true);

                                    double x1 = LastX;
                                    double y1 = LastY;
                                    double x2 = LastX;
                                    double y2 = LastY;

                                    if (GLS.HasAfter("G", "X"))
                                    {
                                        x2 = GNF.ScaleFileToMM(GLS.GetAfter("G", "X") * Scaler); LastX = x2;
                                    }
                                    if (GLS.HasAfter("G", "Y"))
                                    {
                                        y2 = GNF.ScaleFileToMM(GLS.GetAfter("G", "Y") * Scaler); LastY = y2;
                                    }
                                    if (Compensation == CutterCompensation.None)
                                    {
                                        CurrentTool.Slots.Add(new ExcellonTool.SlotInfo()
                                            {
                                                Start = new PointD(x1 * drillscaler, y1 * drillscaler), End = new PointD(x2 * drillscaler, y2 * drillscaler)
                                            });
                                    }
                                    else
                                    {
                                        PathCompensation.Add(new PointD(x2 * drillscaler, y2 * drillscaler));
                                    }

                                    LastX = x2;
                                    LastY = y2;
                                }
                                else if (GS.Has("G") && GS.Get("G") == 40)         /* cutter compensation off */
                                {
                                    var comp = CutCompensation(PathCompensation, Compensation, CurrentTool.Radius * drillscaler);

                                    if (WarnIntersections)
                                    {
                                        /* warn about path intersections */
                                        for (int i = 0; i < comp.Count - 1; i++)
                                        {
                                            for (int j = i + 2; j < comp.Count - 1; j++)
                                            {
                                                var intersection = Helpers.SegmentSegmentIntersect(comp[i], comp[i + 1], comp[j], comp[j + 1]);
                                                if (intersection != null)
                                                {
                                                    log.AddString("Path with intersections found on cut compensation! Inspect output for accuracy!");
                                                    WarnIntersections = false;
                                                    break;
                                                }
                                            }

                                            if (!WarnIntersections)
                                            {
                                                break;
                                            }
                                        }
                                    }

                                    /* create line segments from set of points */
                                    var array = comp.Zip(comp.Skip(1), Tuple.Create);
                                    CurrentTool.Slots.AddRange(array.Select(i => new ExcellonTool.SlotInfo()
                                        {
                                            Start = i.Item1, End = i.Item2
                                        }));

                                    Compensation = CutterCompensation.None;
                                    PathCompensation.Clear();
                                }
                                else if (GS.Has("G") && GS.Get("G") == 41)         /* cutter compensation left: offset of the cutter radius is to the LEFT of contouring direction */
                                {
                                    if (Compensation != CutterCompensation.None)
                                    {
                                        log.AddString("Unterminated cutter compensation block found! Inspect output for accuracy!");
                                    }

                                    Compensation = CutterCompensation.Left;
                                    PathCompensation.Clear();
                                    PathCompensation.Add(new PointD(LastX * drillscaler, LastY * drillscaler));
                                }
                                else if (GS.Has("G") && GS.Get("G") == 42)         /* cutter compensation right: offset of the cutter radius is to the RIGHT of contouring direction */
                                {
                                    if (Compensation != CutterCompensation.None)
                                    {
                                        log.AddString("Unterminated cutter compensation block found! Inspect output for accuracy!");
                                    }

                                    Compensation = CutterCompensation.Right;
                                    PathCompensation.Clear();
                                    PathCompensation.Add(new PointD(LastX * drillscaler, LastY * drillscaler));
                                }
                                else
                                {
                                    //Deal with the repeat code
                                    if (GS.Has("R") && (GS.Has("X") || GS.Has("Y")))
                                    {
                                        double repeatX = 0;
                                        double repeatY = 0;

                                        if (GS.Has("X"))
                                        {
                                            repeatX = GNF.ScaleFileToMM(GS.Get("X") * Scaler);
                                        }
                                        if (GS.Has("Y"))
                                        {
                                            repeatY = GNF.ScaleFileToMM(GS.Get("Y") * Scaler);
                                        }

                                        for (int repeatIndex = 1; repeatIndex <= GS.Get("R"); repeatIndex++)
                                        {
                                            double X = LastX;
                                            if (GS.Has("X"))
                                            {
                                                X += repeatX;
                                            }

                                            double Y = LastY;
                                            if (GS.Has("Y"))
                                            {
                                                Y += repeatY;
                                            }

                                            CurrentTool.Drills.Add(new PointD(X * drillscaler, Y * drillscaler));
                                            LastX = X;
                                            LastY = Y;
                                        }
                                    }
                                    else if (GS.Has("X") || GS.Has("Y"))
                                    {
                                        double X = LastX;
                                        if (GS.Has("X"))
                                        {
                                            X = GNF.ScaleFileToMM(GS.Get("X") * Scaler);
                                        }
                                        double Y = LastY;
                                        if (GS.Has("Y"))
                                        {
                                            Y = GNF.ScaleFileToMM(GS.Get("Y") * Scaler);
                                        }
                                        if (Compensation == CutterCompensation.None)
                                        {
                                            CurrentTool.Drills.Add(new PointD(X * drillscaler, Y * drillscaler));
                                        }
                                        else
                                        {
                                            PathCompensation.Add(new PointD(X * drillscaler, Y * drillscaler));
                                        }
                                        LastX = X;
                                        LastY = Y;
                                    }
                                }
                            }
                            break;
                            }
                        }
                    }
                }
                currentline++;
            }
            log.PopActivity(LogID);
            return(headerdone);
        }