Esempio n. 1
0
        public void FixEagleDrillExportIssues(ProgressLog Logger)
        {
            List<ParsedGerber> DrillFiles = new List<ParsedGerber>();
            List<Tuple<double, ParsedGerber>> DrillFilesToReload = new List<Tuple<double, ParsedGerber>>();
            Bounds BB = new Bounds();
            foreach (var a in PLSs)
            {
                if (a.Layer == BoardLayer.Drill)
                {
                    DrillFiles.Add(a);
                }
                else
                {
                    BB.AddBox(a.BoundingBox);
                }
            }

            foreach (var a in DrillFiles)
            {
                var b = a.BoundingBox;
                if (b.Width() > BB.Width() * 1.5 || b.Height() > BB.Height() * 1.5)
                {
                    var MaxRatio = Math.Max(b.Width() / BB.Width(), b.Height() / BB.Height());
                    if (Logger != null) Logger.AddString(String.Format("Note: Really large drillfile found({0})-fix your export scripts!", a.Name));
                    Console.WriteLine("Note: Really large drillfile found ({0})- fix your export scripts!", a.Name);
                    DrillFilesToReload.Add(new Tuple<double, ParsedGerber>(MaxRatio, a));
                }

            }
            foreach (var a in DrillFilesToReload)
            {
                PLSs.Remove(a.Item2);
                var scale = 1.0;
                if (Double.IsInfinity(a.Item1) || Double.IsNaN(a.Item1))
                {
                    Errors.Add("Drill file size reached infinity - ignoring it");
                    if (Logger != null) Logger.AddString("Drill file size reached infinity - ignoring it");
                }
                else
                {
                    var R = a.Item1;
                    while (R >= 1.5)
                    {
                        R /= 10;
                        scale /= 10;
                    }
                    AddFileToSet(a.Item2.Name, Logger, scale);
                }
            }

            BoundingBox = new Bounds();
            foreach (var a in PLSs)
            {
                //Console.WriteLine("Progress: Adding board {6} to box::{0:N2},{1:N2} - {2:N2},{3:N2} -> {4:N2},{5:N2}", a.BoundingBox.TopLeft.X, a.BoundingBox.TopLeft.Y, a.BoundingBox.BottomRight.X, a.BoundingBox.BottomRight.Y, a.BoundingBox.Width(), a.BoundingBox.Height(), Path.GetFileName( a.Name));


                //Console.WriteLine("adding box for {0}:{1},{2}", a.Name, a.BoundingBox.Width(), a.BoundingBox.Height());
                BoundingBox.AddBox(a.BoundingBox);
            }
        }
Esempio n. 2
0
        private static void MultiMerge(string file1, List <string> otherfiles, string output, ProgressLog Log)
        {
            int MM = Log.PushActivity("Excellon MultiMerge");

            if (File.Exists(file1) == false)
            {
                Log.AddString(String.Format("{0} not found! stopping process!", file1));
                Log.PopActivity(MM);
                return;
            }
            foreach (var otherfile in otherfiles)
            {
                if (File.Exists(otherfile) == false)
                {
                    Log.AddString(String.Format("{0} not found! stopping process!", otherfile));
                    Log.PopActivity(MM);
                    return;
                }
            }

            Log.AddString(String.Format("Reading {0}:", file1));
            ExcellonFile File1Parsed = new ExcellonFile();

            File1Parsed.Load(Log, file1);
            List <ExcellonFile> OtherFilesParsed = new List <ExcellonFile>();

            foreach (var otherfile in otherfiles)
            {
                Log.AddString(String.Format("Reading {0}:", otherfile));
                ExcellonFile OtherFileParsed = new ExcellonFile();
                OtherFileParsed.Load(Log, otherfile);
                OtherFilesParsed.Add(OtherFileParsed);
            }
            int MaxID = 0;

            foreach (var D in File1Parsed.Tools)
            {
                if (D.Value.ID > MaxID)
                {
                    MaxID = D.Value.ID + 1;
                }
            }
            foreach (var F in OtherFilesParsed)
            {
                foreach (var D in F.Tools)
                {
                    File1Parsed.AddToolWithHoles(D.Value);;
                    //                D.Value.ID += MaxID;
                    //              File1Parsed.Tools[D.Value.ID] = D.Value;
                }
            }
            File1Parsed.Write(output, 0, 0, 0, 0);

            Log.PopActivity(MM);
        }
Esempio n. 3
0
        public static void MergeAll(List <string> Files, string output, ProgressLog Log)
        {
            var LogDepth = Log.PushActivity("Excellon MergeAll");

            if (Files.Count >= 2)
            {
                MultiMerge(Files[0], Files.Skip(1).ToList(), output, Log);
                Log.PopActivity(LogDepth);
                return;
            }
            if (Files.Count < 2)
            {
                if (Files.Count == 1)
                {
                    Log.AddString("Merging 1 file is copying... doing so...");
                    if (File.Exists(output))
                    {
                        File.Delete(output);
                    }
                    File.Copy(Files[0], output);
                }
                else
                {
                    Log.AddString("Need files to do anything??");
                }
                Log.PopActivity(LogDepth);
                return;
            }

            string        LastFile  = Files[0];
            List <string> TempFiles = new List <string>();

            for (int i = 1; i < Files.Count - 1; i++)
            {
                string NewFile = Path.GetTempFileName();
                TempFiles.Add(NewFile);
                Merge(LastFile, Files[i], NewFile, Log);
                LastFile = NewFile;
            }

            Merge(LastFile, Files.Last(), output, Log);
            Log.AddString("Removing merge tempfiles");

            foreach (string s in TempFiles)
            {
                File.Delete(s);
            }
            Log.PopActivity(LogDepth);
        }
Esempio n. 4
0
        public static void Merge(string file1, string file2, string outputfile, ProgressLog Log)
        {
            Log.PushActivity("Excellon Merge");
            if (File.Exists(file1) == false)
            {
                Log.AddString(String.Format("{0} not found! stopping process!", file1));
                Log.PopActivity();
                return;
            }

            if (File.Exists(file2) == false)
            {
                Log.AddString(String.Format("{0} not found! stopping process!", file2));
                Log.PopActivity();
                return;
            }

            Log.AddString(String.Format("Reading {0}:", file1));
            ExcellonFile File1Parsed = new ExcellonFile();

            File1Parsed.Load(Log, file1);
            Log.AddString(String.Format("Reading {0}:", file2));
            ExcellonFile File2Parsed = new ExcellonFile();

            File2Parsed.Load(Log, file2);

            Log.AddString(String.Format("Merging {0} with {1}", file1, file2));

            int MaxID = 0;

            foreach (var D in File1Parsed.Tools)
            {
                if (D.Value.ID > MaxID)
                {
                    MaxID = D.Value.ID + 1;
                }
            }

            foreach (var D in File2Parsed.Tools)
            {
                D.Value.ID += MaxID;
                File1Parsed.Tools[D.Value.ID] = D.Value;
            }

            File1Parsed.Write(outputfile, 0, 0, 0, 0);

            Log.PopActivity();
        }
Esempio n. 5
0
        private void RemapPair(ProgressLog log, string from, string to, bool overridevalue)
        {
            log.PushActivity("RemapPair");
            if (from != to)
            {
                var F = FindEntry(from, overridevalue);
                var T = FindEntry(to, overridevalue);
                if (F != null)
                {
                    if (T != null)
                    {
                        foreach (var rd in F.RefDes)
                        {
                            T.RefDes.Add(rd);
                        }
                        F.RefDes.Clear();

                        RemoveEntry(F);
                    }
                    else
                    {
                        log.AddString(String.Format("From found, but no To: {0}", from));
                        F.SetCombined(to);
                    }
                }
            }
            log.PopActivity();
        }
Esempio n. 6
0
        public static void WriteContainedOnly(string inputfile, PolyLine Boundary, string outputfilename, ProgressLog Log)
        {
            Log.PushActivity("Excellon Clipper");
            if (File.Exists(inputfile) == false)
            {
                Log.AddString(String.Format("{0} not found! stopping process!", Path.GetFileName(inputfile)));
                Log.PopActivity();
                return;
            }
            Log.AddString(String.Format("Clipping {0} to {1}", Path.GetFileName(inputfile), Path.GetFileName(outputfilename)));

            ExcellonFile EF = new ExcellonFile();

            EF.Load(Log, inputfile);
            EF.WriteContained(Boundary, outputfilename, Log);
            Log.PopActivity();
        }
Esempio n. 7
0
 public void AddFileToSet(string aname, ProgressLog Logger, double drillscaler = 1.0)
 {
     if (Streams.ContainsKey(aname))
     {
         AddFileToSet(Streams[aname], aname, Logger, drillscaler);
     }
     else
     {
         Logger.AddString(String.Format("[ERROR] no stream for {0}!!!", aname));
     }
 }
Esempio n. 8
0
        private bool InventOutline(ProgressLog log)
        {
            double       largest = 0;
            ParsedGerber Largest = null;
            PolyLine     Outline = null;

            foreach (var a in PLSs)
            {
                var P = a.FindLargestPolygon();
                if (P != null)
                {
                    if (P.Item1 > largest)
                    {
                        largest = P.Item1;
                        Largest = a;
                        Outline = P.Item2;
                    }
                }
            }

            if (largest < BoundingBox.Area() / 3.0)
            {
                return(false);
            }
            bool zerowidth  = true;
            bool precombine = true;

            log.AddString(String.Format("Note: Using {0} to extract outline file", Path.GetFileName(Largest.Name)));
            if (Largest.Layer == BoardLayer.Mill)
            {
                Largest.OutlineShapes.Remove(Outline);
                Largest.Shapes.Remove(Outline);
            }

            var b = AddBoardToSet(log, Largest.Name, zerowidth, precombine, 1.0);

            b.Layer = BoardLayer.Outline;
            b.Side  = BoardSide.Both;
            b.DisplayShapes.Clear();
            b.OutlineShapes.Clear();
            b.Shapes.Clear();
            Outline.Close();
            b.Shapes.Add(Outline);
            b.OutlineShapes.Add(Outline);
            //b.DisplayShapes.Add(Outline);
            //b.BuildBoundary();
            b.FixPolygonWindings();
            b.CalcPathBounds();

            return(true);
        }
Esempio n. 9
0
        public void CheckRelativeBoundingBoxes(ProgressLog Logger)
        {
            List <ParsedGerber> DrillFiles         = new List <ParsedGerber>();
            List <ParsedGerber> DrillFilesToReload = new List <ParsedGerber>();
            Bounds BB = new Bounds();

            foreach (var a in PLSs)
            {
                if (a.Layer == BoardLayer.Drill)
                {
                    DrillFiles.Add(a);
                }
                else
                {
                    BB.AddBox(a.BoundingBox);
                }
            }

            foreach (var a in DrillFiles)
            {
                if (a.BoundingBox.Intersects(BB) == false)
                {
                    Errors.Add(String.Format("Drill file {0} does not seem to touch the main bounding box!", Path.GetFileName(a.Name)));
                    if (Logger != null)
                    {
                        Logger.AddString(String.Format("Drill file {0} does not seem to touch the main bounding box!", Path.GetFileName(a.Name)));
                    }
                    PLSs.Remove(a);
                }
            }



            BoundingBox = new Bounds();
            foreach (var a in PLSs)
            {
                //   Console.WriteLine("Progress: Adding board {6} to box::{0:N2},{1:N2} - {2:N2},{3:N2} -> {4:N2},{5:N2}", a.BoundingBox.TopLeft.X, a.BoundingBox.TopLeft.Y, a.BoundingBox.BottomRight.X, a.BoundingBox.BottomRight.Y, a.BoundingBox.Width(), a.BoundingBox.Height(), Path.GetFileName(a.Name));


                //Console.WriteLine("adding box for {0}:{1},{2}", a.Name, a.BoundingBox.Width(), a.BoundingBox.Height());
                BoundingBox.AddBox(a.BoundingBox);
            }
        }
Esempio n. 10
0
        public void Remap(ProgressLog log, string basefolder)
        {
            log.PushActivity("Remap");

            var D = PartLibrary.CreatePassivesMapping();

            File.WriteAllLines(Path.Combine(basefolder, "genmapping.txt"), (from i in D select i.Key + " " + i.Value).ToList());
            var map = File.ReadAllLines(Path.Combine(basefolder, "bommapping.txt"));

            log.AddString("Loaded bommapping!");
            foreach (var l in map)
            {
                var A = l.Split(' ');
                if (A.Count() >= 2)
                {
                    string from = A[0];
                    string to   = A[1];

                    bool dooverride = false;
                    if (A.Count() > 2)
                    {
                        if (A[2] == "override")
                        {
                            dooverride = true;
                        }
                        ;
                    }
                    RemapPair(log, from, to, dooverride);
                    //Console.WriteLine("remapped {0} to {1}", from, to);
                }
            }
            foreach (var l in D)
            {
                RemapPair(log, l.Key, l.Value, false);
            }
            log.PopActivity();
        }
Esempio n. 11
0
        public void AddBoardsToSet(List <string> FileList, bool fixgroup = true, ProgressLog Logger = null)
        {
            foreach (var a in FileList)
            {
                BoardSide  aSide  = BoardSide.Unknown;
                BoardLayer aLayer = BoardLayer.Unknown;
                string     ext    = Path.GetExtension(a);
                if (ext == ".zip")
                {
                    using (ZipFile zip1 = ZipFile.Read(a))
                    {
                        foreach (ZipEntry e in zip1)
                        {
                            MemoryStream MS = new MemoryStream();
                            if (e.IsDirectory == false)
                            {
                                //                              e.Extract(MS);
                                //                                MS.Seek(0, SeekOrigin.Begin);
                                Gerber.DetermineBoardSideAndLayer(e.FileName, out aSide, out aLayer);
                                if (aLayer == BoardLayer.Outline)
                                {
                                    HasLoadedOutline = true;
                                }

                                //     AddFileStream(MS, e.FileName, drillscaler);
                            }
                        }
                    }
                }
                else
                {
                    Gerber.DetermineBoardSideAndLayer(a, out aSide, out aLayer);
                }
                if (aLayer == BoardLayer.Outline)
                {
                    HasLoadedOutline = true;
                }
            }

            foreach (var a in FileList)
            {
                if (Logger != null)
                {
                    Logger.AddString(String.Format("Loading {0}", Path.GetFileName(a)));
                }
                string ext = Path.GetExtension(a);
                if (ext == ".zip")
                {
                    using (ZipFile zip1 = ZipFile.Read(a))
                    {
                        foreach (ZipEntry e in zip1)
                        {
                            MemoryStream MS = new MemoryStream();
                            if (e.IsDirectory == false)
                            {
                                if (Logger != null)
                                {
                                    Logger.AddString(String.Format("Loading inside zip: {0}", Path.GetFileName(e.FileName)));
                                }

                                e.Extract(MS);
                                MS.Seek(0, SeekOrigin.Begin);
                                AddFileToSet(MS, e.FileName, Logger);
                            }
                        }
                    }
                }
                else
                {
                    MemoryStream MS2 = new MemoryStream();
                    FileStream   FS  = File.OpenRead(a);
                    FS.CopyTo(MS2);
                    MS2.Seek(0, SeekOrigin.Begin);
                    AddFileToSet(MS2, a, Logger);
                }
            }

            if (fixgroup)
            {
                if (Logger != null)
                {
                    Logger.AddString("Checking for common file format mistakes.");
                }
                FixEagleDrillExportIssues(Logger);
                CheckRelativeBoundingBoxes(Logger);
                CheckForOutlineFiles(Logger);

                CheckRelativeBoundingBoxes(Logger);
            }
        }
Esempio n. 12
0
        public void CheckForOutlineFiles(ProgressLog Logger)
        {
            List <ParsedGerber> Outlines = new List <ParsedGerber>();
            List <ParsedGerber> Mills    = new List <ParsedGerber>();
            List <ParsedGerber> Unknowns = new List <ParsedGerber>();

            foreach (var a in PLSs)
            {
                if (a.Side == BoardSide.Both && (a.Layer == BoardLayer.Outline))
                {
                    Outlines.Add(a);
                }
                if (a.Side == BoardSide.Both && (a.Layer == BoardLayer.Mill))
                {
                    Mills.Add(a);
                }
                if (a.Side == BoardSide.Unknown && a.Layer == BoardLayer.Unknown)
                {
                    Unknowns.Add(a);
                    Errors.Add(String.Format("Unknown file in set:{0}", Path.GetFileName(a.Name)));
                    if (Logger != null)
                    {
                        Logger.AddString(String.Format("Unknown file in set:{0}", Path.GetFileName(a.Name)));
                    }
                }
            }

            if (Outlines.Count == 0)
            {
                if (Unknowns.Count == 0)
                {
                    Errors.Add(String.Format("No outline file found and all other files accounted for! "));
                    if (Logger != null)
                    {
                        Logger.AddString(String.Format("No outline file found and all other files accounted for! "));
                    }

                    // if (Mills.Count == 1)
                    // {
                    //    Mills[0].Layer = BoardLayer.Outline;
                    //   Errors.Add(String.Format("Elevating mill file to outline!"));
                    //  if (Logger != null) Logger.AddString(String.Format("Elevating mill file to outline!"));
                    // }
                    // else
                    //                    if (!InventOutlineFromMill())
                    {
                        CreateBoxOutline();
                    }
                }
                else
                {
                    CreateBoxOutline();
                    return;

                    //InventOutline();
                    //return;
                    //foreach (var a in Unknowns)
                    //{
                    //    PLSs.Remove(a);
                    //    hasgko = true;
                    //    a.Layer = BoardLayer.Outline;
                    //    a.Side = BoardSide.Both;
                    //    Console.WriteLine("Note: Using {0} as outline file", Path.GetFileName(a.Name));

                    //    if (Logger != null) Logger.AddString(String.Format("Note: Using {0} as outline file", Path.GetFileName(a.Name)));

                    //    bool zerowidth = true;
                    //    bool precombine = true;

                    //    var b = AddBoardToSet(a.Name, zerowidth, precombine, 1.0);
                    //    b.Layer = BoardLayer.Outline;
                    //    b.Side = BoardSide.Both;

                    //}
                }
            }
        }
        public static void MergeFrameIntoGerberSet(string FrameFolder, string OutlineFolder, string OutputFolder, FrameSettings FS, ProgressLog log, string basename)
        {
            log.PushActivity("MergeFrame");
            GerberPanel PNL = new GerberPanel();

            PNL.AddGerberFolder(log, FrameFolder);
            PNL.AddGerberFolder(log, OutlineFolder);
            PNL.TheSet.ClipToOutlines = false;



            var FrameInstance   = PNL.AddInstance(FrameFolder, new PointD(0, 0));
            var OutlineInstance = PNL.AddInstance(OutlineFolder, new PointD(0, 0));

            PNL.UpdateShape(log);

            var BB = OutlineInstance.BoundingBox;

            foreach (var s in OutlineInstance.TransformedOutlines)
            {
                bool ClockWise = s.ClockWise();

                if (s.Vertices.Count >= 2)
                {
                    for (int i = 0; i < s.Vertices.Count; i++)
                    {
                        PointD p1 = s.Vertices[i];
                        PointD p2 = s.Vertices[(i + 1) % s.Vertices.Count];

                        var D = p2 - p1;
                        if (Math.Abs(D.X) < 0.5 && Math.Abs(D.Y) >= FS.mmbetweentabs)
                        {
                            // perfect vertical!
                            log.AddString(String.Format("vertical found: {0} -> {1}", p1, p2));

                            double dy = p2.Y - p1.Y;

                            double x         = 0;
                            double rad       = 0;
                            bool   rightside = (dy > 0);
                            if (ClockWise)
                            {
                                rightside = !rightside;
                            }

                            if (rightside)
                            {
                                x   = (p1.X + (BB.BottomRight.X + FS.margin)) / 2;
                                rad = Math.Abs((p1.X - (BB.BottomRight.X + FS.margin))) / 2.0 + FS.margin;
                            }
                            else
                            {
                                x   = (p1.X + (BB.TopLeft.X - FS.margin)) / 2;
                                rad = Math.Abs((p1.X - (BB.TopLeft.X - FS.margin))) / 2.0 + FS.margin;
                            }


                            int tabs = (int)Math.Floor(Math.Abs(dy) / FS.mmbetweentabs);
                            for (int j = 0; j < tabs; j++)
                            {
                                double y  = p1.Y + (dy / (float)tabs) * (j + 0.5);
                                var    BR = PNL.AddTab(new PointD(x, y));
                                log.AddString(String.Format("tab at {0} - radius {1}", BR.Center, rad));
                                BR.Radius = (float)rad;
                            }
                        }
                    }
                }
            }


            PNL.UpdateShape(log);

            Directory.CreateDirectory(OutputFolder);
            PNL.SaveGerbersToFolder("MergedFrame", OutputFolder, log, true, false, true, basename);

            log.PopActivity();

//            PNL.SaveOutlineTo(OutputFolder, "mergedframeblended");
            return;



            var           FrameFiles   = Directory.GetFiles(FrameFolder);
            var           OutlineFiles = Directory.GetFiles(OutlineFolder);
            List <String> AllFiles     = new List <string>();

            AllFiles.AddRange(FrameFiles);
            foreach (var a in OutlineFiles)
            {
                BoardLayer layer;
                BoardSide  Side;

                Gerber.DetermineBoardSideAndLayer(a, out Side, out layer);

                if (layer != BoardLayer.Outline)
                {
                    AllFiles.Add(a);
                }
            }

            //  AllFiles.AddRange(OutlineFiles);
            GerberMerger.MergeAllByFileType(AllFiles, OutputFolder, "MergedFrame", log);
        }
Esempio n. 14
0
        public static void MergeFrameIntoGerberSet(string FrameFolder, string OutlineFolder, string OutputFolder, FrameSettings FS, ProgressLog log, string basename)
        {
            log.PushActivity("MergeFrame");
            // log.AddString(".....");
            if (Directory.Exists(FrameFolder) == false)
            {
                log.AddString(String.Format("Framefolder {0} does not exist?", FrameFolder));
            }
            if (Directory.Exists(OutlineFolder) == false)
            {
                log.AddString(String.Format("OutlineFolder {0} does not exist?", OutlineFolder));
            }
            if (Directory.Exists(OutputFolder) == false)
            {
                log.AddString(String.Format("OutputFolder {0} does not exist?", OutputFolder));
            }
            GerberPanel PNL = new GerberPanel();

            PNL.AddGerberFolder(log, FrameFolder);
            PNL.AddGerberFolder(log, OutlineFolder);
            PNL.TheSet.ClipToOutlines = false;



            var FrameInstance   = PNL.AddInstance(FrameFolder, new PointD(0, 0));
            var OutlineInstance = PNL.AddInstance(OutlineFolder, new PointD(0, 0));

            PNL.UpdateShape(log);

            var BB = OutlineInstance.BoundingBox;

            foreach (var s in OutlineInstance.TransformedOutlines)
            {
                bool ClockWise = s.ClockWise();

                if (s.Vertices.Count >= 2)
                {
                    for (int i = 0; i < s.Vertices.Count; i++)
                    {
                        PointD p1 = s.Vertices[i];
                        PointD p2 = s.Vertices[(i + 1) % s.Vertices.Count];

                        var D = p2 - p1;
                        if (Math.Abs(D.X) < 0.5 && Math.Abs(D.Y) >= FS.mmbetweentabs && FS.VerticalTabs)
                        {
                            // perfect vertical!
                            log.AddString(String.Format("vertical found: {0} -> {1}", p1, p2));

                            double dy = p2.Y - p1.Y;

                            double x         = 0;
                            double rad       = 0;
                            bool   rightside = (dy > 0);
                            if (ClockWise)
                            {
                                rightside = !rightside;
                            }

                            if (FS.InsideEdgeMode == FrameSettings.InsideMode.RegularEdge)
                            {
                                if (rightside)
                                {
                                    x   = (p1.X + (BB.BottomRight.X + FS.margin)) / 2;
                                    rad = Math.Abs((p1.X - (BB.BottomRight.X + FS.margin))) / 2.0 + FS.margin;
                                }
                                else
                                {
                                    x   = (p1.X + (BB.TopLeft.X - FS.margin)) / 2;
                                    rad = Math.Abs((p1.X - (BB.TopLeft.X - FS.margin))) / 2.0 + FS.margin;
                                }
                            }

                            if (FS.InsideEdgeMode == FrameSettings.InsideMode.FormFitting)
                            {
                                if (rightside)
                                {
                                    x   = p1.X + (FS.margin / 2);
                                    rad = FS.margin;
                                }
                                else
                                {
                                    x   = p1.X - (FS.margin / 2);
                                    rad = FS.margin;
                                }
                            }


                            int tabs = (int)Math.Floor(Math.Abs(dy) / FS.mmbetweentabs);
                            for (int j = 0; j < tabs; j++)
                            {
                                double y  = p1.Y + (dy / (float)tabs) * (j + 0.5);
                                var    BR = PNL.AddTab(new PointD(x, y));
                                log.AddString(String.Format("tab at {0} - radius {1}", BR.Center, rad));
                                BR.Radius = (float)rad;
                            }
                        }

                        if (Math.Abs(D.Y) < 0.5 && Math.Abs(D.X) >= FS.mmbetweentabs && FS.HorizontalTabs)
                        {
                            // perfect vertical!
                            log.AddString(String.Format("horizontal found: {0} -> {1}", p1, p2));

                            double dx = p2.X - p1.X;

                            double y         = 0;
                            double rad       = 0;
                            bool   rightside = (dx < 0);
                            if (ClockWise)
                            {
                                rightside = !rightside;
                            }

                            if (FS.InsideEdgeMode == FrameSettings.InsideMode.RegularEdge)
                            {
                                if (rightside)
                                {
                                    y   = (p1.Y + (BB.BottomRight.Y + FS.margin)) / 2;
                                    rad = Math.Abs((p1.Y - (BB.BottomRight.Y + FS.margin))) / 2.0 + FS.margin;
                                }
                                else
                                {
                                    y   = (p1.Y + (BB.TopLeft.Y - FS.margin)) / 2;
                                    rad = Math.Abs((p1.Y - (BB.TopLeft.Y - FS.margin))) / 2.0 + FS.margin;
                                }
                            }

                            if (FS.InsideEdgeMode == FrameSettings.InsideMode.FormFitting)
                            {
                                if (rightside)
                                {
                                    y   = p1.Y + (FS.margin / 2);
                                    rad = FS.margin;
                                }
                                else
                                {
                                    y   = p1.Y - (FS.margin / 2);
                                    rad = FS.margin;
                                }
                            }


                            int tabs = (int)Math.Floor(Math.Abs(dx) / FS.mmbetweentabs);
                            for (int j = 0; j < tabs; j++)
                            {
                                double x  = p1.X + (dx / (float)tabs) * (j + 0.5);
                                var    BR = PNL.AddTab(new PointD(x, y));
                                log.AddString(String.Format("tab at {0} - radius {1}", BR.Center, rad));
                                BR.Radius = (float)rad;
                            }
                        }
                    }
                }
            }


            PNL.UpdateShape(log);
            log.AddString("postupdateshape");
            try
            {
                Directory.CreateDirectory(OutputFolder);
                var PNLFiles = PNL.SaveGerbersToFolder("MergedFrame", OutputFolder, log, true, false, true, basename);
            }
            catch (Exception E)
            {
                log.AddString("save gerbers to folder Exceptions: " + E.ToString());
            }
            try
            {
                if (FS.RenderSample)
                {
                    GerberImageCreator GIC = new GerberImageCreator();
                    GIC.AddBoardsToSet(Directory.GetFiles(OutputFolder).ToList(), new SilentLog());
                    GIC.WriteImageFiles(basename, 200, true, false, true, null);
                }
            }
            catch (Exception E)
            {
                log.AddString("GIC Exceptions: " + E.ToString());
            }

            log.PopActivity();

            //            PNL.SaveOutlineTo(OutputFolder, "mergedframeblended");
            return;



            var           FrameFiles   = Directory.GetFiles(FrameFolder);
            var           OutlineFiles = Directory.GetFiles(OutlineFolder);
            List <String> AllFiles     = new List <string>();

            AllFiles.AddRange(FrameFiles);
            foreach (var a in OutlineFiles)
            {
                BoardLayer layer;
                BoardSide  Side;

                Gerber.DetermineBoardSideAndLayer(a, out Side, out layer);

                if (layer != BoardLayer.Outline)
                {
                    AllFiles.Add(a);
                }
            }

            //  AllFiles.AddRange(OutlineFiles);
            GerberMerger.MergeAllByFileType(AllFiles, OutputFolder, "MergedFrame", log);
        }
Esempio n. 15
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);
        }
Esempio n. 16
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. 17
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(ProgressLog log, string sourcefile, string destfile, double DX, double DY, double DXp, double DYp, double AngleInDeg = 0)
        {
            log.PushActivity("Gerber Transform");
            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(log, lines, true, false, new GerberParserState()
            {
                GenerateGeometry = false
            });

            if (Gerber.ShowProgress)
            {
                log.AddString("found apertures: ");
                foreach (var a in Parsed.State.Apertures)
                {
                    log.AddString(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)
                    {
                        log.AddString(String.Format("Skipping bad aperture definition: {0}", lines[i]));
                    }
                    else
                    {
                        int ATID     = (int)GCC.numbercommands[0];
                        var Aperture = Parsed.State.Apertures[ATID];
                        if (Gerber.ShowProgress)
                        {
                            log.AddString(String.Format("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)
                        {
                            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;
                            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)
                        {
                            //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(destfile, PolyLineSet.SanitizeInputLines(PostProcLines));
            }
            catch (Exception E)
            {
                log.AddString(String.Format(E.Message));
            }
            log.PopActivity();
        }
Esempio n. 18
0
        public static bool SaveDebugImage(string GerberFilename, string BitmapFilename, float dpi, Color Foreground, Color Background, ProgressLog log)
        {
            log.PushActivity("debug image");
            ParsedGerber      PLS;
            GerberParserState State = new GerberParserState()
            {
                PreCombinePolygons = false
            };

            var FileType = Gerber.FindFileType(GerberFilename);

            Gerber.DetermineBoardSideAndLayer(GerberFilename, out State.Side, out State.Layer);
            bool forcezero = false;

            if (State.Layer == BoardLayer.Outline)
            {
                //    PLS.PreCombinePolygons = true;

                //    forcezero = true;
            }
            if (FileType == BoardFileType.Drill)
            {
                PLS = PolyLineSet.LoadExcellonDrillFile(log, GerberFilename);
            }
            else
            {
                PLS = PolyLineSet.LoadGerberFile(GerberFilename, forcezero, Gerber.WriteSanitized, State);
            }
            double WidthInMM  = PLS.BoundingBox.BottomRight.X - PLS.BoundingBox.TopLeft.X;
            double HeightInMM = PLS.BoundingBox.BottomRight.Y - PLS.BoundingBox.TopLeft.Y;
            int    Width      = (int)(Math.Ceiling((WidthInMM) * (dpi / 25.4)));
            int    Height     = (int)(Math.Ceiling((HeightInMM) * (dpi / 25.4)));

            log.AddString(String.Format("Exporting {0} ({2},{3}mm) to {1} ({4},{5})", GerberFilename, BitmapFilename, WidthInMM, HeightInMM, Width, Height));
            GerberImageCreator GIC = new GerberImageCreator();

            GIC.scale = dpi / 25.4f; // dpi
            GIC.BoundingBox.AddBox(PLS.BoundingBox);

            var Tr = GIC.BuildMatrix(Width, Height);

            Bitmap B2 = GIC.RenderToBitmap(Width, Height, Tr, Foreground, Background, PLS, true);

            if (B2 == null)
            {
                return(false);
            }

            var    GerberLines = PolyLineSet.SanitizeInputLines(System.IO.File.ReadAllLines(GerberFilename).ToList());
            double LastX       = 0;
            double LastY       = 0;



            Graphics G2 = Graphics.FromImage(B2);

            GerberImageCreator.ApplyAASettings(G2);
            //G2.Clear(Background);
            G2.Transform = Tr.Clone();



            foreach (var L in GerberLines)
            {
                if (L[0] != '%')
                {
                    GerberSplitter GS = new GerberSplitter();
                    GS.Split(L, PLS.State.CoordinateFormat);

                    if (GS.Has("G") && (int)GS.Get("G") == 3)
                    {
                        double X = PLS.State.CoordinateFormat.ScaleFileToMM(GS.Get("X"));
                        double Y = PLS.State.CoordinateFormat.ScaleFileToMM(GS.Get("Y"));

                        double I = PLS.State.CoordinateFormat.ScaleFileToMM(GS.Get("I"));
                        double J = PLS.State.CoordinateFormat.ScaleFileToMM(GS.Get("J"));

                        //Console.WriteLine("Counterclockwise Curve {0},{1} -> {2},{3}", LastX, LastY, X, Y);
                        DrawCross(G2, X, Y, Color.Blue);
                        DrawCross(G2, LastX, LastY, Color.Red);

                        DrawCross(G2, LastX + I, LastY - J, Color.Yellow);
                        DrawCross(G2, LastX + I, LastY + J, Color.Purple);
                        DrawCross(G2, LastX - I, LastY - J, Color.Green);
                        DrawCross(G2, LastX - I, LastY + J, Color.Orange);
                    }

                    if (GS.Has("X"))
                    {
                        LastX = PLS.State.CoordinateFormat.ScaleFileToMM(GS.Get("X"));
                    }
                    if (GS.Has("Y"))
                    {
                        LastY = PLS.State.CoordinateFormat.ScaleFileToMM(GS.Get("Y"));
                    }
                }
            }


            B2.Save(BitmapFilename);
            log.PopActivity();
            return(true);
        }
Esempio n. 19
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);
        }