Skip to content

Commit 5cf44f1

Browse files
committed
Optimized memory usage (instead of 1.2G on 30Mb gcode firefox only uses 470mb now). Refactored speed coloring thing.
1 parent ec2c938 commit 5cf44f1

File tree

8 files changed

+964
-98
lines changed

8 files changed

+964
-98
lines changed

bootstrap.html

+11-2
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@
33
<head>
44
<title></title>
55
<link rel="stylesheet" type="text/css" href="css/cupertino/jquery-ui-1.9.0.custom.css" media="screen" />
6-
<link rel="stylesheet" type="text/css" href="css/bootstrap.css" media="screen" />
6+
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" media="screen" />
7+
<link rel="stylesheet" type="text/css" href="lib/codemirror.css" media="screen" />
78
<link rel="stylesheet" type="text/css" href="css/style.css" media="screen" />
89
<script type="text/javascript" src="lib/jquery-1.8.2.js"></script>
910
<script type="text/javascript" src="lib/jquery-ui-1.9.0.custom.js"></script>
1011

12+
<script type="text/javascript" src="lib/codemirror.js"></script>
13+
<script type="text/javascript" src="lib/mode_gcode/gcode_mode.js"></script>
1114
<script type="text/javascript" src="lib/three.js"></script>
12-
<script type="text/javascript" src="lib/bootstrap.js"></script>
15+
<script type="text/javascript" src="lib/bootstrap/bootstrap-transition.js"></script>
16+
<script type="text/javascript" src="lib/bootstrap/bootstrap-tab.js"></script>
17+
<script type="text/javascript" src="lib/bootstrap/bootstrap-collapse.js"></script>
1318
<script type="text/javascript" src="lib/modernizr.custom.09684.js"></script>
1419
<script type="text/javascript" src="lib/TrackballControls.js"></script>
1520
<script type="text/javascript" src="js/ui.js"></script>
@@ -131,6 +136,7 @@
131136
<ul id="myTab" class="nav nav-tabs">
132137
<li class="active"><a href="#tab2d" data-toggle="tab">2D</a></li>
133138
<li class=""><a href="#tab3d" data-toggle="tab">3D</a></li>
139+
<li class=""><a href="#tabGCode" data-toggle="tab">GCode</a></li>
134140
</ul>
135141
<div class="tab-content">
136142
<div class="tab-pane active" id="tab2d">
@@ -141,6 +147,9 @@
141147
<div class="tab-pane" id="tab3d">
142148
<div id="3d_container"></div>
143149
</div>
150+
<div class="tab-pane" id="tabGCode">
151+
<div id="gCodeContainer"></div>
152+
</div>
144153
</div>
145154
</div>
146155
</div>

css/bootstrap.min.css

+836-9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@
119119
These require re-analyzing file:<br>
120120
<input type="checkbox" id="sortLayersCheckbox" value="4" onclick="GCODE.ui.processOptions()" checked>Sort layers by Z</input><br>
121121
<input type="checkbox" id="purgeEmptyLayersCheckbox" value="5" onclick="GCODE.ui.processOptions()" checked>Hide empty layers</input><br>
122-
<input type="checkbox" id="analyzeModelCheckbox" value="6" onclick="GCODE.ui.processOptions()" checked>Analyze size and filament usage</input><br>
122+
<input type="checkbox" id="showGCodeCheckbox" value="6" onclick="GCODE.ui.processOptions()" checked>Show GCode in GCode tab (memory intensive!)</input><br>
123123
</div>
124124
</div>
125125
</div>

js/Worker.js

+55-44
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
* Time: 12:18 PM
55
*/
66

7-
var GCODE = {}
8-
9-
GCODE.worker = (function(){
107
var gcode;
118
var firstReport;
129
var z_heights = {};
@@ -24,8 +21,8 @@ GCODE.worker = (function(){
2421
var printTime=0;
2522
var layerHeight=0;
2623
var layerCnt = 0;
27-
var speeds = [];
28-
var speedsByLayer = {};
24+
var speeds = {extrude: [], retract: [], move: []};
25+
var speedsByLayer = {extrude: {}, retract: {}, move: {}};
2926

3027

3128
var sendLayerToParent = function(layerNum, z, progress){
@@ -103,7 +100,7 @@ GCODE.worker = (function(){
103100
for(j=0;j<cmds.length;j++){
104101
x_ok=false;
105102
y_ok=false;
106-
if(typeof(cmds[j].x) !== 'undefined'&&typeof(cmds[j].prevX) !== 'undefined'&&typeof(cmds[j].extrude) !== 'undefined'&&cmds[j].extrude)
103+
if(typeof(cmds[j].x) !== 'undefined'&&typeof(cmds[j].prevX) !== 'undefined'&&typeof(cmds[j].extrude) !== 'undefined'&&cmds[j].extrude&&!isNaN(cmds[j].x))
107104
{
108105
max.x = parseFloat(max.x)>parseFloat(cmds[j].x)?parseFloat(max.x):parseFloat(cmds[j].x);
109106
max.x = parseFloat(max.x)>parseFloat(cmds[j].prevX)?parseFloat(max.x):parseFloat(cmds[j].prevX);
@@ -112,15 +109,15 @@ GCODE.worker = (function(){
112109
x_ok=true;
113110
}
114111

115-
if(typeof(cmds[j].y) !== 'undefined'&&typeof(cmds[j].prevY) !== 'undefined'&&typeof(cmds[j].extrude) !== 'undefined'&&cmds[j].extrude){
112+
if(typeof(cmds[j].y) !== 'undefined'&&typeof(cmds[j].prevY) !== 'undefined'&&typeof(cmds[j].extrude) !== 'undefined'&&cmds[j].extrude&&!isNaN(cmds[j].y)){
116113
max.y = parseFloat(max.y)>parseFloat(cmds[j].y)?parseFloat(max.y):parseFloat(cmds[j].y);
117114
max.y = parseFloat(max.y)>parseFloat(cmds[j].prevY)?parseFloat(max.y):parseFloat(cmds[j].prevY);
118115
min.y = parseFloat(min.y)<parseFloat(cmds[j].y)?parseFloat(min.y):parseFloat(cmds[j].y);
119116
min.y = parseFloat(min.y)<parseFloat(cmds[j].prevY)?parseFloat(min.y):parseFloat(cmds[j].prevY);
120117
y_ok=true;
121118
}
122119

123-
if(typeof(cmds[j].prevZ) !== 'undefined'&&typeof(cmds[j].extrude) !== 'undefined'&&cmds[j].extrude){
120+
if(typeof(cmds[j].prevZ) !== 'undefined'&&typeof(cmds[j].extrude) !== 'undefined'&&cmds[j].extrude&&!isNaN(cmds[j].prevZ)){
124121
max.z = parseFloat(max.z)>parseFloat(cmds[j].prevZ)?parseFloat(max.z):parseFloat(cmds[j].prevZ);
125122
min.z = parseFloat(min.z)<parseFloat(cmds[j].prevZ)?parseFloat(min.z):parseFloat(cmds[j].prevZ);
126123
}
@@ -141,25 +138,29 @@ GCODE.worker = (function(){
141138
printTime += Math.abs(parseFloat(cmds[j].extrusion)/(cmds[j].speed/60));
142139
}
143140

144-
speedIndex = speeds.indexOf(cmds[j].speed);
141+
if(cmds[j].extrude&&cmds[j].retract===0){
142+
type = 'extrude';
143+
}else if(cmds[j].retract!==0){
144+
type = 'retract';
145+
}else if(!cmds[j].extrude&&cmds[j].retract===0){
146+
type = 'move';
147+
// if(cmds[j].prevZ == '17.1'){
148+
// self.postMessage({cmd: 'Got speed ' + cmds[j].speed + 'with line ' + cmds[j].gcodeLine});
149+
// }
150+
}else {
151+
self.postMessage({cmd: 'unknown type of move'});
152+
type = 'unknown';
153+
}
154+
speedIndex = speeds[type].indexOf(cmds[j].speed);
145155
if (speedIndex === -1) {
146-
speeds.push(cmds[j].speed);
147-
speedIndex = speeds.indexOf(cmds[j].speed);
156+
speeds[type].push(cmds[j].speed);
157+
speedIndex = speeds[type].indexOf(cmds[j].speed);
148158
}
149-
if(typeof(speedsByLayer[cmds[j].prevZ]) === 'undefined'){
150-
speedsByLayer[cmds[j].prevZ] = [];
159+
if(typeof(speedsByLayer[type][cmds[j].prevZ]) === 'undefined'){
160+
speedsByLayer[type][cmds[j].prevZ] = [];
151161
}
152-
if(speedsByLayer[cmds[j].prevZ].indexOf(cmds[j].speed) === -1){
153-
if(cmds[j].extrude&&cmds[j].retract===0){
154-
type = 'extrude';
155-
}else if(cmds[j].retract!==0){
156-
type = 'retract';
157-
}else if(!cmds[j].extrude&&cmds[j].retract===0){
158-
type = 'move';
159-
}else {
160-
type = 'unknown';
161-
}
162-
speedsByLayer[cmds[j].prevZ][speedIndex] = {speed: cmds[j].speed, type: type};
162+
if(speedsByLayer[type][cmds[j].prevZ].indexOf(cmds[j].speed) === -1){
163+
speedsByLayer[type][cmds[j].prevZ][speedIndex] = cmds[j].speed;
163164
}
164165

165166
}
@@ -171,7 +172,6 @@ GCODE.worker = (function(){
171172
modelSize.x = Math.abs(max.x - min.x);
172173
modelSize.y = Math.abs(max.y - min.y);
173174
modelSize.z = Math.abs(max.z - min.z);
174-
self.postMessage('max: ' + max.z + "min = " + min.z);
175175
layerHeight = (max.z-min.z)/(layerCnt-1);
176176

177177
sendAnalyzeDone();
@@ -191,6 +191,7 @@ GCODE.worker = (function(){
191191
x=undefined;
192192
y=undefined;
193193
z=undefined;
194+
retract = 0;
194195

195196

196197
extrude=false;
@@ -205,9 +206,15 @@ GCODE.worker = (function(){
205206
switch(argChar = args[j].charAt(0).toLowerCase()){
206207
case 'x':
207208
x=args[j].slice(1);
209+
// if(x === prevX){
210+
// x=undefined;
211+
// }
208212
break;
209213
case 'y':
210214
y=args[j].slice(1);
215+
// if(y===prevY){
216+
// y=undefined;
217+
// }
211218
break;
212219
case 'z':
213220
z=args[j].slice(1);
@@ -226,7 +233,7 @@ GCODE.worker = (function(){
226233
prevZ = z;
227234
break;
228235
case 'e'||'a'||'b'||'c':
229-
numSlice = args[j].slice(1);
236+
numSlice = parseFloat(args[j].slice(1)).toFixed(3);
230237
if(!extrudeRelative){
231238
// absolute extrusion positioning
232239
prev_extrude["abs"] = parseFloat(numSlice)-parseFloat(prev_extrude[argChar]);
@@ -261,7 +268,8 @@ GCODE.worker = (function(){
261268
}
262269
}
263270
if(!model[layer])model[layer]=[];
264-
if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined'||retract!=0) model[layer][model[layer].length] = {x: x, y: y, z: z, extrude: extrude, retract: retract, extrusion: (extrude||retract)?prev_extrude["abs"]:0, prevX: prevX, prevY: prevY, prevZ: prevZ, speed: lastF, gcodeLine: i};
271+
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)};
272+
//{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};
265273
if(typeof(x) !== 'undefined') prevX = x;
266274
if(typeof(y) !== 'undefined') prevY = y;
267275
} else if(gcode[i].match(/^(?:M82)/i)){
@@ -299,14 +307,14 @@ GCODE.worker = (function(){
299307
}
300308
}
301309
if(!model[layer])model[layer]=[];
302-
if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined') model[layer][model[layer].length] = {x: x, y: y, z: z, extrude: extrude, retract: retract, noMove: true, extrusion: (extrude||retract)?prev_extrude["abs"]:0, prevX: prevX, prevY: prevY, prevZ: prevZ, speed: lastF,gcodeLine: i};
310+
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)};
303311
}else if(gcode[i].match(/^(?:G28)/i)){
304312
x=0, y=0,z=0,prevZ=0, extrude=false;
305313
if(typeof(prevX) === 'undefined'){prevX=0;}
306314
if(typeof(prevY) === 'undefined'){prevY=0;}
307315

308316
if(!model[layer])model[layer]=[];
309-
if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined') model[layer][model[layer].length] = {x: x, y: y, z: z, extrude: extrude, retract: retract, extrusion: (extrude||retract)?prev_extrude["abs"]:0, prevX: prevX, prevY: prevY, prevZ: prevZ, speed: lastF, gcodeLine: i};
317+
if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined') model[layer][model[layer].length] = {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};
310318
}
311319
if(typeof(sendLayer) !== "undefined"){
312320
sendLayerToParent(sendLayer, sendLayerZ, i/gcode.length*100);
@@ -319,45 +327,48 @@ GCODE.worker = (function(){
319327
};
320328

321329

322-
return {
323-
parseGCode: function(message){
330+
var parseGCode = function(message){
324331
gcode = message.gcode;
325332
firstReport = message.options.firstReport;
326333

327334

328335
doParse();
336+
gcode = [];
329337
self.postMessage({
330338
"cmd": "returnModel",
331339
"msg": {
332340
// model: model
333341
}
334342
});
335343

336-
},
337-
runAnalyze: function(message){
338-
analyzeModel();
339-
},
340-
setOption: function(options){
344+
};
345+
346+
var runAnalyze = function(message){
347+
analyzeModel();
348+
model = [];
349+
z_heights = [];
350+
filamentByLayer = [];
351+
speeds = [];
352+
speedsByLayer = [];
353+
};
354+
var setOption = function(options){
341355
for(var opt in options){
342356
gCodeOptions[opt] = options[opt];
343357
}
344-
}
345-
}
346-
}());
347-
358+
};
348359

349360
onmessage = function (e){
350361
var data = e.data;
351-
362+
// for some reason firefox doesn't garbage collect when something inside closures is deleted, so we delete and recreate whole object eaech time
352363
switch (data.cmd) {
353364
case 'parseGCode':
354-
GCODE.worker.parseGCode(data.msg);
365+
parseGCode(data.msg);
355366
break;
356367
case 'setOption':
357-
GCODE.worker.setOption(data.msg);
368+
setOption(data.msg);
358369
break;
359370
case 'analyzeModel':
360-
GCODE.worker.runAnalyze(data.msg);
371+
runAnalyze(data.msg);
361372
break;
362373

363374
default:

js/gCodeReader.js

+15-10
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ GCODE.gCodeReader = (function(){
1414
var modelSize = {x: undefined, y: undefined, z: undefined};
1515
var filamentByLayer = {};
1616
var totalFilament=0;
17-
var speeds = [];
17+
var printTime=0;
18+
var speeds = {};
1819
var speedsByLayer = {};
1920
var gCodeOptions = {
2021
sortLayers: false,
@@ -83,6 +84,7 @@ GCODE.gCodeReader = (function(){
8384
z_heights = [];
8485

8586
lines = reader.target.result.split(/\n/);
87+
reader.target.result = null;
8688
// prepareGCode();
8789

8890
worker.postMessage({
@@ -95,6 +97,8 @@ GCODE.gCodeReader = (function(){
9597
}
9698
}
9799
);
100+
delete lines;
101+
98102

99103

100104
},
@@ -112,15 +116,14 @@ GCODE.gCodeReader = (function(){
112116

113117
},
114118
processLayerFromWorker: function(msg){
115-
var cmds = msg.cmds;
116-
var layerNum = msg.layerNum;
117-
var zHeightObject = msg.zHeightObject;
118-
var isEmpty = msg.isEmpty;
119+
// var cmds = msg.cmds;
120+
// var layerNum = msg.layerNum;
121+
// var zHeightObject = msg.zHeightObject;
122+
// var isEmpty = msg.isEmpty;
119123
// console.log(zHeightObject);
120-
model[layerNum] = cmds;
121-
z_heights[zHeightObject.zValue] = zHeightObject.layer;
122-
// GCODE.renderer.doRender(model, layerNum);
123-
124+
model[msg.layerNum] = msg.cmds;
125+
z_heights[msg.zHeightObject.zValue] = msg.zHeightObject.layer;
126+
// GCODE.renderer.doRender(model, msg.layerNum);
124127
},
125128
processAnalyzeModelDone: function(msg){
126129
min = msg.min;
@@ -130,6 +133,7 @@ GCODE.gCodeReader = (function(){
130133
filamentByLayer = msg.filamentByLayer;
131134
speeds = msg.speeds;
132135
speedsByLayer = msg.speedsByLayer;
136+
printTime = msg.printTime;
133137
},
134138
getLayerFilament: function(z){
135139
return filamentByLayer[z];
@@ -144,7 +148,8 @@ GCODE.gCodeReader = (function(){
144148
modelSize: modelSize,
145149
totalFilament: totalFilament,
146150
speeds: speeds,
147-
speedsByLayer: speedsByLayer
151+
speedsByLayer: speedsByLayer,
152+
printTime: printTime
148153
};
149154
},
150155
getGCodeLines: function(layer, fromSegments, toSegments){

js/renderer.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,12 @@ GCODE.renderer = (function(){
241241
if(!cmds[i].y)y=prevY/zoomFactor;
242242
else y = -cmds[i].y;
243243
if(renderOptions["differentiateColors"]){
244-
if(speedsByLayer[prevZ]){
245-
speedIndex = GCODE.ui.ArrayIndexOf(speedsByLayer[prevZ], function(obj) {return obj.speed === cmds[i].speed;});
246-
} else {
247-
speedIndex = -1;
248-
}
244+
// if(speedsByLayer['extrude'][prevZ]){
245+
speedIndex = speeds['extrude'].indexOf(cmds[i].speed);
246+
// speedIndex = GCODE.ui.ArrayIndexOf(speedsByLayer['extrude'][prevZ], function(obj) {return obj.speed === cmds[i].speed;});
247+
// } else {
248+
// speedIndex = -1;
249+
// }
249250
if(speedIndex === -1){
250251
speedIndex = 0;
251252
}else if(speedIndex > renderOptions["colorLine"].length -1){

0 commit comments

Comments
 (0)