public long estimatedCommandTime; // safe estimate of execution time in milliseconds public GCodeAnalyzer(bool privAnal) { privateAnalyzer = privAnal; foreach (int k in extruder.Keys) extruder[k] = new ExtruderData(k); if (!extruder.ContainsKey(activeExtruderId)) extruder.Add(activeExtruderId, new ExtruderData(activeExtruderId)); activeExtruder = extruder[activeExtruderId]; bedTemp = 0; }
public void analyzeShort(GCodeShort code) { isG1Move = false; switch (code.compressedCommand) { case 1: isG1Move = true; eChanged = false; if (code.hasF) f = code.f; if (relative) { if (code.hasX) { x += code.x; //if (x < 0) { x = 0; hasXHome = NO; } //if (x > printerWidth) { hasXHome = NO; } } if (code.hasY) { y += code.y; //if (y < 0) { y = 0; hasYHome = NO; } //if (y > printerDepth) { hasYHome = NO; } } if (code.hasZ) { z += code.z; //if (z < 0) { z = 0; hasZHome = NO; } //if (z > printerHeight) { hasZHome = NO; } } if (code.hasE) { if (eChanged = code.e != 0) { if (code.e < 0) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; } else activeExtruder.e += code.e; if (activeExtruder.e > activeExtruder.emax) { activeExtruder.emax = activeExtruder.e; if (z > lastZPrint) { lastZPrint = z; layer++; } } } } } else { if (code.x != -99999) { x = xOffset + code.x; //if (x < 0) { x = 0; hasXHome = NO; } //if (x > printerWidth) { hasXHome = NO; } } if (code.y != -99999) { y = yOffset + code.y; //if (y < 0) { y = 0; hasYHome = NO; } //if (y > printerDepth) { hasYHome = NO; } } if (code.z != -99999) { z = zOffset + code.z; //if (z < 0) { z = 0; hasZHome = NO; } //if (z > printerHeight) { hasZHome = NO; } } if (code.e != -99999) { if (eRelative) { if (eChanged = code.e != 0) { if (code.e < 0) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; } else activeExtruder.e += code.e; } } else { if (eChanged = activeExtruder.e != (activeExtruder.eOffset + code.e)) { activeExtruder.e = activeExtruder.eOffset + code.e; if (activeExtruder.e < activeExtruder.lastE) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; activeExtruder.eOffset = activeExtruder.e - code.e; } } } if (activeExtruder.e > activeExtruder.emax) { activeExtruder.emax = activeExtruder.e; if (z != lastZPrint) { lastZPrint = z; layer++; } } } } if (eventPosChangedFast != null) eventPosChangedFast(x, y, z, activeExtruder.e); float dx = Math.Abs(x - lastX); float dy = Math.Abs(y - lastY); float dz = Math.Abs(z - lastZ); float de = Math.Abs(activeExtruder.e - activeExtruder.lastE); if (dx + dy + dz > 0.001) { printingTime += Math.Sqrt(dx * dx + dy * dy + dz * dz) * 60.0f / f; } else printingTime += de * 60.0f / f; lastX = x; lastY = y; lastZ = z; activeExtruder.lastE = activeExtruder.e; break; case 2: case 3: { isG1Move = true; eChanged = false; if (code.hasF) f = code.f; if (relative) { if (code.hasX) { x += code.x; //if (x < 0) { x = 0; hasXHome = NO; } //if (x > printerWidth) { hasXHome = NO; } } if (code.hasY) { y += code.y; //if (y < 0) { y = 0; hasYHome = NO; } //if (y > printerDepth) { hasYHome = NO; } } if (code.hasZ) { z += code.z; //if (z < 0) { z = 0; hasZHome = NO; } //if (z > printerHeight) { hasZHome = NO; } } if (code.hasE) { if (eChanged = code.e != 0) { if (code.e < 0) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; } else activeExtruder.e += code.e; if (activeExtruder.e > activeExtruder.emax) { activeExtruder.emax = activeExtruder.e; if (z > lastZPrint) { lastZPrint = z; layer++; } } } } } else { if (code.x != -99999) { x = xOffset + code.x; //if (x < 0) { x = 0; hasXHome = NO; } //if (x > printerWidth) { hasXHome = NO; } } if (code.y != -99999) { y = yOffset + code.y; //if (y < 0) { y = 0; hasYHome = NO; } //if (y > printerDepth) { hasYHome = NO; } } if (code.z != -99999) { z = zOffset + code.z; //if (z < 0) { z = 0; hasZHome = NO; } //if (z > printerHeight) { hasZHome = NO; } } if (code.e != -99999) { if (eRelative) { if (eChanged = code.e != 0) { if (code.e < 0) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; } else activeExtruder.e += code.e; } } else { if (eChanged = activeExtruder.e != (activeExtruder.eOffset + code.e)) { activeExtruder.e = activeExtruder.eOffset + code.e; if (activeExtruder.e < activeExtruder.lastE) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; activeExtruder.eOffset = activeExtruder.e - code.e; } } } } } float[] offset = new float[] { code.getValueFor("I", 0), code.getValueFor("J", 0) }; /* if(unit_inches) { offset[0]*=25.4; offset[1]*=25.4; }*/ float[] position = new float[] { lastX, lastY }; float[] target = new float[] { x, y }; float r = code.getValueFor("R", -1000000); if (r > 0) { /* We need to calculate the center of the circle that has the designated radius and passes through both the current position and the target position. This method calculates the following set of equations where [x,y] is the vector from current to target position, d == magnitude of that vector, h == hypotenuse of the triangle formed by the radius of the circle, the distance to the center of the travel vector. A vector perpendicular to the travel vector [-y,x] is scaled to the length of h [-y/d*h, x/d*h] and added to the center of the travel vector [x/2,y/2] to form the new point [i,j] at [x/2-y/d*h, y/2+x/d*h] which will be the center of our arc. d^2 == x^2 + y^2 h^2 == r^2 - (d/2)^2 i == x/2 - y/d*h j == y/2 + x/d*h O <- [i,j] - | r - | - | - | h - | [0,0] -> C -----------------+--------------- T <- [x,y] | <------ d/2 ---->| C - Current position T - Target position O - center of circle that pass through both C and T d - distance from C to T r - designated radius h - distance from center of CT to O Expanding the equations: d -> sqrt(x^2 + y^2) h -> sqrt(4 * r^2 - x^2 - y^2)/2 i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 Which can be written: i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2 j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2 Which we for size and speed reasons optimize to: h_x2_div_d = sqrt(4 * r^2 - x^2 - y^2)/sqrt(x^2 + y^2) i = (x - (y * h_x2_div_d))/2 j = (y + (x * h_x2_div_d))/2 */ //if(unit_inches) r*=25.4; // Calculate the change in position along each selected axis float cx = target[0] - position[0]; float cy = target[1] - position[1]; float h_x2_div_d = -(float)Math.Sqrt(4 * r * r - cx * cx - cy * cy) / (float)Math.Sqrt(cx * cx + cy * cy); // == -(h * 2 / d) // If r is smaller than d, the arc is now traversing the complex plane beyond the reach of any // real CNC, and thus - for practical reasons - we will terminate promptly: // if(isnan(h_x2_div_d)) { OUT_P_LN("error: Invalid arc"); break; } // Invert the sign of h_x2_div_d if the circle is counter clockwise (see sketch below) if (code.compressedCommand == 3) { h_x2_div_d = -h_x2_div_d; } /* The counter clockwise circle lies to the left of the target direction. When offset is positive, the left hand circle will be generated - when it is negative the right hand circle is generated. T <-- Target position ^ Clockwise circles with this center | Clockwise circles with this center will have will have > 180 deg of angular travel | < 180 deg of angular travel, which is a good thing! \ | / center of arc when h_x2_div_d is positive -> x <----- | -----> x <- center of arc when h_x2_div_d is negative | | C <-- Current position */ // Negative R is g-code-alese for "I want a circle with more than 180 degrees of travel" (go figure!), // even though it is advised against ever generating such circles in a single line of g-code. By // inverting the sign of h_x2_div_d the center of the circles is placed on the opposite side of the line of // travel and thus we get the unadvisably long arcs as prescribed. if (r < 0) { h_x2_div_d = -h_x2_div_d; r = -r; // Finished with r. Set to positive for mc_arc } // Complete the operation by calculating the actual center of the arc offset[0] = 0.5f * (cx - (cy * h_x2_div_d)); offset[1] = 0.5f * (cy + (cx * h_x2_div_d)); } else { // Offset mode specific computations r = (float)Math.Sqrt(offset[0] * offset[0] + offset[1] * offset[1]); // Compute arc radius for mc_arc } // Set clockwise/counter-clockwise sign for mc_arc computations bool isclockwise = code.compressedCommand == 2; // Trace the arc arc(position, target, offset, r, isclockwise,null); lastX = x; lastY = y; lastZ = z; activeExtruder.lastE = activeExtruder.e; if (activeExtruder.e > activeExtruder.emax) { activeExtruder.emax = activeExtruder.e; if (z > lastZPrint) { lastZPrint = z; layer++; } } } break; case 4: { bool homeAll = !(code.hasX || code.hasY || code.hasZ); if (code.hasX || homeAll) { xOffset = 0; x = Main.printerSettings.XHomePos; hasXHome = true; } if (code.hasY || homeAll) { yOffset = 0; y = Main.printerSettings.YHomePos; hasYHome = true; } if (code.hasZ || homeAll) { zOffset = 0; z = Main.printerSettings.ZHomePos; hasZHome = true; } if (code.hasE) { activeExtruder.eOffset = 0; activeExtruder.e = 0; activeExtruder.emax = 0; } // [delegate positionChangedFastX:x y:y z:z e:e]; } break; case 5: { bool homeAll = !(code.hasX || code.hasY || code.hasZ); if (code.hasX || homeAll) { xOffset = 0; x = Main.printerSettings.XMax; hasXHome = true; } if (code.hasY || homeAll) { yOffset = 0; y = Main.printerSettings.YMax; hasYHome = true; } if (code.hasZ || homeAll) { zOffset = 0; z = Main.printerSettings.PrintAreaHeight; hasZHome = true; } //[delegate positionChangedFastX:x y:y z:z e:e]; } break; case 6: relative = false; break; case 7: relative = true; break; case 8: if (code.hasX) { xOffset = x - code.x; x = xOffset; } if (code.hasY) { yOffset = y - code.y; y = yOffset; } if (code.hasZ) { zOffset = z - code.z; z = zOffset; } if (code.hasE) { activeExtruder.eOffset = activeExtruder.e - code.e; activeExtruder.lastE = activeExtruder.e = activeExtruder.eOffset; } break; case 12: // Host command { string hc = code.text.Trim(); if (hc == "@hide") drawing = false; else if (hc == "@show") drawing = true; else if (hc == "@isathome") { hasXHome = hasYHome = hasZHome = true; x = xOffset = Main.printerSettings.XHomePos; y = yOffset = Main.printerSettings.YHomePos; z = zOffset = Main.printerSettings.ZHomePos; } } break; case 9: eRelative = false; break; case 10: eRelative = true; break; case 11: activeExtruderId = code.tool; if (!extruder.ContainsKey(activeExtruderId)) extruder.Add(activeExtruderId, new ExtruderData(activeExtruderId)); activeExtruder = extruder[activeExtruderId]; break; } if (layer != lastlayer) { foreach (GCodeShort c in unchangedLayer) { c.layer = layer; } unchangedLayer.Clear(); layerZ = z; lastlayer = layer; } else if (z != layerZ) unchangedLayer.AddLast(code); code.layer = layer; code.tool = activeExtruderId; code.emax = totalFilamentUsed(); }
public void Analyze(GCode code) { if (code.hostCommand) { string cmd = code.getHostCommand(); if (cmd.Equals("@hide")) drawing = false; else if (cmd.Equals("@show")) drawing = true; else if (cmd.Equals("@isathome")) { hasXHome = hasYHome = hasZHome = true; x = Main.printerSettings.XHomePos; y = Main.printerSettings.YHomePos; z = Main.printerSettings.ZHomePos; xOffset = yOffset = zOffset = 0; } return; } //if (code.forceAscii) return; // Don't analyse host commands and unknown commands if (code.hasN) lastline = code.N; if (uploading && !code.hasM && code.M != 29) return; // ignore upload commands if (code.hasG) { switch (code.G) { case 0: case 1: eChanged = false; if (code.hasF) f = code.F; if (relative) { if (code.hasX) x += code.X; if (code.hasY) y += code.Y; if (code.hasZ) z += code.Z; if (code.hasE) { if (eChanged = code.E != 0) { if (code.E < 0) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; } else activeExtruder.e += code.E; } } } else { if (code.hasX) x = xOffset + code.X; if (code.hasY) y = yOffset + code.Y; if (code.hasZ) { z = zOffset + code.Z; } if (code.hasE) { if (eRelative) { if (eChanged = code.E != 0) { if (code.E < 0) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; } else activeExtruder.e += code.E; } } else { if (eChanged = activeExtruder.e != (activeExtruder.eOffset + code.E)) { activeExtruder.e = activeExtruder.eOffset + code.E; if (activeExtruder.e < activeExtruder.lastE) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; activeExtruder.eOffset = activeExtruder.e - code.E; } } } } } if (x < Main.printerSettings.XMin) { x = Main.printerSettings.XMin; hasXHome = false; } if (y < Main.printerSettings.YMin) { y = Main.printerSettings.YMin; hasYHome = false; } if (z < 0 && FormPrinterSettings.ps.printerType!=3) { z = 0; hasZHome = false; } if (x > Main.printerSettings.XMax) { hasXHome = false; } if (y > Main.printerSettings.YMax) { hasYHome = false; } if (z > printerHeight) { hasZHome = false; } if (activeExtruder.e > activeExtruder.emax) { activeExtruder.emax = activeExtruder.e; if (z != lastZPrint) { layer++; lastZPrint = z; if (!privateAnalyzer && Main.conn.job.hasData() && Main.conn.job.maxLayer >= 0) { //PrinterConnection.logInfo("Printing layer " + layer.ToString() + " of " + Main.conn.job.maxLayer.ToString()); PrinterConnection.logInfo(Trans.T2("L_PRINTING_LAYER_X_OF_Y", layer.ToString(), Main.conn.job.maxLayer.ToString())); } } } if (eventPosChanged != null) if (privateAnalyzer) eventPosChanged(code, x, y, z); else Main.main.Invoke(eventPosChanged, code, x, y, z); float dx = Math.Abs(x - lastX); float dy = Math.Abs(y - lastY); float dz = Math.Abs(z - lastZ); float de = Math.Abs(activeExtruder.e - activeExtruder.lastE); if (dx + dy + dz > 0.001) { printingTime += Math.Sqrt(dx * dx + dy * dy + dz * dz) * 60.0f / f; } else printingTime += de * 60.0f / f; if (z != lastZ) unchangedLayer.Clear(); lastX = x; lastY = y; lastZ = z; activeExtruder.lastE = activeExtruder.e; break; case 2: case 3: { isG1Move = true; eChanged = false; if (code.hasF) f = code.F; if (relative) { if (code.hasX) { x += code.X; } if (code.hasY) { y += code.Y; } if (code.hasZ) { z += code.Z; } if (code.hasE) { if (eChanged = code.E != 0) { if (code.E < 0) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; } else activeExtruder.e += code.E; } } } else { if (code.hasX) { x = xOffset + code.X; } if (code.hasY) { y = yOffset + code.Y; } if (code.hasZ) { z = zOffset + code.Z; //if (z < 0) { z = 0; hasZHome = NO; } //if (z > printerHeight) { hasZHome = NO; } } if (code.hasE ) { if (eRelative) { if (eChanged = code.E != 0) { if (code.E < 0) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; } else activeExtruder.e += code.E; } } else { if (eChanged = activeExtruder.e != (activeExtruder.eOffset + code.E)) { activeExtruder.e = activeExtruder.eOffset + code.E; if (activeExtruder.e < activeExtruder.lastE) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; activeExtruder.eOffset = activeExtruder.e - code.E; } } } } } float[] offset = new float[] { code.I, code.J}; /* if(unit_inches) { offset[0]*=25.4; offset[1]*=25.4; }*/ float[] position = new float[] { lastX, lastY }; float[] target = new float[] { x, y }; float r = code.R; if (r > 0) { /* We need to calculate the center of the circle that has the designated radius and passes through both the current position and the target position. This method calculates the following set of equations where [x,y] is the vector from current to target position, d == magnitude of that vector, h == hypotenuse of the triangle formed by the radius of the circle, the distance to the center of the travel vector. A vector perpendicular to the travel vector [-y,x] is scaled to the length of h [-y/d*h, x/d*h] and added to the center of the travel vector [x/2,y/2] to form the new point [i,j] at [x/2-y/d*h, y/2+x/d*h] which will be the center of our arc. d^2 == x^2 + y^2 h^2 == r^2 - (d/2)^2 i == x/2 - y/d*h j == y/2 + x/d*h O <- [i,j] - | r - | - | - | h - | [0,0] -> C -----------------+--------------- T <- [x,y] | <------ d/2 ---->| C - Current position T - Target position O - center of circle that pass through both C and T d - distance from C to T r - designated radius h - distance from center of CT to O Expanding the equations: d -> sqrt(x^2 + y^2) h -> sqrt(4 * r^2 - x^2 - y^2)/2 i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2)) / sqrt(x^2 + y^2)) / 2 Which can be written: i -> (x - (y * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2 j -> (y + (x * sqrt(4 * r^2 - x^2 - y^2))/sqrt(x^2 + y^2))/2 Which we for size and speed reasons optimize to: h_x2_div_d = sqrt(4 * r^2 - x^2 - y^2)/sqrt(x^2 + y^2) i = (x - (y * h_x2_div_d))/2 j = (y + (x * h_x2_div_d))/2 */ //if(unit_inches) r*=25.4; // Calculate the change in position along each selected axis float cx = target[0] - position[0]; float cy = target[1] - position[1]; float h_x2_div_d = -(float)Math.Sqrt(4 * r * r - cx * cx - cy * cy) / (float)Math.Sqrt(cx * cx + cy * cy); // == -(h * 2 / d) // If r is smaller than d, the arc is now traversing the complex plane beyond the reach of any // real CNC, and thus - for practical reasons - we will terminate promptly: // if(isnan(h_x2_div_d)) { OUT_P_LN("error: Invalid arc"); break; } // Invert the sign of h_x2_div_d if the circle is counter clockwise (see sketch below) if (code.G == 3) { h_x2_div_d = -h_x2_div_d; } /* The counter clockwise circle lies to the left of the target direction. When offset is positive, the left hand circle will be generated - when it is negative the right hand circle is generated. T <-- Target position ^ Clockwise circles with this center | Clockwise circles with this center will have will have > 180 deg of angular travel | < 180 deg of angular travel, which is a good thing! \ | / center of arc when h_x2_div_d is positive -> x <----- | -----> x <- center of arc when h_x2_div_d is negative | | C <-- Current position */ // Negative R is g-code-alese for "I want a circle with more than 180 degrees of travel" (go figure!), // even though it is advised against ever generating such circles in a single line of g-code. By // inverting the sign of h_x2_div_d the center of the circles is placed on the opposite side of the line of // travel and thus we get the unadvisably long arcs as prescribed. if (r < 0) { h_x2_div_d = -h_x2_div_d; r = -r; // Finished with r. Set to positive for mc_arc } // Complete the operation by calculating the actual center of the arc offset[0] = 0.5f * (cx - (cy * h_x2_div_d)); offset[1] = 0.5f * (cy + (cx * h_x2_div_d)); } else { // Offset mode specific computations r = (float)Math.Sqrt(offset[0] * offset[0] + offset[1] * offset[1]); // Compute arc radius for mc_arc } // Set clockwise/counter-clockwise sign for mc_arc computations bool isclockwise = code.G == 2; // Trace the arc arc(position, target, offset, r, isclockwise,code); lastX = x; lastY = y; lastZ = z; activeExtruder.lastE = activeExtruder.e; if (x < Main.printerSettings.XMin) { x = Main.printerSettings.XMin; hasXHome = false; } if (y < Main.printerSettings.YMin) { y = Main.printerSettings.YMin; hasYHome = false; } if (z < 0) { z = 0; hasZHome = false; } if (x > Main.printerSettings.XMax) { hasXHome = false; } if (y > Main.printerSettings.YMax) { hasYHome = false; } if (z > printerHeight) { hasZHome = false; } if (activeExtruder.e > activeExtruder.emax) { activeExtruder.emax = activeExtruder.e; if (z > lastZPrint) { lastZPrint = z; layer++; } } } break; case 28: case 161: { bool homeAll = !(code.hasX || code.hasY || code.hasZ); if (code.hasX || homeAll) { xOffset = 0; x = Main.printerSettings.XHomePos; hasXHome = true; } if (code.hasY || homeAll) { yOffset = 0; y = Main.printerSettings.YHomePos; hasYHome = true; } if (code.hasZ || homeAll) { zOffset = 0; z = Main.printerSettings.ZHomePos; hasZHome = true; } if (code.hasE) { activeExtruder.eOffset = 0; activeExtruder.e = 0; activeExtruder.emax = 0; } if (eventPosChanged != null) if (privateAnalyzer) eventPosChanged(code, x, y, z); else Main.main.Invoke(eventPosChanged, code, x, y, z); } break; case 162: { bool homeAll = !(code.hasX || code.hasY || code.hasZ); if (code.hasX || homeAll) { xOffset = 0; x = Main.printerSettings.XMax; hasXHome = true; } if (code.hasY || homeAll) { yOffset = 0; y = Main.printerSettings.YMax; hasYHome = true; } if (code.hasZ || homeAll) { zOffset = 0; z = Main.printerSettings.PrintAreaHeight; hasZHome = true; } if (eventPosChanged != null) if (privateAnalyzer) eventPosChanged(code, x, y, z); else Main.main.Invoke(eventPosChanged, code, x, y, z); } break; case 90: relative = false; break; case 91: relative = true; break; case 92: if (code.hasX) { xOffset = x - code.X; x = xOffset; } if (code.hasY) { yOffset = y - code.Y; y = yOffset; } if (code.hasZ) { zOffset = z - code.Z; z = zOffset; } if (code.hasE) { activeExtruder.eOffset = activeExtruder.e - code.E; activeExtruder.lastE = activeExtruder.e = activeExtruder.eOffset; } if (eventPosChanged != null) if (privateAnalyzer) eventPosChanged(code, x, y, z); else Main.main.Invoke(eventPosChanged, code, x, y, z); break; } } else if (code.hasM) { switch (code.M) { case 28: uploading = true; break; case 29: uploading = false; break; case 80: powerOn = true; fireChanged(); break; case 81: powerOn = false; fireChanged(); break; case 82: eRelative = false; break; case 83: eRelative = true; break; case 104: case 109: { int idx = activeExtruderId; if (code.hasT) idx = code.T; if (code.hasS) setTemperature(idx, code.S); } fireChanged(); break; case 106: fanOn = true; if (code.hasS) fanVoltage = code.S; fireChanged(); break; case 107: fanOn = false; fireChanged(); break; case 110: lastline = code.N; break; case 111: if (code.hasS) { debugLevel = code.S; } break; case 140: case 190: if (code.hasS) bedTemp = code.S; fireChanged(); break; case 203: // Temp monitor if (code.hasS) tempMonitor = code.S; break; case 220: if (code.hasS) speedMultiply = code.S; break; } } else if (code.hasT) { activeExtruderId = code.T; if (!extruder.ContainsKey(activeExtruderId)) extruder.Add(activeExtruderId, new ExtruderData(activeExtruderId)); activeExtruder = extruder[activeExtruderId]; fireChanged(); } }
// set to start condition public void start() { relative = false; eRelative = false; activeExtruderId = 0; List<int> keys = new List<int>(); foreach (int k in extruder.Keys) keys.Add(k); if(!keys.Contains(activeExtruderId)) keys.Add(activeExtruderId); foreach (int k in keys) extruder[k] = new ExtruderData(k); activeExtruder = extruder[activeExtruderId]; bedTemp = 0; fanOn = false; powerOn = true; fanVoltage = 0; maxDrawMethod = 2; drawing = true; lastline = 0; layer = 0; lastlayer = 0; layerZ = 0; x = y = z = lastZPrint = 0; xOffset = yOffset = zOffset = 0; lastX = 0; lastY = 0; lastZ = 0; hasXHome = hasYHome = hasZHome = false; printerWidth = Main.printerSettings.PrintAreaWidth; printerDepth = Main.printerSettings.PrintAreaDepth; printerHeight = Main.printerSettings.PrintAreaHeight; if (!privateAnalyzer) Main.main.jobVisual.ResetQuality(); fireChanged(); }
public void setTemperature(int extr, float t) { if (extr < 0) extr = activeExtruderId; if (!extruder.ContainsKey(extr)) { ExtruderData ed = new ExtruderData(extr); ed.temperature = t; extruder.Add(extr, ed); } else extruder[extr].temperature = t; }
public void Analyze(GCode code) { if (code.hostCommand) { string cmd = code.getHostCommand(); if (cmd.Equals("@hide")) drawing = false; else if (cmd.Equals("@show")) drawing = true; else if (cmd.Equals("@isathome")) { hasXHome = hasYHome = hasZHome = true; x = Main.printerSettings.XHomePos; y = Main.printerSettings.YHomePos; zr = Main.printerSettings.ZHomePos; xOffset = yOffset = zOffset = 0; } return; } //if (code.forceAscii) return; // Don't analyse host commands and unknown commands if (code.hasN) lastline = code.N; if (uploading && !code.hasM && code.M != 29) return; // ignore upload commands if (code.hasG) { switch (code.G) { case 0: case 1: eChanged = false; if (code.hasF) f = code.F; if (relative) { if (code.hasX) x += code.X; if (code.hasY) y += code.Y; if (code.hasZ) { zr += code.Z; zl += code.Z; } if (code.hasR) zr += code.R; if (code.hasL) zl += code.L; } else { if (code.hasX) x = xOffset + code.X; if (code.hasY) y = yOffset + code.Y; if (code.hasZ) { zr = zOffset + code.Z; zl = zl + code.Z; } if (code.hasR) { zr = zOffset + code.R; } if (code.hasL) { zl += code.L; } if (code.hasE) { if (eRelative) { if (eChanged = code.E != 0) { if (code.E < 0) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; } else activeExtruder.e += code.E; } } else { if (eChanged = activeExtruder.e != (activeExtruder.eOffset + code.E)) { activeExtruder.e = activeExtruder.eOffset + code.E; if (activeExtruder.e < activeExtruder.lastE) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; activeExtruder.eOffset = activeExtruder.e - code.E; } } } } } if (x < Main.printerSettings.XMin) { x = Main.printerSettings.XMin; hasXHome = false; } if (y < Main.printerSettings.YMin) { y = Main.printerSettings.YMin; hasYHome = false; } if (zr < 0 && FormPrinterSettings.ps.printerType!=3) { zr = 0; hasZHome = false; } if (x > Main.printerSettings.XMax) { hasXHome = false; } if (y > Main.printerSettings.YMax) { hasYHome = false; } if (zr > printerHeight) { hasZHome = false; } if (activeExtruder.e > activeExtruder.emax) { activeExtruder.emax = activeExtruder.e; if (zr != lastZPrint) { layer++; lastZPrint = zr; if (!privateAnalyzer && Main.conn.job.hasData() && Main.conn.job.maxLayer >= 0) { //PrinterConnection.logInfo("Printing layer " + layer.ToString() + " of " + Main.conn.job.maxLayer.ToString()); PrinterConnection.logInfo(Trans.T2("L_PRINTING_LAYER_X_OF_Y", layer.ToString(), Main.conn.job.maxLayer.ToString())); } } } if (eventPosChanged != null) if (privateAnalyzer) eventPosChanged(code, x, y, zr); else Main.main.Invoke(eventPosChanged, code, x, y, zr); float dx = Math.Abs(x - lastX); float dy = Math.Abs(y - lastY); float dz = Math.Abs(zr - lastZ); float de = Math.Abs(activeExtruder.e - activeExtruder.lastE); if (dx + dy + dz > 0.001) { printingTime += Math.Sqrt(dx * dx + dy * dy + dz * dz) * 60.0f / f; } else printingTime += de * 60.0f / f; if (zr != lastZ) unchangedLayer.Clear(); lastX = x; lastY = y; lastZ = zr; activeExtruder.lastE = activeExtruder.e; break; case 2: case 3: { isG1Move = true; eChanged = false; if (code.hasF) f = code.F; if (relative) { if (code.hasX) { x += code.X; } if (code.hasY) { y += code.Y; } if (code.hasZ) { zr += code.Z; zl += code.Z; } if (code.hasR) { zr += code.R; } if (code.hasL) { zr += code.L; } if (code.hasE) { if (eChanged = code.E != 0) { if (code.E < 0) activeExtruder.retracted = true; else if (activeExtruder.retracted) { activeExtruder.retracted = false; activeExtruder.e = activeExtruder.emax; } else activeExtruder.e += code.E; } } } else { if (code.hasX) { x = xOffset + code.X; } if (code.hasY) { y = yOffset + code.Y; } if (code.hasZ) { zr = zOffset + code.Z; zl = zl + code.Z; } if (code.hasR) { zr = zOffset + code.R; } if (code.hasL) { zl = zl + code.L; } } float[] offset = new float[] { code.I, code.J}; /* if(unit_inches) { offset[0]*=25.4; offset[1]*=25.4; }*/ float[] position = new float[] { lastX, lastY }; float[] target = new float[] { x, y }; float r = (float)Math.Sqrt(offset[0] * offset[0] + offset[1] * offset[1]); // Compute arc radius for mc_arc // Set clockwise/counter-clockwise sign for mc_arc computations bool isclockwise = code.G == 2; // Trace the arc arc(position, target, offset, r, isclockwise,code); lastX = x; lastY = y; lastZ = zr; activeExtruder.lastE = activeExtruder.e; if (x < Main.printerSettings.XMin) { x = Main.printerSettings.XMin; hasXHome = false; } if (y < Main.printerSettings.YMin) { y = Main.printerSettings.YMin; hasYHome = false; } if (zr < 0) { zr = 0; hasZHome = false; } if (x > Main.printerSettings.XMax) { hasXHome = false; } if (y > Main.printerSettings.YMax) { hasYHome = false; } if (zr > printerHeight) { hasZHome = false; } if (activeExtruder.e > activeExtruder.emax) { activeExtruder.emax = activeExtruder.e; if (zr > lastZPrint) { lastZPrint = zr; layer++; } } } break; case 28: case 161: { bool homeAll = !(code.hasX || code.hasY || code.hasZ); if (code.hasX || homeAll) { xOffset = 0; x = Main.printerSettings.XHomePos; hasXHome = true; } if (code.hasY || homeAll) { yOffset = 0; y = Main.printerSettings.YHomePos; hasYHome = true; } if (code.hasZ || homeAll) { zOffset = 0; zr = Main.printerSettings.ZHomePos; hasZHome = true; } if (code.hasE) { activeExtruder.eOffset = 0; activeExtruder.e = 0; activeExtruder.emax = 0; } if (eventPosChanged != null) if (privateAnalyzer) eventPosChanged(code, x, y, zr); else Main.main.Invoke(eventPosChanged, code, x, y, zr); } break; case 162: { bool homeAll = !(code.hasX || code.hasY || code.hasZ); if (code.hasX || homeAll) { xOffset = 0; x = Main.printerSettings.XMax; hasXHome = true; } if (code.hasY || homeAll) { yOffset = 0; y = Main.printerSettings.YMax; hasYHome = true; } if (code.hasZ || homeAll) { zOffset = 0; zr = Main.printerSettings.PrintAreaHeight; hasZHome = true; } if (eventPosChanged != null) if (privateAnalyzer) eventPosChanged(code, x, y, zr); else Main.main.Invoke(eventPosChanged, code, x, y, zr); } break; case 90: relative = false; break; case 91: relative = true; break; case 92: if (code.hasX) { xOffset = x - code.X; x = xOffset; } if (code.hasY) { yOffset = y - code.Y; y = yOffset; } if (code.hasZ) { zOffset = zr - code.Z; zr = zOffset; zl = zl - code.Z; } if (code.hasR) { zOffset = zr - code.R; zr = zOffset; } if (code.hasL) { zl = zl - code.L; } if (code.hasE) { activeExtruder.eOffset = activeExtruder.e - code.E; activeExtruder.lastE = activeExtruder.e = activeExtruder.eOffset; } if (eventPosChanged != null) if (privateAnalyzer) eventPosChanged(code, x, y, zr); else Main.main.Invoke(eventPosChanged, code, x, y, zr); break; } } else if (code.hasM) { switch (code.M) { case 28: uploading = true; break; case 29: uploading = false; break; case 80: powerOn = true; fireChanged(); break; case 81: powerOn = false; fireChanged(); break; case 82: eRelative = false; break; case 83: eRelative = true; break; case 104: case 109: { int idx = activeExtruderId; if (code.hasT) idx = code.T; if (code.hasS) setTemperature(idx, code.S); } fireChanged(); break; case 106: fanOn = true; if (code.hasS) fanVoltage = code.S; fireChanged(); break; case 107: fanOn = false; fireChanged(); break; case 110: lastline = code.N; break; case 111: if (code.hasS) { debugLevel = code.S; } break; case 140: case 190: if (code.hasS) bedTemp = code.S; fireChanged(); break; case 203: // Temp monitor if (code.hasS) tempMonitor = code.S; break; case 220: if (code.hasS) speedMultiply = code.S; break; case 600: laserOn = true; if (code.hasS) laserVoltage = code.S; fireChanged(); break; case 601: laserOn = false; break; } } else if (code.hasT) { activeExtruderId = code.T; if (!extruder.ContainsKey(activeExtruderId)) extruder.Add(activeExtruderId, new ExtruderData(activeExtruderId)); activeExtruder = extruder[activeExtruderId]; fireChanged(); } if (laserOn) { code.laserOn = true; } else { code.laserOn = false; } }