/* * This is the thread that controls the build process * it needs to read the lines of gcode, one by one * send them to the printer interface, * wait for the printer to respond, * and also wait for the layer interval timer */ void BuildThread() { int now = GetTimerValue(); int nextlayertime = 0; int sltime = -1, bltime = -1; while (m_running) { try { Thread.Sleep(0); // sleep for 1 ms max switch (m_state) { case BuildManager.STATE_START: //start things off, reset some variables RaiseStatusEvent(eBuildStatus.eBuildStarted, "Build Started"); m_state = BuildManager.STATE_DO_NEXT_COMMAND; // go to the first layer UVDLPApp.Instance().m_deviceinterface.SetReady(true); // say we're ready m_gcodeline = 0; // set the start line m_curlayer = 0; m_printstarttime = new DateTime(); break; case BuildManager.STATE_WAITING_FOR_DELAY: // general delay statement //check time var if (GetTimerValue() >= nextlayertime) { m_state = BuildManager.STATE_DO_NEXT_COMMAND; // move onto next layer } else { Thread.Sleep(1); // sleep for 1 ms to eliminate unnecessary cpu usage. } break; case BuildManager.STATE_IDLE: // do nothing break; case BuildManager.STATE_WAIT_DISPLAY: // we're waiting on the display to tell us we're done // this is used in the LaserSLA plugin, the normal DLP mode uses just a simple <Delay> command //do nothing break; case BuildManager.STATE_DO_NEXT_COMMAND: //check for done if (m_gcodeline >= m_gcode.Lines.Length) { //we're done.. m_state = BuildManager.STATE_DONE; continue; } string line = ""; // if the driver reports we're ready for the next command, or // if we choose to ignore the driver ready status if (UVDLPApp.Instance().m_deviceinterface.ReadyForCommand() || (UVDLPApp.Instance().m_appconfig.m_ignore_response == true)) { // go through the gcode, line by line line = m_gcode.Lines[m_gcodeline++]; #if (DEBUG) DebugLogger.Instance().LogInfo("Building : " + line); #endif } else { continue; // device is not ready } line = line.Trim(); if (line.Length > 0) // if the line is not blank { // send the line, whether or not it's a comment - this is for a reason.... // should check to see if the firmware is ready for another line UVDLPApp.Instance().m_deviceinterface.SendCommandToDevice(line + "\r\n"); // if the line is a comment, parse it to see if we need to take action if (line.ToLower().Contains("<delay> ")) // get the delay { nextlayertime = GetTimerValue() + getvarfromline(line); m_state = STATE_WAITING_FOR_DELAY; continue; } else if (line.ToLower().Contains("<dispcmd>")) // display command { PerformDisplayCommand(line); } else if (line.ToLower().Contains("<waitfordisplay>")) // wait for display to be done { m_state = BuildManager.STATE_WAIT_DISPLAY; } else if (line.ToLower().Contains("<auxcmd>")) //auxillary command to run a pre-defined sequence { PerformAuxCommand(line); } else if (line.ToLower().Contains("<slice> ")) //get the slice number { int layer = getvarfromline(line); int curtype = BuildManager.SLICE_NORMAL; // assume it's a normal image to begin with Bitmap bmp = null; bool isoutline = false; if (layer == SLICE_BLANK) { MakeBlank(m_sf.XRes, m_sf.YRes); bmp = m_blankimage; curtype = BuildManager.SLICE_BLANK; bltime = GetTimerValue(); } else if (layer == SLICE_SPECIAL) // plugins can override special images by named resource { // get the special image from the plugin (no caching for now..) string special = GetSpecialName(line); bmp = UVDLPApp.Instance().GetPluginImage(special); bmp.Tag = BuildManager.SLICE_SPECIAL; if (bmp == null) // no special image, even though it's specified.. { MakeBlank(m_sf.XRes, m_sf.YRes); bmp = m_blankimage; } curtype = BuildManager.SLICE_BLANK; } else if (layer == SLICE_OUTLINE) { isoutline = true; // we're rendering the layer in an outline image // get the curlayer from the line m_curlayer = outlinelayer; if (m_sf != null) { bmp = m_sf.GetSliceImage(m_curlayer, true); // get the rendered image slice or load it if already rendered if (bmp == null) { DebugLogger.Instance().LogError("Buildmanager bitmap is null layer = " + m_curlayer + " "); } else // not null { bmp.Tag = BuildManager.SLICE_NORMAL; // set the tag to normal so it is destroyed } } else { DebugLogger.Instance().LogWarning("Slice File is null during build and slice image is specified"); } sltime = GetTimerValue(); } else { m_curlayer = layer; if (m_sf != null) { bmp = m_sf.GetSliceImage(m_curlayer); // get the rendered image slice or load it if already rendered if (bmp == null) { DebugLogger.Instance().LogError("Buildmanager bitmap is null layer = " + m_curlayer + " "); } else // not null { bmp.Tag = BuildManager.SLICE_NORMAL; } } else { DebugLogger.Instance().LogWarning("Slice File is null during build and slice image is specified"); } sltime = GetTimerValue(); } // if a pause is requested, stop here... if (m_pause_request == true) { m_pause_request = false; ImplementPause(); // if the slice is blank, continue on to display it // if it's a new image slice (non-blank) continue the loop to go to the next state if (curtype != BuildManager.SLICE_BLANK) { continue; } } //raise a delegate so the main form can catch it and display layer information. if (PrintLayer != null) { PrintLayer(bmp, m_curlayer, curtype); } // make sure we raise this event only once if (!isoutline) { RaiseStatusEvent(eBuildStatus.eLayerCompleted, "Completed Layer"); } } } break; case BuildManager.STATE_DONE: try { m_running = false; m_state = BuildManager.STATE_IDLE; StopBuildTimer(); DateTime endtime = new DateTime(); double totalminutes = (endtime - m_printstarttime).TotalMinutes; m_printing = false; // mark printing doe //raise done message RaiseStatusEvent(eBuildStatus.eBuildStatusUpdate, "Build 100% Completed"); RaiseStatusEvent(eBuildStatus.eBuildCompleted, "Build Completed"); } catch (Exception ex) { DebugLogger.Instance().LogError(ex.StackTrace); } break; } } catch (Exception ex) { DebugLogger.Instance().LogError(ex.StackTrace); } } }
/* * This is the thread that controls the build process * it needs to read the lines of gcode, one by one * send them to the printer interface, * wait for the printer to respond, * and also wait for the layer interval timer */ void BuildThread() { int now = GetTimerValue(); int nextlayertime = 0; int sltime = -1, bltime = -1; while (m_running) { try { //Thread.Sleep(1); // sleep for 1 ms max Thread.Sleep(0); // sleep for 1 ms max switch (m_state) { case BuildManager.STATE_START: //start things off, reset some variables RaiseStatusEvent(eBuildStatus.eBuildStarted, "Build Started"); m_state = BuildManager.STATE_DO_NEXT_LAYER; // go to the first layer m_gcodeline = 0; // set the start line m_curlayer = 0; m_printstarttime = new DateTime(); break; case BuildManager.STATE_WAITING_FOR_LAYER: //check time var if (GetTimerValue() >= nextlayertime) { // DebugLogger.Instance().LogInfo("elapsed Layer time: " + GetTimerValue().ToString()); // DebugLogger.Instance().LogInfo("Diff = " + (GetTimerValue() - nextlayertime).ToString()); m_state = BuildManager.STATE_DO_NEXT_LAYER; // move onto next layer } break; case BuildManager.STATE_IDLE: // do nothing break; case BuildManager.STATE_DO_NEXT_LAYER: //check for done if (m_gcodeline >= m_gcode.Lines.Length) { //we're done.. m_state = BuildManager.STATE_DONE; continue; } string line = ""; // if the driver reports we're ready for the next command, or // if we choose to ignore the driver ready status if (UVDLPApp.Instance().m_deviceinterface.ReadyForCommand() || (UVDLPApp.Instance().m_appconfig.m_ignoreGCrsp == true)) { // go through the gcode, line by line line = m_gcode.Lines[m_gcodeline++]; } else { continue; // device is not ready } line = line.Trim(); if (line.Length > 0) // if the line is not blank { // send the line, whether or not it's a comment // should check to see if the firmware is ready for another line UVDLPApp.Instance().m_deviceinterface.SendCommandToDevice(line + "\r\n"); // if the line is a comment, parse it to see if we need to take action if (line.Contains("<Delay> ")) // get the delay { nextlayertime = GetTimerValue() + getvarfromline(line); //DebugLogger.Instance().LogInfo("Next Layer time: " + nextlayertime.ToString()); m_state = STATE_WAITING_FOR_LAYER; continue; } else if (line.Contains("<DispCmd>")) // display command { PerformDisplayCommand(line); } else if (line.Contains("<Slice> ")) //get the slice number { int layer = getvarfromline(line); int curtype = BuildManager.SLICE_NORMAL; // assume it's a normal image to begin with Bitmap bmp = null; if (layer == SLICE_BLANK) { if (m_blankimage == null) // blank image is null, create it { MakeBlank(m_sf.XRes, m_sf.YRes); } bmp = m_blankimage; curtype = BuildManager.SLICE_BLANK; bltime = GetTimerValue(); //DebugLogger.Instance().LogInfo("Showing Blank image at :" + bltime.ToString()); if (sltime != -1 && bltime != -1) { DebugLogger.Instance().LogInfo("Time between Blank and Slice :" + (bltime - sltime).ToString()); } } else if (layer == SLICE_SPECIAL) // plugins can override special images by named resource { // get the special image from the plugin (no caching for now..) string special = GetSpecialName(line); bmp = UVDLPApp.Instance().GetPluginImage(special); if (bmp == null) // no special image, even though it's specified.. { if (m_blankimage == null) // blank image is null, create it { MakeBlank(m_sf.XRes, m_sf.YRes); } bmp = m_blankimage; } curtype = BuildManager.SLICE_BLANK; } else { m_curlayer = layer; bmp = m_sf.GetSliceImage(m_curlayer); // get the rendered image slice or load it if already rendered if (bmp == null) { DebugLogger.Instance().LogError("Buildmanager bitmap is null layer = " + m_curlayer + " "); } sltime = GetTimerValue(); //DebugLogger.Instance().LogInfo("Showing Slice image at :" + sltime.ToString()); if (sltime != -1 && bltime != -1) { DebugLogger.Instance().LogInfo("Time between slice and blank :" + (sltime - bltime).ToString()); } } //raise a delegate so the main form can catch it and display layer information. if (PrintLayer != null) { PrintLayer(bmp, m_curlayer, curtype); } } } break; case BuildManager.STATE_DONE: try { m_running = false; m_state = BuildManager.STATE_IDLE; StopBuildTimer(); DateTime endtime = new DateTime(); double totalminutes = (endtime - m_printstarttime).TotalMinutes; m_printing = false; // mark printing doe //raise done message RaiseStatusEvent(eBuildStatus.eBuildStatusUpdate, "Build 100% Completed"); RaiseStatusEvent(eBuildStatus.eBuildCompleted, "Build Completed"); } catch (Exception ex) { DebugLogger.Instance().LogError(ex.StackTrace); } break; } } catch (Exception ex) { DebugLogger.Instance().LogError(ex.StackTrace); } } }
/* * This is the thread that controls the build process * it needs to read the lines of gcode, one by one * send them to the printer interface, * wait for the printer to respond, * and also wait for the layer interval timer */ void BuildThread() { int now = Environment.TickCount; int nextlayertime = 0; while (m_running) { Thread.Sleep(0); // moved this sleep here for if the switch (m_state) { case BuildManager.STATE_START: //start things off, reset some variables RaiseStatusEvent(eBuildStatus.eBuildStarted, "Build Started"); m_state = BuildManager.STATE_DO_NEXT_LAYER; // go to the first layer m_gcodeline = 0; // set the start line m_curlayer = 0; m_printstarttime = new DateTime(); break; case BuildManager.STATE_WAITING_FOR_LAYER: //check time var if (Environment.TickCount >= nextlayertime) { m_state = BuildManager.STATE_DO_NEXT_LAYER; // move onto next layer } break; case BuildManager.STATE_IDLE: // do nothing break; case BuildManager.STATE_DO_NEXT_LAYER: //check for done if (m_gcodeline >= m_gcode.Lines.Length) { //we're done.. m_state = BuildManager.STATE_DONE; continue; } string line = ""; if (UVDLPApp.Instance().m_deviceinterface.ReadyForCommand()) { // go through the gcode, line by line line = m_gcode.Lines[m_gcodeline++]; } else { continue; // device is not ready } line = line.Trim(); if (line.Length > 0) // if the line is not blank { // send the line, whether or not it's a comment // should check to see if the firmware is ready for another line UVDLPApp.Instance().m_deviceinterface.SendCommandToDevice(line + "\r\n"); // if the line is a comment, parse it to see if we need to take action if (line.Contains("<Delay> ")) // get the delay { nextlayertime = Environment.TickCount + getvarfromline(line); m_state = STATE_WAITING_FOR_LAYER; continue; } else if (line.Contains("<Slice> ")) //get the slice number { int layer = getvarfromline(line); int curtype = BuildManager.SLICE_NORMAL; // assume it's a normal image to begin with Bitmap bmp = null; if (layer == SLICE_BLANK) { if (m_blankimage == null) // blank image is null, create it { m_blankimage = new Bitmap(m_sf.XProjRes, m_sf.YProjRes); // fill it with black using (Graphics gfx = Graphics.FromImage(m_blankimage)) using (SolidBrush brush = new SolidBrush(Color.Black)) { gfx.FillRectangle(brush, 0, 0, m_sf.XProjRes, m_sf.YProjRes); } } bmp = m_blankimage; curtype = BuildManager.SLICE_BLANK; } else { m_curlayer = layer; bmp = m_sf.GetSliceImage(m_curlayer); // get the rendered image slice or load it if already rendered } //raise a delegate so the main form can catch it and display layer information. if (PrintLayer != null) { PrintLayer(bmp, m_curlayer, curtype); } } } break; case BuildManager.STATE_DONE: m_running = false; m_state = BuildManager.STATE_IDLE; StopBuildTimer(); DateTime endtime = new DateTime(); double totalminutes = (endtime - m_printstarttime).TotalMinutes; m_printing = false; // mark printing doe //raise done message RaiseStatusEvent(eBuildStatus.eBuildStatusUpdate, "Build 100% Completed"); RaiseStatusEvent(eBuildStatus.eBuildCompleted, "Build Completed"); break; } } }