private bool Process(bool Save) { //Check if there is any loaded geometry at all if (shapes == null) { MessageBox.Show("No geometry found", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } //Gets the parameters from the form and check if they are valid GCodeSettings settings = ReadSettings(); if (settings == null) { MessageBox.Show("Invalid settings configuration", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } //Create the GCode string string gCode = GenerateGCode(shapes, settings); //If the return string is empty, something went wrong... if (gCode.Length == 0) { MessageBox.Show("Could not generate the G-Code", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } //If opted to save, dump the contents to the file. Otherwise, show the preview form if (Save) { try { File.WriteAllText(txtOutput.Text, gCode); MessageBox.Show("G-Code successfully generated", "File saved", MessageBoxButtons.OK, MessageBoxIcon.Information); return(true); } catch { MessageBox.Show("Failed to save the file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } } else { frmPreview formPreview = new frmPreview(); formPreview.txtGCode.Text = gCode; formPreview.ShowDialog(); return(true); } }
private GCodeSettings ReadSettings() { GCodeSettings settings = new GCodeSettings(); settings.gcLaserOn = txtLaserOn.Text; settings.gcLaserOff = txtLaserOff.Text; settings.gcSpindleOn = txtSpindleOn.Text; settings.gcSpindleOff = txtSpindleOff.Text; settings.gcUnit = rdoMilimiters.Checked ? "G21" : "G20"; settings.gcPositioning = rdoAbsolute.Checked ? "G90" : "G91"; settings.gcHeader = txtHeader.Text; settings.gcFooter = txtFooter.Text; settings.gcZTravelHeight = (double)nudTravelHeight.Value; settings.gcZChange = (double)nudZChange.Value; settings.gcPass = (int)nudPasses.Value; settings.gcRapidRaise = true; if (!int.TryParse(txtFastFeed.Text, out settings.gcMoveFeed)) { MessageBox.Show("Invalid fast feed value", "Invalid value", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } if (!int.TryParse(txtLinearFeed.Text, out settings.gcLinearFeed)) { MessageBox.Show("Invalid linear feed value", "Invalid value", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } settings.gcMoveFeedCmd = txtFastFeedCmd.Text; settings.gcLinearFeedCmd = txtLinearFeedCmd.Text; settings.gcComments = chkComments.Checked; settings.gcType = cboProcess.SelectedIndex == 0 ? GCodeType.SINGLE_PASS : GCodeType.MULTIPLE_PASS; settings.gcPrecisionFormat = cboPrecision.Text; settings.gcReturnOrigin = chkOrigin.Checked; settings.gcIsSpindle = rdoSpindle.Checked; return(settings); }
private string GenerateGCode(List <Shape> Shapes, GCodeSettings Settings) { StringBuilder sb = new StringBuilder(); int shapeCount; if (Settings.gcHeader != "") { sb.AppendLine(Settings.gcHeader); } sb.AppendLine(Settings.gcUnit); sb.AppendLine(Settings.gcPositioning); if (Settings.gcType == GCodeType.SINGLE_PASS) { //SINGLE PASS (for laser engraving or cutting thing surfaces) shapeCount = 1; foreach (Shape shape in Shapes) { if (Settings.gcComments) { sb.AppendLine("; Shape " + shapeCount); } //Turn the laser off sb.AppendLine(Settings.gcLaserOff); //Dwell for 100ms sb.AppendLine("G4 P100"); //Fast move to the shape's start position sb.AppendLine(Settings.gcMoveFeedCmd + " X" + shape.Vertices[0].X.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture) + " Y" + shape.Vertices[0].Y.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture) + " F" + Settings.gcMoveFeed.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture)); //Wait for moves to finish sb.AppendLine("M400"); //Turn the laser on sb.AppendLine(Settings.gcLaserOn); //Dwell for 100ms sb.AppendLine("G4 P100"); //Linear move with slower feedrate (where the actual engraving occurs) foreach (Vector2d point in shape.Vertices) { sb.AppendLine(Settings.gcLinearFeedCmd + " X" + point.X.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture) + " Y" + point.Y.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture) + " F" + Settings.gcLinearFeed.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture)); } //Wait for moves to finish sb.AppendLine("M400"); shapeCount++; } //Turn the laser off sb.AppendLine(Settings.gcLaserOff); sb.AppendLine("G4 P100"); //Dwell for 100ms } else { //MULTI-PASS MODE (for milling or laser cutting that involves multiple passes with different heights) double currentDepth; if (Settings.gcIsSpindle) { currentDepth = -Settings.gcZChange; } else { currentDepth = 0; } //If using spindle motor, make sure we raise the spindle before turning it on if (Settings.gcIsSpindle) { sb.AppendLine(Settings.gcMoveFeedCmd + " Z" + Settings.gcZTravelHeight.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture) + " F" + Settings.gcLinearFeed.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture)); sb.AppendLine("M400"); sb.AppendLine(Settings.gcSpindleOn); sb.AppendLine("G4 P100"); } else { sb.AppendLine(Settings.gcSpindleOff); sb.AppendLine("G4 P100"); } for (int a = 0; a < Settings.gcPass; a++) { shapeCount = 1; if (Settings.gcComments) { sb.AppendLine("; \r\n; PASS " + (a + 1) + "\r\n; "); } //If using laser, we only move the Z axis every pass (the spindle needs to move the Z axis every shape) in relative space if (!Settings.gcIsSpindle) { sb.AppendLine("G91"); sb.AppendLine(Settings.gcLinearFeedCmd + " Z" + currentDepth.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture) + " F" + Settings.gcLinearFeed.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture)); sb.AppendLine("M400"); //Restore the original positioning mode (relative/absolute) sb.AppendLine(Settings.gcPositioning); } foreach (Shape shape in Shapes) { if (Settings.gcComments) { sb.AppendLine("; Shape " + shapeCount); } //Fast move to initial shape coordinate sb.AppendLine(Settings.gcMoveFeedCmd + " X" + shape.Vertices[0].X.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture) + " Y" + shape.Vertices[0].Y.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture) + " F" + Settings.gcMoveFeed.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture)); sb.AppendLine("M400"); if (Settings.gcIsSpindle) { //If using spindle, lower it to the current pass depth sb.AppendLine(Settings.gcLinearFeedCmd + " Z" + currentDepth.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture) + " F" + Settings.gcLinearFeed.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture)); sb.AppendLine("M400"); } else { //Otherwise turn the layer on sb.AppendLine(Settings.gcSpindleOn); sb.AppendLine("G4 P100"); } //Linear move to start milling/laser cutting foreach (Vector2d point in shape.Vertices) { sb.AppendLine(Settings.gcLinearFeedCmd + " X" + point.X.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture) + " Y" + point.Y.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture) + " F" + Settings.gcLinearFeed.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture)); } sb.AppendLine("M400"); if (Settings.gcIsSpindle) { //If using spindle, raised it to the travel height sb.AppendLine(Settings.gcLinearFeedCmd + " Z" + Settings.gcZTravelHeight.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture) + " F" + Settings.gcLinearFeed.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture)); sb.AppendLine("M400"); } else { //Otherwise turn the layer off to move into the next shape sb.AppendLine(Settings.gcSpindleOff); sb.AppendLine("G4 P100"); } shapeCount++; } //Go deeper for the next pass currentDepth = -Settings.gcZChange; } //Make sure we end with the spindle off sb.AppendLine(Settings.gcSpindleOff); sb.AppendLine("G4 P100"); } //Return to origin if (Settings.gcReturnOrigin) { sb.AppendLine("G0 X0 Y0 F" + Settings.gcMoveFeed.ToString(Settings.gcPrecisionFormat, CultureInfo.InvariantCulture)); } if (Settings.gcFooter != "") { sb.AppendLine(Settings.gcFooter); } return(sb.ToString()); }