Multi extruder support for GCODE viewer

Filament usage calculation per layer is still buggy though
This commit is contained in:
Gina Häußge 2014-01-01 02:37:44 +01:00
parent cec2bdb805
commit 084ffb0dc1
3 changed files with 381 additions and 372 deletions

View file

@ -11,22 +11,24 @@
var gCodeOptions = {
sortLayers: false,
purgeEmptyLayers: true,
analyzeModel: false
analyzeModel: false,
toolOffsets: [
{x: 0, y: 0},
{x: 0, y: -21.6}
]
};
var max = {x: undefined, y: undefined, z: undefined};
var min = {x: undefined, y: undefined, z: undefined};
var modelSize = {x: undefined, y: undefined, z: undefined};
var filamentByLayer = {};
var totalFilament=0;
var printTime=0;
var totalFilament = [0];
var printTime = 0;
var printTimeByLayer = {};
var layerHeight=0;
var layerHeight = 0;
var layerCnt = 0;
var speeds = {extrude: [], retract: [], move: []};
var speedsByLayer = {extrude: {}, retract: {}, move: {}};
var sendLayerToParent = function(layerNum, z, progress){
self.postMessage({
"cmd": "returnLayer",
@ -79,7 +81,7 @@
max: max,
min: min,
modelSize: modelSize,
totalFilament:totalFilament,
totalFilament: totalFilament,
filamentByLayer: filamentByLayer,
printTime: printTime,
layerHeight: layerHeight,
@ -106,95 +108,108 @@
layerCnt+=1;
}
}
// self.postMessage('LayerCnt: ' + layerCnt);
};
var analyzeModel = function(){
var i,j;
var x_ok=false, y_ok=false;
var cmds;
var tmp1= 0, tmp2=0;
var speedIndex=0;
var analyzeModel = function() {
var tmp1 = 0, tmp2 = 0;
var speedIndex = 0;
var type;
var printTimeAdd=0;
// var moveTime=0;
var printTimeAdd = 0;
for(i=0;i<model.length;i++){
cmds = model[i];
if(!cmds)continue;
for(j=0;j<cmds.length;j++){
x_ok=false;
y_ok=false;
if(typeof(cmds[j].x) !== 'undefined'&&typeof(cmds[j].prevX) !== 'undefined'&&typeof(cmds[j].extrude) !== 'undefined'&&cmds[j].extrude&&!isNaN(cmds[j].x))
{
max.x = parseFloat(max.x)>parseFloat(cmds[j].x)?parseFloat(max.x):parseFloat(cmds[j].x);
max.x = parseFloat(max.x)>parseFloat(cmds[j].prevX)?parseFloat(max.x):parseFloat(cmds[j].prevX);
min.x = parseFloat(min.x)<parseFloat(cmds[j].x)?parseFloat(min.x):parseFloat(cmds[j].x);
min.x = parseFloat(min.x)<parseFloat(cmds[j].prevX)?parseFloat(min.x):parseFloat(cmds[j].prevX);
x_ok=true;
for (var i = 0; i < model.length; i++) {
var cmds = model[i];
if(!cmds) continue;
for (var j = 0; j < cmds.length; j++) {
var tool = cmds[j].tool;
var x_ok = false;
var y_ok = false;
if (typeof(cmds[j].x) !== 'undefined'
&& typeof(cmds[j].prevX) !== 'undefined'
&& typeof(cmds[j].extrude) !== 'undefined'
&& cmds[j].extrude
&& !isNaN(cmds[j].x)) {
var x = cmds[j].x;
max.x = max.x !== undefined ? Math.max(max.x, x) : x;
min.x = min.x !== undefined ? Math.min(min.x, x) : x;
x_ok = true;
}
if(typeof(cmds[j].y) !== 'undefined'&&typeof(cmds[j].prevY) !== 'undefined'&&typeof(cmds[j].extrude) !== 'undefined'&&cmds[j].extrude&&!isNaN(cmds[j].y)){
max.y = parseFloat(max.y)>parseFloat(cmds[j].y)?parseFloat(max.y):parseFloat(cmds[j].y);
max.y = parseFloat(max.y)>parseFloat(cmds[j].prevY)?parseFloat(max.y):parseFloat(cmds[j].prevY);
min.y = parseFloat(min.y)<parseFloat(cmds[j].y)?parseFloat(min.y):parseFloat(cmds[j].y);
min.y = parseFloat(min.y)<parseFloat(cmds[j].prevY)?parseFloat(min.y):parseFloat(cmds[j].prevY);
y_ok=true;
if (typeof(cmds[j].y) !== 'undefined'
&& typeof(cmds[j].prevY) !== 'undefined'
&& typeof(cmds[j].extrude) !== 'undefined'
&& cmds[j].extrude
&& !isNaN(cmds[j].y)){
var y = cmds[j].y;
max.y = max.y !== undefined ? Math.max(max.y, y) : y;
min.y = min.y !== undefined ? Math.min(min.y, y) : y;
y_ok = true;
}
if(typeof(cmds[j].prevZ) !== 'undefined'&&typeof(cmds[j].extrude) !== 'undefined'&&cmds[j].extrude&&!isNaN(cmds[j].prevZ)){
max.z = parseFloat(max.z)>parseFloat(cmds[j].prevZ)?parseFloat(max.z):parseFloat(cmds[j].prevZ);
min.z = parseFloat(min.z)<parseFloat(cmds[j].prevZ)?parseFloat(min.z):parseFloat(cmds[j].prevZ);
if (typeof(cmds[j].prevZ) !== 'undefined'
&& typeof(cmds[j].extrude) !== 'undefined'
&& cmds[j].extrude
&& !isNaN(cmds[j].prevZ)) {
var z = cmds[j].prevZ;
max.z = max.z !== undefined ? Math.max(max.z, z) : z;
min.z = min.z !== undefined ? Math.min(min.z, z) : z;
}
if(typeof(cmds[j].extrude) !== 'undefined'||cmds[j].retract!=0){
totalFilament+=cmds[j].extrusion;
if(!filamentByLayer[cmds[j].prevZ])filamentByLayer[cmds[j].prevZ]=0;
filamentByLayer[cmds[j].prevZ]+=cmds[j].extrusion;
if (!totalFilament[tool]) totalFilament[tool] = 0;
if (!filamentByLayer[cmds[j].prevZ]) filamentByLayer[cmds[j].prevZ] = [0];
if (!filamentByLayer[cmds[j].prevZ][tool]) filamentByLayer[cmds[j].prevZ][tool] = 0;
if (cmds[j].extrusion) {
totalFilament[tool] += cmds[j].extrusion;
filamentByLayer[cmds[j].prevZ][tool] += cmds[j].extrusion;
}
if(x_ok&&y_ok){
printTimeAdd = Math.sqrt(Math.pow(parseFloat(cmds[j].x)-parseFloat(cmds[j].prevX),2)+Math.pow(parseFloat(cmds[j].y)-parseFloat(cmds[j].prevY),2))/(cmds[j].speed/60);
}else if(cmds[j].retract===0&&cmds[j].extrusion!==0){
tmp1 = Math.sqrt(Math.pow(parseFloat(cmds[j].x)-parseFloat(cmds[j].prevX),2)+Math.pow(parseFloat(cmds[j].y)-parseFloat(cmds[j].prevY),2))/(cmds[j].speed/60);
tmp2 = Math.abs(parseFloat(cmds[j].extrusion)/(cmds[j].speed/60));
printTimeAdd = tmp1>=tmp2?tmp1:tmp2;
}else if(cmds[j].retract!==0){
printTimeAdd = Math.abs(parseFloat(cmds[j].extrusion)/(cmds[j].speed/60));
if (x_ok && y_ok) {
printTimeAdd = Math.sqrt(Math.pow(cmds[j].x - cmds[j].prevX, 2) + Math.pow(cmds[j].y - cmds[j].prevY,2)) / (cmds[j].speed / 60);
} else if (cmds[j].retract === 0 && cmds[j].extrusion !== 0) {
tmp1 = Math.sqrt(Math.pow(cmds[j].x - cmds[j].prevX, 2) + Math.pow(cmds[j].y - cmds[j].prevY, 2)) / (cmds[j].speed/60);
tmp2 = Math.abs(cmds[j].extrusion / (cmds[j].speed / 60));
printTimeAdd = Math.max(tmp1, tmp2);
} else if (cmds[j].retract !== 0) {
printTimeAdd = Math.abs(cmds[j].extrusion / (cmds[j].speed/60));
}
printTime += printTimeAdd;
if(typeof(printTimeByLayer[cmds[j].prevZ])==='undefined'){printTimeByLayer[cmds[j].prevZ]=0;}
if (typeof(printTimeByLayer[cmds[j].prevZ]) === 'undefined') {
printTimeByLayer[cmds[j].prevZ] = 0;
}
printTimeByLayer[cmds[j].prevZ] += printTimeAdd;
if(cmds[j].extrude&&cmds[j].retract===0){
if (cmds[j].extrude && cmds[j].retract === 0){
type = 'extrude';
}else if(cmds[j].retract!==0){
} else if (cmds[j].retract !== 0) {
type = 'retract';
}else if(!cmds[j].extrude&&cmds[j].retract===0){
} else if (!cmds[j].extrude && cmds[j].retract === 0) {
type = 'move';
// if(cmds[j].prevZ == '17.1'){
// self.postMessage({cmd: 'Got speed ' + cmds[j].speed + 'with line ' + cmds[j].gcodeLine});
// }
}else {
} else {
self.postMessage({cmd: 'unknown type of move'});
type = 'unknown';
}
speedIndex = speeds[type].indexOf(cmds[j].speed);
if (speedIndex === -1) {
speeds[type].push(cmds[j].speed);
speedIndex = speeds[type].indexOf(cmds[j].speed);
}
if(typeof(speedsByLayer[type][cmds[j].prevZ]) === 'undefined'){
if (typeof(speedsByLayer[type][cmds[j].prevZ]) === 'undefined'){
speedsByLayer[type][cmds[j].prevZ] = [];
}
if(speedsByLayer[type][cmds[j].prevZ].indexOf(cmds[j].speed) === -1){
if (speedsByLayer[type][cmds[j].prevZ].indexOf(cmds[j].speed) === -1){
speedsByLayer[type][cmds[j].prevZ][speedIndex] = cmds[j].speed;
}
}
sendSizeProgress(i/model.length*100);
sendSizeProgress(i / model.length * 100);
}
purgeLayers();
@ -202,30 +217,39 @@
modelSize.x = Math.abs(max.x - min.x);
modelSize.y = Math.abs(max.y - min.y);
modelSize.z = Math.abs(max.z - min.z);
layerHeight = (max.z-min.z)/(layerCnt-1);
layerHeight = (max.z-min.z) / (layerCnt - 1);
sendAnalyzeDone();
};
var doParse = function(){
var argChar, numSlice;
model=[];
var sendLayer = undefined;
var sendLayerZ = 0;
var sendMultiLayer = [];
var sendMultiLayerZ = [];
var lastSend = 0;
// console.time("parseGCode timer");
var reg = new RegExp(/^(?:G0|G1)\s/i);
var comment = new RegExp()
var j, layer= 0, extrude=false, prevRetract= 0, retract=0, x, y, z=0, f, prevZ=0, prevX, prevY,lastF=4000, prev_extrude = {a: undefined, b: undefined, c: undefined, e: undefined, abs: undefined}, extrudeRelative=false;
var layer = 0;
var x, y, z = 0;
var prevX = 0, prevY = 0, prevZ = 0;
var f, lastF = 4000;
var extrude = false, extrudeRelative = false, retract = 0;
var positionRelative = false;
var dcExtrude=false;
var assumeNonDC = false;
for(var i=0;i<gcode.length;i++){
x=undefined;
y=undefined;
z=undefined;
var tool = 0;
var prev_extrude = [{a: 0, b: 0, c: 0, e: 0, abs: 0}];
var prev_retract = [0];
var offset = gCodeOptions.toolOffsets[0];
model = [];
for (var i=0; i < gcode.length; i++) {
x = undefined;
y = undefined;
z = undefined;
retract = 0;
var line = gcode[i].line;
@ -234,169 +258,242 @@
extrude=false;
line = line.split(/[\(;]/)[0];
if(reg.test(line)){
var addToModel = false;
var move = false;
var log = false;
if (/^(?:G0|G1)\s/i.test(line)) {
var args = line.split(/\s/);
for(j=0;j<args.length;j++){
for (var j = 0; j < args.length; j++) {
switch(argChar = args[j].charAt(0).toLowerCase()){
case 'x':
x=args[j].slice(1);
if (positionRelative) {
x = prevX + Number(args[j].slice(1)) + offset.x;
} else {
x = Number(args[j].slice(1)) + offset.x;
}
break;
case 'y':
y=args[j].slice(1);
if (positionRelative) {
y = prevY + Number(args[j].slice(1)) + offset.y;
} else {
y = Number(args[j].slice(1)) + offset.y;
}
break;
case 'z':
z=args[j].slice(1);
z = Number(z);
if(z == prevZ) continue;
if(z_heights.hasOwnProperty(z)){
layer = z_heights[z];
}else{
layer = model.length;
z_heights[z] = layer;
if (positionRelative) {
z = prevZ + Number(args[j].slice(1));
} else {
z = Number(args[j].slice(1));
}
sendLayer = layer;
sendLayerZ = z;
prevZ = z;
break;
case 'e':
case 'a':
case 'b':
case 'c':
case 'e' || 'a' || 'b' || 'c':
assumeNonDC = true;
numSlice = parseFloat(args[j].slice(1)).toFixed(3);
numSlice = Number(args[j].slice(1));
if(!extrudeRelative){
if (!extrudeRelative) {
// absolute extrusion positioning
prev_extrude["abs"] = parseFloat(numSlice)-parseFloat(prev_extrude[argChar]);
prev_extrude[tool]["abs"] = numSlice - prev_extrude[tool][argChar];
prev_extrude[tool][argChar] = numSlice;
} else {
prev_extrude[tool]["abs"] = numSlice;
prev_extrude[tool][argChar] += numSlice;
}
}else{
prev_extrude["abs"] = parseFloat(numSlice);
}
extrude = prev_extrude["abs"]>0;
if(prev_extrude["abs"]<0){
prevRetract = -1;
extrude = prev_extrude[tool]["abs"] > 0;
if (prev_extrude[tool]["abs"] < 0) {
prev_retract[tool] = -1;
retract = -1;
}
else if(prev_extrude["abs"]==0){
} else if (prev_extrude[tool]["abs"] == 0) {
retract = 0;
}else if(prev_extrude["abs"]>0&&prevRetract < 0){
prevRetract = 0;
} else if (prev_extrude[tool]["abs"] > 0 && prev_retract[tool] < 0) {
prev_retract[tool] = 0;
retract = 1;
} else {
retract = 0;
}
prev_extrude[argChar] = numSlice;
break;
case 'f':
numSlice = args[j].slice(1);
numSlice = parseFloat(args[j].slice(1));
lastF = numSlice;
break;
default:
break;
}
}
if(dcExtrude&&!assumeNonDC){
if (dcExtrude && !assumeNonDC) {
extrude = true;
prev_extrude["abs"] = Math.sqrt((prevX-x)*(prevX-x)+(prevY-y)*(prevY-y));
prev_extrude[tool]["abs"] = Math.sqrt((prevX - x) * (prevX - x) + (prevY - y) * (prevY - y));
}
if(!model[layer])model[layer]=[];
if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined'||retract!=0) model[layer][model[layer].length] = {x: Number(x), y: Number(y), z: Number(z), extrude: extrude, retract: Number(retract), noMove: false, extrusion: (extrude||retract)?Number(prev_extrude["abs"]):0, prevX: Number(prevX), prevY: Number(prevY), prevZ: Number(prevZ), speed: Number(lastF), gcodeLine: Number(i), percentage: percentage};
//{x: x, y: y, z: z, extrude: extrude, retract: retract, noMove: false, extrusion: (extrude||retract)?prev_extrude["abs"]:0, prevX: prevX, prevY: prevY, prevZ: prevZ, speed: lastF, gcodeLine: i};
if(typeof(x) !== 'undefined') prevX = x;
if(typeof(y) !== 'undefined') prevY = y;
} else if(line.match(/^(?:M82)/i)){
if (typeof(x) !== 'undefined' || typeof(y) !== 'undefined' || typeof(z) !== 'undefined' || retract != 0) {
addToModel = true;
move = true;
}
} else if (/^(?:M82)/i.test(line)) {
extrudeRelative = false;
}else if(line.match(/^(?:G91)/i)){
extrudeRelative=true;
}else if(line.match(/^(?:G90)/i)){
extrudeRelative=false;
}else if(line.match(/^(?:M83)/i)){
extrudeRelative=true;
}else if(line.match(/^(?:M101)/i)){
dcExtrude=true;
}else if(line.match(/^(?:M103)/i)){
dcExtrude=false;
}else if(line.match(/^(?:G92)/i)){
} else if (/^(?:G91)/i.test(line)) {
positionRelative = true;
extrudeRelative = true;
} else if (/^(?:G90)/i.test(line)) {
positionRelative = false;
extrudeRelative = false;
} else if (/^(?:M83)/i.test(line)) {
extrudeRelative = true;
} else if (/^(?:M101)/i.test(line)) {
dcExtrude = true;
} else if (/^(?:M103)/i.test(line)) {
dcExtrude = false;
} else if (/^(?:G92)/i.test(line)) {
var args = line.split(/\s/);
for(j=0;j<args.length;j++){
switch(argChar = args[j].charAt(0).toLowerCase()){
case 'x':
x=args[j].slice(1);
break;
case 'y':
y=args[j].slice(1);
break;
case 'z':
z=args[j].slice(1);
prevZ = z;
break;
case 'e'||'a'||'b'||'c':
numSlice = args[j].slice(1);
if(!extrudeRelative)
prev_extrude[argChar] = 0;
else {
prev_extrude[argChar] = numSlice;
}
break;
default:
break;
for (var j=0; j < args.length; j++) {
if (!args[j]) continue;
if (args.length == 1) {
// G92 without coordinates => reset all axes to 0
x = 0;
y = 0;
z = 0;
prev_extrude[tool]["e"] = 0;
prev_extrude[tool]["a"] = 0;
prev_extrude[tool]["b"] = 0;
prev_extrude[tool]["c"] = 0;
} else {
switch (argChar = args[j].charAt(0).toLowerCase()) {
case 'x':
x = Number(args[j].slice(1)) + offset.x;
break;
case 'y':
y = Number(args[j].slice(1)) + offset.y;
break;
case 'z':
z = Number(args[j].slice(1));
prevZ = z;
break;
case 'e'||'a'||'b'||'c':
numSlice = Number(args[j].slice(1));
if(!extrudeRelative)
prev_extrude[tool][argChar] = 0;
else {
prev_extrude[tool][argChar] = numSlice;
}
break;
default:
break;
}
}
}
if(!model[layer])model[layer]=[];
if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined') model[layer][model[layer].length] = {x: parseFloat(x), y: parseFloat(y), z: parseFloat(z), extrude: extrude, retract: parseFloat(retract), noMove: true, extrusion: (extrude||retract)?parseFloat(prev_extrude["abs"]):0, prevX: parseFloat(prevX), prevY: parseFloat(prevY), prevZ: parseFloat(prevZ), speed: parseFloat(lastF),gcodeLine: parseFloat(i), percentage: percentage};
}else if(line.match(/^(?:G28)/i)){
var args = line.split(/\s/);
for(j=0;j<args.length;j++){
switch(argChar = args[j].charAt(0).toLowerCase()){
case 'x':
x=args[j].slice(1);
break;
case 'y':
y=args[j].slice(1);
break;
case 'z':
z=args[j].slice(1);
z = Number(z);
if(z === prevZ)continue;
sendLayer = layer;
sendLayerZ = z;//}
if(z_heights.hasOwnProperty(z)){
layer = z_heights[z];
}else{
layer = model.length;
z_heights[z] = layer;
}
prevZ = z;
break;
default:
break;
}
}
// G28 with no arguments
if(args.length == 1){
//need to init values to default here
}
// if it's the first layer and G28 was without
if(layer==0&&typeof(z) === 'undefined'){
z=0;
if(z_heights.hasOwnProperty(z)){
layer = z_heights[z];
}else{
layer = model.length;
z_heights[z] = layer;
}
prevZ = z;
}
if(!model[layer])model[layer]=[];
if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined'||retract!=0) model[layer][model[layer].length] = {x: Number(x), y: Number(y), z: Number(z), extrude: extrude, retract: Number(retract), noMove: false, extrusion: (extrude||retract)?Number(prev_extrude["abs"]):0, prevX: Number(prevX), prevY: Number(prevY), prevZ: Number(prevZ), speed: Number(lastF), gcodeLine: Number(i), percentage: percentage};
if (typeof(x) !== 'undefined' || typeof(y) !== 'undefined' || typeof(z) !== 'undefined') {
addToModel = true;
move = false;
}
} else if (/^(?:G28)/i.test(line)) {
var args = line.split(/\s/);
if (args.length == 1) {
// G28 with no arguments => home all axis
x = 0;
y = 0;
z = 0;
} else {
for(j = 0; j < args.length; j++){
switch(argChar = args[j].charAt(0).toLowerCase()){
case 'x':
x = 0;
break;
case 'y':
y = 0;
break;
case 'z':
z = 0;
break;
default:
break;
}
}
}
// if it's the first layer and G28 was without z
if (layer == 0 && typeof(z) === 'undefined') {
z = 0;
}
if (typeof(x) !== 'undefined' || typeof(y) !== 'undefined' || typeof(z) !== 'undefined' || retract != 0) {
addToModel = true;
move = true;
}
} else if (/^(?:T\d+)/i.test(line)) {
tool = Number(line.split(/\s/)[0].slice(1));
if (!prev_extrude[tool]) prev_extrude[tool] = {a: 0, b: 0, c: 0, e: 0, abs: 0};
if (!prev_retract[tool]) prev_retract[tool] = 0;
offset = gCodeOptions.toolOffsets[tool];
}
if(typeof(sendLayer) !== "undefined"){
if(i-lastSend > gcode.length*0.02 && sendMultiLayer.length != 0){
if (typeof(z) !== 'undefined' && z != prevZ) {
if (z_heights[z]) {
layer = z_heights[z];
} else {
layer = model.length;
z_heights[z] = layer;
}
sendLayer = layer;
sendLayerZ = z;
prevZ = z;
} else if (typeof(z) == 'undefined' && typeof(prevZ) != 'undefined') {
if (z_heights.hasOwnProperty(prevZ)) {
layer = z_heights[prevZ];
} else {
layer = model.length;
z_heights[prevZ] = layer;
}
}
if (addToModel) {
if (!model[layer]) model[layer] = [];
model[layer].push({
x: x,
y: y,
z: z,
extrude: extrude,
retract: retract,
noMove: !move,
extrusion: (extrude || retract) && prev_extrude[tool]["abs"] ? prev_extrude[tool]["abs"] : 0,
prevX: prevX,
prevY: prevY,
prevZ: prevZ,
speed: lastF,
gcodeLine: i,
percentage: percentage,
tool: tool
});
}
if (move) {
if (typeof(x) !== 'undefined') prevX = x;
if (typeof(y) !== 'undefined') prevY = y;
}
if (typeof(sendLayer) !== "undefined") {
if (i - lastSend > gcode.length*0.02 && sendMultiLayer.length != 0){
lastSend = i;
sendMultiLayerToParent(sendMultiLayer, sendMultiLayerZ, i/gcode.length*100);
sendMultiLayerToParent(sendMultiLayer, sendMultiLayerZ, i / gcode.length * 100);
sendMultiLayer = [];
sendMultiLayerZ = [];
}
@ -406,7 +503,7 @@
sendLayerZ = undefined;
}
}
sendMultiLayerToParent(sendMultiLayer, sendMultiLayerZ, i/gcode.length*100);
sendMultiLayerToParent(sendMultiLayer, sendMultiLayerZ, i / gcode.length*100);
};
@ -414,16 +511,12 @@
gcode = message.gcode;
firstReport = message.options.firstReport;
doParse();
gcode = [];
self.postMessage({
"cmd": "returnModel",
"msg": {
// model: model
}
"msg": {}
});
};
var runAnalyze = function(message){
@ -446,6 +539,7 @@
speeds = {extrude: [], retract: [], move: []};
speedsByLayer = {extrude: {}, retract: {}, move: {}};
};
var setOption = function(options){
for(var opt in options){
gCodeOptions[opt] = options[opt];

View file

@ -15,7 +15,6 @@ GCODE.renderer = (function(){
var ctxHeight, ctxWidth;
var prevX=0, prevY=0;
// var colorGrid="#bbbbbb", colorLine="#000000";
var sliderHor, sliderVer;
var layerNumStore, progressStore={from: 0, to: -1};
var lastX, lastY;
@ -28,8 +27,8 @@ GCODE.renderer = (function(){
showRetracts: true,
colorGrid: "#bbbbbb",
extrusionWidth: 1,
// colorLine: ["#000000", "#aabb88", "#ffe7a0", "#6e7700", "#331a00", "#44ba97", "#08262f", "#db0e00", "#ff9977"],
colorLine: ["#000000", "#45c7ba", "#a9533a", "#ff44cc", "#dd1177", "#eeee22", "#ffbb55", "#ff5511", "#777788"],
// #000000", "#45c7ba", "#a9533a", "#ff44cc", "#dd1177", "#eeee22", "#ffbb55", "#ff5511", "#777788"
colorLine: ["#000000", "#3333cc", "#cc3333", "#33cc33", "#cc33cc"],
colorMove: "#00ff00",
colorRetract: "#ff0000",
colorRestart: "#0000ff",
@ -198,95 +197,77 @@ GCODE.renderer = (function(){
};
var drawLayer = function(layerNum, fromProgress, toProgress, isNextLayer){
var i, speedIndex= 0, prevZ = 0;
var i, speedIndex= 0;
isNextLayer = typeof isNextLayer !== 'undefined' ? isNextLayer : false;
if(!isNextLayer){
if (!isNextLayer) {
layerNumStore=layerNum;
progressStore = {from: fromProgress, to: toProgress};
}
if(!model||!model[layerNum])return;
if (!model || !model[layerNum]) return;
var cmds = model[layerNum];
var x, y;
// if(toProgress === -1){
// toProgress=cmds.length;
// }
if(fromProgress>0){
prevX = cmds[fromProgress-1].x*zoomFactor;
prevY = -cmds[fromProgress-1].y*zoomFactor;
}else if(fromProgress===0 && layerNum==0){
if(model[0]&&model[0].x !== undefined &&model[0].y !== undefined){
prevX = model[0].x*zoomFactor;
prevY = -model[0].y*zoomFactor;
}else {
if (fromProgress > 0) {
prevX = cmds[fromProgress-1].x * zoomFactor;
prevY = -cmds[fromProgress-1].y * zoomFactor;
} else if (fromProgress === 0 && layerNum == 0) {
if (model[0] && model[0].x !== undefined && model[0].y !== undefined) {
prevX = model[0].x * zoomFactor;
prevY = -model[0].y * zoomFactor;
} else {
prevX = 0;
prevY = 0;
}
}else if(typeof(cmds[0].prevX) !== 'undefined' && typeof(cmds[0].prevY) !== 'undefined'){
prevX = cmds[0].prevX*zoomFactor;
prevY = -cmds[0].prevY*zoomFactor;
}else{
if(model[layerNum-1]){
prevX=undefined;
prevY=undefined;
for(i=model[layerNum-1].length-1;i>=0;i--){
if(prevX === undefined && model[layerNum-1][i].x!==undefined)prevX=model[layerNum-1][i].x*zoomFactor;
if(prevY === undefined && model[layerNum-1][i].y!==undefined)prevY=-model[layerNum-1][i].y*zoomFactor;
} else if(typeof(cmds[0].prevX) !== 'undefined' && typeof(cmds[0].prevY) !== 'undefined') {
prevX = cmds[0].prevX * zoomFactor;
prevY = -cmds[0].prevY * zoomFactor;
} else {
if (model[layerNum-1]) {
prevX = undefined;
prevY = undefined;
for (i = model[layerNum-1].length-1; i >= 0; i--) {
if (prevX === undefined && model[layerNum-1][i].x !== undefined) prevX = model[layerNum-1][i].x * zoomFactor;
if (prevY === undefined && model[layerNum-1][i].y !== undefined) prevY =- model[layerNum-1][i].y * zoomFactor;
}
if(prevX === undefined)prevX=0;
if(prevY === undefined)prevY=0;
}else{
prevX=0;
prevY=0;
if (prevX === undefined) prevX=0;
if (prevY === undefined) prevY=0;
} else {
prevX = 0;
prevY = 0;
}
}
prevZ = GCODE.renderer.getZ(layerNum);
// ctx.strokeStyle = renderOptions["colorLine"];
for(i=fromProgress;i<=toProgress;i++){
for (i = fromProgress; i <= toProgress; i++) {
ctx.lineWidth = 1;
if(typeof(cmds[i]) === 'undefined')continue;
if (typeof(cmds[i]) === 'undefined') continue;
if(typeof(cmds[i].prevX) !== 'undefined' && typeof(cmds[i].prevY) !== 'undefined'){
prevX = cmds[i].prevX*zoomFactor;
prevY = -cmds[i].prevY*zoomFactor;
}
// console.log(cmds[i]);
if(typeof(cmds[i].x)==='undefined'||isNaN(cmds[i].x))x=prevX/zoomFactor;
else x = cmds[i].x;
if(typeof(cmds[i].y) === 'undefined'||isNaN(cmds[i].y))y=prevY/zoomFactor;
else y = -cmds[i].y;
if(renderOptions["differentiateColors"]&&!renderOptions['showNextLayer']){
// if(speedsByLayer['extrude'][prevZ]){
speedIndex = speeds['extrude'].indexOf(cmds[i].speed);
// speedIndex = GCODE.ui.ArrayIndexOf(speedsByLayer['extrude'][prevZ], function(obj) {return obj.speed === cmds[i].speed;});
// } else {
// speedIndex = -1;
// }
if(speedIndex === -1){
speedIndex = 0;
}else if(speedIndex > renderOptions["colorLine"].length -1){
speedIndex = speedIndex % (renderOptions["colorLine"].length-1);
// console.log("Too much colors");
}
}else if(renderOptions['showNextLayer']&&isNextLayer){
speedIndex=3;
}else{
speedIndex=0;
if (typeof(cmds[i].prevX) !== 'undefined' && typeof(cmds[i].prevY) !== 'undefined') {
prevX = cmds[i].prevX * zoomFactor;
prevY = -cmds[i].prevY * zoomFactor;
}
if (typeof(cmds[i].x) === 'undefined' || isNaN(cmds[i].x)) {
x = prevX / zoomFactor;
} else {
x = cmds[i].x;
}
if (typeof(cmds[i].y) === 'undefined' || isNaN(cmds[i].y)) {
y=prevY/zoomFactor;
} else {
y = -cmds[i].y;
}
if(!cmds[i].extrude&&!cmds[i].noMove){
// ctx.stroke();
if(cmds[i].retract == -1){
if(renderOptions["showRetracts"]){
ctx.strokeStyle = renderOptions["colorRetract"];
ctx.fillStyle = renderOptions["colorRetract"];
var alpha = renderOptions['showNextLayer'] && isNextLayer ? 0.5 : 1.0;
var shade = cmds[i].tool * 0.15;
if (!cmds[i].extrude && !cmds[i].noMove) {
if (cmds[i].retract == -1) {
if (renderOptions["showRetracts"]) {
ctx.strokeStyle = pusher.color(renderOptions["colorRetract"]).shade(shade).alpha(alpha).html();
ctx.fillStyle = pusher.color(renderOptions["colorRetract"]).shade(shade).alpha(alpha).html();
ctx.beginPath();
ctx.arc(prevX, prevY, renderOptions["sizeRetractSpot"], 0, Math.PI*2, true);
ctx.stroke();
@ -294,41 +275,33 @@ GCODE.renderer = (function(){
}
}
if(renderOptions["showMoves"]){
ctx.strokeStyle = renderOptions["colorMove"];
ctx.strokeStyle = pusher.color(renderOptions["colorMove"]).shade(shade).alpha(alpha).html();
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(x*zoomFactor,y*zoomFactor);
ctx.stroke();
}
// ctx.strokeStyle = renderOptions["colorLine"][0];
// ctx.beginPath();
// console.log("moveto: "+cmds[i].x+":"+cmds[i].y)
// ctx.moveTo(cmds[i].x*zoomFactor,cmds[i].y*zoomFactor);
}
else if(cmds[i].extrude){
if(cmds[i].retract==0){
ctx.strokeStyle = renderOptions["colorLine"][speedIndex];
} else if(cmds[i].extrude) {
if (cmds[i].retract == 0) {
ctx.strokeStyle = pusher.color(renderOptions["colorLine"][cmds[i].tool]).alpha(alpha).html();
ctx.lineWidth = renderOptions['extrusionWidth'];
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(x*zoomFactor,y*zoomFactor);
ctx.stroke();
}else {
if(renderOptions["showRetracts"]){
// ctx.stroke();
ctx.strokeStyle = renderOptions["colorRestart"];
ctx.fillStyle = renderOptions["colorRestart"];
} else {
if (renderOptions["showRetracts"]) {
ctx.strokeStyle = pusher.color(renderOptions["colorRestart"]).shade(shade).alpha(alpha).html();
ctx.fillStyle = pusher.color(renderOptions["colorRestart"]).shade(shade).alpha(alpha).html();
ctx.beginPath();
ctx.arc(prevX, prevY, renderOptions["sizeRetractSpot"], 0, Math.PI*2, true);
ctx.stroke();
ctx.fill();
// ctx.strokeStyle = renderOptions["colorLine"][0];
// ctx.beginPath();
}
}
}
prevX = x*zoomFactor;
prevY = y*zoomFactor;
prevX = x * zoomFactor;
prevY = y * zoomFactor;
}
ctx.stroke();
};
@ -360,17 +333,16 @@ GCODE.renderer = (function(){
drawGrid();
}else{
if(layerNum < model.length){
var p1 = ctx.transformedPoint(0,0);
var p2 = ctx.transformedPoint(canvas.width,canvas.height);
ctx.clearRect(p1.x,p1.y,p2.x-p1.x,p2.y-p1.y);
var p1 = ctx.transformedPoint(0, 0);
var p2 = ctx.transformedPoint(canvas.width, canvas.height);
ctx.clearRect(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y);
drawGrid();
// ctx.globalAlpha = 0.5;
if(renderOptions['showNextLayer'] && layerNum < model.length - 1) {
drawLayer(layerNum+1, 0, this.getLayerNumSegments(layerNum+1), true);
}
drawLayer(layerNum, fromProgress, toProgress);
}else{
console.log("Got request to render non-existent layer!!");
console.log("Got request to render non-existent layer");
}
}
},
@ -394,12 +366,11 @@ GCODE.renderer = (function(){
mdlInfo = GCODE.gCodeReader.getModelInfo();
speeds = mdlInfo.speeds;
speedsByLayer = mdlInfo.speedsByLayer;
// console.log(speeds);
// console.log(mdlInfo.min.x + ' ' + mdlInfo.modelSize.x);
offsetModelX = (gridSizeX/2-(mdlInfo.min.x+mdlInfo.modelSize.x/2))*zoomFactor;
offsetModelY = (mdlInfo.min.y+mdlInfo.modelSize.y/2)*zoomFactor-gridSizeY/2*zoomFactor;
if(ctx)ctx.translate(offsetModelX, offsetModelY);
if (!model[layerNum]) return;
this.render(layerNum, 0, model[layerNum].length);
},
getZ: function(layerNum){

View file

@ -21,67 +21,27 @@ GCODE.ui = (function(){
};
var chooseAccordion = function(id){
// debugger;
$('#'+id).collapse("show");
};
var setLinesColor = function(toggle){
// var i=0;
// for(i=gCodeLines.first;i<gCodeLines.last; i++){
// if(toggle){
// myCodeMirror.setLineClass(Number(i), null, "activeline");
// }else{
// myCodeMirror.setLineClass(Number(i), null, null);
// }
// }
}
var printLayerInfo = function(layerNum){
var z = GCODE.renderer.getZ(layerNum);
var segments = GCODE.renderer.getLayerNumSegments(layerNum);
var filament = GCODE.gCodeReader.getLayerFilament(z);
var layerSpeeds = GCODE.gCodeReader.getModelInfo().speedsByLayer;
var renderOptions = GCODE.renderer.getOptions();
var colors = renderOptions["colorLine"];
var speedIndex = 0;
var keys, type;
var showMove=false;
var i = 0;
var output = [];
output.push("Layer number: " + layerNum);
output.push("Layer height (mm): " + z);
output.push("GCODE commands in layer: " + segments);
output.push("Filament used by layer (mm): " + filament.toFixed(2));
output.push("Print time for layer: " + parseFloat(GCODE.gCodeReader.getModelInfo().printTimeByLayer[z]).toFixed(1) + "sec");
output.push("Extrude speeds:");
for(i=0;i<layerSpeeds['extrude'][z].length;i++){
if(typeof(layerSpeeds['extrude'][z][i])==='undefined'){continue;}
speedIndex = i;
if(speedIndex > colors.length -1){speedIndex = speedIndex % (colors.length-1);}
output.push("<div id='colorBox"+i+"' class='colorBox' style='background-color: "+colors[speedIndex] + "'></div> = " + (parseFloat(layerSpeeds['extrude'][z][i])/60).toFixed(2)+"mm/s");
}
if(typeof(layerSpeeds['move'][z]) !== 'undefined'){
output.push("Move speeds:");
for(i=0;i<layerSpeeds['move'][z].length;i++){
if(typeof(layerSpeeds['move'][z][i])==='undefined'){continue;}
speedIndex = i;
if(speedIndex > colors.length -1){speedIndex = speedIndex % (colors.length-1);}
output.push("<div id='colorBox"+i+"' class='colorBox' style='background-color: "+renderOptions['colorMove'] + "'></div> = " + (parseFloat(layerSpeeds['move'][z][i])/60).toFixed(2)+"mm/s");
}
}
if(typeof(layerSpeeds['retract'][z]) !== 'undefined'){
output.push("Retract speeds:");
for(i=0;i<layerSpeeds['retract'][z].length;i++){
if(typeof(layerSpeeds['retract'][z][i])==='undefined'){continue;}
speedIndex = i;
if(speedIndex > colors.length -1){speedIndex = speedIndex % (colors.length-1);}
output.push("<span style='color: " + renderOptions['colorRetract'] +"'>&#9679;</span> <span style='color: " + renderOptions['colorRestart'] +"'>&#9679;</span> = " +(parseFloat(layerSpeeds['retract'][z][i])/60).toFixed(2)+"mm/s");
if (filament.length == 1) {
output.push("Filament used by layer: " + filament[0].toFixed(2)) + "mm";
} else {
for (var i = 0; i < filament.length; i++) {
output.push("Filament used by layer (Tool " + i + "): " + filament[i].toFixed(2) + "mm");
}
}
output.push("Print time for layer: " + parseFloat(GCODE.gCodeReader.getModelInfo().printTimeByLayer[z]).toFixed(1) + "sec");
$('#layerInfo').html(output.join('<br>'));
// chooseAccordion('layerAccordionTab');
};
var handleFileSelect = function(evt) {
@ -136,9 +96,7 @@ GCODE.ui = (function(){
var progress = GCODE.renderer.getLayerNumSegments(val)-1;
GCODE.renderer.render(val,0, progress);
sliderHor.slider({max: progress, values: [0,progress]});
setLinesColor(false); //clear current selection
gCodeLines = GCODE.gCodeReader.getGCodeLines(val, sliderHor.slider("values",0), sliderHor.slider("values",1));
setLinesColor(true); // highlight lines
printLayerInfo(val);
};
@ -193,8 +151,7 @@ GCODE.ui = (function(){
setProgress('loadProgress', 100);
worker.postMessage({
"cmd":"analyzeModel",
"msg":{
}
"msg":{}
}
);
break;
@ -205,14 +162,19 @@ GCODE.ui = (function(){
GCODE.gCodeReader.processAnalyzeModelDone(data.msg);
GCODE.gCodeReader.passDataToRenderer();
initSliders();
resultSet.push("Model size is: " + data.msg.modelSize.x.toFixed(2) + 'x' + data.msg.modelSize.y.toFixed(2) + 'x' + data.msg.modelSize.z.toFixed(2)+'mm<br>');
resultSet.push("Total filament used: " + data.msg.totalFilament.toFixed(2) + "mm<br>");
resultSet.push("Estimated print time: " + parseInt(parseFloat(data.msg.printTime)/60/60) + ":" + parseInt((parseFloat(data.msg.printTime)/60)%60) + ":" + parseInt(parseFloat(data.msg.printTime)%60) + "<br>");
resultSet.push("Model size is: " + data.msg.modelSize.x.toFixed(2) + 'mm &times; ' + data.msg.modelSize.y.toFixed(2) + 'mm &times; ' + data.msg.modelSize.z.toFixed(2)+'mm<br>');
if (data.msg.totalFilament.length == 0) {
resultSet.push("Total filament used: " + data.msg.totalFilament.toFixed(2) + "mm<br>");
} else {
for (var i = 0; i < data.msg.totalFilament.length; i++) {
resultSet.push("Total filament used (Tool " + i + "): " + data.msg.totalFilament[i].toFixed(2) + "mm<br>");
}
}
resultSet.push("Estimated print time: " + formatDuration(data.msg.printTime) + "<br>");
resultSet.push("Estimated layer height: " + data.msg.layerHeight.toFixed(2) + "mm<br>");
resultSet.push("Layer count: " + data.msg.layerCnt.toFixed(0) + "printed, " + data.msg.layerTotal.toFixed(0) + 'visited<br>');
resultSet.push("Layer count: " + data.msg.layerCnt.toFixed(0) + " printed, " + data.msg.layerTotal.toFixed(0) + " visited<br>");
document.getElementById('list').innerHTML = resultSet.join('');
chooseAccordion('infoAccordionTab');
$('#myTab a[href="#tab2d"]').tab('show');
break;
case 'returnLayer':
GCODE.gCodeReader.processLayerFromWorker(data.msg);
@ -239,7 +201,6 @@ GCODE.ui = (function(){
});
if(!Modernizr.canvas)fatal.push("<li>Your browser doesn't seem to support HTML5 Canvas, this application won't work without it.</li>");
//if(!Modernizr.filereader)fatal.push("<li>Your browser doesn't seem to support HTML5 File API, this application won't work without it.</li>");
if(!Modernizr.webworkers)fatal.push("<li>Your browser doesn't seem to support HTML5 Web Workers, this application won't work without it.</li>");
if(!Modernizr.svg)fatal.push("<li>Your browser doesn't seem to support HTML5 SVG, this application won't work without it.</li>");
@ -307,20 +268,6 @@ GCODE.ui = (function(){
if(document.getElementById('purgeEmptyLayersCheckbox').checked)GCODE.gCodeReader.setOption({purgeEmptyLayers: true});
else GCODE.gCodeReader.setOption({purgeEmptyLayers: false});
if(document.getElementById('showGCodeCheckbox').checked)showGCode = true;
else showGCode = false;
// if(document.getElementById('sortLayersCheckbox').checked) worker.postMessage({"cmd":"setOption", "msg":{sortLayers: true}});
// else worker.postMessage({"cmd":"setOption", "msg":{sortLayers: false}});
//
// if(document.getElementById('purgeEmptyLayersCheckbox').checked)worker.postMessage({"cmd":"setOption", "msg":{purgeEmptyLayers: true}});
// else worker.postMessage({"cmd":"setOption", "msg":{purgeEmptyLayers: false}});
// if(document.getElementById('analyzeModelCheckbox').checked)worker.postMessage({"cmd":"setOption", "msg":{analyzeModel: true}});
// else worker.postMessage({"cmd":"setOption", "msg":{analyzeModel: false}});
if(document.getElementById('moveModelCheckbox').checked)GCODE.renderer.setOption({moveModel: true});
else GCODE.renderer.setOption({moveModel: false});
@ -330,9 +277,6 @@ GCODE.ui = (function(){
if(document.getElementById('showRetractsCheckbox').checked)GCODE.renderer.setOption({showRetracts: true});
else GCODE.renderer.setOption({showRetracts: false});
if(document.getElementById('differentiateColorsCheckbox').checked)GCODE.renderer.setOption({differentiateColors: true});
else GCODE.renderer.setOption({differentiateColors: false});
var widthMod = 2;
if(Number($('#widthModifier').attr('value'))) {widthMod = Number($('#widthModifier').attr('value'));}
if(document.getElementById('thickExtrusionCheckbox').checked)GCODE.renderer.setOption({extrusionWidth: widthMod});