Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor gCode generation allowing marlin compatibility #473

Merged
merged 3 commits into from Apr 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/components/settings.js
Expand Up @@ -264,7 +264,8 @@ class Settings extends React.Component {
<NumberField {...{ object: this.props.settings, field: 'dpiBitmap', setAttrs: setSettingsAttrs, description: 'Bitmap DPI', units: 'dpi' }} />
</SettingsPanel>
<SettingsPanel collapsible header="Gcode" eventKey="3" bsStyle="info" errors={this.state.errors}>

<SelectField {...{ object: this.props.settings, field: 'gcodeGenerator', setAttrs: setSettingsAttrs, data: ['default', 'marlin'], defaultValue: 'default', description: 'GCode Generator', selectProps: { clearable: false } }} />

<TextField {...{ object: this.props.settings, field: 'gcodeStart', setAttrs: setSettingsAttrs, description: 'Gcode Start', rows: 5, style: { resize: "vertical" } }} />
<TextField {...{ object: this.props.settings, field: 'gcodeEnd', setAttrs: setSettingsAttrs, description: 'Gcode End', rows: 5, style: { resize: "vertical" } }} />
<TextField {...{ object: this.props.settings, field: 'gcodeHoming', setAttrs: setSettingsAttrs, description: 'Gcode Homing', rows: 5, style: { resize: "vertical" } }} />
Expand Down
14 changes: 14 additions & 0 deletions src/lib/action2gcode/gcode-generator.js
@@ -0,0 +1,14 @@
'use strict';

import DefaultGenerator from "./generators/default-generator"
import MarlinGenerator from "./generators/marlin-generator"

export function getGenerator(gcodeGenerator, settings) {
switch(gcodeGenerator){
case "marlin" :
return new MarlinGenerator(settings);
case "default" :
default :
return new DefaultGenerator(settings);
}
}
13 changes: 13 additions & 0 deletions src/lib/action2gcode/generators/abstract-generator.js
@@ -0,0 +1,13 @@

// AbstractDriver class
class AbstractGenerator {
// Class constructor...
constructor(settings) {
this.settings = settings;
}

}

// Exports
export { AbstractGenerator }
export default AbstractGenerator
76 changes: 76 additions & 0 deletions src/lib/action2gcode/generators/default-generator.js
@@ -0,0 +1,76 @@

import AbstractGenerator from "./abstract-generator"

// AbstractDriver class
class DefaultGenerator extends AbstractGenerator{
// Class constructor...
constructor(settings) {
super(settings);
}

moveRapid(params, optimized=false){
if(params == null)
return "";

let gcode = "";
if(!optimized) gcode+="G0 ";
gcode += this.move(params);
return gcode;
}

moveTool(params, optimized=false){
if(params == null)
return "";

let gcode = "";
if(!optimized) gcode+="G1 ";
gcode += this.move(params);
return gcode;
}

toolOn(gcode, params){
if(gcode == null)
return "";

if(params.hasOwnProperty("i"))
gcode = gcode.split("$INTENSITY").join(params.i);
return gcode;
}

toolOff(gcode, params){
if(gcode == null)
return "";

if(params.hasOwnProperty("i"))
gcode = gcode.split("$INTENSITY").join(params.i);
return gcode;
}

move(params){
let gcode = "";
if(params.hasOwnProperty("x"))
gcode += ` X${params.x}`;

if(params.hasOwnProperty("y"))
gcode += ` Y${params.y}`;

if(params.hasOwnProperty("a"))
gcode += ` A${params.a}`;

if(params.hasOwnProperty("i"))
gcode += ` ${params.i}`;

if(params.hasOwnProperty("s"))
gcode += ` S${params.s}`;

if(params.hasOwnProperty("f"))
gcode += ` F${params.f}`;

return gcode.trim();
}

}

// Exports
export { DefaultGenerator }
export default DefaultGenerator
83 changes: 83 additions & 0 deletions src/lib/action2gcode/generators/marlin-generator.js
@@ -0,0 +1,83 @@

import AbstractGenerator from "./abstract-generator"

// AbstractDriver class
class MarlinGenerator extends AbstractGenerator{
// Class constructor...
constructor(settings) {
super(settings);
}

moveRapid(params, optimized=false){
if(params == null)
return "";

return this.move("G0", params);
}

moveTool(params, optimized=false){
if(params == null)
return "";

return this.move("G1", params);
}

toolOn(gcode, params){
if(gcode == null)
return "";

if(params.hasOwnProperty("i"))
gcode = gcode.split("$INTENSITY").join(params.i);
return gcode;
}

toolOff(gcode, params){
if(gcode == null)
return "";

if(params.hasOwnProperty("i"))
gcode = gcode.split("$INTENSITY").join(params.i);
return gcode;
}

move(prefix, params){
let gcode = "";

if(params.hasOwnProperty("s")){
if(this.settings.gcodeToolOn.indexOf("$INTENSITY") > -1){
gcode += `${this.settings.gcodeToolOn.split("$INTENSITY").join(this.settings.gcodeLaserIntensity+params.s)}\r\n`;
}else{
gcode += `${this.settings.gcodeToolOn} S${params.s}\r\n`;
}
}

if(params.hasOwnProperty("i")){
if(this.settings.gcodeToolOn.indexOf("$INTENSITY") > -1){
gcode += `${this.settings.gcodeToolOn.split("$INTENSITY").join(params.i)}\r\n`;
}else{
gcode += `${this.settings.gcodeToolOn} ${params.i}\r\n`;
}
}

gcode += prefix;

if(params.hasOwnProperty("x"))
gcode += ` X${params.x}`;

if(params.hasOwnProperty("y"))
gcode += ` Y${params.y}`;

if(params.hasOwnProperty("a"))
gcode += ` A${params.a}`;

if(params.hasOwnProperty("f"))
gcode += ` F${params.f}`;

return gcode.trim();
}

}

// Exports
export { MarlinGenerator }
export default MarlinGenerator
39 changes: 27 additions & 12 deletions src/lib/cam-gcode-laser-cut.js
Expand Up @@ -17,6 +17,7 @@

import { dist, cut, fillPath, insideOutside, pocket, reduceCamPaths, separateTabs, vCarve } from './cam';
import { mmToClipperScale, offset, rawPathsToClipperPaths, union } from './mesh';
import { getGenerator } from "./action2gcode/gcode-generator";

// Convert laser cut paths to gcode.
// paths: Array of CamPath
Expand All @@ -32,7 +33,7 @@ import { mmToClipperScale, offset, rawPathsToClipperPaths, union } from './mesh'
// gcodeToolOff: Laser off (may be empty)
// gcodeSMaxValue: Max S value
export function getLaserCutGcode(props) {
let { paths, scale, offsetX, offsetY, decimal, cutFeed, laserPower, passes,
let { paths, generator, scale, offsetX, offsetY, decimal, cutFeed, laserPower, passes,
useA, aAxisDiameter,
tabGeometry, gcodeToolOn, gcodeToolOff,
gcodeLaserIntensity, gcodeLaserIntensitySeparateLine, gcodeSMinValue, gcodeSMaxValue,
Expand All @@ -59,7 +60,8 @@ export function getLaserCutGcode(props) {
lastX = roundedX;
lastY = adjustedY;
lastA = roundedA;
return 'G0 X' + x.toFixed(decimal) + ' A' + a.toFixed(decimal);
//return 'G0 X' + x.toFixed(decimal) + ' A' + a.toFixed(decimal);
return {x: x.toFixed(decimal), a: a.toFixed(decimal)};
} else {
let dx = roundedX - lastX, dy = adjustedY - lastY, da = roundedA - lastA;
let travelTime = Math.sqrt(dx * dx + dy * dy) / cutFeed;
Expand All @@ -69,17 +71,20 @@ export function getLaserCutGcode(props) {
else if (da)
f = Math.abs(da) / travelTime;
else
return '';
return null;
//return '';
lastX = roundedX;
lastY = adjustedY;
lastA = roundedA;
return 'G1 X' + x.toFixed(decimal) + ' A' + a.toFixed(decimal) + ' F' + f.toFixed(decimal);
return {x: x.toFixed(decimal), a: a.toFixed(decimal), f: f.toFixed(decimal)};
//return 'G1 X' + x.toFixed(decimal) + ' A' + a.toFixed(decimal) + ' F' + f.toFixed(decimal);
}
} else {
if (rapid)
return {x: x.toFixed(decimal), y: y.toFixed(decimal)};
/*if (rapid)
return 'G0 X' + x.toFixed(decimal) + ' Y' + y.toFixed(decimal);
else
return 'G1 X' + x.toFixed(decimal) + ' Y' + y.toFixed(decimal);
return 'G1 X' + x.toFixed(decimal) + ' Y' + y.toFixed(decimal);*/
}
}

Expand Down Expand Up @@ -113,7 +118,7 @@ export function getLaserCutGcode(props) {
gcode += '; Skip tab\r\n';
continue;
}
gcode += convertPoint(selectedPath[0], true) + '\r\n';
gcode += generator.moveRapid(convertPoint(selectedPath[0], true)) + '\r\n';

if (useZ && !usedZposition) {
usedZposition = true;
Expand All @@ -122,21 +127,28 @@ export function getLaserCutGcode(props) {
gcode += 'G0 Z' + zHeight.toFixed(decimal) + '\r\n\r\n';
}

gcode += gcodeToolOn;
gcode += generator.toolOn(gcodeToolOn, {i:laserOnS});

for (let i = 1; i < selectedPath.length; ++i) {
if (i == 1 && gcodeLaserIntensitySeparateLine)
gcode += laserOnS + '\n';
gcode += convertPoint(selectedPath[i], false);
let action = convertPoint(selectedPath[i], false);
//gcode += convertPoint(selectedPath[i], false);
if (i == 1 && !gcodeLaserIntensitySeparateLine)
gcode += ' ' + laserOnS;
action.i = laserOnS;
//gcode += ' ' + laserOnS;
if (i == 1 && !useA)
gcode += ' F' + cutFeed;
action.f = cutFeed;
//gcode += ' F' + cutFeed;
gcode += generator.moveTool(action);
gcode += '\r\n';
}
gcode += gcodeToolOff;

gcode += generator.toolOff(gcodeToolOff, {i:laserOnS});
}
}


if (useBlower) {
if (useBlower.blowerOff) {
gcode += `\r\n ${useBlower.blowerOff}; Disable Air assist\r\n`;
Expand Down Expand Up @@ -229,7 +241,10 @@ export function getLaserCutGcodeFromOp(settings, opIndex, op, geometry, openGeom

if (op.hookOperationStart.length) gcode += op.hookOperationStart;

let generator = getGenerator(settings.gcodeGenerator, settings);

gcode += getLaserCutGcode({
generator: generator,
paths: camPaths,
scale: 1 / mmToClipperScale,
offsetX: 0,
Expand Down
20 changes: 16 additions & 4 deletions src/lib/cam-gcode-raster.js
Expand Up @@ -61,12 +61,14 @@ export function getLaserRasterGcodeFromOp(settings, opIndex, op, docsWithImages,

// POSTPROCESS GCODE;
const postProcessing = (gc) => {

let g = '';
let raster = '';

let firstMove = gc.find((line)=>{
return line.match(/^G[0-1]\s+[XYZ]/gi);
})

for (let line of gc) {
if (op.useA) {
line = line.replace(/Y(\s*-?[0-9\.]{1,})/gi, (str,float)=>{
Expand Down Expand Up @@ -98,7 +100,7 @@ export function getLaserRasterGcodeFromOp(settings, opIndex, op, docsWithImages,

if (firstMove) {
g+= `\r\n; First Move\r\n`;
g+= firstMove.replace(/^G[0-1]/gi,'G0').replace(/S[0\.]+/gi,'');
g+= firstMove.replace(/^G[0-1]/gi,'G0').replace(/S[0\.]+/gi,'')+'\r\n';
}

if (settings.machineZEnabled) {
Expand All @@ -107,8 +109,14 @@ export function getLaserRasterGcodeFromOp(settings, opIndex, op, docsWithImages,
g += 'G0 Z' + zHeight.toFixed(settings.decimal || 3) + '\r\n';
}

if (settings.gcodeToolOn && settings.gcodeToolOn.length)
g += `${settings.gcodeToolOn} \r\n`;
if (settings.gcodeToolOn && settings.gcodeToolOn.length){
if(settings.gcodeToolOn.indexOf("$INTENSITY") > -1){
g += `${settings.gcodeToolOn.split("$INTENSITY").join(settings.gcodeLaserIntensity+settings.gcodeSMaxValue.toFixed(4))}\r\n`;
}else{
g += `${settings.gcodeToolOn} \r\n`;
}
//g += `${settings.gcodeToolOn} \r\n`;
}

g += raster;

Expand Down Expand Up @@ -192,6 +200,10 @@ export function getLaserRasterGcodeFromOp(settings, opIndex, op, docsWithImages,
verboseG: op.verboseGcode,
diagonal: op.diagonal,
overscan: op.overScan,
gcodeGenerator : settings.gcodeGenerator,
gcodeToolOn : settings.gcodeToolOn,
gcodeToolOff : settings.gcodeToolOff,
gcodeLaserIntensity: settings.gcodeLaserIntensity,
nonBlocking: false,
milling: false,
filters: {
Expand Down