Skip to content

Commit 07b3e4a

Browse files
committed
Initial implementation of slicer detection and parsing of needed info from it. Calculate line width from filament diameter, nozzle size and layer height.
1 parent dfd25d3 commit 07b3e4a

File tree

5 files changed

+108
-12
lines changed

5 files changed

+108
-12
lines changed

README

+5-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1-
gCodeVisualizer - a web-based visual gcode analyzer
1+
gCodeVisualizer - a web-based visual gcode viewer and analyzer.
2+
Available online at http://gcode.ws/
3+
4+
If you want to use it locally with chrome - you will need to add "--allow-file-access-from-files" command line parameter,
5+
which is unsafe (and you should never browse internet with that option "on").

index.html

+5-3
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@
176176
<label for="moveModelCheckbox"><input type="checkbox" id="moveModelCheckbox" value="3" onclick="GCODE.ui.processOptions()" checked> Move model to the center of the grid</label>
177177
<label for="differentiateColorsCheckbox"><input type="checkbox" id="differentiateColorsCheckbox" value="7" onclick="GCODE.ui.processOptions()" checked> Show different speeds with different colors</label>
178178
<label for="thickExtrusionCheckbox"><input type="checkbox" id="thickExtrusionCheckbox" value="8" onclick="GCODE.ui.processOptions()"> Emulate extrusion width</label>
179-
<label for="widthModifier">Width modifier: <input type="text" value="2" id="widthModifier" onchange="GCODE.ui.processOptions()"/></label>
179+
<label for="alphaCheckbox"><input type="checkbox" id="alphaCheckbox" value="10" onclick="GCODE.ui.processOptions()" > Render lines slightly transparent</label>
180+
<!--<label for="widthModifier">Width modifier: <input type="text" value="2" id="widthModifier" onchange="GCODE.ui.processOptions()"/></label>-->
180181
<label for="showNextLayer"><input type="checkbox" id="showNextLayer" value="9" onclick="GCODE.ui.processOptions()" > Show +1 layer</label>
181182
</div>
182183
</div>
@@ -251,8 +252,9 @@ <h1>gCodeViewer</h1>
251252
<li>Show retracts and restarts</li>
252253
<li>Show print/move/retract speeds</li>
253254
<li>Display only part of layer, animate sequence of layer printing</li>
254-
<li><b>NEW!!</b> Show two layers simultaneously so you can check overhangs</li>
255-
<li><b>NEW!!</b> Adjust line width to simulate print more closely</li>
255+
<li>Show two layers simultaneously so you can check overhangs</li>
256+
<li>Adjust line width to simulate print more closely</li>
257+
<li><b>Gcode viewer will try to parse nozzle and filament diameters from gcode, but it may fail to do so. In that case you will need to set it manually in 'Printer Info' tab</b></li>
256258
</ul>
257259
</li>
258260
<li>Analyze GCode

js/gCodeReader.js

+72-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ GCODE.gCodeReader = (function(){
2121
var layerCnt = 0;
2222
var layerTotal = 0;
2323
var speeds = {};
24+
var slicer = 'unknown';
2425
var speedsByLayer = {};
2526
var gCodeOptions = {
2627
sortLayers: false,
@@ -88,6 +89,69 @@ GCODE.gCodeReader = (function(){
8889
}
8990
};
9091

92+
var getParamsFromKISSlicer = function(gcode){
93+
var nozzle = gcode.match(/extrusion_width_mm\s*=\s*(\d*\.\d+)/m);
94+
if(nozzle){
95+
gCodeOptions['nozzleDia'] = nozzle[1];
96+
}
97+
var filament = gcode.match(/fiber_dia_mm\s*=\s*(\d*\.\d+)/m);
98+
if(filament){
99+
gCodeOptions['filamentDia'] = filament[1];
100+
}
101+
}
102+
103+
var getParamsFromSlic3r = function(gcode){
104+
var nozzle = gcode.match(/nozzle_diameter\s*=\s*(\d*\.\d+)/m);
105+
if(nozzle){
106+
gCodeOptions['nozzleDia'] = nozzle[1];
107+
}
108+
var filament = gcode.match(/filament_diameter\s*=\s*(\d*\.\d+)/m);
109+
if(filament){
110+
gCodeOptions['filamentDia'] = filament[1];
111+
}
112+
}
113+
114+
var getParamsFromSkeinforge =function(gcode){
115+
116+
var nozzle = gcode.match(/nozzle_diameter\s*=\s*(\d*\.\d+)/m);
117+
if(nozzle){
118+
gCodeOptions['nozzleDia'] = nozzle[1];
119+
}
120+
var filament = gcode.match(/Filament_Diameter_(mm)\s*:\s*(\d*\.\d+)/m);
121+
if(filament){
122+
gCodeOptions['filamentDia'] = filament[1];
123+
}
124+
}
125+
126+
var getParamsFromMiracleGrue = function(gcode){
127+
128+
}
129+
130+
var getParamsFromCura = function(gcode){
131+
132+
}
133+
134+
var detectSlicer = function(gcode){
135+
136+
if(gcode.match(/Slic3r/)){
137+
slicer = 'Slic3r';
138+
getParamsFromSlic3r(gcode);
139+
}else if(gcode.match(/KISSlicer/)){
140+
slicer = 'KISSlicer';
141+
getParamsFromKISSlicer(gcode);
142+
}else if(gcode.match(/skeinforge/)){
143+
slicer = 'skeinforge';
144+
getParamsFromSkeinforge(gcode);
145+
}else if(gcode.match(/Cura/)){
146+
slicer = 'cura';
147+
getParamsFromCura(gcode);
148+
}else if(gcode.match(/Miracle/)){
149+
slicer = 'makerbot';
150+
getParamsFromMiracleGrue(gcode);
151+
}
152+
153+
}
154+
91155

92156

93157
// ***** PUBLIC *******
@@ -97,7 +161,7 @@ GCODE.gCodeReader = (function(){
97161
// console.log("loadFile");
98162
model = [];
99163
z_heights = [];
100-
164+
detectSlicer(reader.target.result);
101165
lines = reader.target.result.split(/\n/);
102166
reader.target.result = null;
103167
// prepareGCode();
@@ -170,6 +234,13 @@ GCODE.gCodeReader = (function(){
170234
density = 1.24;
171235
}
172236
totalWeight = 3.141*gCodeOptions['filamentDia']/10*gCodeOptions['filamentDia']/10/4*totalFilament/10;
237+
238+
gCodeOptions['wh'] = parseFloat(gCodeOptions['nozzleDia'])/parseFloat(layerHeight);
239+
if(slicer === 'Slic3r'){
240+
// slic3r stores actual nozzle diameter, but extrusion is usually slightly thicker, here we compensate for that
241+
// kissslicer stores actual extrusion width - so no need for that.
242+
gCodeOptions['wh'] = gCodeOptions['wh']*1.1;
243+
}
173244
},
174245
getLayerFilament: function(z){
175246
return filamentByLayer[z];

js/renderer.js

+13-3
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ GCODE.renderer = (function(){
3737
modelCenter: {x: 0, y: 0},
3838
moveModel: true,
3939
differentiateColors: true,
40-
showNextLayer: false
40+
showNextLayer: false,
41+
alpha: false,
42+
actualWidth: false
4143
};
4244

4345
var offsetModelX=0, offsetModelY=0;
@@ -46,10 +48,15 @@ GCODE.renderer = (function(){
4648

4749

4850
var reRender = function(){
51+
var gCodeOpts = GCODE.gCodeReader.getOptions();
4952
var p1 = ctx.transformedPoint(0,0);
5053
var p2 = ctx.transformedPoint(canvas.width,canvas.height);
5154
ctx.clearRect(p1.x,p1.y,p2.x-p1.x,p2.y-p1.y);
5255
drawGrid();
56+
if(renderOptions['alpha']){ctx.globalAlpha = 0.6;}
57+
else {ctx.globalAlpha = 1;}
58+
if(renderOptions['actualWidth']){renderOptions['extrusionWidth'] = gCodeOpts['filamentDia']*gCodeOpts['wh']/zoomFactor;}
59+
else {renderOptions['extrusionWidth'] = gCodeOpts['filamentDia']*gCodeOpts['wh']/zoomFactor/2;}
5360
if(renderOptions['showNextLayer'] && layerNumStore < model.length - 1) {
5461
drawLayer(layerNumStore+1, 0, GCODE.renderer.getLayerNumSegments(layerNumStore+1), true);
5562
}
@@ -355,6 +362,7 @@ GCODE.renderer = (function(){
355362
return model;
356363
},
357364
render: function(layerNum, fromProgress, toProgress){
365+
var gCodeOpts = GCODE.gCodeReader.getOptions();
358366
if(!initialized)this.init();
359367
if(!model){
360368
drawGrid();
@@ -364,7 +372,10 @@ GCODE.renderer = (function(){
364372
var p2 = ctx.transformedPoint(canvas.width,canvas.height);
365373
ctx.clearRect(p1.x,p1.y,p2.x-p1.x,p2.y-p1.y);
366374
drawGrid();
367-
// ctx.globalAlpha = 0.5;
375+
if(renderOptions['alpha']){ctx.globalAlpha = 0.6;}
376+
else {ctx.globalAlpha = 1;}
377+
if(renderOptions['actualWidth']){renderOptions['extrusionWidth'] = gCodeOpts['filamentDia']*gCodeOpts['wh']/zoomFactor;}
378+
else {renderOptions['extrusionWidth'] = gCodeOpts['filamentDia']*gCodeOpts['wh']/zoomFactor/2;}
368379
if(renderOptions['showNextLayer'] && layerNum < model.length - 1) {
369380
drawLayer(layerNum+1, 0, this.getLayerNumSegments(layerNum+1), true);
370381
}
@@ -399,7 +410,6 @@ GCODE.renderer = (function(){
399410
offsetModelX = (gridSizeX/2-(mdlInfo.min.x+mdlInfo.modelSize.x/2))*zoomFactor;
400411
offsetModelY = (mdlInfo.min.y+mdlInfo.modelSize.y/2)*zoomFactor-gridSizeY/2*zoomFactor;
401412
if(ctx)ctx.translate(offsetModelX, offsetModelY);
402-
403413
this.render(layerNum, 0, model[layerNum].length);
404414
},
405415
getZ: function(layerNum){

js/ui.js

+13-4
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ GCODE.ui = (function(){
220220
printModelInfo();
221221
printLayerInfo(0);
222222
chooseAccordion('infoAccordionTab');
223+
GCODE.ui.updateOptions();
223224
$('#myTab').find('a[href="#tab2d"]').tab('show');
224225
break;
225226
case 'returnLayer':
@@ -347,10 +348,11 @@ GCODE.ui = (function(){
347348
if(document.getElementById('differentiateColorsCheckbox').checked)GCODE.renderer.setOption({differentiateColors: true});
348349
else GCODE.renderer.setOption({differentiateColors: false});
349350

350-
var widthMod = 2;
351-
if(Number($('#widthModifier').attr('value'))) {widthMod = Number($('#widthModifier').attr('value'));}
352-
if(document.getElementById('thickExtrusionCheckbox').checked)GCODE.renderer.setOption({extrusionWidth: widthMod});
353-
else GCODE.renderer.setOption({extrusionWidth: 1});
351+
if(document.getElementById('thickExtrusionCheckbox').checked)GCODE.renderer.setOption({actualWidth: true});
352+
else GCODE.renderer.setOption({actualWidth: false});
353+
354+
if(document.getElementById('alphaCheckbox').checked)GCODE.renderer.setOption({alpha: true});
355+
else GCODE.renderer.setOption({alpha: false});
354356

355357
if(document.getElementById('showNextLayer').checked)GCODE.renderer.setOption({showNextLayer: true});
356358
else GCODE.renderer.setOption({showNextLayer: false});
@@ -365,6 +367,13 @@ GCODE.ui = (function(){
365367

366368
if(document.getElementById('plasticABS').checked)GCODE.gCodeReader.setOption({filamentType: "ABS"});
367369
if(document.getElementById('plasticPLA').checked)GCODE.gCodeReader.setOption({filamentType: "PLA"});
370+
},
371+
372+
updateOptions: function(){
373+
var gcodeOptions = GCODE.gCodeReader.getOptions();
374+
375+
document.getElementById('nozzleDia').value = gcodeOptions['nozzleDia'];
376+
document.getElementById('filamentDia').value = gcodeOptions['filamentDia'];
368377
}
369378
}
370379
}());

0 commit comments

Comments
 (0)