Beispiel #1
0
        static void Main(string[] args)
        {
            //GerberSplitter GS = new GerberSplitter();
            //GS.Split("G03*", new GerberLibrary.Core.Primitives.GerberNumberFormat());
            //GS.Split("%SRX1Y1I0.00000J1.76100*%", new GerberLibrary.Core.Primitives.GerberNumberFormat(),true);
            //Console.WriteLine("{0}", GS.Pairs.Count);
            Gerber.ShowProgress        = true;
            Gerber.DumpSanitizedOutput = true;
            Gerber.WriteSanitized      = true;

            if (args.Count() < 2)
            {
                Console.WriteLine("usage: ");
                Console.WriteLine("GerberCombiner <outputfile> <inputfile1> <inputfile2> <inputfileN> ");
                Console.WriteLine("<outputfile>: file to write - if the outputfile extension is .txt, all input files will be treated as excellon");
                Console.WriteLine("<inputfileN>: files to load");

                return;
            }
            for (int j = 1; j < args.Count(); j++)
            {
                if (File.Exists(args[j]) == false)
                {
                    Console.WriteLine("file not found! {0}", args[j]);
                    return;
                }
            }
            BoardSide  S;
            BoardLayer L;

            var FileType = Gerber.FindFileType(args[1]);

            Gerber.DetermineBoardSideAndLayer(args[1], out S, out L);

            for (int j = 2; j < args.Count(); j++)
            {
                var FileType2 = Gerber.FindFileType(args[1]);

                Gerber.DetermineBoardSideAndLayer(args[1], out S, out L);
                if (FileType2 != FileType)
                {
                    Console.WriteLine("Warning! Filetypes seem to be mismatched! First file ({0}) is a {1}, but {2} is a {3}", args[1], FileType, args[j], FileType2);
                }
            }

            if (FileType == BoardFileType.Drill)
            {
                List <string> ExcellonFiles = new List <string>();
                ExcellonFiles.AddRange(args.Skip(1));
                ExcellonFile.MergeAll(ExcellonFiles, args[0], new StandardConsoleLog());
            }
            else
            {
                List <string> GerberFiles = new List <string>();
                GerberFiles.AddRange(args.Skip(1));
                GerberMerger.MergeAll(GerberFiles, args[0], new StandardConsoleLog());
            }
            //  Console.WriteLine("Press any key to continue..");
            //  Console.ReadKey();
        }
Beispiel #2
0
        static void Slice(string slicefile, List <string> inputgerbers)
        {
            List <PolyLine> SliceSet = new List <PolyLine>();

            var OutputFolder = Path.GetDirectoryName(slicefile) + @"\Output\" + Path.GetFileNameWithoutExtension(slicefile);

            ParsedGerber P = PolyLineSet.LoadGerberFile(new StandardConsoleLog(), slicefile);

            foreach (var l in P.Shapes)
            {
                /* Polygon Pp = new Polygon();
                *  Pp.Closed = true;
                *  var vertL = from i in l.Vertices select new vec2(i.X, i.Y);
                *  Pp.Vertices.AddRange(vertL);*/
                SliceSet.Add(l);
            }

            int slid = 1;

            foreach (var S in SliceSet)
            {
                Console.WriteLine("Slicing {0}/{1}", slid, SliceSet.Count);
                var SliceOutputFolder = Path.GetDirectoryName(slicefile) + @"\Output\" + Path.GetFileNameWithoutExtension(slicefile) + "\\Slice" + slid.ToString();
                if (Directory.Exists(SliceOutputFolder) == false)
                {
                    Directory.CreateDirectory(SliceOutputFolder);
                }

                foreach (var a in inputgerbers)
                {
                    try
                    {
                        var bf = GerberLibrary.Gerber.FindFileType(a);
                        if (bf == BoardFileType.Gerber)
                        {
                            BoardSide  bs;
                            BoardLayer L;
                            GerberLibrary.Gerber.DetermineBoardSideAndLayer(a, out bs, out L);

                            GerberMerger.WriteContainedOnly(a, S, Path.Combine(SliceOutputFolder + "\\", Path.GetFileName(a)), new StandardConsoleLog());
                        }
                    }
                    catch (Exception) { };
                }
                slid++;
            }
        }
Beispiel #3
0
        public static void ZipGerberFolderToFactoryFolder(string Name, string BoardGerbersFolder, string BoardFactoryFolder)
        {
            if (Directory.Exists(BoardGerbersFolder))
            {
                string TargetZip = Path.Combine(BoardFactoryFolder, Name + "_gerbers.zip");
                if (File.Exists(TargetZip))
                {
                    File.Delete(TargetZip);
                }
                Console.WriteLine("Zipping gerbers to {0}", TargetZip);
                ZipFile       Z            = new ZipFile();
                List <string> OutlineMerge = new List <string>();
                foreach (var F in Directory.GetFiles(BoardGerbersFolder))
                {
                    bool AddToZip = false;
                    var  T        = GerberLibrary.Gerber.FindFileType(F);
                    if (T == BoardFileType.Drill)
                    {
                        AddToZip = true;
                    }
                    else
                    {
                        GerberLibrary.Gerber.DetermineBoardSideAndLayer(F, out BoardSide Side, out BoardLayer Layer);
                        switch (Layer)
                        {
                        case BoardLayer.Mill:
                        case BoardLayer.Outline:
                            OutlineMerge.Add(F);
                            break;

                        case BoardLayer.Carbon:
                        case BoardLayer.Paste:
                        case BoardLayer.Silk:
                        case BoardLayer.SolderMask:
                        case BoardLayer.Copper:
                        case BoardLayer.Drill:
                            AddToZip = true;
                            break;

                        case BoardLayer.Assembly:
                            string TargetGerb = Path.Combine(BoardFactoryFolder, Name + "_" + Path.GetFileName(F));
                            File.Copy(F, TargetGerb, true);
                            break;
                        }
                    }
                    if (AddToZip)
                    {
                        Console.WriteLine("Adding {0} to zip.", F);
                        Z.AddFile(F, ".");
                    }
                }
                if (OutlineMerge.Count > 0)
                {
                    if (OutlineMerge.Count == 1)
                    {
//                        string TargetGerb = Path.Combine(BoardFactoryFolder, Name + "_" + Path.GetFileName(OutlineMerge[0]));
//                      File.Copy(OutlineMerge[0], TargetGerb, true);
                        Z.AddFile(OutlineMerge[0], ".");
                    }
                    else
                    {
                        string TargetGerb = Path.Combine(BoardFactoryFolder, Name + "_" + "MergedOutlines.gko");
                        GerberMerger.MergeAll(OutlineMerge, TargetGerb, new StandardConsoleLog());
                        Z.AddFile(TargetGerb, ".");
                    }
                }
                Z.Save(TargetZip);
            }
        }
        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);
        }
Beispiel #5
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);
        }
Beispiel #6
0
        private void VScore_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] D = e.Data.GetData(DataFormats.FileDrop) as string[];

                BackColor = Color.Green;

                foreach (string S in D)
                {
                    if (Directory.Exists(S))
                    {
                        try
                        {
                            GerberLibrary.GerberImageCreator GIC = new GerberLibrary.GerberImageCreator();
                            var A = Directory.GetFiles(S);

                            GIC.AddBoardsToSet(A.ToList(), new StandardConsoleLog());

                            GerberFrameWriter.FrameSettings FS = new GerberFrameWriter.FrameSettings();
                            List <String> OutputLines          = new List <string>();

                            OutputLines.Add(String.Format("Panel for {0}", Path.GetDirectoryName(S)));
                            Bounds PanelBounds = new Bounds();
                            double w           = GIC.BoundingBox.Width();
                            double h           = GIC.BoundingBox.Height();
                            double bx          = GIC.BoundingBox.TopLeft.X;
                            double by          = GIC.BoundingBox.TopLeft.Y;

                            GerberPanel Pnl = new GerberPanel();
                            Pnl.TheSet.ClipToOutlines = false;
                            Pnl.AddGerberFolder(new StandardConsoleLog(), S);
                            double ginbetween = (double)numericUpDown1.Value;

                            for (int x = 0; x < (int)xbox.Value; x++)
                            {
                                for (int y = 0; y < (int)ybox.Value; y++)
                                {
                                    var I = Pnl.AddInstance(S, new PointD(x * (w + ginbetween), y * (h + ginbetween)));

                                    OutputLines.Add(String.Format("Adding board instance: {0}mm x {1}mm offset", x * (w + ginbetween), y * (h + ginbetween)));

                                    if (theMode == PanelMode.Groovy)
                                    {
                                        I.IgnoreOutline = true;
                                    }

                                    PanelBounds.FitPoint(bx + ((x + 0) * (w + ginbetween)), by + ((y + 0) * (h + ginbetween)));
                                    PanelBounds.FitPoint(bx + (w + (x + 0) * (w + ginbetween)), by + ((y + 0) * (h + ginbetween)));
                                    PanelBounds.FitPoint(bx + (w + (x + 0) * (w + ginbetween)), by + (h + (y + 0) * (h + ginbetween)));
                                    PanelBounds.FitPoint(bx + ((x + 0) * (w + ginbetween)), by + (h + (y + 0) * (h + ginbetween)));
                                }
                            }
                            if (theMode == PanelMode.Tabby)
                            {
                                OutputLines.Add("Panel created as Tabby board");
                                OutputLines.Add(String.Format("Space inbetween: {0}mm", ginbetween));


                                FS.FrameTitle   = FrameTitle.Text;;
                                FS.RenderSample = false;
                                FS.margin       = ginbetween;
                                FS.topEdge      = FS.leftEdge = (double)framebox.Value;
                                OutputLines.Add(String.Format("Frame width: {0}mm", FS.leftEdge));
                                FS.roundedInnerCorners = 0;
                                FS.roundedOuterCorners = 0;
                                FS.RenderSample        = false;
                                FS.DirectionArrowSide  = GerberLibrary.Core.BoardSide.Top;

                                FS.RenderDirectionArrow = true;
                                //FS.DefaultFiducials = true;
                                //FS.FiducialSide = BoardSide.Both;
                                FS.HorizontalTabs = false;
                                FS.VerticalTabs   = false;
                                FS.InsideEdgeMode = GerberFrameWriter.FrameSettings.InsideMode.RegularEdge;
                                FS.PositionAround(PanelBounds);

                                string sS = String.Format("Frame size: {0} mm x {1} mm", FS.innerWidth + FS.margin * 2 + FS.leftEdge, FS.innerHeight + FS.margin * 2 + FS.topEdge);
                                OutputLines.Add(sS);
                                var OutputFolder = Path.Combine(S, "../" + Path.GetFileNameWithoutExtension(S) + "_TABBY");
                                Directory.CreateDirectory(OutputFolder);

                                String FrameFolder = Path.Combine(OutputFolder, "frame");
                                Directory.CreateDirectory(FrameFolder);


                                //Directory.CreateDirectory(Path.Combine(OutputFolder, "merged"));
                                Directory.CreateDirectory(Path.Combine(OutputFolder, "merged"));
                                GerberFrameWriter.WriteSideEdgeFrame(null, FS, Path.Combine(FrameFolder, "panelframe"), null);
                                Pnl.AddGerberFolder(new StandardConsoleLog(), FrameFolder);
                                Pnl.AddInstance(FrameFolder, new PointD(0, 0));
                                Pnl.TheSet.MergeFileTypes = false;

                                int    tabcount = 2;
                                double tx       = (w - (tabcount * ginbetween * 2)) / (tabcount + 1.0f);
                                double ty       = (h - (tabcount * ginbetween * 2)) / (tabcount + 1.0f);
                                double txs      = tx + ginbetween;
                                double tys      = ty + ginbetween;
                                tx += ginbetween * 2;
                                ty += ginbetween * 2;

                                for (int x = 0; x < (int)xbox.Value + 1; x++)
                                {
                                    for (int y = 0; y < (int)ybox.Value + 1; y++)
                                    {
                                        for (int i = 0; i < tabcount; i++)
                                        {
                                            if (x < (int)xbox.Value)
                                            {
                                                var BT1 = Pnl.AddTab(new PointD(bx + (x + 0) * (w + ginbetween) + tx * (i) + txs, by + ((y + 0) * (h + ginbetween)) - ginbetween / 2));
                                                BT1.Radius = (float)ginbetween;
                                            }
                                            if (y < (int)ybox.Value)
                                            {
                                                var BT2 = Pnl.AddTab(new PointD(bx + (x + 0) * (w + ginbetween) - ginbetween / 2, by + ((y + 0) * (h + ginbetween)) + ty * (i) + tys));
                                                BT2.Radius = (float)ginbetween;
                                            }
                                        }
                                    }
                                }



                                Pnl.UpdateShape(new StandardConsoleLog());
                                Pnl.SaveGerbersToFolder(Path.GetFileNameWithoutExtension(S) + "_Panel", Path.Combine(OutputFolder, "merged"), new StandardConsoleLog());
                                File.WriteAllLines(Path.Combine(OutputFolder, "PanelReport.txt"), OutputLines);


                                List <String> FilesInFolder = Directory.GetFiles(Path.Combine(OutputFolder, "merged"), "*.frontpanelholes").ToList();
                                if (FilesInFolder.Count > 0)
                                {
                                    String JigFolder = Path.Combine(OutputFolder, "jig");
                                    Directory.CreateDirectory(JigFolder);
                                    File.Copy(FilesInFolder[0], Path.Combine(JigFolder, "jig.gml"), true);
                                    FS.InsideEdgeMode = GerberFrameWriter.FrameSettings.InsideMode.NoEdge;
                                    GerberFrameWriter.WriteSideEdgeFrame(null, FS, Path.Combine(JigFolder, "jig"), null);
                                    GerberMerger.Merge(Path.Combine(JigFolder, "jig.gml"), Path.Combine(JigFolder, "jig.gko"), Path.Combine(JigFolder, "jig.gko2"), new StandardConsoleLog());
                                    File.Delete(Path.Combine(JigFolder, "jig.gko"));
                                    File.Delete(Path.Combine(JigFolder, "jig.gml"));
                                    File.Move(Path.Combine(JigFolder, "jig.gko2"), Path.Combine(JigFolder, "jig.gko"));
                                }
                            }

                            if (theMode == PanelMode.Groovy)
                            {
                                FS.FrameTitle           = FrameTitle.Text;;
                                FS.RenderSample         = false;
                                FS.margin               = 0;
                                FS.topEdge              = FS.leftEdge = (double)framebox.Value;
                                FS.roundedInnerCorners  = 0;
                                FS.roundedOuterCorners  = 0;
                                FS.RenderSample         = false;
                                FS.RenderDirectionArrow = false;
                                FS.DirectionArrowSide   = GerberLibrary.Core.BoardSide.Top;
                                //FS.DefaultFiducials = true;
                                //FS.FiducialSide = BoardSide.Both;
                                FS.HorizontalTabs = false;
                                FS.VerticalTabs   = false;
                                FS.InsideEdgeMode = GerberFrameWriter.FrameSettings.InsideMode.NoEdge;
                                FS.PositionAround(PanelBounds);


                                var OutputFolder = Path.Combine(S, "../" + Path.GetFileNameWithoutExtension(S) + "_GROOVY");
                                Directory.CreateDirectory(OutputFolder);

                                GerberOutlineWriter GOW = new GerberOutlineWriter();
                                int xmax = (int)xbox.Value + 1;
                                int ymax = (int)ybox.Value + 1;
                                if (ginbetween > 0)
                                {
                                    xmax--;
                                    ymax--;
                                }

                                for (int x = 0; x < xmax; x++)
                                {
                                    PolyLine PL = new PolyLine();
                                    PL.Add(bx + (x) * (w + ginbetween), PanelBounds.TopLeft.Y - (float)framebox.Value - 10);
                                    PL.Add(bx + (x) * (w + ginbetween), PanelBounds.BottomRight.Y + (float)framebox.Value + 10);
                                    GOW.AddPolyLine(PL);

                                    if (ginbetween > 0)
                                    {
                                        PolyLine PL2 = new PolyLine();
                                        PL2.Add(bx + (x) * (w + ginbetween) + w, PanelBounds.TopLeft.Y - (float)framebox.Value - 10);
                                        PL2.Add(bx + (x) * (w + ginbetween) + w, PanelBounds.BottomRight.Y + (float)framebox.Value + 10);
                                        GOW.AddPolyLine(PL2);
                                    }
                                }

                                for (int y = 0; y < ymax; y++)
                                {
                                    PolyLine PL = new PolyLine();
                                    PL.Add(PanelBounds.TopLeft.X - (float)framebox.Value - 10, by + (y) * (h + ginbetween));
                                    PL.Add(PanelBounds.BottomRight.X + (float)framebox.Value + 10, by + (y) * (h + ginbetween));
                                    GOW.AddPolyLine(PL);

                                    if (ginbetween > 0)
                                    {
                                        PolyLine PL2 = new PolyLine();
                                        PL2.Add(PanelBounds.TopLeft.X - (float)framebox.Value - 10, by + (y) * (h + ginbetween) + h);
                                        PL2.Add(PanelBounds.BottomRight.X + (float)framebox.Value + 10, by + (y) * (h + ginbetween) + h);
                                        GOW.AddPolyLine(PL2);
                                    }
                                }
                                GOW.Write(Path.Combine(OutputFolder, "VGrooves.gbr"));

                                String FrameFolder = Path.Combine(OutputFolder, "frame");
                                Directory.CreateDirectory(FrameFolder);
                                Directory.CreateDirectory(Path.Combine(OutputFolder, "merged"));
                                GerberFrameWriter.WriteSideEdgeFrame(null, FS, Path.Combine(FrameFolder, "panelframe"), null);



                                Pnl.AddGerberFolder(new StandardConsoleLog(), FrameFolder);
                                Pnl.AddInstance(FrameFolder, new PointD(0, 0));
                                Pnl.UpdateShape(new StandardConsoleLog());
                                Pnl.SaveGerbersToFolder(Path.GetFileNameWithoutExtension(S) + "_Panel", Path.Combine(OutputFolder, "merged"), new StandardConsoleLog());
                            }



                            CountDown = 10;
                        }
                        catch (Exception)
                        {
                            BackColor = Color.Red;
                        }
                    }
                }
            }
        }