Skip to content

Commit

Permalink
First cut of GCode viewer. Actually works!
Browse files Browse the repository at this point in the history
Includes:
- Basic UI structure
- WebGL rendering (using three.js)
- Mouse operations to rotate (hold down 'S' and mouse move to zoom)
- GCode parser
- Interpretation of 'G1' GCode instruction, which is enough to show a
  pretty good model.
  • Loading branch information
Joe Walnes committed Mar 31, 2012
0 parents commit 973cb08
Show file tree
Hide file tree
Showing 9 changed files with 76,052 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
*.swp
4,476 changes: 4,476 additions & 0 deletions web/examples/15mm_cube.gcode

Large diffs are not rendered by default.

25,592 changes: 25,592 additions & 0 deletions web/examples/octocat.gcode

Large diffs are not rendered by default.

44,305 changes: 44,305 additions & 0 deletions web/examples/part.gcode

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions web/index.html
@@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>GCode Viewer</title>
<link rel="stylesheet" href="lib/bootstrap.min.css">
<style>
#renderArea {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 40px;
}
</style>
<script src="lib/jquery-1.7.1.min.js"></script>
<script src="lib/Three.js"></script>
<script src="viewer.js"></script>
</head>
<body>

<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<span class="brand" href="#">GCode Viewer</span>
<ul class="nav">
<li><a href="#help">Open File</a></li>
<li><a href="#help">Help</a></li>
<li><a href="#help">GitHub</a></li>
</ul>
<ul class="nav pull-right">
<li><a href="http://twitter.com/joewalnes">@joewalnes</a></li>
</ul>
</div>
</div>
</div>

<div id="renderArea"></div>
</body>
</html>
794 changes: 794 additions & 0 deletions web/lib/Three.js

Large diffs are not rendered by default.

632 changes: 632 additions & 0 deletions web/lib/bootstrap.min.css

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions web/lib/jquery-1.7.1.min.js

Large diffs are not rendered by default.

208 changes: 208 additions & 0 deletions web/viewer.js
@@ -0,0 +1,208 @@
function error(msg) {
alert(msg);
}

function loadFile(path, callback /* function(contents) */) {
$.get(path, null, callback, 'text')
.error(function() { error() });
}

function parseGCode(gcode, handlers) {
var abort = false;
gcode.split('\n').forEach(function(line, i) {
if (abort) {
return;
}
line = line.replace(/;.*$/, '').trim(); // Remove comments
if (line) {
var tokens = line.split(' ');
if (tokens) {
var cmd = tokens[0];
var args = {};
tokens.splice(1).forEach(function(token) {
var key = token[0].toLowerCase();
var value = parseFloat(token.substring(1));
args[key] = value;
});
var handler = handlers[tokens[0]];
if (handler) {
var result = handler(args, i + 1);
if (result === false) {
abort = true;
return;
}
} else {
error('Unsupported GCode command at line ' + (i + 1) + ': ' + tokens[0]);
abort = true;
return;
}
}
}
});
}

function createObjectFromGCode(gcode) {
// GCode descriptions come from:
// http://reprap.org/wiki/G-code
// http://en.wikipedia.org/wiki/G-code
// SprintRun source code

var object = new THREE.Object3D();

var geometry = new THREE.Geometry();

parseGCode(gcode, {

G1: function(args, line) {
// 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.

if (args.x !== undefined && args.y !== undefined && args.z !== undefined) {
geometry.vertices.push(new THREE.Vertex(
new THREE.Vector3(args.x, args.y, args.z)));
}
},

G21: function(args) {
// G21: Set Units to Millimeters
// Example: G21
// Units from now on are in millimeters. (This is the RepRap default.)

// No-op: So long as G20 is not supported.
},

G90: function(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.)

// TODO!
},

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

// TODO!
},

G92: function(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
},

M82: function(args) {
// M82: Set E codes absolute (default)
// Descriped in Sprintrun source code.

// No-op, so long as M83 is not supported.
},

M84: function(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
},
});

var lineMaterial = new THREE.LineBasicMaterial({color:0xFFFFFF, opacity:0.2, linewidth: 1});
object.add(new THREE.Line(geometry, lineMaterial));

// Center
geometry.computeBoundingBox();
var center = new THREE.Vector3()
.add(geometry.boundingBox.min, geometry.boundingBox.max)
.divideScalar(2);
var scale = 3; // TODO: Auto size
object.position = center.multiplyScalar(-scale);
object.scale.multiplyScalar(scale);

return object;
}

function createScene(element) {

// Renderer
var renderer = new THREE.WebGLRenderer({clearColor:0x000000, clearAlpha: 1});
renderer.setSize(element.width(), element.height());
element.append(renderer.domElement);
renderer.clear();

// Scene
var scene = new THREE.Scene();

// Lights...
[[0,0,1, 0xFFFFCC],
[0,1,0, 0xFFCCFF],
[1,0,0, 0xCCFFFF],
[0,0,-1, 0xCCCCFF],
[0,-1,0, 0xCCFFCC],
[-1,0,0, 0xFFCCCC]].forEach(function(position) {
var light = new THREE.DirectionalLight(position[3]);
light.position.set(position[0], position[1], position[2]).normalize();
scene.add(light);
});

// Camera...
var fov = 45,
aspect = element.width() / element.height(),
near = 1,
far = 10000,
camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
//camera.rotationAutoUpdate = true;
//camera.position.x = 0;
//camera.position.y = 500;
camera.position.z = 300;
//camera.lookAt(scene.position);
scene.add(camera);
controls = new THREE.TrackballControls(camera);
controls.noPan = true;
controls.dynamicDampingFactor = 0.15;

// Action!
function render() {
controls.update();
renderer.render(scene, camera);

requestAnimationFrame(render); // And repeat...
}
render();

// Fix coordinates up if window is resized.
$(window).on('resize', function() {
renderer.setSize(element.width(), element.height());
camera.aspect = element.width() / element.height();
camera.updateProjectionMatrix();
controls.screen.width = window.innerWidth;
controls.screen.height = window.innerHeight;
});

return scene;
}

$(function() {
var scene = createScene($('#renderArea'));
loadFile('./examples/octocat.gcode', function(gcode) {
scene.add(createObjectFromGCode(gcode));
});
});

0 comments on commit 973cb08

Please sign in to comment.