Skip to content

Basic featureset #1

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

Open
wants to merge 34 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
f0d865a
docs(README): tweaks & minor improvements to readme
kaosat-dev Nov 5, 2016
7452ef2
refactor(): spliting up old code base into to more manageable chunks …
kaosat-dev Nov 5, 2016
b131492
chore(split up): more code split up etc
kaosat-dev Nov 5, 2016
5b87503
feat(gcodeHandlers): migrating gcodeHandlers & parseFunction towards …
kaosat-dev Nov 5, 2016
2c1d2c8
refactor(geometries): further cleanup of 'geometries' (arcs, segments):
kaosat-dev Nov 5, 2016
39231a4
refactor(gcodeHandlers): continued cleanup:
kaosat-dev Nov 5, 2016
ea03a95
refactor(objFromGcode): split out layers & lineGroup code into sepera…
kaosat-dev Nov 5, 2016
6f58a50
refactor(): continued restructure/reorganize/regroup of logical varia…
kaosat-dev Nov 6, 2016
ca47ad3
fix(): minor typos fix
kaosat-dev Nov 6, 2016
5f98e77
test(): tweaked data type, added data for basic test
kaosat-dev Nov 12, 2016
848d37b
refactor(): continued overall reshape:
kaosat-dev Nov 12, 2016
8184f4a
refactor(): very basic parsing works!
kaosat-dev Nov 13, 2016
6233981
test(): fleshed out basic test a bit
kaosat-dev Nov 13, 2016
de6de70
refactor(makebasestate): renamed, cleaned up
kaosat-dev Nov 13, 2016
4b6e9b3
refactor(): modified data structure to be more generic , less three.js
kaosat-dev Nov 13, 2016
5aeec89
refactor(drawObject): attempt at making sense of draw object:
kaosat-dev Nov 13, 2016
0e89145
feat(index): added doneCallback, various cleanups & doc additions
kaosat-dev Nov 13, 2016
ca65924
refactor(): minor tweaks
kaosat-dev Nov 13, 2016
33e0f45
feat(doneCallback): added (back?) call to doneCallback
kaosat-dev Nov 13, 2016
9a9d101
refactor(): migrating towards new data structures
kaosat-dev Nov 16, 2016
189c631
refactor(): further changes for up to date output etc
kaosat-dev Nov 18, 2016
3b5334c
tests(travis): slight node version tweak for travis CI
kaosat-dev Nov 21, 2016
3d5ead3
refactor():phasing out more obsolete code
kaosat-dev Nov 21, 2016
18ef168
feat(segements): updated segements parsing to new data structure, upd…
kaosat-dev Nov 21, 2016
83b9173
test(): moved test data to external repo, added test for multi materi…
kaosat-dev Nov 22, 2016
6ee3e94
chore(package): added devdepency to lw-sample-files , for testing
kaosat-dev Nov 22, 2016
2f37ddb
fix(handlers): minor fix of missing state for some handlers
kaosat-dev Nov 22, 2016
f12816e
feat(segments): further changes/tweaks for new data structure
kaosat-dev Nov 22, 2016
13025f3
feat(data storage): added automatic resizing of typedArrays used for …
kaosat-dev Nov 23, 2016
4de3dd8
refactor(): more 'binning' of obsolete code
kaosat-dev Nov 23, 2016
b63fa97
feat(state): modified/simplified base state
kaosat-dev Nov 24, 2016
241bbe9
refactor(): minor tweaks
kaosat-dev Nov 24, 2016
d080c77
refacto(): more cleanup, clutter removal
kaosat-dev Nov 30, 2016
51aedf3
test(): added additional specs for different type of gcode
kaosat-dev Nov 30, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
language: node_js
node_js:
- "4.2"
- "4.4"
- "6.9"
sudo: false
26 changes: 23 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,43 @@

[![GitHub version](https://badge.fury.io/gh/LaserWeb%2Flw-gcode-parser.svg)](https://badge.fury.io/gh/LaserWeb%2Flw-gcode-parser)

## Table of Contents

## General information
- [Background](#background)
- [Installation](#installation)
- [Usage](#usage)
- [API](#api)
- [Contribute](#contribute)
- [License](#license)


## Background

To a large extent based on John Lauer's & contributors work

##Installation

To a large extent based on John Lauer's & contributors work

## Usage


## TODO
## API


## Contribute

PRs accepted.

Small note: If editing the Readme, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.

## LICENSE

[The MIT License (MIT)](https://github.com/LaserWeb/lw-gcode-parser/blob/master/LICENSE)

- - -

[![Standard - JavaScript Style Guide](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)

[![Build Status](https://travis-ci.org/LaserWeb/lw-gcode-parser.svg?branch=master)](https://travis-ci.org/LaserWeb/lw-gcode-parser)
[![Dependency Status](https://david-dm.org/LaserWeb/lw-gcode-parser.svg)](https://david-dm.org/LaserWeb/lw-gcode-parser)
[![devDependency Status](https://david-dm.org/LaserWeb/lw-gcode-parser/dev-status.svg)](https://david-dm.org/LaserWeb/lw-gcode-parser#info=devDependencies)
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"dependencies": {
},
"devDependencies": {
"lw-sample-files":"LaserWeb/lw-sample-files",
"ava": "0.16",
"babel-cli": "^6.6.5",
"babel-core": "^6.2.1",
Expand Down
312 changes: 312 additions & 0 deletions src/gcodeHandlers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,312 @@
import { absolute, delta } from './utils'
import { addSegment, addLineSegment, addFakeSegment } from './geometries/segments'
import { newLayer } from './layers'

export default function makeHandlers (params) {
const handlers = {
// set the g92 offsets for the parser - defaults to no offset
// When doing CNC, generally G0 just moves to a new location
// as fast as possible which means no milling or extruding is happening in G0.
// So, let's color it uniquely to indicate it's just a toolhead move.
G0: function (state, args, index) {
const {lastLine} = state
const newLine = {
g: 0,
x: args.x !== undefined ? absolute(state.relative, lastLine.x, args.x) + state.specifics.G92.offset.x : lastLine.x,
y: args.y !== undefined ? absolute(state.relative, lastLine.y, args.y) + state.specifics.G92.offset.y : lastLine.y,
z: args.z !== undefined ? absolute(state.relative, lastLine.z, args.z) + state.specifics.G92.offset.z : lastLine.z,
a: args.a !== undefined ? absolute(state.relative, lastLine.a, args.a) + state.specifics.G92.offset.a : lastLine.a,
e: args.e !== undefined ? absolute(state.relative, lastLine.e, args.e) + state.specifics.G92.offset.e : lastLine.e,
f: args.f !== undefined ? args.f : lastLine.f,
s: 100,
t: undefined
}
addLineSegment(state, args, lastLine, newLine)
state.lastLine = newLine
},
G1: function (state, args, index) {
const {lastLine, layer} = state
// Example: G1 Z1.0 F3000
// G1 X99.9948 Y80.0611 Z15.0 F1500.0 E981.64869
// G1 E104.25841 F1800.0
// Go in a straight line from the current (X, Y) point
// to the point (90.6, 13.8), extruding material as the move
// happens from the current extruded length to a length of
// 22.4 mm.

const newLine = {
g: 1,
x: args.x !== undefined ? absolute(state.relative, lastLine.x, args.x) + state.specifics.G92.offset.x : lastLine.x,
y: args.y !== undefined ? absolute(state.relative, lastLine.y, args.y) + state.specifics.G92.offset.y : lastLine.y,
z: args.z !== undefined ? absolute(state.relative, lastLine.z, args.z) + state.specifics.G92.offset.z : lastLine.z,
a: args.a !== undefined ? absolute(state.relative, lastLine.a, args.a) + state.specifics.G92.offset.a : lastLine.a,
e: args.e !== undefined ? absolute(state.relative, lastLine.e, args.e) + state.specifics.G92.offset.e : lastLine.e,
f: args.f !== undefined ? args.f : lastLine.f,
s: args.s !== undefined ? args.s : lastLine.s,
t: args.t !== undefined ? args.t : lastLine.t
}
/* layer change detection is or made by watching Z, it's made by
watching when we extrude at a new Z position */
if (delta(state.relative, lastLine.e, newLine.e) > 0) {
newLine.extruding = delta(state.relative, lastLine.e, newLine.e) > 0
if (layer === undefined || newLine.z !== layer.z) {
newLayer(newLine, state.layers.layers3d)
}
}
addLineSegment(state, args, lastLine, newLine)
state.lastLine = newLine
},
G2: function (state, args, index, gcp) {
const {plane, lastLine} = state
// this is an arc move from lastLine's xy to the new xy. we'll
// show it as a light gray line, but we'll also sub-render the
// arc itself by figuring out the sub-segments

args.plane = plane // set the plane for this command to whatever the current plane is

const newLine = {
x: args.x !== undefined ? absolute(state.relative, lastLine.x, args.x) + state.specifics.G92.offset.x : lastLine.x,
y: args.y !== undefined ? absolute(state.relative, lastLine.y, args.y) + state.specifics.G92.offset.y : lastLine.y,
z: args.z !== undefined ? absolute(state.relative, lastLine.z, args.z) + state.specifics.G92.offset.z : lastLine.z,
a: args.a !== undefined ? absolute(state.relative, lastLine.a, args.a) + state.specifics.G92.offset.a : lastLine.a,
e: args.e !== undefined ? absolute(state.relative, lastLine.e, args.e) + state.specifics.G92.offset.e : lastLine.e,
f: args.f !== undefined ? args.f : lastLine.f,
s: args.s !== undefined ? args.s : lastLine.s,
t: args.t !== undefined ? args.t : lastLine.t,
arci: args.i ? args.i : null,
arcj: args.j ? args.j : null,
arck: args.k ? args.k : null,
arcr: args.r ? args.r : null,

arc: true,
clockwise: !args.clockwise ? true : args.clockwise // FIXME : always true ??
}
// if (args.clockwise === false) newLine.clockwise = args.clockwise
addSegment(state, args, lastLine, newLine)
state.lastLine = newLine
},
G3: function (state, args, index, gcp) {
const {plane, lastLine} = state

// this is an arc move from lastLine's xy to the new xy. same
// as G2 but reverse
args.arc = true
args.clockwise = false
args.plane = plane // set the plane for this command to whatever the current plane is

const newLine = {
x: args.x !== undefined ? absolute(state.relative, lastLine.x, args.x) + state.specifics.G92.offset.x : lastLine.x,
y: args.y !== undefined ? absolute(state.relative, lastLine.y, args.y) + state.specifics.G92.offset.y : lastLine.y,
z: args.z !== undefined ? absolute(state.relative, lastLine.z, args.z) + state.specifics.G92.offset.z : lastLine.z,
a: args.a !== undefined ? absolute(state.relative, lastLine.a, args.a) + state.specifics.G92.offset.a : lastLine.a,
e: args.e !== undefined ? absolute(state.relative, lastLine.e, args.e) + state.specifics.G92.offset.e : lastLine.e,
f: args.f !== undefined ? args.f : lastLine.f,
s: args.s !== undefined ? args.s : lastLine.s,
t: args.t !== undefined ? args.t : lastLine.t,
arci: args.i ? args.i : null,
arcj: args.j ? args.j : null,
arck: args.k ? args.k : null,
arcr: args.r ? args.r : null,

arc: true,
clockwise: !args.clockwise ? true : args.clockwise // FIXME : always true ??
}
// if (args.clockwise === false) newLine.clockwise = args.clockwise
addSegment(state, args, lastLine, newLine)
state.lastLine = newLine
},

G7: function (state, args, index) {
const {lastLine} = state
// Example: G7 L68 D//////sljasflsfagdxsd,.df9078rhfnxm (68 of em)
// G7 $1 L4 DAAA=
// G7 $0 L4 D2312
// Move right (if $1) or left (if $0) 51 steps (from L68)
// (the number of steps is found when decoding the data)
// and burn the laser with the intensity in the base64-encoded
// data in D. Data in D is 51 base64-encoded bytes with grayscale
// intensity. When base64-encoded the string becomes 68 bytes long.
//
// SpotSize comes from a previous M649 S100 R0.1
// where S is intensity (100 is max) and R gives spotsize in mm.
// Actual laser power is then D-value * S-value in every pixel
// A direction change with $0/$1 gives a spotSize long movement in Y
// for the next row.

var buf = atob(args.d)

if (typeof args.dollar !== 'undefined') { // Move Y, change direction
state.specifics.G7.dir = args.dollar

const newLine = {
g: 0,
x: lastLine.x,
y: lastLine.y + state.specifics.G7.spotSize,
z: lastLine.z,
a: lastLine.a,
e: lastLine.e,
f: lastLine.f,
s: 100,
t: lastLine.t
}
addLineSegment(state, args, lastLine, newLine)
state.lastLine = newLine
}
for (var i = 0; i < buf.length; i++) { // Process a base64-encoded chunk
const intensity = 255 - buf.charCodeAt(i) // 255 - 0
const newLine = {
g: 7,
x: lastLine.x + state.specifics.G7.spotSize * (state.specifics.G7.dir === 1 ? 1 : -1),
y: lastLine.y,
z: lastLine.z,
a: lastLine.a,
e: lastLine.e,
f: lastLine.f,
s: intensity,
t: lastLine.t
}
addLineSegment(state, args, lastLine, newLine)
state.lastLine = newLine
}
},

G17: function (state, args) {
console.log('SETTING XY PLANE')
state.plane = 'G17'
addFakeSegment(state, args)
},

G18: function (state, args) {
console.log('SETTING XZ PLANE')
state.plane = 'G18'
addFakeSegment(state, args)
},

G19: function (state, args) {
console.log('SETTING YZ PLANE')
state.plane = 'G19'
addFakeSegment(state, args)
},

G20: function (state, args) {
// G21: Set Units to Inches
// We don't really have to do anything since 3d viewer is unit agnostic
// However, we need to set a global property so the trinket decorations
// like toolhead, axes, grid, and extent labels are scaled correctly
// later on when they are drawn after the gcode is rendered
// console.log("SETTING UNITS TO INCHES!!!")
state.unitsMm = false // false means inches cuz default is mm
addFakeSegment(state, args)
},

G21: function (state, args) {
// G21: Set Units to Millimeters
// Example: G21
// Units from now on are in millimeters. (This is the RepRap default.)
// console.log("SETTING UNITS TO MM!!!")
state.unitsMm = true
addFakeSegment(state, args)
},

G73: function (state, args, index, gcp) {
// peck drilling. just treat as g1
console.log('G73 gcp:', gcp)
gcp.handlers.G1(args)
},
G90: function (state, args) {
// G90: Set to Absolute Positioning
// Example: G90
// All coordinates from now on are absolute relative to the
// origin of the machine. (This is the RepRap default.)

state.relative = false
addFakeSegment(state, args)
},

G91: function (state, args) {
// G91: Set to Relative Positioning
// Example: G91
// All coordinates from now on are relative to the last position.

// TODO!
state.relative = true
addFakeSegment(state, args)
},

G92: function (state, args) { // E0
// G92: Set Position
// Example: G92 E0
// Allows programming of absolute zero point, by reseting the
// current position to the values specified. This would set the
// machine's X coordinate to 10, and the extrude coordinate to 90.
// No physical motion will occur.

// TODO: Only support E0
let newLine = state.lastLine
state.specifics.G92.offset.x = (args.x !== undefined ? (args.x === 0 ? newLine.x : newLine.x - args.x) : 0)
state.specifics.G92.offset.y = (args.y !== undefined ? (args.y === 0 ? newLine.y : newLine.y - args.y) : 0)
state.specifics.G92.offset.z = (args.z !== undefined ? (args.z === 0 ? newLine.z : newLine.z - args.z) : 0)
state.specifics.G92.offset.a = (args.a !== undefined ? (args.a === 0 ? newLine.a : newLine.a - args.a) : 0)
state.specifics.G92.offset.e = (args.e !== undefined ? (args.e === 0 ? newLine.e : newLine.e - args.e) : 0)

// newLine.x = args.x !== undefined ? args.x + newLine.x : newLine.x
// newLine.y = args.y !== undefined ? args.y + newLine.y : newLine.y
// newLine.z = args.z !== undefined ? args.z + newLine.z : newLine.z
// newLine.e = args.e !== undefined ? args.e + newLine.e : newLine.e

// console.log("G92", lastLine, newLine, state, args.specifics.G92.offset)

// state.lastLine = newLine
addFakeSegment(state, args)
},
M30: function (state, args) {
addFakeSegment(state, args)
},
M82: function (state, args) {
// M82: Set E codes absolute (default)
// Descriped in Sprintrun source code.

// No-op, so long as M83 is not supported.
addFakeSegment(state, args)
},

M84: function (state, args) {
// M84: Stop idle hold
// Example: M84
// Stop the idle hold on all axis and extruder. In some cases the
// idle hold causes annoying noises, which can be stopped by
// disabling the hold. Be aware that by disabling idle hold during
// printing, you will get quality issues. This is recommended only
// in between or after printjobs.

// No-op
addFakeSegment(state, args)
},

M649: function (state, args) {
// M649: Laser options for Marlin
// M649 S<Intensity> R<Spotsize> B2
// Intensity = lasermultiply?
if (typeof args.r !== 'undefined') { state.specifics.G7.spotSize = args.r }
},

// Dual Head 3D Printing Support
T0: function (state, args) {
// console.log('Found Tool: ', args)
state.lastLine.t = 0
addFakeSegment(state, args)
},

T1: function (state, args) {
// console.log('Found Tool: ', args)
state.lastLine.t = 1
addFakeSegment(state, args)
},

'default': function (state, args, index) {
addFakeSegment(state, args)
}
}

return handlers
}
Loading