include("scripts/Cam/CamExport/CamExporter.js"); function GCode(documentInterface, newDocumentInterface) { CamExporter.call(this, documentInterface, newDocumentInterface); this.toolPosition = GCode.ToolPosition.Up; this.alwaysWriteGCode = false; this.g = undefined; this.gPrev = undefined; this.x = undefined; this.xPrev = undefined; this.y = undefined; this.yPrev = undefined; this.i = undefined; this.j = undefined; this.z = undefined; this.zPrev = undefined; this.f = undefined; this.fPrev = undefined; this.lineNumber = 10; this.separator = " "; this.decimals = 3; this.globalOptions = "GCode"; this.layerOptions = "GCodeLayer"; this.absoluteIJ = false; } GCode.prototype = new CamExporter(); GCode.Mode = { Rapid : 0, Normal : 1, CircularCW: 2, CircularCCW: 3 }; GCode.ToolPosition = { Clear : 0, Up : 1, Down : 2 }; GCode.prototype.initGlobalOptionWidget = function(w) { switch (w.objectName) { case "ZSafety": w.addItems(["200", "150", "100", "50"]); w.setEditText("100"); break; case "ZClear": w.addItems(["1", "2", "3"]); w.setEditText("2"); break; case "ZCutting": w.addItems(["-1", "-2", "-3"]); w.setEditText("-2"); break; } }; GCode.prototype.initLayerOptionWidget = function(w) { switch (w.objectName) { case "ZCutting": w.addItems(["default", "-1", "-2", "-3"]); w.currentText = "default"; break; } }; GCode.prototype.getFileExtensions = function() { return ["nc"]; }; GCode.prototype.getRapidMoveCode = function() { return "G00"; }; GCode.prototype.getLinearMoveCode = function() { return "G01"; }; GCode.prototype.getCircularCWMoveCode = function() { return "G02"; }; GCode.prototype.getCircularCCWMoveCode = function() { return "G03"; }; GCode.prototype.getLineNumberCode = function() { var ret = sprintf("N%d", this.lineNumber); this.lineNumber += 10; return ret; }; GCode.prototype.getXCode = function(value) { var v = value; if (this.getIncrementalXYZ()) { v -= this.xPrev; } return sprintf("X%.%1f".arg(this.decimals), v); }; GCode.prototype.getYCode = function(value) { var v = value; if (this.getIncrementalXYZ()) { v -= this.yPrev; } return sprintf("Y%.%1f".arg(this.decimals), v); }; GCode.prototype.getZCode = function(value) { var v = value; if (this.getIncrementalXYZ()) { v -= this.zPrev; } return sprintf("Z%.%1f".arg(this.decimals), v); }; GCode.prototype.getICode = function(value) { return sprintf("I%.%1f".arg(this.decimals), value); }; GCode.prototype.getJCode = function(value) { return sprintf("J%.%1f".arg(this.decimals), value); }; GCode.prototype.getFCode = function(value) { return sprintf("F%d", value); }; GCode.prototype.getSafetyZLevel = function() { return parseFloat(this.document.getVariable("Cam/ZSafety", 100.0)); }; GCode.prototype.getToolUpLevel = function() { return parseFloat(this.document.getVariable("Cam/ZClear", 2.0)); }; GCode.prototype.getToolDownLevel = function() { // document wide default value: var docValue = parseFloat(this.document.getVariable("Cam/ZCutting", -1.0)); var entity = this.getEntity(); if (isNull(entity)) { return docValue; } // layer specific value: var layerId = entity.getLayerId(); var layer = this.document.queryLayer(layerId); if (isNull(layer)) { return docValue; } var layerValue = layer.getCustomProperty("QCADCAM", "Cam/ZCutting", docValue); if (layerValue==="default") { return docValue; } else { return layerValue; } }; GCode.prototype.getFeedrate = function() { return parseFloat(this.document.getVariable("Cam/Feedrate", 200)); }; GCode.prototype.toolIsUp = function() { this.g = GCode.Mode.Rapid; this.toolPosition = GCode.ToolPosition.Up; }; GCode.prototype.toolIsDown = function() { this.g = GCode.Mode.Normal; this.toolPosition = GCode.ToolPosition.Down; }; GCode.prototype.writeToolUp = function() { this.g = GCode.Mode.Rapid; this.z = this.getToolUpLevel(); this.toolPosition = GCode.ToolPosition.Up; if (this.feedRateSet!==true) { this.writeLine(undefined, "F200"); this.feedRateSet=true; } else { this.writeLine(); } this.toolIsUp(); }; GCode.prototype.writeToolDown = function() { this.g = GCode.Mode.Normal; this.z = this.getToolDownLevel(); this.toolPosition = GCode.ToolPosition.Down; this.writeLine(); this.toolIsDown(); }; GCode.prototype.writeRapidZMove = function(z) { this.g = GCode.Mode.Rapid; this.z = z; this.writeLine(); }; GCode.prototype.writeZMove = function(z) { this.g = GCode.Mode.Normal; this.z = z; this.writeLine(); }; // G00: GCode.prototype.writeRapidLinearMove = function(x, y) { if (!this.gotXMove(x) && !this.gotYMove(y)) { return; } this.writeBeforeRapidLinearMove(x, y); // force tool up before Rapid move: if (this.toolPosition !== GCode.ToolPosition.Up && this.toolPosition !== GCode.ToolPosition.Clear) { this.writeToolUp(); } this.g = GCode.Mode.Rapid; this.x = x; this.y = y; this.writeLine(); this.writeAfterRapidLinearMove(x, y); }; GCode.prototype.writeBeforeRapidLinearMove = function(x, y) { }; GCode.prototype.writeAfterRapidLinearMove = function(x, y) { }; GCode.prototype.prepareForCutting = function() { // force tool down before normal move: if (this.toolPosition !== GCode.ToolPosition.Down) { // force tool up before tool down: if (this.toolPosition !== GCode.ToolPosition.Up) { this.writeToolUp(); } this.writeToolDown(); } }; // G01: GCode.prototype.writeLinearMove = function(x, y) { this.prepareForCutting(); this.g = GCode.Mode.Normal; this.x = x; this.y = y; this.writeLine(); }; // G02 / G03: GCode.prototype.writeCircularMove = function(x, y, center, radius, startAngle, endAngle, isLarge, isReversed) { this.prepareForCutting(); if (isReversed) { this.g = GCode.Mode.CircularCW; } else { this.g = GCode.Mode.CircularCCW; } if (this.absoluteIJ) { this.i = center.x; this.j = center.y; } else { this.i = center.x - this.x; this.j = center.y - this.y; } this.x = x; this.y = y; this.writeLine(); }; GCode.prototype.writeHeader = function() { this.writeRapidZMove(this.getSafetyZLevel()); this.toolPosition = GCode.ToolPosition.Clear; }; GCode.prototype.writeFooter = function() { this.writeToolUp(); this.writeRapidZMove(this.getSafetyZLevel()); this.toolPosition = GCode.ToolPosition.Clear; this.writeLine("M30"); }; GCode.prototype.gotModeChange = function(m) { return (isNull(this.gPrev) && !isNull(m)) || (!isNull(m) && this.gPrev!=m); }; GCode.prototype.gotXMove = function(x) { return (isNull(this.xPrev) && !isNull(x)) || (!isNull(x) && !this.fuzzyCompare(x, this.xPrev)); }; GCode.prototype.gotYMove = function(y) { return (isNull(this.yPrev) && !isNull(y)) || (!isNull(y) && !this.fuzzyCompare(y, this.yPrev)); }; GCode.prototype.gotZMove = function(z) { return (isNull(this.zPrev) && !isNull(z)) || (!isNull(z) && !this.fuzzyCompare(z, this.zPrev)); }; GCode.prototype.gotZUpMove = function(z) { return this.gotZMove(z) && z>this.zPrev; }; GCode.prototype.gotFeedrateChange = function(f) { return (isNull(this.fPrev) && !isNull(f)) || (!isNull(f) && f!==this.fPrev); }; GCode.prototype.getCamLayerId = function() { if (this.duringRapidMove===true) { return CamExporter.prototype.getCamLayerId.call(this); } return this.createLayer("cut at " + this.getToolDownLevel(), new RColor("white")); }; GCode.prototype.append = function(line, str) { if (line.length===0) { return str; } else { return line + this.separator + str; } }; /** * Writes the next line of the file or the given custom line with line nummer. * * \param custom string (optional) custom line contents * \param append string (optional) append to line contents */ GCode.prototype.writeLine = function(custom, append) { var line = ""; if (!isNull(custom)) { line = this.getLineNumberCode(); line = this.append(line, custom); CamExporter.prototype.writeLine.call(this, line); return; } var gotModeChange = this.gotModeChange(this.g); var gotXMove = this.gotXMove(this.x); var gotYMove = this.gotYMove(this.y); var gotZMove = this.gotZMove(this.z); var gotFeedrateChange = this.gotFeedrateChange(this.f); // nothing to do: if (this.g!==GCode.Mode.CircularCW && this.g!==GCode.Mode.CircularCCW && !gotXMove && !gotYMove && !gotZMove && !gotFeedrateChange) { return; } line = this.getLineNumberCode(); switch (this.g) { case GCode.Mode.Rapid: if (gotModeChange) { line = this.append(line, this.getRapidMoveCode()); } break; case GCode.Mode.Normal: if (gotModeChange) { line = this.append(line, this.getLinearMoveCode()); } break; case GCode.Mode.CircularCW: line = this.append(line, this.getCircularCWMoveCode()); break; case GCode.Mode.CircularCCW: line = this.append(line, this.getCircularCCWMoveCode()); break; } if (gotXMove || this.g===GCode.Mode.CircularCW || this.g===GCode.Mode.CircularCCW) { line = this.append(line, this.getXCode(this.x)); } if (gotYMove || this.g===GCode.Mode.CircularCW || this.g===GCode.Mode.CircularCCW) { line = this.append(line, this.getYCode(this.y)); } if (gotZMove) { line = this.append(line, this.getZCode(this.z)); } if (gotFeedrateChange) { line = this.append(line, this.getFCode(this.f)); } if (this.g===GCode.Mode.CircularCW || this.g===GCode.Mode.CircularCCW) { line = this.append(line, this.getICode(this.i)); line = this.append(line, this.getJCode(this.j)); } if (!isNull(append)) { line = this.append(line, append); } CamExporter.prototype.writeLine.call(this, line); //this.lineNumber += 10; this.xPrev = this.x; this.yPrev = this.y; this.zPrev = this.z; this.fPrev = this.f; this.gPrev = this.g; };