Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
5203ce801This file is pinned to the selected release. Download the original to open it in your design tool.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
// using System.Windows.Forms;
using GerberLibrary.Core.Primitives;
using GerberLibrary.Core;
namespace GerberLibrary
{
public static class GerberMerger
{
public static void MergeAll(List<string> Files, string output, ProgressLog Log)
{
int Check = Log.PushActivity("Gerber MergeAll");
if (Files.Count > 1)
{
MultiMerge(Files[0], Files.Skip(1).ToList(), output, Log);
Log.PopActivity(Check);
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(Check);
return;
}
List<string> TempFiles = new List<string>();
if (true)
{
List<String> LeftOverFiles = new List<string>();
foreach (var a in Files)
{
LeftOverFiles.Add(a);
}
while (LeftOverFiles.Count > 1)
{
Log.AddString(String.Format("{0} files left in mergequeue", LeftOverFiles.Count));
string File1 = LeftOverFiles[0];
string File2 = LeftOverFiles[1];
LeftOverFiles.Remove(File1);
LeftOverFiles.Remove(File2);
string NewFile = Path.GetTempFileName();
Merge(File1, File2, NewFile, Log);
TempFiles.Add(NewFile);
LeftOverFiles.Add(NewFile);
}
if (File.Exists(output)) File.Delete(output);
File.Move(LeftOverFiles[0], output);
}
else
{
string LastFile = Files[0];
for (int i = 1; i < Files.Count - 1; i++)
{
string NewFile = Path.GetTempFileName();
TempFiles.Add(NewFile);
Merge(LastFile, Files[i], NewFile, Log);
LastFile = NewFile;
}
if (File.Exists(output)) File.Delete(output);
Merge(LastFile, Files.Last(), output, Log);
}
Log.AddString("Removing merge tempfiles");
foreach (string s in TempFiles)
{
try
{
File.Delete(s);
}
catch (Exception) { }
}
Log.PopActivity(Check);
}
public static void MultiMerge(string file1, List<string> filestomergein, string output, ProgressLog Log)
{
int check = Log.PushActivity("Gerber MultiMerge");
if (File.Exists(file1) == false)
{
Log.AddString(String.Format("{0} not found! stopping process!", Path.GetFileName(file1)));
Log.PopActivity(check);
return;
}
List<ParsedGerber> OtherFiles = new List<ParsedGerber>();
int MaxDigitsBefore = 0;
int MaxDigitsAfter = 0;
foreach (var otherfile in filestomergein)
{
if (File.Exists(otherfile) == false)
{
Log.AddString(String.Format("{0} not found! stopping process!", Path.GetFileName(otherfile)));
Log.PopActivity(check);
return;
}
List<string> OtherLines = File.ReadAllLines(otherfile).ToList();
OtherLines = PolyLineSet.SanitizeInputLines(OtherLines);
ParsedGerber OtherFileParsed = PolyLineSet.ParseGerber274x(Log, OtherLines, true, false, new GerberParserState() { PreCombinePolygons = false, GenerateGeometry = false });
OtherFiles.Add(OtherFileParsed);
OtherFileParsed.OriginalLines = OtherLines;
MaxDigitsAfter = Math.Max(OtherFileParsed.State.CoordinateFormat.DigitsAfter, MaxDigitsAfter);
MaxDigitsBefore = Math.Max(OtherFileParsed.State.CoordinateFormat.DigitsBefore, MaxDigitsBefore);
}
List<string> File1Lines = File.ReadAllLines(file1).ToList();
File1Lines = PolyLineSet.SanitizeInputLines(File1Lines);
ParsedGerber File1Parsed = PolyLineSet.ParseGerber274x(Log, File1Lines, true, false, new GerberParserState() { PreCombinePolygons = false, GenerateGeometry = false });
List<string> OutputLines = new List<string>();
GerberNumberFormat GNF = new GerberNumberFormat();
GNF.DigitsBefore = Math.Max(File1Parsed.State.CoordinateFormat.DigitsBefore, MaxDigitsBefore);
GNF.DigitsAfter = Math.Max(File1Parsed.State.CoordinateFormat.DigitsAfter, MaxDigitsAfter);
GNF.SetImperialMode();
//OutputLines.Add(String.Format("G04 merged from {0} and {1}", Path.GetFileNameWithoutExtension(file1), Path.GetFileNameWithoutExtension(file2)));
OutputLines.Add(GNF.BuildMetricImperialFormatLine());
OutputLines.Add("%OFA0B0*%");
OutputLines.Add(GNF.BuildGerberFormatLine());
OutputLines.Add("%IPPOS*%");
OutputLines.Add("%LPD*%");
Dictionary<string, string> MacroDict = new Dictionary<string, string>();
foreach (var a in File1Parsed.State.ApertureMacros)
{
//a.Value.Name = a.Value.Name + "_FILE0";
OutputLines.Add(a.Value.BuildGerber(GNF, 0, "_FILE0").Trim());
MacroDict[a.Value.Name ] = a.Value.Name;
}
int FileN = 1;
foreach (var fileparsed in OtherFiles)
{
string FileSuffix = "_FILE" + FileN.ToString();
FileN++;
foreach (var a in fileparsed.State.ApertureMacros)
{
/*a.Value.Name = a.Value.Name + FileSuffix;
int off = 0;
string name = string.Format("{0}", a.Value.Name);
while (MacroDict.Values.Contains(name))
{
off++;
name = string.Format("{0}_{1}", a.Value.Name, off);
}*/
MacroDict[a.Value.Name] = a.Value.Name;
OutputLines.Add(a.Value.BuildGerber(GNF, 0, FileSuffix).Trim());
}
}
CheckAllApertures(File1Parsed, File1Lines, Log);
foreach (var a in File1Parsed.State.Apertures)
{
//if (a.Value.ShapeType == GerberApertureShape.Macro)
//{
//a.Value.MacroName = a.Value.MacroName + "_FILE0";
//}
OutputLines.Add(a.Value.BuildGerber(GNF, "_FILE0"));
}
int ApertureOffset = 0;
if (File1Parsed.State.Apertures.Count > 0) ApertureOffset = File1Parsed.State.Apertures.Keys.Max() + 1;
int LastID = ApertureOffset + 10;
FileN = 1;
foreach (var fileparsed in OtherFiles)
{
CheckAllApertures(fileparsed, fileparsed.OriginalLines, Log);
string FileSuffix = "_FILE" + FileN.ToString();
FileN++;
foreach (var a in fileparsed.State.Apertures)
{
if (a.Value.ShapeType == GerberApertureShape.Macro )
{
a.Value.MacroName = a.Value.MacroName + FileSuffix;
// a.Value.MacroName = MacroDict[a.Value.MacroName];
}
a.Value.ID = LastID++;
OutputLines.Add(a.Value.BuildGerber(GNF, FileSuffix));
}
}
// stuff goes here.
//OutputLines.Add(String.Format("G04 :starting {0}", Path.GetFileNameWithoutExtension(file1)));
string CurrentPolarity = "LPD";
bool Repeating = false;
double X = 0;
double Y = 0;
for (int i = 0; i < File1Lines.Count; i++)
{
string CurrentLine = File1Lines[i];
if (CurrentLine.Length == 0) continue;
try
{
GCodeCommand GCC = new GCodeCommand();
GCC.Decode(CurrentLine, GNF);
switch (CurrentLine[0])
{
case '%':
{
string FinalLine = "" + CurrentLine;
FinalLine = FinalLine.Replace("%", "").Replace("*", "").Trim();
switch (FinalLine)
{
case "LPD":
if (CurrentPolarity != "LPD") { OutputLines.Add("%LPD*%"); CurrentPolarity = "LPD"; }
break;
case "LPC":
if (CurrentPolarity != "LPC") { OutputLines.Add("%LPC*%"); CurrentPolarity = "LPC"; }
break;
default:
if (CurrentLine.StartsWith("%SR"))
{
OutputLines.Add(CurrentLine);
// Console.WriteLine("StepRepeatYay!", CurrentLine);
if (GCC.numbercommands.Count > 0)
{
int x = (int)GCC.numbercommands[0];
int y = (int)GCC.numbercommands[1];
if (x > 1 && y > 1)
{
Repeating = true;
}
else
{
Repeating = false;
}
}
else
{
Repeating = false;
}
}
else
{
//Console.WriteLine("eating % commands... {0}", CurrentLine);
if (CurrentLine.Length > 1 && CurrentLine[CurrentLine.Length - 1] != '%')
{
while (CurrentLine[CurrentLine.Length - 1] != '%')
{
i++;
CurrentLine = File1Lines[i];
}
}
}
break;
}
}
break;
case 'G': // machine status commands and interpolations?
{
GerberSplitter GS = new GerberSplitter();
GS.Split(GCC.originalline, File1Parsed.State.CoordinateFormat);
if ((int)GS.Get("G") == 54)
{
if (GS.Has("D") && GS.Get("D") > 3)
{
OutputLines.Add(CurrentLine);
}
}
else
if ((int)GCC.numbercommands[0] == 3 || (int)GCC.numbercommands[0] == 2 || (int)GCC.numbercommands[0] == 1)
{
//GS.Split(GCC.originalline, File1Parsed.State.CoordinateFormat);
GS.ScaleToMM(File1Parsed.State.CoordinateFormat);
if (File1Parsed.State.CoordinateFormat.Relativemode)
{
if (GS.Has("X"))
{
X += GS.Get("X");
GS.Set("X", X);
}
if (GS.Has("Y"))
{
Y += GS.Get("Y");
GS.Set("Y", Y);
}
}
GS.ScaleToFile(GNF);
OutputLines.Add(GS.Rebuild(GNF));
// Log.AddString("Unsupported arc command found!");
// MessageBox.Show("Unsupported arc type found during merge! File will NOT be exported correctly!", "Error during export", MessageBoxButtons.OK, MessageBoxIcon.Error);
// Log.AddString("Unsupported arc command found!");
// MessageBox.Show("Unsupported arc type found during merge! File will NOT be exported correctly!", "Error during export", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
if (GS.Has("G") && (GS.Get("G") == 71 || GS.Get("G") == 70))
{
if (GS.Get("G") == 71)
{
File1Parsed.State.CoordinateFormat.SetMetricMode();
}
if (GS.Get("G") == 70)
{
File1Parsed.State.CoordinateFormat.SetImperialMode();
}
// skip changing metric mode!
Log.AddString(String.Format("ignoring metric/imperial gcode: G{0}", GS.Get("G")));
}
else
{
if (GS.Get("G") == 4)
{
Log.AddString(String.Format("skipping comment: {0}", CurrentLine));
}
else
{
OutputLines.Add(CurrentLine);
}
//OutputLines.Add(CurrentLine);
}
//tputLines.Add(CurrentLine);
}
}
break;
default: // move commands -> transform
{
GerberSplitter GS = new GerberSplitter();
if (File1Parsed.State.CoordinateFormat.Relativemode == false)
{
X = 0;
Y = 0;
}
GS.Split(GCC.originalline, File1Parsed.State.CoordinateFormat);
GS.ApplyMirroring(File1Parsed.State);
if (GS.Has("D") || GS.Has("X") || GS.Has("Y"))
{
if (GS.Get("D") > 3)
{
OutputLines.Add(CurrentLine);
}
else
{
if (GS.Has("X") == false && GS.Has("Y") == false)
{
OutputLines.Add(CurrentLine);
}
else
{
string OutLine = ";";
if (GS.Has("X") && GS.Has("Y"))
{
X += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("X"));
Y += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("Y"));
OutLine = String.Format("X{0}Y{1}", GNF.Format(GNF._ScaleMMToFile(X)), GNF.Format(GNF._ScaleMMToFile(Y)));
}
else
{
if (GS.Has("X"))
{
X += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("X"));
OutLine = String.Format("X{0}", GNF.Format(GNF._ScaleMMToFile(X)));
}
else
{
if (GS.Has("Y"))
{
Y += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("Y"));
OutLine = String.Format("Y{0}", GNF.Format(GNF._ScaleMMToFile(Y)));
}
else
{
OutLine = "";
}
}
}
if (GS.Has("I"))
{
var I = File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("I"));
OutLine += String.Format("I{0}", GNF.Format(GNF._ScaleMMToFile(I)));
}
if (GS.Has("J"))
{
var J = File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("J"));
OutLine += String.Format("J{0}", GNF.Format(GNF._ScaleMMToFile(J)));
}
if (GS.Has("D"))
{
OutLine += String.Format("D{0}", ((int)GS.Get("D")).ToString("D2"));
}
OutLine += "*";
OutputLines.Add(OutLine);
}
}
// OutputLines.Add(String.Format("X{0}Y{1}D{2}*", GNF.Format(GNF.ScaleMMToFile(X)), GNF.Format(GNF.ScaleMMToFile(Y)), ((int)GS.Get("D")).ToString("D2")));
}
}
break;
case 'M': // skip
break;
}
}
catch (Exception)
{
}
}
// TODO: set polarity back to "neutral" - or should each file do this at the start anyway?
if (Repeating)
{
OutputLines.Add("G04 previous file was still repeating.. stopping that*");
OutputLines.Add("%SR*%");
Repeating = false;
}
if (Gerber.ShowProgress)
{
Log.AddString(String.Format("File 1 format: {0}", File1Parsed.State.CoordinateFormat));
}
foreach (var otherfile in OtherFiles)
{
X = 0;
Y = 0;
if (Gerber.ShowProgress)
{
Log.AddString(String.Format("File 2 format: {0}", otherfile.State.CoordinateFormat));
}
OutputLines.Add("G04 next file*");
if (CurrentPolarity != "LPD") { OutputLines.Add("%LPD*%"); CurrentPolarity = "LPD"; }
//OutputLines.Add( String.Format("G04 :starting {0}", Path.GetFileNameWithoutExtension(file2)));
for (int i = 0; i < otherfile.OriginalLines.Count; i++)
{
string CurrentLine = otherfile.OriginalLines[i];
if (CurrentLine.Length == 0) continue;
try
{
GCodeCommand GCC = new GCodeCommand();
GCC.Decode(CurrentLine, GNF);
switch (CurrentLine[0])
{
case '%':
{
string FinalLine = ("" + CurrentLine).Replace("%", "").Replace("*", "").Trim();
switch (FinalLine)
{
case "LPD":
if (CurrentPolarity != "LPD") { OutputLines.Add("%LPD*%"); CurrentPolarity = "LPD"; }
break;
case "LPC":
if (CurrentPolarity != "LPC") { OutputLines.Add("%LPC*%"); CurrentPolarity = "LPC"; }
break;
default:
if (CurrentLine.StartsWith("%SR"))
{
OutputLines.Add(CurrentLine);
//Console.WriteLine("StepRepeatYay!", CurrentLine);
if (GCC.numbercommands.Count > 0)
{
int x = (int)GCC.numbercommands[0];
int y = (int)GCC.numbercommands[1];
if (x > 1 && y > 1)
{
Repeating = true;
}
else
{
Repeating = false;
}
}
else
{
Repeating = false;
}
}
else
{
//Console.WriteLine("Eating gerber % commands here too! {0}", FinalLine);
if (CurrentLine.Length > 1 && CurrentLine[CurrentLine.Length - 1] != '%')
{
while (CurrentLine[CurrentLine.Length - 1] != '%')
{
i++;
CurrentLine = otherfile.OriginalLines[i];
}
}
}
break;
}
break;
}
case 'G': // machine status commands and interpolations?
{
GerberSplitter GS = new GerberSplitter();
GS.Split(GCC.originalline, otherfile.State.CoordinateFormat);
GS.ApplyMirroring(otherfile.State);
if ((int)GS.Get("G") == 54)
{
if (GS.Has("D") && GS.Get("D") > 3)
{
OutputLines.Add(otherfile.State.Apertures[(int)GS.Get("D")].BuildSelectGerber());
//OutputLines.Add(CurrentLine);
}
}
else
switch ((int)GS.Get("G"))
{
case 1:
case 2:
case 3:
{
// double X = 0;
// double Y = 0;
//GS.Split(GCC.originalline, otherfile.State.CoordinateFormat);
GS.ScaleToMM(otherfile.State.CoordinateFormat);
if (otherfile.State.CoordinateFormat.Relativemode)
{
if (GS.Has("X"))
{
X += GS.Get("X");
GS.Set("X", X);
}
if (GS.Has("Y"))
{
Y += GS.Get("Y");
GS.Set("Y", Y);
}
}
GS.ScaleToFile(GNF);
// if (GS.Has("X")) GS.Set("X", File2Parsed.CoordinateFormat.ScaleFileToMM(GS.Get("X")));
// if (GS.Has("Y")) GS.Set("Y", File2Parsed.CoordinateFormat.ScaleFileToMM(GS.Get("Y")));
// if (GS.Has("I")) GS.Set("I", File2Parsed.CoordinateFormat.ScaleFileToMM(GS.Get("I")));
// if (GS.Has("J")) GS.Set("J", File2Parsed.CoordinateFormat.ScaleFileToMM(GS.Get("J")));
OutputLines.Add(GS.Rebuild(GNF));
// Log.AddString("Unsupported arc command found!");
// MessageBox.Show("Unsupported arc type found during merge! File will NOT be exported correctly!", "Error during export", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
break;
default:
switch ((int)GS.Get("G"))
{
case 70:
OutputLines.Add("G04 skipping 70");
otherfile.State.CoordinateFormat.SetImperialMode();
break;
case 71:
OutputLines.Add("G04 skipping 71");
otherfile.State.CoordinateFormat.SetMetricMode();
break;
default:
OutputLines.Add(CurrentLine);
break;
}
break;
}
}
break;
default: // move commands -> transform
{
GerberSplitter GS = new GerberSplitter();
if (otherfile.State.CoordinateFormat.Relativemode == false)
{
X = 0;
Y = 0;
}
GS.Split(GCC.originalline, otherfile.State.CoordinateFormat);
GS.ApplyMirroring(otherfile.State);
if (GS.Has("D") || GS.Has("X") || GS.Has("Y"))
{
if (GS.Get("D") > 3)
{
OutputLines.Add(otherfile.State.Apertures[(int)GCC.numbercommands[0]].BuildSelectGerber());
}
else
{
if (GS.Has("X") == false && GS.Has("Y") == false)
{
OutputLines.Add(CurrentLine);
}
else
{
string OutLine = ";";
if (GS.Has("X") && GS.Has("Y"))
{
X += otherfile.State.CoordinateFormat.ScaleFileToMM(GS.Get("X"));
Y += otherfile.State.CoordinateFormat.ScaleFileToMM(GS.Get("Y"));
OutLine = String.Format("X{0}Y{1}", GNF.Format(GNF._ScaleMMToFile(X)), GNF.Format(GNF._ScaleMMToFile(Y)));
}
else
{
if (GS.Has("X"))
{
X += otherfile.State.CoordinateFormat.ScaleFileToMM(GS.Get("X"));
OutLine = String.Format("X{0}", GNF.Format(GNF._ScaleMMToFile(X)));
}
else
{
if (GS.Has("Y"))
{
Y += otherfile.State.CoordinateFormat.ScaleFileToMM(GS.Get("Y"));
OutLine = String.Format("Y{0}", GNF.Format(GNF._ScaleMMToFile(Y)));
}
else
{
OutLine = "";
}
}
}
if (GS.Has("I"))
{
var I = otherfile.State.CoordinateFormat.ScaleFileToMM(GS.Get("I"));
OutLine += String.Format("I{0}", GNF.Format(GNF._ScaleMMToFile(I)));
}
if (GS.Has("J"))
{
var J = otherfile.State.CoordinateFormat.ScaleFileToMM(GS.Get("J"));
OutLine += String.Format("J{0}", GNF.Format(GNF._ScaleMMToFile(J)));
}
if (GS.Has("D"))
{
OutLine += String.Format("D{0}", ((int)GS.Get("D")).ToString("D2"));
}
OutLine += "*";
OutputLines.Add(OutLine);
}
}
}
else
{
if (GS.Has("G") && (GS.Get("G") == 71 || GS.Get("G") == 70))
{
if (GS.Get("G") == 71)
{
otherfile.State.CoordinateFormat.SetMetricMode();
}
if (GS.Get("G") == 70)
{
otherfile.State.CoordinateFormat.SetImperialMode();
}
Log.AddString(String.Format("ignoring metric/imperial gcode: G{0}", GS.Get("G")));
// skip changing metric mode!
}
else
{
if (GS.Get("G") == 4)
{
Log.AddString(String.Format("skipping comment: {0}", CurrentLine));
}
else
{
OutputLines.Add(CurrentLine);
}
}
}
}
break;
case 'M': // skip
break;
}
}
catch (Exception) { }
}
if (Repeating)
{
OutputLines.Add("G04 previous file was still repeating.. stopping that*");
OutputLines.Add("%SR*%");
Repeating = false;
}
}
OutputLines.Add(Gerber.EOF);
Gerber.WriteAllLines(output, PolyLineSet.SanitizeInputLines(OutputLines));
Log.PopActivity(check);
}
internal static void MergeAllByFileType(List<string> allFiles, string targetfolder, string combinedfilename, ProgressLog Logger)
{
Dictionary<string, List<string>> FilesPerExt = new Dictionary<string, List<string>>();
Dictionary<string, BoardFileType> FileTypePerExt = new Dictionary<string, BoardFileType>();
foreach (var s in allFiles)
{
string ext = Path.GetExtension(s).ToLower(); ;
if (ext == "xln") ext = "txt";
if (ext == "drl") ext = "txt";
BoardLayer layer;
BoardSide Side;
Gerber.DetermineBoardSideAndLayer(s, out Side, out layer);
ext = String.Format(".{0}_{1}", layer, Side);
if (FilesPerExt.ContainsKey(ext) == false)
{
FilesPerExt[ext] = new List<string>();
}
FileTypePerExt[ext] = Gerber.FindFileType(s);
FilesPerExt[ext].Add(s);
}
int count = 0;
foreach (var a in FilesPerExt)
{
count++;
Logger.AddString("merging *" + a.Key.ToLower(), ((float)count / (float)FilesPerExt.Keys.Count) * 0.5f + 0.3f);
switch (FileTypePerExt[a.Key])
{
case BoardFileType.Drill:
{
string Filename = Path.Combine(targetfolder, combinedfilename + a.Key);
//FinalFiles.Add(Filename);
ExcellonFile.MergeAll(a.Value, Filename, Logger);
}
break;
case BoardFileType.Gerber:
{
if (a.Key.ToLower() != ".gko")
{
string Filename = Path.Combine(targetfolder, combinedfilename + a.Key);
// FinalFiles.Add(Filename);
GerberMerger.MergeAll(a.Value, Filename, Logger);
}
}
break;
}
}
}
private static void CheckAllApertures(ParsedGerber file1Parsed, List<string> File1Lines, ProgressLog Log)
{
for (int i = 0; i < File1Lines.Count; i++)
{
string CurrentLine = File1Lines[i];
if (CurrentLine.Length == 0) continue;
try
{
GCodeCommand GCC = new GCodeCommand();
GCC.Decode(CurrentLine, file1Parsed.State.CoordinateFormat);
switch (CurrentLine[0])
{
case 'G': // machine status commands and interpolations?
{
GerberSplitter GS = new GerberSplitter();
GS.Split(GCC.originalline, file1Parsed.State.CoordinateFormat);
if ((int)GS.Get("G") == 54)
{
if (GS.Has("D") && GS.Get("D") > 3)
{
int ApertureID = (int)GS.Get("D");
if (file1Parsed.State.Apertures.ContainsKey(ApertureID) == false)
{
Log.AddString(String.Format("ERROR: Undefined aperture D{1} found in line {0}", i, ApertureID));
var GAT = new GerberApertureType() { ID = ApertureID }; ;
GAT.SetCircle(0);
file1Parsed.State.Apertures[ApertureID] = GAT;
}
}
}
}
break;
case 'D':
{
GerberSplitter GS = new GerberSplitter();
GS.Split(GCC.originalline, file1Parsed.State.CoordinateFormat);
if (GS.Has("D") && GS.Get("D") > 3)
{
int ApertureID = (int)GS.Get("D");
if (file1Parsed.State.Apertures.ContainsKey(ApertureID) == false)
{
var GAT = new GerberApertureType() { ID = ApertureID }; ;
GAT.SetCircle(0);
file1Parsed.State.Apertures[ApertureID] = GAT;
}
}
}
break;
}
}
catch (Exception) { }
}
}
public static void Merge(string file1, string file2, string output, ProgressLog Log)
{
Log.PushActivity("Gerber Merge");
if (File.Exists(file1) == false)
{
Log.AddString(String.Format("{0} not found! stopping process!", Path.GetFileName(file1)));
Log.PopActivity();
return;
}
if (File.Exists(file2) == false)
{
Log.AddString(String.Format("{0} not found! stopping process!", Path.GetFileName(file2)));
Log.PopActivity();
return;
}
Log.AddString(String.Format("Merging {0} with {1} in to {2}", Path.GetFileName(file1), Path.GetFileName(file2), Path.GetFileName(output)));
List<string> File1Lines = File.ReadAllLines(file1).ToList();
File1Lines = PolyLineSet.SanitizeInputLines(File1Lines);
ParsedGerber File1Parsed = PolyLineSet.ParseGerber274x(Log, File1Lines, true, false, new GerberParserState() { PreCombinePolygons = false, GenerateGeometry = false });
List<string> File2Lines = File.ReadAllLines(file2).ToList();
File2Lines = PolyLineSet.SanitizeInputLines(File2Lines);
ParsedGerber File2Parsed = PolyLineSet.ParseGerber274x(Log, File2Lines, true, false, new GerberParserState() { PreCombinePolygons = false, GenerateGeometry = false });
CheckAllApertures(File1Parsed, File1Lines, Log);
CheckAllApertures(File2Parsed, File2Lines, Log);
int ApertureOffset = 0;
if (File1Parsed.State.Apertures.Count > 0) ApertureOffset = File1Parsed.State.Apertures.Keys.Max() + 1;
List<string> OutputLines = new List<string>();
GerberNumberFormat GNF = new GerberNumberFormat();
GNF.DigitsBefore = Math.Max(File1Parsed.State.CoordinateFormat.DigitsBefore, File2Parsed.State.CoordinateFormat.DigitsBefore);
GNF.DigitsAfter = Math.Max(File1Parsed.State.CoordinateFormat.DigitsAfter, File2Parsed.State.CoordinateFormat.DigitsAfter);
if (File1Parsed.State.CoordinateFormat.CurrentNumberScale == GerberNumberFormat.NumberScale.Metric
|| File2Parsed.State.CoordinateFormat.CurrentNumberScale == GerberNumberFormat.NumberScale.Metric
)
{
GNF.SetMetricMode();
}
else
{
GNF.SetImperialMode();
}
GNF.SetImperialMode();
//OutputLines.Add(String.Format("G04 merged from {0} and {1}", Path.GetFileNameWithoutExtension(file1), Path.GetFileNameWithoutExtension(file2)));
OutputLines.Add(GNF.BuildMetricImperialFormatLine());
OutputLines.Add("%OFA0B0*%");
OutputLines.Add(GNF.BuildGerberFormatLine());
OutputLines.Add("%IPPOS*%");
OutputLines.Add("%LPD*%");
Dictionary<string, string> MacroDict = new Dictionary<string, string>();
foreach (var a in File1Parsed.State.ApertureMacros)
{
OutputLines.Add(a.Value.BuildGerber(GNF, 0, "_FILE0").Trim());
MacroDict[a.Value.Name + "_FILE0"] = a.Value.Name;
}
foreach (var a in File2Parsed.State.ApertureMacros)
{
MacroDict[a.Value.Name + "_FILE1"] = a.Value.Name;
OutputLines.Add(a.Value.BuildGerber(GNF, 0,"_FILE1").Trim());
}
foreach (var a in File1Parsed.State.Apertures)
{
OutputLines.Add(a.Value.BuildGerber(GNF, "_FILE0"));
}
foreach (var a in File2Parsed.State.Apertures)
{
if (a.Value.ShapeType == GerberApertureShape.Macro || a.Value.ShapeType == GerberApertureShape.Compound)
{
// a.Value.MacroName = MacroDict[a.Value.MacroName];
}
a.Value.ID += ApertureOffset;
OutputLines.Add(a.Value.BuildGerber(GNF, "_FILE1"));
}
// stuff goes here.
//OutputLines.Add(String.Format("G04 :starting {0}", Path.GetFileNameWithoutExtension(file1)));
string CurrentPolarity = "LPD";
bool Repeating = false;
double X = 0;
double Y = 0;
for (int i = 0; i < File1Lines.Count; i++)
{
string CurrentLine = File1Lines[i];
if (CurrentLine.Length == 0) continue;
try
{
GCodeCommand GCC = new GCodeCommand();
GCC.Decode(CurrentLine, GNF);
switch (CurrentLine[0])
{
case '%':
{
string FinalLine = "" + CurrentLine;
FinalLine = FinalLine.Replace("%", "").Replace("*", "").Trim();
switch (FinalLine)
{
case "LPD":
if (CurrentPolarity != CurrentLine) { OutputLines.Add("%LPD*%"); CurrentPolarity = CurrentLine; }
break;
case "LPC":
if (CurrentPolarity != CurrentLine) { OutputLines.Add("%LPC*%"); CurrentPolarity = CurrentLine; }
break;
default:
if (CurrentLine.StartsWith("%SR"))
{
OutputLines.Add(CurrentLine);
//Console.WriteLine("StepRepeatYay!", CurrentLine);
if (GCC.numbercommands.Count > 0)
{
int x = (int)GCC.numbercommands[0];
int y = (int)GCC.numbercommands[1];
if (x > 1 && y > 1)
{
Repeating = true;
}
else
{
Repeating = false;
}
}
else
{
Repeating = false;
}
}
else
{
//Console.WriteLine("eating % commands! {0}", CurrentLine);
if (CurrentLine.Length > 1 && CurrentLine[CurrentLine.Length - 1] != '%')
{
while (CurrentLine[CurrentLine.Length - 1] != '%')
{
i++;
CurrentLine = File1Lines[i];
}
}
}
break;
}
}
break;
case 'G': // machine status commands and interpolations?
{
GerberSplitter GS = new GerberSplitter();
GS.Split(GCC.originalline, File1Parsed.State.CoordinateFormat);
if ((int)GS.Get("G") == 54)
{
if (GS.Has("D") && GS.Get("D") > 3)
{
OutputLines.Add(CurrentLine);
}
}
else
if ((int)GCC.numbercommands[0] == 3 || (int)GCC.numbercommands[0] == 2 || (int)GCC.numbercommands[0] == 1)
{
//GS.Split(GCC.originalline, File1Parsed.State.CoordinateFormat);
GS.ScaleToMM(File1Parsed.State.CoordinateFormat);
GS.ScaleToFile(GNF);
OutputLines.Add(GS.Rebuild(GNF));
// Log.AddString("Unsupported arc command found!");
// MessageBox.Show("Unsupported arc type found during merge! File will NOT be exported correctly!", "Error during export", MessageBoxButtons.OK, MessageBoxIcon.Error);
// Log.AddString("Unsupported arc command found!");
// MessageBox.Show("Unsupported arc type found during merge! File will NOT be exported correctly!", "Error during export", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
if (GS.Has("G") && (GS.Get("G") == 71 || GS.Get("G") == 70))
{
if (GS.Get("G") == 71)
{
File1Parsed.State.CoordinateFormat.SetMetricMode();
}
if (GS.Get("G") == 70)
{
File1Parsed.State.CoordinateFormat.SetImperialMode();
}
// skip changing metric mode!
Log.AddString(String.Format("ignoring metric/imperial gcode: G{0}", GS.Get("G")));
}
else
{
if (GS.Get("G") == 4)
{
Log.AddString(String.Format("skipping comment: {0}", CurrentLine));
}
else
{
OutputLines.Add(CurrentLine);
}
//OutputLines.Add(CurrentLine);
}
//tputLines.Add(CurrentLine);
}
}
break;
default: // move commands -> transform
{
GerberSplitter GS = new GerberSplitter();
if (File1Parsed.State.CoordinateFormat.Relativemode == false)
{
X = 0;
Y = 0;
}
GS.Split(GCC.originalline, File1Parsed.State.CoordinateFormat);
if (GS.Has("D") || GS.Has("X") || GS.Has("Y"))
{
if (GS.Get("D") > 3)
{
OutputLines.Add(CurrentLine);
}
else
{
if (GS.Has("X") == false && GS.Has("Y") == false)
{
OutputLines.Add(CurrentLine);
}
else
{
string OutLine = ";";
if (GS.Has("X") && GS.Has("Y"))
{
X += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("X"));
Y += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("Y"));
OutLine = String.Format("X{0}Y{1}", GNF.Format(GNF._ScaleMMToFile(X)), GNF.Format(GNF._ScaleMMToFile(Y)));
}
else
{
if (GS.Has("X"))
{
X += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("X"));
OutLine = String.Format("X{0}", GNF.Format(GNF._ScaleMMToFile(X)));
}
else
{
if (GS.Has("Y"))
{
Y += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("Y"));
OutLine = String.Format("Y{0}", GNF.Format(GNF._ScaleMMToFile(Y)));
}
else
{
OutLine = "";
}
}
}
if (GS.Has("I"))
{
var I = File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("I"));
OutLine += String.Format("I{0}", GNF.Format(GNF._ScaleMMToFile(I)));
}
if (GS.Has("J"))
{
var J = File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("J"));
OutLine += String.Format("J{0}", GNF.Format(GNF._ScaleMMToFile(J)));
}
if (GS.Has("D"))
{
OutLine += String.Format("D{0}", ((int)GS.Get("D")).ToString("D2"));
}
OutLine += "*";
OutputLines.Add(OutLine);
}
}
// OutputLines.Add(String.Format("X{0}Y{1}D{2}*", GNF.Format(GNF.ScaleMMToFile(X)), GNF.Format(GNF.ScaleMMToFile(Y)), ((int)GS.Get("D")).ToString("D2")));
}
}
break;
case 'M': // skip
break;
}
}
catch (Exception)
{
}
}
// TODO: set polarity back to "neutral" - or should each file do this at the start anyway?
if (Repeating)
{
OutputLines.Add("G04 previous file was still repeating.. stopping that*");
OutputLines.Add("%SR*%");
Repeating = false;
}
if (Gerber.ShowProgress)
{
Log.AddString(String.Format("File 1 format: {0}", File1Parsed.State.CoordinateFormat));
Log.AddString(String.Format("File 2 format: {0}", File2Parsed.State.CoordinateFormat));
}
OutputLines.Add("G04 next file*");
if (CurrentPolarity != "LPD") { OutputLines.Add("%LPD*%"); CurrentPolarity = "LPD"; }
X = 0;Y = 0;
//OutputLines.Add( String.Format("G04 :starting {0}", Path.GetFileNameWithoutExtension(file2)));
for (int i = 0; i < File2Lines.Count; i++)
{
string CurrentLine = File2Lines[i];
if (CurrentLine.Length == 0) continue;
try
{
GCodeCommand GCC = new GCodeCommand();
GCC.Decode(CurrentLine, GNF);
switch (CurrentLine[0])
{
case '%':
{
string FinalLine = ("" + CurrentLine).Replace("%", "").Replace("*", "").Trim();
switch (FinalLine)
{
case "LPD":
if (CurrentPolarity != "LPD") { OutputLines.Add("%LPD*%"); CurrentPolarity = "LPD"; }
break;
case "LPC":
if (CurrentPolarity != "LPC") { OutputLines.Add("%LPC*%"); CurrentPolarity = "LPC"; }
break;
default:
if (CurrentLine.Length > 1 && CurrentLine[CurrentLine.Length - 1] != '%')
{
while (CurrentLine[CurrentLine.Length - 1] != '%')
{
i++;
CurrentLine = File2Lines[i];
}
}
break;
}
break;
}
case 'G': // machine status commands and interpolations?
{
GerberSplitter GS = new GerberSplitter();
GS.Split(GCC.originalline, File2Parsed.State.CoordinateFormat);
if ((int)GS.Get("G") == 54)
{
if (GS.Has("D") && GS.Get("D") > 3)
{
OutputLines.Add(File2Parsed.State.Apertures[(int)GS.Get("D")].BuildSelectGerber());
//OutputLines.Add(CurrentLine);
}
}
else
switch ((int)GS.Get("G"))
{
case 1:
case 2:
case 3:
{
//double X = 0;
// double Y = 0;
// GS.Split(GCC.originalline, File2Parsed.State.CoordinateFormat);
GS.ScaleToMM(File2Parsed.State.CoordinateFormat);
GS.ScaleToFile(GNF);
// if (GS.Has("X")) GS.Set("X", File2Parsed.CoordinateFormat.ScaleFileToMM(GS.Get("X")));
// if (GS.Has("Y")) GS.Set("Y", File2Parsed.CoordinateFormat.ScaleFileToMM(GS.Get("Y")));
// if (GS.Has("I")) GS.Set("I", File2Parsed.CoordinateFormat.ScaleFileToMM(GS.Get("I")));
// if (GS.Has("J")) GS.Set("J", File2Parsed.CoordinateFormat.ScaleFileToMM(GS.Get("J")));
OutputLines.Add(GS.Rebuild(GNF));
// Log.AddString("Unsupported arc command found!");
// MessageBox.Show("Unsupported arc type found during merge! File will NOT be exported correctly!", "Error during export", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
break;
default:
switch ((int)GS.Get("G"))
{
case 70:
OutputLines.Add("G04 skipping 70");
File2Parsed.State.CoordinateFormat.SetImperialMode();
break;
case 71:
OutputLines.Add("G04 skipping 71");
File2Parsed.State.CoordinateFormat.SetMetricMode();
break;
default:
OutputLines.Add(CurrentLine);
break;
}
break;
}
}
break;
default: // move commands -> transform
{
GerberSplitter GS = new GerberSplitter();
if (File2Parsed.State.CoordinateFormat.Relativemode == false)
{
X = 0;
Y = 0;
}
GS.Split(GCC.originalline, File2Parsed.State.CoordinateFormat);
if (GS.Has("D") || GS.Has("X") || GS.Has("Y"))
{
if (GS.Get("D") > 3)
{
OutputLines.Add(File2Parsed.State.Apertures[(int)GCC.numbercommands[0]].BuildSelectGerber());
}
else
{
if (GS.Has("X") == false && GS.Has("Y") == false)
{
OutputLines.Add(CurrentLine);
}
else
{
string OutLine = ";";
if (GS.Has("X") && GS.Has("Y"))
{
X += File2Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("X"));
Y += File2Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("Y"));
OutLine = String.Format("X{0}Y{1}", GNF.Format(GNF._ScaleMMToFile(X)), GNF.Format(GNF._ScaleMMToFile(Y)));
}
else
{
if (GS.Has("X"))
{
X += File2Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("X"));
OutLine = String.Format("X{0}", GNF.Format(GNF._ScaleMMToFile(X)));
}
else
{
if (GS.Has("Y"))
{
Y += File2Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("Y"));
OutLine = String.Format("Y{0}", GNF.Format(GNF._ScaleMMToFile(Y)));
}
else
{
OutLine = "";
}
}
}
if (GS.Has("I"))
{
var I = File2Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("I"));
OutLine += String.Format("I{0}", GNF.Format(GNF._ScaleMMToFile(I)));
}
if (GS.Has("J"))
{
var J = File2Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("J"));
OutLine += String.Format("J{0}", GNF.Format(GNF._ScaleMMToFile(J)));
}
if (GS.Has("D"))
{
OutLine += String.Format("D{0}", ((int)GS.Get("D")).ToString("D2"));
}
OutLine += "*";
OutputLines.Add(OutLine);
}
}
}
else
{
if (GS.Has("G") && (GS.Get("G") == 71 || GS.Get("G") == 70))
{
if (GS.Get("G") == 71)
{
File2Parsed.State.CoordinateFormat.SetMetricMode();
}
if (GS.Get("G") == 70)
{
File2Parsed.State.CoordinateFormat.SetImperialMode();
}
Log.AddString(String.Format("ignoring metric/imperial gcode: G{0}", GS.Get("G")));
// skip changing metric mode!
}
else
{
if (GS.Get("G") == 4)
{
Log.AddString(String.Format("skipping comment: {0}", CurrentLine));
}
else
{
OutputLines.Add(CurrentLine);
}
}
}
}
break;
case 'M': // skip
break;
}
}
catch (Exception) { }
}
if (Repeating)
{
OutputLines.Add("G04 previous file was still repeating.. stopping that*");
OutputLines.Add("%SR*%");
Repeating = false;
}
OutputLines.Add(Gerber.EOF);
Gerber.WriteAllLines(output, PolyLineSet.SanitizeInputLines(OutputLines));
Log.PopActivity();
}
public static void WriteContainedOnly(string inputfile, PolyLine Boundary, string outputfilename, ProgressLog Log)
{
Log.PushActivity("Gerber 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)));
List<string> File1Lines = File.ReadAllLines(inputfile).ToList();
File1Lines = PolyLineSet.SanitizeInputLines(File1Lines);
ParsedGerber File1Parsed = PolyLineSet.ParseGerber274x(Log, File1Lines, true, false, new GerberParserState() { PreCombinePolygons = false, GenerateGeometry = false });
CheckAllApertures(File1Parsed, File1Lines, Log);
int ApertureOffset = 0;
if (File1Parsed.State.Apertures.Count > 0) ApertureOffset = File1Parsed.State.Apertures.Keys.Max() + 1;
List<string> OutputLines = new List<string>();
GerberNumberFormat GNF = new GerberNumberFormat();
GNF.DigitsBefore = File1Parsed.State.CoordinateFormat.DigitsBefore;
GNF.DigitsAfter = File1Parsed.State.CoordinateFormat.DigitsAfter;
if (File1Parsed.State.CoordinateFormat.CurrentNumberScale == GerberNumberFormat.NumberScale.Metric)
{
GNF.SetMetricMode();
}
else
{
GNF.SetImperialMode();
}
GNF.SetImperialMode();
//OutputLines.Add(String.Format("G04 merged from {0} and {1}", Path.GetFileNameWithoutExtension(file1), Path.GetFileNameWithoutExtension(file2)));
OutputLines.Add(GNF.BuildMetricImperialFormatLine());
OutputLines.Add("%OFA0B0*%");
OutputLines.Add(GNF.BuildGerberFormatLine());
OutputLines.Add("%IPPOS*%");
OutputLines.Add("%LPD*%");
Dictionary<string, string> MacroDict = new Dictionary<string, string>();
foreach (var a in File1Parsed.State.ApertureMacros)
{
OutputLines.Add(a.Value.BuildGerber(GNF, 0,"_FILE0").Trim());
MacroDict[a.Value.Name + "_FILE0"] = a.Value.Name;
}
foreach (var a in File1Parsed.State.Apertures)
{
OutputLines.Add(a.Value.BuildGerber(GNF,"_FILE0"));
}
// stuff goes here.
//OutputLines.Add(String.Format("G04 :starting {0}", Path.GetFileNameWithoutExtension(file1)));
string CurrentPolarity = "LPD";
double X = 0;
double Y = 0;
for (int i = 0; i < File1Lines.Count; i++)
{
string CurrentLine = File1Lines[i];
if (CurrentLine.Length == 0) continue;
try
{
GCodeCommand GCC = new GCodeCommand();
GCC.Decode(CurrentLine, GNF);
switch (CurrentLine[0])
{
case '%':
{
string FinalLine = "" + CurrentLine;
FinalLine = FinalLine.Replace("%", "").Replace("*", "").Trim();
switch (FinalLine)
{
case "LPD":
if (CurrentPolarity != CurrentLine) { OutputLines.Add("%LPD*%"); CurrentPolarity = CurrentLine; }
break;
case "LPC":
if (CurrentPolarity != CurrentLine) { OutputLines.Add("%LPC*%"); CurrentPolarity = CurrentLine; }
break;
default:
if (CurrentLine.Length > 1 && CurrentLine[CurrentLine.Length - 1] != '%')
{
while (CurrentLine[CurrentLine.Length - 1] != '%')
{
i++;
CurrentLine = File1Lines[i];
}
}
break;
}
}
break;
case 'G': // machine status commands and interpolations?
{
GerberSplitter GS = new GerberSplitter();
GS.Split(GCC.originalline, File1Parsed.State.CoordinateFormat);
if ((int)GS.Get("G") == 54)
{
if (GS.Has("D") && GS.Get("D") > 3)
{
OutputLines.Add(CurrentLine);
}
}
else
if ((int)GCC.numbercommands[0] == 3 || (int)GCC.numbercommands[0] == 2 || (int)GCC.numbercommands[0] == 1)
{
//GS.Split(GCC.originalline, File1Parsed.State.CoordinateFormat);
GS.ScaleToMM(File1Parsed.State.CoordinateFormat);
GS.ScaleToFile(GNF);
bool skipline = false;
if (GS.Has("X") && GS.Has("Y"))
{
X += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("X"));
Y += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("Y"));
if (Boundary.PointInPoly(new PointD(X, Y)) == false)
{
skipline = true;
}
// OutLine = String.Format("X{0}Y{1}", GNF.Format(GNF._ScaleMMToFile(X)), GNF.Format(GNF._ScaleMMToFile(Y)));
}
if (!skipline) OutputLines.Add(GS.Rebuild(GNF));
// Log.AddString("Unsupported arc command found!");
// MessageBox.Show("Unsupported arc type found during merge! File will NOT be exported correctly!", "Error during export", MessageBoxButtons.OK, MessageBoxIcon.Error);
// Log.AddString("Unsupported arc command found!");
// MessageBox.Show("Unsupported arc type found during merge! File will NOT be exported correctly!", "Error during export", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
if (GS.Has("G") && (GS.Get("G") == 71 || GS.Get("G") == 70))
{
if (GS.Get("G") == 71)
{
File1Parsed.State.CoordinateFormat.SetMetricMode();
}
if (GS.Get("G") == 70)
{
File1Parsed.State.CoordinateFormat.SetImperialMode();
}
// skip changing metric mode!
Log.AddString(String.Format("ignoring metric/imperial gcode: G{0}", GS.Get("G")));
}
else
{
if (GS.Get("G") == 4)
{
//Console.WriteLine("skipping comment: {0}", CurrentLine);
}
else
{
OutputLines.Add(CurrentLine);
}
//OutputLines.Add(CurrentLine);
}
//tputLines.Add(CurrentLine);
}
}
break;
default: // move commands -> transform
{
GerberSplitter GS = new GerberSplitter();
if (File1Parsed.State.CoordinateFormat.Relativemode == false)
{
X = 0;
Y = 0;
}
GS.Split(GCC.originalline, File1Parsed.State.CoordinateFormat);
if (GS.Has("D") || GS.Has("X") || GS.Has("Y"))
{
if (GS.Get("D") > 3)
{
OutputLines.Add(CurrentLine);
}
else
{
if (GS.Has("X") == false && GS.Has("Y") == false)
{
OutputLines.Add(CurrentLine);
}
else
{
string OutLine = ";";
bool skipline = false;
if (GS.Has("X") && GS.Has("Y"))
{
X += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("X"));
Y += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("Y"));
if (Boundary.PointInPoly(new PointD(X, Y)) == false)
{
skipline = true;
}
OutLine = String.Format("X{0}Y{1}", GNF.Format(GNF._ScaleMMToFile(X)), GNF.Format(GNF._ScaleMMToFile(Y)));
}
else
{
if (GS.Has("X"))
{
X += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("X"));
OutLine = String.Format("X{0}", GNF.Format(GNF._ScaleMMToFile(X)));
}
else
{
if (GS.Has("Y"))
{
Y += File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("Y"));
OutLine = String.Format("Y{0}", GNF.Format(GNF._ScaleMMToFile(Y)));
}
else
{
OutLine = "";
}
}
}
if (GS.Has("I"))
{
var I = File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("I"));
OutLine += String.Format("I{0}", GNF.Format(GNF._ScaleMMToFile(I)));
}
if (GS.Has("J"))
{
var J = File1Parsed.State.CoordinateFormat.ScaleFileToMM(GS.Get("J"));
OutLine += String.Format("J{0}", GNF.Format(GNF._ScaleMMToFile(J)));
}
if (GS.Has("D"))
{
OutLine += String.Format("D{0}", ((int)GS.Get("D")).ToString("D2"));
}
OutLine += "*";
if (skipline == false) OutputLines.Add(OutLine);
}
}
// OutputLines.Add(String.Format("X{0}Y{1}D{2}*", GNF.Format(GNF.ScaleMMToFile(X)), GNF.Format(GNF.ScaleMMToFile(Y)), ((int)GS.Get("D")).ToString("D2")));
}
}
break;
case 'M': // skip
break;
}
}
catch (Exception)
{
}
}
// TODO: set polarity back to "neutral" - or should each file do this at the start anyway?
if (Gerber.ShowProgress)
{
Log.AddString(String.Format("File 1 format: {0}", File1Parsed.State.CoordinateFormat));
}
OutputLines.Add("G04 next file*");
if (CurrentPolarity != "LPD") { OutputLines.Add("%LPD*%"); CurrentPolarity = "LPD"; }
//OutputLines.Add( String.Format("G04 :starting {0}", Path.GetFileNameWithoutExtension(file2)));
OutputLines.Add(Gerber.EOF);
Gerber.WriteAllLines(outputfilename, PolyLineSet.SanitizeInputLines(OutputLines));
Log.PopActivity();
}
}
}