Moved octoprint sources to "src" folder, adjusted setup.py and run script accordingly

This commit is contained in:
Gina Häußge 2013-09-15 21:45:31 +02:00
parent a87541c354
commit 51ae782f02
133 changed files with 1699 additions and 1670 deletions

View file

@ -1,2 +1,2 @@
recursive-include octoprint/static * recursive-include src/octoprint/static *
recursive-include octoprint/templates * recursive-include src/octoprint/templates *

View file

@ -1 +0,0 @@

View file

@ -6,3 +6,5 @@ PyYAML==3.10
Flask-Login==0.2.2 Flask-Login==0.2.2
Flask-Principal==0.3.5 Flask-Principal==0.3.5
netaddr>=0.7.10 netaddr>=0.7.10
mock>=1.0.1
nose>=1.3.0

View file

@ -5,7 +5,6 @@ sockjs-tornado>=1.0.0
PyYAML==3.10 PyYAML==3.10
Flask-Login==0.2.2 Flask-Login==0.2.2
Flask-Principal==0.3.5 Flask-Principal==0.3.5
numpy>=1.6.2
pyserial>=2.6 pyserial>=2.6
netaddr>=0.7.10 netaddr>=0.7.10
mock>=1.0.1 mock>=1.0.1

75
run
View file

@ -1,65 +1,16 @@
#!/usr/bin/env python #!/usr/bin/env python
print """
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!! You are using an old startup method for OctoPrint. !!!
!!! Please perform 'sudo python setup.py install' and !!!
!!! use the 'octoprint' executable instead. !!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
"""
import sys import sys
from octoprint.daemon import Daemon sys.path.append("src")
from octoprint.server import Server
class Main(Daemon): import octoprint
def __init__(self, pidfile, configfile, basedir, host, port, debug): octoprint.main()
Daemon.__init__(self, pidfile)
self._configfile = configfile
self._basedir = basedir
self._host = host
self._port = port
self._debug = debug
def run(self):
octoprint = Server(self._configfile, self._basedir, self._host, self._port, self._debug)
octoprint.run()
def main():
import argparse
parser = argparse.ArgumentParser(prog="run")
parser.add_argument("-d", "--debug", action="store_true", dest="debug",
help="Enable debug mode")
parser.add_argument("--host", action="store", type=str, dest="host",
help="Specify the host on which to bind the server")
parser.add_argument("--port", action="store", type=int, dest="port",
help="Specify the port on which to bind the server")
parser.add_argument("-c", "--config", action="store", dest="config",
help="Specify the config file to use. OctoPrint needs to have write access for the settings dialog to work. Defaults to ~/.octoprint/config.yaml")
parser.add_argument("-b", "--basedir", action="store", dest="basedir",
help="Specify the basedir to use for uploads, timelapses etc. OctoPrint needs to have write access. Defaults to ~/.octoprint")
parser.add_argument("--daemon", action="store", type=str, choices=["start", "stop", "restart"],
help="Daemonize/control daemonized OctoPrint instance (only supported under Linux right now)")
parser.add_argument("--pid", action="store", type=str, dest="pidfile", default="/tmp/octoprint.pid",
help="Pidfile to use for daemonizing, defaults to /tmp/octoprint.pid")
parser.add_argument("--iknowwhatimdoing", action="store_true", dest="allowRoot",
help="Allow OctoPrint to run as user root")
args = parser.parse_args()
if args.daemon:
if sys.platform == "darwin" or sys.platform == "win32":
print >> sys.stderr, "Sorry, daemon mode is only supported under Linux right now"
sys.exit(2)
daemon = Main(args.pidfile, args.config, args.basedir, args.host, args.port, args.debug)
if "start" == args.daemon:
daemon.start()
elif "stop" == args.daemon:
daemon.stop()
elif "restart" == args.daemon:
daemon.restart()
else:
octoprint = Server(args.config, args.basedir, args.host, args.port, args.debug, args.allowRoot)
octoprint.run()
if __name__ == "__main__":
main()

0
octoprint.init → scripts/octoprint.init Executable file → Normal file
View file

View file

@ -3,7 +3,7 @@
from setuptools import setup, find_packages from setuptools import setup, find_packages
VERSION = "0.1.0" VERSION = "1.1.0-dev"
def params(): def params():
name = "OctoPrint" name = "OctoPrint"
@ -34,11 +34,23 @@ def params():
url = "http://octoprint.org" url = "http://octoprint.org"
license = "AGPLv3" license = "AGPLv3"
packages = find_packages() packages = find_packages(where="src")
package_dir = {"octoprint": "src/octoprint"}
include_package_data = True include_package_data = True
zip_safe = False zip_safe = False
install_requires = open("requirements.txt").read().split("\n") install_requires = open("requirements.txt").read().split("\n")
entry_points = {
"console_scripts": [
"octoprint = octoprint:main"
]
}
#scripts = {
# "scripts/octoprint.init": "/etc/init.d/octoprint"
#}
return locals() return locals()
setup(**params()) setup(**params())

66
src/octoprint/__init__.py Normal file
View file

@ -0,0 +1,66 @@
#!/usr/bin/env python
import sys
from octoprint.daemon import Daemon
from octoprint.server import Server
class Main(Daemon):
def __init__(self, pidfile, configfile, basedir, host, port, debug):
Daemon.__init__(self, pidfile)
self._configfile = configfile
self._basedir = basedir
self._host = host
self._port = port
self._debug = debug
def run(self):
octoprint = Server(self._configfile, self._basedir, self._host, self._port, self._debug)
octoprint.run()
def main():
import argparse
parser = argparse.ArgumentParser(prog="run")
parser.add_argument("-d", "--debug", action="store_true", dest="debug",
help="Enable debug mode")
parser.add_argument("--host", action="store", type=str, dest="host",
help="Specify the host on which to bind the server")
parser.add_argument("--port", action="store", type=int, dest="port",
help="Specify the port on which to bind the server")
parser.add_argument("-c", "--config", action="store", dest="config",
help="Specify the config file to use. OctoPrint needs to have write access for the settings dialog to work. Defaults to ~/.octoprint/config.yaml")
parser.add_argument("-b", "--basedir", action="store", dest="basedir",
help="Specify the basedir to use for uploads, timelapses etc. OctoPrint needs to have write access. Defaults to ~/.octoprint")
parser.add_argument("--daemon", action="store", type=str, choices=["start", "stop", "restart"],
help="Daemonize/control daemonized OctoPrint instance (only supported under Linux right now)")
parser.add_argument("--pid", action="store", type=str, dest="pidfile", default="/tmp/octoprint.pid",
help="Pidfile to use for daemonizing, defaults to /tmp/octoprint.pid")
parser.add_argument("--iknowwhatimdoing", action="store_true", dest="allowRoot",
help="Allow OctoPrint to run as user root")
args = parser.parse_args()
if args.daemon:
if sys.platform == "darwin" or sys.platform == "win32":
print >> sys.stderr, "Sorry, daemon mode is only supported under Linux right now"
sys.exit(2)
daemon = Main(args.pidfile, args.config, args.basedir, args.host, args.port, args.debug)
if "start" == args.daemon:
daemon.start()
elif "stop" == args.daemon:
daemon.stop()
elif "restart" == args.daemon:
daemon.restart()
else:
octoprint = Server(args.config, args.basedir, args.host, args.port, args.debug, args.allowRoot)
octoprint.run()
if __name__ == "__main__":
main()

View file

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 135 KiB

View file

Before

Width:  |  Height:  |  Size: 890 B

After

Width:  |  Height:  |  Size: 890 B

View file

Before

Width:  |  Height:  |  Size: 112 B

After

Width:  |  Height:  |  Size: 112 B

View file

@ -1,161 +1,161 @@
/*body,*/ /*body,*/
/*#wrap {*/ /*#wrap {*/
/*width:1000px;*/ /*width:1000px;*/
/*height: 680px;*/ /*height: 680px;*/
/*position: absolute;*/ /*position: absolute;*/
/*top: 50%;*/ /*top: 50%;*/
/*margin-top: -350px;*/ /*margin-top: -350px;*/
/*left: 50%;*/ /*left: 50%;*/
/*margin-left: -500px;*/ /*margin-left: -500px;*/
/**/ /**/
/*background:#ffffff;*/ /*background:#ffffff;*/
/*border: 5px outset #bbb;*/ /*border: 5px outset #bbb;*/
/*-moz-border-radius: 5px;*/ /*-moz-border-radius: 5px;*/
/*-webkit-border-radius: 5px;*/ /*-webkit-border-radius: 5px;*/
/*border-radius: 5px;*/ /*border-radius: 5px;*/
/*}*/ /*}*/
/*#control {*/ /*#control {*/
/*float:left;*/ /*float:left;*/
/*width:300px;*/ /*width:300px;*/
/*margin-top: 10px;*/ /*margin-top: 10px;*/
/*margin-left: 10px;*/ /*margin-left: 10px;*/
/*background:#ffffff;*/ /*background:#ffffff;*/
/*margin-right: 10px;*/ /*margin-right: 10px;*/
/*height: 680px;*/ /*height: 680px;*/
/*}*/ /*}*/
#file_block { #file_block {
/*margin-top: 20px;*/ /*margin-top: 20px;*/
/*margin-left: 20px;*/ /*margin-left: 20px;*/
} }
#control_bottom { #control_bottom {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
width: 300px; width: 300px;
margin-bottom: 10px; margin-bottom: 10px;
} }
#options{ #options{
float: left; float: left;
margin-left: 5px; margin-left: 5px;
margin-bottom: 5px; margin-bottom: 5px;
} }
/*#gcode { /*#gcode {
background: #ffffff; background: #ffffff;
float:right; float:right;
width: 680px; width: 680px;
height: 680px; height: 680px;
border-width: 2px; border-width: 2px;
border-style: none none none solid; border-style: none none none solid;
}*/ }*/
#canvas{ #canvas{
/*float: left;*/ /*float: left;*/
clear:none; clear:none;
} }
#drop_zone { #drop_zone {
border: 2px dashed #bbb; border: 2px dashed #bbb;
-moz-border-radius: 5px; -moz-border-radius: 5px;
-webkit-border-radius: 5px; -webkit-border-radius: 5px;
border-radius: 5px; border-radius: 5px;
padding: 40px; padding: 40px;
margin: 5px; margin: 5px;
text-align: center; text-align: center;
font: 20pt bold; font: 20pt bold;
color: #bbb color: #bbb
} }
#slider-vertical { #slider-vertical {
/*position: absolute;*/ /*position: absolute;*/
/*right: 0;*/ /*right: 0;*/
/*top: 0;*/ /*top: 0;*/
height: 580px; height: 580px;
width: 10px; width: 10px;
float: right; float: right;
} }
#slider-horizontal { #slider-horizontal {
height: 10px; height: 10px;
width: 570px; width: 570px;
/*position: absolute;*/ /*position: absolute;*/
/*bottom: 0;*/ /*bottom: 0;*/
} }
#main_button_block { #main_button_block {
/*float: right;*/ /*float: right;*/
margin-bottom: 5px; margin-bottom: 5px;
margin-right: 5px; margin-right: 5px;
} }
#gcode .mbut{ #gcode .mbut{
height:60px; height:60px;
width: 250px; width: 250px;
font-size: 1em; font-size: 1em;
} }
#tabs-min { #tabs-min {
height: 680px; height: 680px;
padding: 0px; padding: 0px;
} }
#gcode .mtab{ #gcode .mtab{
background: transparent; background: transparent;
border: none; border: none;
font-weight: normal; font-weight: normal;
font-size: 0.5em; font-size: 0.5em;
} }
#gcode .mtab-defstate{ #gcode .mtab-defstate{
background: transparent; background: transparent;
border: none; border: none;
} }
#gcode .mtab-content{ #gcode .mtab-content{
background: #ffffff; background: #ffffff;
background-image: none; background-image: none;
border: 0px none #dddddd; border: 0px none #dddddd;
border-bottom-style: none; border-bottom-style: none;
margin: 0px; margin: 0px;
} }
#gcode .bar { #gcode .bar {
-webkit-transition: width 0s linear !important; -webkit-transition: width 0s linear !important;
-moz-transition: width 0s linear !important; -moz-transition: width 0s linear !important;
-o-transition: width 0s linear !important; -o-transition: width 0s linear !important;
transition: width 0s linear !important; transition: width 0s linear !important;
} }
#gcode .nav { #gcode .nav {
margin-bottom: 0px !important; margin-bottom: 0px !important;
} }
#gcode .tab-content { #gcode .tab-content {
overflow: visible; overflow: visible;
} }
#gcode .aboutpage { #gcode .aboutpage {
margin: 10px; margin: 10px;
} }
#accordion_top .ui-accordion-content{ #accordion_top .ui-accordion-content{
padding: 5px; padding: 5px;
} }
#tabs-min .ui-tabs-panel { #tabs-min .ui-tabs-panel {
padding: 0px; padding: 0px;
} }
#progressBlock { #progressBlock {
margin-left: 10px; margin-left: 10px;
margin-right: 10px; margin-right: 10px;
margin-bottom: 10px; margin-bottom: 10px;
} }
#gcode .colorBox { #gcode .colorBox {
width: 50px; width: 50px;
height: 15px; height: 15px;
border: 1px solid #000000; border: 1px solid #000000;
float:left; float:left;
} }
#gcode .activeline {background: #fff0b6 !important;} #gcode .activeline {background: #fff0b6 !important;}

View file

@ -1,473 +1,473 @@
/** /**
* User: hudbrog (hudbrog@gmail.com) * User: hudbrog (hudbrog@gmail.com)
* Date: 10/24/12 * Date: 10/24/12
* Time: 12:18 PM * Time: 12:18 PM
*/ */
var gcode; var gcode;
var firstReport; var firstReport;
var z_heights = {}; var z_heights = {};
var model = []; var model = [];
var gCodeOptions = { var gCodeOptions = {
sortLayers: false, sortLayers: false,
purgeEmptyLayers: true, purgeEmptyLayers: true,
analyzeModel: false analyzeModel: false
}; };
var max = {x: undefined, y: undefined, z: undefined}; var max = {x: undefined, y: undefined, z: undefined};
var min = {x: undefined, y: undefined, z: undefined}; var min = {x: undefined, y: undefined, z: undefined};
var modelSize = {x: undefined, y: undefined, z: undefined}; var modelSize = {x: undefined, y: undefined, z: undefined};
var filamentByLayer = {}; var filamentByLayer = {};
var totalFilament=0; var totalFilament=0;
var printTime=0; var printTime=0;
var printTimeByLayer = {}; var printTimeByLayer = {};
var layerHeight=0; var layerHeight=0;
var layerCnt = 0; var layerCnt = 0;
var speeds = {extrude: [], retract: [], move: []}; var speeds = {extrude: [], retract: [], move: []};
var speedsByLayer = {extrude: {}, retract: {}, move: {}}; var speedsByLayer = {extrude: {}, retract: {}, move: {}};
var sendLayerToParent = function(layerNum, z, progress){ var sendLayerToParent = function(layerNum, z, progress){
self.postMessage({ self.postMessage({
"cmd": "returnLayer", "cmd": "returnLayer",
"msg": { "msg": {
cmds: model[layerNum], cmds: model[layerNum],
layerNum: layerNum, layerNum: layerNum,
zHeightObject: {zValue: z, layer: z_heights[z]}, zHeightObject: {zValue: z, layer: z_heights[z]},
isEmpty: false, isEmpty: false,
progress: progress progress: progress
} }
}); });
}; };
var sendMultiLayerToParent = function(layerNum, z, progress){ var sendMultiLayerToParent = function(layerNum, z, progress){
var tmpModel = []; var tmpModel = [];
var tmpZHeight = {}; var tmpZHeight = {};
for(var i=0;i<layerNum.length;i++){ for(var i=0;i<layerNum.length;i++){
tmpModel[layerNum[i]] = model[layerNum[i]]; tmpModel[layerNum[i]] = model[layerNum[i]];
tmpZHeight[layerNum[i]] = z_heights[z[i]]; tmpZHeight[layerNum[i]] = z_heights[z[i]];
} }
self.postMessage({ self.postMessage({
"cmd": "returnMultiLayer", "cmd": "returnMultiLayer",
"msg": { "msg": {
model: tmpModel, model: tmpModel,
layerNum: layerNum, layerNum: layerNum,
zHeightObject: {zValue: z, layer: tmpZHeight}, zHeightObject: {zValue: z, layer: tmpZHeight},
isEmpty: false, isEmpty: false,
progress: progress progress: progress
} }
}); });
}; };
var sendSizeProgress = function(progress){ var sendSizeProgress = function(progress){
self.postMessage({ self.postMessage({
"cmd": "analyzeProgress", "cmd": "analyzeProgress",
"msg": { "msg": {
progress: progress, progress: progress,
printTime: printTime printTime: printTime
} }
}); });
}; };
var sendAnalyzeDone = function(){ var sendAnalyzeDone = function(){
self.postMessage({ self.postMessage({
"cmd": "analyzeDone", "cmd": "analyzeDone",
"msg": { "msg": {
max: max, max: max,
min: min, min: min,
modelSize: modelSize, modelSize: modelSize,
totalFilament:totalFilament, totalFilament:totalFilament,
filamentByLayer: filamentByLayer, filamentByLayer: filamentByLayer,
printTime: printTime, printTime: printTime,
layerHeight: layerHeight, layerHeight: layerHeight,
layerCnt: layerCnt, layerCnt: layerCnt,
layerTotal: model.length, layerTotal: model.length,
speeds: speeds, speeds: speeds,
speedsByLayer: speedsByLayer, speedsByLayer: speedsByLayer,
printTimeByLayer: printTimeByLayer printTimeByLayer: printTimeByLayer
} }
}); });
}; };
var purgeLayers = function(){ var purgeLayers = function(){
var purge=true; var purge=true;
for(var i=0;i<model.length;i++){ for(var i=0;i<model.length;i++){
purge=true; purge=true;
if(!model[i])purge=true; if(!model[i])purge=true;
else { else {
for(var j=0;j<model[i].length;j++){ for(var j=0;j<model[i].length;j++){
if(model[i][j].extrude)purge=false; if(model[i][j].extrude)purge=false;
} }
} }
if(!purge){ if(!purge){
layerCnt+=1; layerCnt+=1;
} }
} }
// self.postMessage('LayerCnt: ' + layerCnt); // self.postMessage('LayerCnt: ' + layerCnt);
}; };
var analyzeModel = function(){ var analyzeModel = function(){
var i,j; var i,j;
var x_ok=false, y_ok=false; var x_ok=false, y_ok=false;
var cmds; var cmds;
var tmp1= 0, tmp2=0; var tmp1= 0, tmp2=0;
var speedIndex=0; var speedIndex=0;
var type; var type;
var printTimeAdd=0; var printTimeAdd=0;
// var moveTime=0; // var moveTime=0;
for(i=0;i<model.length;i++){ for(i=0;i<model.length;i++){
cmds = model[i]; cmds = model[i];
if(!cmds)continue; if(!cmds)continue;
for(j=0;j<cmds.length;j++){ for(j=0;j<cmds.length;j++){
x_ok=false; x_ok=false;
y_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)) 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].x)?parseFloat(max.x):parseFloat(cmds[j].x);
max.x = parseFloat(max.x)>parseFloat(cmds[j].prevX)?parseFloat(max.x):parseFloat(cmds[j].prevX); 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].x)?parseFloat(min.x):parseFloat(cmds[j].x);
min.x = parseFloat(min.x)<parseFloat(cmds[j].prevX)?parseFloat(min.x):parseFloat(cmds[j].prevX); min.x = parseFloat(min.x)<parseFloat(cmds[j].prevX)?parseFloat(min.x):parseFloat(cmds[j].prevX);
x_ok=true; 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)){ 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].y)?parseFloat(max.y):parseFloat(cmds[j].y);
max.y = parseFloat(max.y)>parseFloat(cmds[j].prevY)?parseFloat(max.y):parseFloat(cmds[j].prevY); 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].y)?parseFloat(min.y):parseFloat(cmds[j].y);
min.y = parseFloat(min.y)<parseFloat(cmds[j].prevY)?parseFloat(min.y):parseFloat(cmds[j].prevY); min.y = parseFloat(min.y)<parseFloat(cmds[j].prevY)?parseFloat(min.y):parseFloat(cmds[j].prevY);
y_ok=true; y_ok=true;
} }
if(typeof(cmds[j].prevZ) !== 'undefined'&&typeof(cmds[j].extrude) !== 'undefined'&&cmds[j].extrude&&!isNaN(cmds[j].prevZ)){ 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); 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); min.z = parseFloat(min.z)<parseFloat(cmds[j].prevZ)?parseFloat(min.z):parseFloat(cmds[j].prevZ);
} }
if(typeof(cmds[j].extrude) !== 'undefined'||cmds[j].retract!=0){ if(typeof(cmds[j].extrude) !== 'undefined'||cmds[j].retract!=0){
totalFilament+=cmds[j].extrusion; totalFilament+=cmds[j].extrusion;
if(!filamentByLayer[cmds[j].prevZ])filamentByLayer[cmds[j].prevZ]=0; if(!filamentByLayer[cmds[j].prevZ])filamentByLayer[cmds[j].prevZ]=0;
filamentByLayer[cmds[j].prevZ]+=cmds[j].extrusion; filamentByLayer[cmds[j].prevZ]+=cmds[j].extrusion;
} }
if(x_ok&&y_ok){ 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); 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){ }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); 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)); tmp2 = Math.abs(parseFloat(cmds[j].extrusion)/(cmds[j].speed/60));
printTimeAdd = tmp1>=tmp2?tmp1:tmp2; printTimeAdd = tmp1>=tmp2?tmp1:tmp2;
}else if(cmds[j].retract!==0){ }else if(cmds[j].retract!==0){
printTimeAdd = Math.abs(parseFloat(cmds[j].extrusion)/(cmds[j].speed/60)); printTimeAdd = Math.abs(parseFloat(cmds[j].extrusion)/(cmds[j].speed/60));
} }
printTime += printTimeAdd; 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; printTimeByLayer[cmds[j].prevZ] += printTimeAdd;
if(cmds[j].extrude&&cmds[j].retract===0){ if(cmds[j].extrude&&cmds[j].retract===0){
type = 'extrude'; type = 'extrude';
}else if(cmds[j].retract!==0){ }else if(cmds[j].retract!==0){
type = 'retract'; type = 'retract';
}else if(!cmds[j].extrude&&cmds[j].retract===0){ }else if(!cmds[j].extrude&&cmds[j].retract===0){
type = 'move'; type = 'move';
// if(cmds[j].prevZ == '17.1'){ // if(cmds[j].prevZ == '17.1'){
// self.postMessage({cmd: 'Got speed ' + cmds[j].speed + 'with line ' + cmds[j].gcodeLine}); // self.postMessage({cmd: 'Got speed ' + cmds[j].speed + 'with line ' + cmds[j].gcodeLine});
// } // }
}else { }else {
self.postMessage({cmd: 'unknown type of move'}); self.postMessage({cmd: 'unknown type of move'});
type = 'unknown'; type = 'unknown';
} }
speedIndex = speeds[type].indexOf(cmds[j].speed); speedIndex = speeds[type].indexOf(cmds[j].speed);
if (speedIndex === -1) { if (speedIndex === -1) {
speeds[type].push(cmds[j].speed); speeds[type].push(cmds[j].speed);
speedIndex = speeds[type].indexOf(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] = []; 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; speedsByLayer[type][cmds[j].prevZ][speedIndex] = cmds[j].speed;
} }
} }
sendSizeProgress(i/model.length*100); sendSizeProgress(i/model.length*100);
} }
purgeLayers(); purgeLayers();
modelSize.x = Math.abs(max.x - min.x); modelSize.x = Math.abs(max.x - min.x);
modelSize.y = Math.abs(max.y - min.y); modelSize.y = Math.abs(max.y - min.y);
modelSize.z = Math.abs(max.z - min.z); modelSize.z = Math.abs(max.z - min.z);
layerHeight = (max.z-min.z)/(layerCnt-1); layerHeight = (max.z-min.z)/(layerCnt-1);
sendAnalyzeDone(); sendAnalyzeDone();
}; };
var doParse = function(){ var doParse = function(){
var argChar, numSlice; var argChar, numSlice;
model=[]; model=[];
var sendLayer = undefined; var sendLayer = undefined;
var sendLayerZ = 0; var sendLayerZ = 0;
var sendMultiLayer = []; var sendMultiLayer = [];
var sendMultiLayerZ = []; var sendMultiLayerZ = [];
var lastSend = 0; var lastSend = 0;
// console.time("parseGCode timer"); // console.time("parseGCode timer");
var reg = new RegExp(/^(?:G0|G1)\s/i); var reg = new RegExp(/^(?:G0|G1)\s/i);
var comment = new RegExp() 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 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 dcExtrude=false; var dcExtrude=false;
var assumeNonDC = false; var assumeNonDC = false;
for(var i=0;i<gcode.length;i++){ for(var i=0;i<gcode.length;i++){
x=undefined; x=undefined;
y=undefined; y=undefined;
z=undefined; z=undefined;
retract = 0; retract = 0;
var line = gcode[i].line; var line = gcode[i].line;
var percentage = gcode[i].percentage; var percentage = gcode[i].percentage;
extrude=false; extrude=false;
line = line.split(/[\(;]/)[0]; line = line.split(/[\(;]/)[0];
if(reg.test(line)){ if(reg.test(line)){
var args = line.split(/\s/); var args = line.split(/\s/);
for(j=0;j<args.length;j++){ for(j=0;j<args.length;j++){
switch(argChar = args[j].charAt(0).toLowerCase()){ switch(argChar = args[j].charAt(0).toLowerCase()){
case 'x': case 'x':
x=args[j].slice(1); x=args[j].slice(1);
break; break;
case 'y': case 'y':
y=args[j].slice(1); y=args[j].slice(1);
break; break;
case 'z': case 'z':
z=args[j].slice(1); z=args[j].slice(1);
z = Number(z); z = Number(z);
if(z == prevZ) continue; if(z == prevZ) continue;
if(z_heights.hasOwnProperty(z)){ if(z_heights.hasOwnProperty(z)){
layer = z_heights[z]; layer = z_heights[z];
}else{ }else{
layer = model.length; layer = model.length;
z_heights[z] = layer; z_heights[z] = layer;
} }
sendLayer = layer; sendLayer = layer;
sendLayerZ = z; sendLayerZ = z;
prevZ = z; prevZ = z;
break; break;
case 'e': case 'e':
case 'a': case 'a':
case 'b': case 'b':
case 'c': case 'c':
assumeNonDC = true; assumeNonDC = true;
numSlice = parseFloat(args[j].slice(1)).toFixed(3); numSlice = parseFloat(args[j].slice(1)).toFixed(3);
if(!extrudeRelative){ if(!extrudeRelative){
// absolute extrusion positioning // absolute extrusion positioning
prev_extrude["abs"] = parseFloat(numSlice)-parseFloat(prev_extrude[argChar]); prev_extrude["abs"] = parseFloat(numSlice)-parseFloat(prev_extrude[argChar]);
}else{ }else{
prev_extrude["abs"] = parseFloat(numSlice); prev_extrude["abs"] = parseFloat(numSlice);
} }
extrude = prev_extrude["abs"]>0; extrude = prev_extrude["abs"]>0;
if(prev_extrude["abs"]<0){ if(prev_extrude["abs"]<0){
prevRetract = -1; prevRetract = -1;
retract = -1; retract = -1;
} }
else if(prev_extrude["abs"]==0){ else if(prev_extrude["abs"]==0){
retract = 0; retract = 0;
}else if(prev_extrude["abs"]>0&&prevRetract < 0){ }else if(prev_extrude["abs"]>0&&prevRetract < 0){
prevRetract = 0; prevRetract = 0;
retract = 1; retract = 1;
} else { } else {
retract = 0; retract = 0;
} }
prev_extrude[argChar] = numSlice; prev_extrude[argChar] = numSlice;
break; break;
case 'f': case 'f':
numSlice = args[j].slice(1); numSlice = args[j].slice(1);
lastF = numSlice; lastF = numSlice;
break; break;
default: default:
break; break;
} }
} }
if(dcExtrude&&!assumeNonDC){ if(dcExtrude&&!assumeNonDC){
extrude = true; extrude = true;
prev_extrude["abs"] = Math.sqrt((prevX-x)*(prevX-x)+(prevY-y)*(prevY-y)); prev_extrude["abs"] = Math.sqrt((prevX-x)*(prevX-x)+(prevY-y)*(prevY-y));
} }
if(!model[layer])model[layer]=[]; 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'||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}; //{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(x) !== 'undefined') prevX = x;
if(typeof(y) !== 'undefined') prevY = y; if(typeof(y) !== 'undefined') prevY = y;
} else if(line.match(/^(?:M82)/i)){ } else if(line.match(/^(?:M82)/i)){
extrudeRelative = false; extrudeRelative = false;
}else if(line.match(/^(?:G91)/i)){ }else if(line.match(/^(?:G91)/i)){
extrudeRelative=true; extrudeRelative=true;
}else if(line.match(/^(?:G90)/i)){ }else if(line.match(/^(?:G90)/i)){
extrudeRelative=false; extrudeRelative=false;
}else if(line.match(/^(?:M83)/i)){ }else if(line.match(/^(?:M83)/i)){
extrudeRelative=true; extrudeRelative=true;
}else if(line.match(/^(?:M101)/i)){ }else if(line.match(/^(?:M101)/i)){
dcExtrude=true; dcExtrude=true;
}else if(line.match(/^(?:M103)/i)){ }else if(line.match(/^(?:M103)/i)){
dcExtrude=false; dcExtrude=false;
}else if(line.match(/^(?:G92)/i)){ }else if(line.match(/^(?:G92)/i)){
var args = line.split(/\s/); var args = line.split(/\s/);
for(j=0;j<args.length;j++){ for(j=0;j<args.length;j++){
switch(argChar = args[j].charAt(0).toLowerCase()){ switch(argChar = args[j].charAt(0).toLowerCase()){
case 'x': case 'x':
x=args[j].slice(1); x=args[j].slice(1);
break; break;
case 'y': case 'y':
y=args[j].slice(1); y=args[j].slice(1);
break; break;
case 'z': case 'z':
z=args[j].slice(1); z=args[j].slice(1);
prevZ = z; prevZ = z;
break; break;
case 'e'||'a'||'b'||'c': case 'e'||'a'||'b'||'c':
numSlice = args[j].slice(1); numSlice = args[j].slice(1);
if(!extrudeRelative) if(!extrudeRelative)
prev_extrude[argChar] = 0; prev_extrude[argChar] = 0;
else { else {
prev_extrude[argChar] = numSlice; prev_extrude[argChar] = numSlice;
} }
break; break;
default: default:
break; break;
} }
} }
if(!model[layer])model[layer]=[]; 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}; 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)){ }else if(line.match(/^(?:G28)/i)){
var args = line.split(/\s/); var args = line.split(/\s/);
for(j=0;j<args.length;j++){ for(j=0;j<args.length;j++){
switch(argChar = args[j].charAt(0).toLowerCase()){ switch(argChar = args[j].charAt(0).toLowerCase()){
case 'x': case 'x':
x=args[j].slice(1); x=args[j].slice(1);
break; break;
case 'y': case 'y':
y=args[j].slice(1); y=args[j].slice(1);
break; break;
case 'z': case 'z':
z=args[j].slice(1); z=args[j].slice(1);
z = Number(z); z = Number(z);
if(z === prevZ)continue; if(z === prevZ)continue;
sendLayer = layer; sendLayer = layer;
sendLayerZ = z;//} sendLayerZ = z;//}
if(z_heights.hasOwnProperty(z)){ if(z_heights.hasOwnProperty(z)){
layer = z_heights[z]; layer = z_heights[z];
}else{ }else{
layer = model.length; layer = model.length;
z_heights[z] = layer; z_heights[z] = layer;
} }
prevZ = z; prevZ = z;
break; break;
default: default:
break; break;
} }
} }
// G28 with no arguments // G28 with no arguments
if(args.length == 1){ if(args.length == 1){
//need to init values to default here //need to init values to default here
} }
// if it's the first layer and G28 was without // if it's the first layer and G28 was without
if(layer==0&&typeof(z) === 'undefined'){ if(layer==0&&typeof(z) === 'undefined'){
z=0; z=0;
if(z_heights.hasOwnProperty(z)){ if(z_heights.hasOwnProperty(z)){
layer = z_heights[z]; layer = z_heights[z];
}else{ }else{
layer = model.length; layer = model.length;
z_heights[z] = layer; z_heights[z] = layer;
} }
prevZ = z; prevZ = z;
} }
if(!model[layer])model[layer]=[]; 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'||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(sendLayer) !== "undefined"){ if(typeof(sendLayer) !== "undefined"){
if(i-lastSend > gcode.length*0.02 && sendMultiLayer.length != 0){ if(i-lastSend > gcode.length*0.02 && sendMultiLayer.length != 0){
lastSend = i; lastSend = i;
sendMultiLayerToParent(sendMultiLayer, sendMultiLayerZ, i/gcode.length*100); sendMultiLayerToParent(sendMultiLayer, sendMultiLayerZ, i/gcode.length*100);
sendMultiLayer = []; sendMultiLayer = [];
sendMultiLayerZ = []; sendMultiLayerZ = [];
} }
sendMultiLayer[sendMultiLayer.length] = sendLayer; sendMultiLayer[sendMultiLayer.length] = sendLayer;
sendMultiLayerZ[sendMultiLayerZ.length] = sendLayerZ; sendMultiLayerZ[sendMultiLayerZ.length] = sendLayerZ;
sendLayer = undefined; sendLayer = undefined;
sendLayerZ = undefined; sendLayerZ = undefined;
} }
} }
sendMultiLayerToParent(sendMultiLayer, sendMultiLayerZ, i/gcode.length*100); sendMultiLayerToParent(sendMultiLayer, sendMultiLayerZ, i/gcode.length*100);
}; };
var parseGCode = function(message){ var parseGCode = function(message){
gcode = message.gcode; gcode = message.gcode;
firstReport = message.options.firstReport; firstReport = message.options.firstReport;
doParse(); doParse();
gcode = []; gcode = [];
self.postMessage({ self.postMessage({
"cmd": "returnModel", "cmd": "returnModel",
"msg": { "msg": {
// model: model // model: model
} }
}); });
}; };
var runAnalyze = function(message){ var runAnalyze = function(message){
analyzeModel(); analyzeModel();
model = []; model = [];
z_heights = []; z_heights = [];
gcode = undefined; gcode = undefined;
firstReport = undefined; firstReport = undefined;
z_heights = {}; z_heights = {};
model = []; model = [];
max = {x: undefined, y: undefined, z: undefined}; max = {x: undefined, y: undefined, z: undefined};
min = {x: undefined, y: undefined, z: undefined}; min = {x: undefined, y: undefined, z: undefined};
modelSize = {x: undefined, y: undefined, z: undefined}; modelSize = {x: undefined, y: undefined, z: undefined};
filamentByLayer = {}; filamentByLayer = {};
totalFilament=0; totalFilament=0;
printTime=0; printTime=0;
printTimeByLayer = {}; printTimeByLayer = {};
layerHeight=0; layerHeight=0;
layerCnt = 0; layerCnt = 0;
speeds = {extrude: [], retract: [], move: []}; speeds = {extrude: [], retract: [], move: []};
speedsByLayer = {extrude: {}, retract: {}, move: {}}; speedsByLayer = {extrude: {}, retract: {}, move: {}};
}; };
var setOption = function(options){ var setOption = function(options){
for(var opt in options){ for(var opt in options){
gCodeOptions[opt] = options[opt]; gCodeOptions[opt] = options[opt];
} }
}; };
onmessage = function (e){ onmessage = function (e){
var data = e.data; var data = e.data;
// for some reason firefox doesn't garbage collect when something inside closures is deleted, so we delete and recreate whole object eaech time // for some reason firefox doesn't garbage collect when something inside closures is deleted, so we delete and recreate whole object eaech time
switch (data.cmd) { switch (data.cmd) {
case 'parseGCode': case 'parseGCode':
parseGCode(data.msg); parseGCode(data.msg);
break; break;
case 'setOption': case 'setOption':
setOption(data.msg); setOption(data.msg);
break; break;
case 'analyzeModel': case 'analyzeModel':
runAnalyze(data.msg); runAnalyze(data.msg);
break; break;
default: default:
self.postMessage('Unknown command: ' + data.msg); self.postMessage('Unknown command: ' + data.msg);
} }
}; };

View file

@ -1,207 +1,207 @@
/** /**
* User: hudbrog (hudbrog@gmail.com) * User: hudbrog (hudbrog@gmail.com)
* Date: 10/21/12 * Date: 10/21/12
* Time: 7:31 AM * Time: 7:31 AM
*/ */
GCODE.gCodeReader = (function(){ GCODE.gCodeReader = (function(){
// ***** PRIVATE ****** // ***** PRIVATE ******
var gcode, lines; var gcode, lines;
var z_heights = {}; var z_heights = {};
var model = []; var model = [];
var max = {x: undefined, y: undefined, z: undefined}; var max = {x: undefined, y: undefined, z: undefined};
var min = {x: undefined, y: undefined, z: undefined}; var min = {x: undefined, y: undefined, z: undefined};
var modelSize = {x: undefined, y: undefined, z: undefined}; var modelSize = {x: undefined, y: undefined, z: undefined};
var filamentByLayer = {}; var filamentByLayer = {};
var printTimeByLayer; var printTimeByLayer;
var totalFilament=0; var totalFilament=0;
var printTime=0; var printTime=0;
var speeds = {}; var speeds = {};
var speedsByLayer = {}; var speedsByLayer = {};
var gCodeOptions = { var gCodeOptions = {
sortLayers: false, sortLayers: false,
purgeEmptyLayers: true, purgeEmptyLayers: true,
analyzeModel: false analyzeModel: false
}; };
var percentageTree = undefined; var percentageTree = undefined;
var prepareGCode = function(totalSize){ var prepareGCode = function(totalSize){
if(!lines)return; if(!lines)return;
gcode = []; gcode = [];
var i, tmp, byteCount; var i, tmp, byteCount;
byteCount = 0; byteCount = 0;
for(i=0;i<lines.length;i++){ for(i=0;i<lines.length;i++){
byteCount += lines[i].length + 1; // line length + \n byteCount += lines[i].length + 1; // line length + \n
tmp = lines[i].indexOf(";"); tmp = lines[i].indexOf(";");
if(tmp > 1 || tmp === -1) { if(tmp > 1 || tmp === -1) {
gcode.push({line: lines[i], percentage: byteCount * 100 / totalSize}); gcode.push({line: lines[i], percentage: byteCount * 100 / totalSize});
} }
} }
lines = []; lines = [];
}; };
var sortLayers = function(){ var sortLayers = function(){
var sortedZ = []; var sortedZ = [];
var tmpModel = []; var tmpModel = [];
for(var layer in z_heights){ for(var layer in z_heights){
sortedZ[z_heights[layer]] = layer; sortedZ[z_heights[layer]] = layer;
} }
sortedZ.sort(function(a,b){ sortedZ.sort(function(a,b){
return a-b; return a-b;
}); });
for(var i=0;i<sortedZ.length;i++){ for(var i=0;i<sortedZ.length;i++){
if(typeof(z_heights[sortedZ[i]]) === 'undefined')continue; if(typeof(z_heights[sortedZ[i]]) === 'undefined')continue;
tmpModel[i] = model[z_heights[sortedZ[i]]]; tmpModel[i] = model[z_heights[sortedZ[i]]];
} }
model = tmpModel; model = tmpModel;
delete tmpModel; delete tmpModel;
}; };
var prepareLinesIndex = function(){ var prepareLinesIndex = function(){
percentageTree = undefined; percentageTree = undefined;
for (var l in model) { for (var l in model) {
for (var i=0; i< model[l].length; i++) { for (var i=0; i< model[l].length; i++) {
var percentage = model[l][i].percentage; var percentage = model[l][i].percentage;
var value = {layer: l, cmd: i}; var value = {layer: l, cmd: i};
if (!percentageTree) { if (!percentageTree) {
percentageTree = new AVLTree({key: percentage, value: value}, "key"); percentageTree = new AVLTree({key: percentage, value: value}, "key");
} else { } else {
percentageTree.add({key: percentage, value: value}); percentageTree.add({key: percentage, value: value});
} }
} }
} }
}; };
var searchInPercentageTree = function(key) { var searchInPercentageTree = function(key) {
if (percentageTree === undefined) { if (percentageTree === undefined) {
return undefined; return undefined;
} }
var elements = percentageTree.findBest(key); var elements = percentageTree.findBest(key);
if (elements.length == 0) { if (elements.length == 0) {
return undefined; return undefined;
} }
return elements[0]; return elements[0];
}; };
var purgeLayers = function(){ var purgeLayers = function(){
var purge=true; var purge=true;
if(!model){ if(!model){
console.log("Something terribly wring just happened."); console.log("Something terribly wring just happened.");
return; return;
} }
for(var i=0;i<model.length;i++){ for(var i=0;i<model.length;i++){
purge=true; purge=true;
if(typeof(model[i])==='undefined')purge=true; if(typeof(model[i])==='undefined')purge=true;
else { else {
for(var j=0;j<model[i].length;j++){ for(var j=0;j<model[i].length;j++){
if(model[i][j].extrude)purge=false; if(model[i][j].extrude)purge=false;
} }
} }
if(purge){ if(purge){
model.splice(i,1); model.splice(i,1);
i--; i--;
} }
} }
}; };
// ***** PUBLIC ******* // ***** PUBLIC *******
return { return {
loadFile: function(reader){ loadFile: function(reader){
model = []; model = [];
z_heights = []; z_heights = [];
var totalSize = reader.target.result.length; var totalSize = reader.target.result.length;
lines = reader.target.result.split(/\n/); lines = reader.target.result.split(/\n/);
reader.target.result = null; reader.target.result = null;
prepareGCode(totalSize); prepareGCode(totalSize);
worker.postMessage({ worker.postMessage({
"cmd":"parseGCode", "cmd":"parseGCode",
"msg":{ "msg":{
gcode: gcode, gcode: gcode,
options: { options: {
firstReport: 5 firstReport: 5
} }
} }
} }
); );
delete lines; delete lines;
delete gcode; delete gcode;
}, },
setOption: function(options){ setOption: function(options){
for(var opt in options){ for(var opt in options){
gCodeOptions[opt] = options[opt]; gCodeOptions[opt] = options[opt];
} }
}, },
passDataToRenderer: function(){ passDataToRenderer: function(){
if(gCodeOptions["sortLayers"])sortLayers(); if(gCodeOptions["sortLayers"])sortLayers();
if(gCodeOptions["purgeEmptyLayers"])purgeLayers(); if(gCodeOptions["purgeEmptyLayers"])purgeLayers();
prepareLinesIndex(); prepareLinesIndex();
GCODE.renderer.doRender(model, 0); GCODE.renderer.doRender(model, 0);
}, },
processLayerFromWorker: function(msg){ processLayerFromWorker: function(msg){
model[msg.layerNum] = msg.cmds; model[msg.layerNum] = msg.cmds;
z_heights[msg.zHeightObject.zValue] = msg.zHeightObject.layer; z_heights[msg.zHeightObject.zValue] = msg.zHeightObject.layer;
}, },
processMultiLayerFromWorker: function(msg){ processMultiLayerFromWorker: function(msg){
for(var i=0;i<msg.layerNum.length;i++){ for(var i=0;i<msg.layerNum.length;i++){
model[msg.layerNum[i]] = msg.model[msg.layerNum[i]]; model[msg.layerNum[i]] = msg.model[msg.layerNum[i]];
z_heights[msg.zHeightObject.zValue[i]] = msg.layerNum[i]; z_heights[msg.zHeightObject.zValue[i]] = msg.layerNum[i];
} }
}, },
processAnalyzeModelDone: function(msg){ processAnalyzeModelDone: function(msg){
min = msg.min; min = msg.min;
max = msg.max; max = msg.max;
modelSize = msg.modelSize; modelSize = msg.modelSize;
totalFilament = msg.totalFilament; totalFilament = msg.totalFilament;
filamentByLayer = msg.filamentByLayer; filamentByLayer = msg.filamentByLayer;
speeds = msg.speeds; speeds = msg.speeds;
speedsByLayer = msg.speedsByLayer; speedsByLayer = msg.speedsByLayer;
printTime = msg.printTime; printTime = msg.printTime;
printTimeByLayer = msg.printTimeByLayer; printTimeByLayer = msg.printTimeByLayer;
}, },
getLayerFilament: function(z){ getLayerFilament: function(z){
return filamentByLayer[z]; return filamentByLayer[z];
}, },
getLayerSpeeds: function(z){ getLayerSpeeds: function(z){
return speedsByLayer[z]?speedsByLayer[z]:{}; return speedsByLayer[z]?speedsByLayer[z]:{};
}, },
getModelInfo: function(){ getModelInfo: function(){
return { return {
min: min, min: min,
max: max, max: max,
modelSize: modelSize, modelSize: modelSize,
totalFilament: totalFilament, totalFilament: totalFilament,
speeds: speeds, speeds: speeds,
speedsByLayer: speedsByLayer, speedsByLayer: speedsByLayer,
printTime: printTime, printTime: printTime,
printTimeByLayer: printTimeByLayer printTimeByLayer: printTimeByLayer
}; };
}, },
getGCodeLines: function(layer, fromSegments, toSegments){ getGCodeLines: function(layer, fromSegments, toSegments){
var i=0; var i=0;
var result = {first: model[layer][fromSegments].gcodeLine, last: model[layer][toSegments].gcodeLine}; var result = {first: model[layer][fromSegments].gcodeLine, last: model[layer][toSegments].gcodeLine};
return result; return result;
}, },
getCmdIndexForPercentage: function(percentage) { getCmdIndexForPercentage: function(percentage) {
var command = searchInPercentageTree(percentage); var command = searchInPercentageTree(percentage);
if (command === undefined) { if (command === undefined) {
return undefined return undefined
} else { } else {
return command.value; return command.value;
} }
} }
} }
}()); }());

View file

@ -1,417 +1,417 @@
/** /**
* User: hudbrog (hudbrog@gmail.com) * User: hudbrog (hudbrog@gmail.com)
* Date: 10/20/12 * Date: 10/20/12
* Time: 1:36 PM * Time: 1:36 PM
* To change this template use File | Settings | File Templates. * To change this template use File | Settings | File Templates.
*/ */
GCODE.renderer = (function(){ GCODE.renderer = (function(){
// ***** PRIVATE ****** // ***** PRIVATE ******
var canvas; var canvas;
var ctx; var ctx;
var zoomFactor= 2.8, zoomFactorDelta = 0.4; var zoomFactor= 2.8, zoomFactorDelta = 0.4;
var gridSizeX=200,gridSizeY=200,gridStep=10; var gridSizeX=200,gridSizeY=200,gridStep=10;
var ctxHeight, ctxWidth; var ctxHeight, ctxWidth;
var prevX=0, prevY=0; var prevX=0, prevY=0;
// var colorGrid="#bbbbbb", colorLine="#000000"; // var colorGrid="#bbbbbb", colorLine="#000000";
var sliderHor, sliderVer; var sliderHor, sliderVer;
var layerNumStore, progressStore={from: 0, to: -1}; var layerNumStore, progressStore={from: 0, to: -1};
var lastX, lastY; var lastX, lastY;
var dragStart,dragged; var dragStart,dragged;
var scaleFactor = 1.1; var scaleFactor = 1.1;
var model; var model;
var initialized=false; var initialized=false;
var renderOptions = { var renderOptions = {
showMoves: true, showMoves: true,
showRetracts: true, showRetracts: true,
colorGrid: "#bbbbbb", colorGrid: "#bbbbbb",
extrusionWidth: 1, extrusionWidth: 1,
// colorLine: ["#000000", "#aabb88", "#ffe7a0", "#6e7700", "#331a00", "#44ba97", "#08262f", "#db0e00", "#ff9977"], // colorLine: ["#000000", "#aabb88", "#ffe7a0", "#6e7700", "#331a00", "#44ba97", "#08262f", "#db0e00", "#ff9977"],
colorLine: ["#000000", "#45c7ba", "#a9533a", "#ff44cc", "#dd1177", "#eeee22", "#ffbb55", "#ff5511", "#777788"], colorLine: ["#000000", "#45c7ba", "#a9533a", "#ff44cc", "#dd1177", "#eeee22", "#ffbb55", "#ff5511", "#777788"],
colorMove: "#00ff00", colorMove: "#00ff00",
colorRetract: "#ff0000", colorRetract: "#ff0000",
colorRestart: "#0000ff", colorRestart: "#0000ff",
sizeRetractSpot: 2, sizeRetractSpot: 2,
modelCenter: {x: 0, y: 0}, modelCenter: {x: 0, y: 0},
moveModel: true, moveModel: true,
differentiateColors: true, differentiateColors: true,
showNextLayer: false showNextLayer: false
}; };
var offsetModelX=0, offsetModelY=0; var offsetModelX=0, offsetModelY=0;
var speeds = []; var speeds = [];
var speedsByLayer = {}; var speedsByLayer = {};
var reRender = function(){ var reRender = function(){
var p1 = ctx.transformedPoint(0,0); var p1 = ctx.transformedPoint(0,0);
var p2 = ctx.transformedPoint(canvas.width,canvas.height); var p2 = ctx.transformedPoint(canvas.width,canvas.height);
ctx.clearRect(p1.x,p1.y,p2.x-p1.x,p2.y-p1.y); ctx.clearRect(p1.x,p1.y,p2.x-p1.x,p2.y-p1.y);
drawGrid(); drawGrid();
if(renderOptions['showNextLayer'] && layerNumStore < model.length - 1) { if(renderOptions['showNextLayer'] && layerNumStore < model.length - 1) {
drawLayer(layerNumStore+1, 0, GCODE.renderer.getLayerNumSegments(layerNumStore+1), true); drawLayer(layerNumStore+1, 0, GCODE.renderer.getLayerNumSegments(layerNumStore+1), true);
} }
drawLayer(layerNumStore, progressStore.from, progressStore.to); drawLayer(layerNumStore, progressStore.from, progressStore.to);
}; };
function trackTransforms(ctx){ function trackTransforms(ctx){
var svg = document.createElementNS("http://www.w3.org/2000/svg",'svg'); var svg = document.createElementNS("http://www.w3.org/2000/svg",'svg');
var xform = svg.createSVGMatrix(); var xform = svg.createSVGMatrix();
ctx.getTransform = function(){ return xform; }; ctx.getTransform = function(){ return xform; };
var savedTransforms = []; var savedTransforms = [];
var save = ctx.save; var save = ctx.save;
ctx.save = function(){ ctx.save = function(){
savedTransforms.push(xform.translate(0,0)); savedTransforms.push(xform.translate(0,0));
return save.call(ctx); return save.call(ctx);
}; };
var restore = ctx.restore; var restore = ctx.restore;
ctx.restore = function(){ ctx.restore = function(){
xform = savedTransforms.pop(); xform = savedTransforms.pop();
return restore.call(ctx); return restore.call(ctx);
}; };
var scale = ctx.scale; var scale = ctx.scale;
ctx.scale = function(sx,sy){ ctx.scale = function(sx,sy){
xform = xform.scaleNonUniform(sx,sy); xform = xform.scaleNonUniform(sx,sy);
return scale.call(ctx,sx,sy); return scale.call(ctx,sx,sy);
}; };
var rotate = ctx.rotate; var rotate = ctx.rotate;
ctx.rotate = function(radians){ ctx.rotate = function(radians){
xform = xform.rotate(radians*180/Math.PI); xform = xform.rotate(radians*180/Math.PI);
return rotate.call(ctx,radians); return rotate.call(ctx,radians);
}; };
var translate = ctx.translate; var translate = ctx.translate;
ctx.translate = function(dx,dy){ ctx.translate = function(dx,dy){
xform = xform.translate(dx,dy); xform = xform.translate(dx,dy);
return translate.call(ctx,dx,dy); return translate.call(ctx,dx,dy);
}; };
var transform = ctx.transform; var transform = ctx.transform;
ctx.transform = function(a,b,c,d,e,f){ ctx.transform = function(a,b,c,d,e,f){
var m2 = svg.createSVGMatrix(); var m2 = svg.createSVGMatrix();
m2.a=a; m2.b=b; m2.c=c; m2.d=d; m2.e=e; m2.f=f; m2.a=a; m2.b=b; m2.c=c; m2.d=d; m2.e=e; m2.f=f;
xform = xform.multiply(m2); xform = xform.multiply(m2);
return transform.call(ctx,a,b,c,d,e,f); return transform.call(ctx,a,b,c,d,e,f);
}; };
var setTransform = ctx.setTransform; var setTransform = ctx.setTransform;
ctx.setTransform = function(a,b,c,d,e,f){ ctx.setTransform = function(a,b,c,d,e,f){
xform.a = a; xform.a = a;
xform.b = b; xform.b = b;
xform.c = c; xform.c = c;
xform.d = d; xform.d = d;
xform.e = e; xform.e = e;
xform.f = f; xform.f = f;
return setTransform.call(ctx,a,b,c,d,e,f); return setTransform.call(ctx,a,b,c,d,e,f);
}; };
var pt = svg.createSVGPoint(); var pt = svg.createSVGPoint();
ctx.transformedPoint = function(x,y){ ctx.transformedPoint = function(x,y){
pt.x=x; pt.y=y; pt.x=x; pt.y=y;
return pt.matrixTransform(xform.inverse()); return pt.matrixTransform(xform.inverse());
} }
} }
var startCanvas = function() { var startCanvas = function() {
canvas = document.getElementById('canvas'); canvas = document.getElementById('canvas');
// Проверяем понимает ли браузер canvas // Проверяем понимает ли браузер canvas
if (!canvas.getContext) { if (!canvas.getContext) {
throw "exception"; throw "exception";
} }
ctx = canvas.getContext('2d'); // Получаем 2D контекст ctx = canvas.getContext('2d'); // Получаем 2D контекст
ctxHeight = canvas.height; ctxHeight = canvas.height;
ctxWidth = canvas.width; ctxWidth = canvas.width;
lastX = ctxWidth/2; lastX = ctxWidth/2;
lastY = ctxHeight/2; lastY = ctxHeight/2;
ctx.lineWidth = 2; ctx.lineWidth = 2;
ctx.lineCap = 'round'; ctx.lineCap = 'round';
trackTransforms(ctx); trackTransforms(ctx);
canvas.addEventListener('mousedown',function(evt){ canvas.addEventListener('mousedown',function(evt){
document.body.style.mozUserSelect = document.body.style.webkitUserSelect = document.body.style.userSelect = 'none'; document.body.style.mozUserSelect = document.body.style.webkitUserSelect = document.body.style.userSelect = 'none';
lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft); lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
lastY = evt.offsetY || (evt.pageY - canvas.offsetTop); lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
dragStart = ctx.transformedPoint(lastX,lastY); dragStart = ctx.transformedPoint(lastX,lastY);
dragged = false; dragged = false;
},false); },false);
canvas.addEventListener('mousemove',function(evt){ canvas.addEventListener('mousemove',function(evt){
lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft); lastX = evt.offsetX || (evt.pageX - canvas.offsetLeft);
lastY = evt.offsetY || (evt.pageY - canvas.offsetTop); lastY = evt.offsetY || (evt.pageY - canvas.offsetTop);
dragged = true; dragged = true;
if (dragStart){ if (dragStart){
var pt = ctx.transformedPoint(lastX,lastY); var pt = ctx.transformedPoint(lastX,lastY);
ctx.translate(pt.x-dragStart.x,pt.y-dragStart.y); ctx.translate(pt.x-dragStart.x,pt.y-dragStart.y);
reRender(); reRender();
} }
},false); },false);
canvas.addEventListener('mouseup',function(evt){ canvas.addEventListener('mouseup',function(evt){
dragStart = null; dragStart = null;
if (!dragged) zoom(evt.shiftKey ? -1 : 1 ); if (!dragged) zoom(evt.shiftKey ? -1 : 1 );
},false); },false);
var zoom = function(clicks){ var zoom = function(clicks){
var pt = ctx.transformedPoint(lastX,lastY); var pt = ctx.transformedPoint(lastX,lastY);
ctx.translate(pt.x,pt.y); ctx.translate(pt.x,pt.y);
var factor = Math.pow(scaleFactor,clicks); var factor = Math.pow(scaleFactor,clicks);
ctx.scale(factor,factor); ctx.scale(factor,factor);
ctx.translate(-pt.x,-pt.y); ctx.translate(-pt.x,-pt.y);
reRender(); reRender();
}; };
var handleScroll = function(evt){ var handleScroll = function(evt){
var delta; var delta;
if(evt.detail<0 || evt.wheelDelta>0)delta=zoomFactorDelta; if(evt.detail<0 || evt.wheelDelta>0)delta=zoomFactorDelta;
else delta=-1*zoomFactorDelta; else delta=-1*zoomFactorDelta;
if (delta) zoom(delta); if (delta) zoom(delta);
return evt.preventDefault() && false; return evt.preventDefault() && false;
}; };
canvas.addEventListener('DOMMouseScroll',handleScroll,false); canvas.addEventListener('DOMMouseScroll',handleScroll,false);
canvas.addEventListener('mousewheel',handleScroll,false); canvas.addEventListener('mousewheel',handleScroll,false);
}; };
var drawGrid = function() { var drawGrid = function() {
var i; var i;
ctx.strokeStyle = renderOptions["colorGrid"]; ctx.strokeStyle = renderOptions["colorGrid"];
ctx.lineWidth = 1; ctx.lineWidth = 1;
var offsetX=0, offsetY=0; var offsetX=0, offsetY=0;
if(renderOptions["moveModel"]){ if(renderOptions["moveModel"]){
offsetX = offsetModelX; offsetX = offsetModelX;
offsetY = offsetModelY; offsetY = offsetModelY;
} }
ctx.beginPath(); ctx.beginPath();
for(i=0;i<=gridSizeX;i+=gridStep){ for(i=0;i<=gridSizeX;i+=gridStep){
ctx.moveTo(i*zoomFactor-offsetX, 0-offsetY); ctx.moveTo(i*zoomFactor-offsetX, 0-offsetY);
ctx.lineTo(i*zoomFactor-offsetX, -gridSizeY*zoomFactor-offsetY); ctx.lineTo(i*zoomFactor-offsetX, -gridSizeY*zoomFactor-offsetY);
} }
ctx.stroke(); ctx.stroke();
ctx.beginPath(); ctx.beginPath();
for(i=0;i<=gridSizeY;i+=gridStep){ for(i=0;i<=gridSizeY;i+=gridStep){
ctx.moveTo(0-offsetX, -i*zoomFactor-offsetY); ctx.moveTo(0-offsetX, -i*zoomFactor-offsetY);
ctx.lineTo(gridSizeX*zoomFactor-offsetX, -i*zoomFactor-offsetY); ctx.lineTo(gridSizeX*zoomFactor-offsetX, -i*zoomFactor-offsetY);
} }
ctx.stroke(); ctx.stroke();
}; };
var drawLayer = function(layerNum, fromProgress, toProgress, isNextLayer){ var drawLayer = function(layerNum, fromProgress, toProgress, isNextLayer){
var i, speedIndex= 0, prevZ = 0; var i, speedIndex= 0, prevZ = 0;
isNextLayer = typeof isNextLayer !== 'undefined' ? isNextLayer : false; isNextLayer = typeof isNextLayer !== 'undefined' ? isNextLayer : false;
if(!isNextLayer){ if(!isNextLayer){
layerNumStore=layerNum; layerNumStore=layerNum;
progressStore = {from: fromProgress, to: toProgress}; progressStore = {from: fromProgress, to: toProgress};
} }
if(!model||!model[layerNum])return; if(!model||!model[layerNum])return;
var cmds = model[layerNum]; var cmds = model[layerNum];
var x, y; var x, y;
// if(toProgress === -1){ // if(toProgress === -1){
// toProgress=cmds.length; // toProgress=cmds.length;
// } // }
if(fromProgress>0){ if(fromProgress>0){
prevX = cmds[fromProgress-1].x*zoomFactor; prevX = cmds[fromProgress-1].x*zoomFactor;
prevY = -cmds[fromProgress-1].y*zoomFactor; prevY = -cmds[fromProgress-1].y*zoomFactor;
}else if(fromProgress===0 && layerNum==0){ }else if(fromProgress===0 && layerNum==0){
if(model[0]&&model[0].x !== undefined &&model[0].y !== undefined){ if(model[0]&&model[0].x !== undefined &&model[0].y !== undefined){
prevX = model[0].x*zoomFactor; prevX = model[0].x*zoomFactor;
prevY = -model[0].y*zoomFactor; prevY = -model[0].y*zoomFactor;
}else { }else {
prevX = 0; prevX = 0;
prevY = 0; prevY = 0;
} }
}else if(typeof(cmds[0].prevX) !== 'undefined' && typeof(cmds[0].prevY) !== 'undefined'){ }else if(typeof(cmds[0].prevX) !== 'undefined' && typeof(cmds[0].prevY) !== 'undefined'){
prevX = cmds[0].prevX*zoomFactor; prevX = cmds[0].prevX*zoomFactor;
prevY = -cmds[0].prevY*zoomFactor; prevY = -cmds[0].prevY*zoomFactor;
}else{ }else{
if(model[layerNum-1]){ if(model[layerNum-1]){
prevX=undefined; prevX=undefined;
prevY=undefined; prevY=undefined;
for(i=model[layerNum-1].length-1;i>=0;i--){ 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(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(prevY === undefined && model[layerNum-1][i].y!==undefined)prevY=-model[layerNum-1][i].y*zoomFactor;
} }
if(prevX === undefined)prevX=0; if(prevX === undefined)prevX=0;
if(prevY === undefined)prevY=0; if(prevY === undefined)prevY=0;
}else{ }else{
prevX=0; prevX=0;
prevY=0; prevY=0;
} }
} }
prevZ = GCODE.renderer.getZ(layerNum); prevZ = GCODE.renderer.getZ(layerNum);
// ctx.strokeStyle = renderOptions["colorLine"]; // ctx.strokeStyle = renderOptions["colorLine"];
for(i=fromProgress;i<=toProgress;i++){ for(i=fromProgress;i<=toProgress;i++){
ctx.lineWidth = 1; 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'){ if(typeof(cmds[i].prevX) !== 'undefined' && typeof(cmds[i].prevY) !== 'undefined'){
prevX = cmds[i].prevX*zoomFactor; prevX = cmds[i].prevX*zoomFactor;
prevY = -cmds[i].prevY*zoomFactor; prevY = -cmds[i].prevY*zoomFactor;
} }
// console.log(cmds[i]); // console.log(cmds[i]);
if(typeof(cmds[i].x)==='undefined'||isNaN(cmds[i].x))x=prevX/zoomFactor; if(typeof(cmds[i].x)==='undefined'||isNaN(cmds[i].x))x=prevX/zoomFactor;
else x = cmds[i].x; else x = cmds[i].x;
if(typeof(cmds[i].y) === 'undefined'||isNaN(cmds[i].y))y=prevY/zoomFactor; if(typeof(cmds[i].y) === 'undefined'||isNaN(cmds[i].y))y=prevY/zoomFactor;
else y = -cmds[i].y; else y = -cmds[i].y;
if(renderOptions["differentiateColors"]&&!renderOptions['showNextLayer']){ if(renderOptions["differentiateColors"]&&!renderOptions['showNextLayer']){
// if(speedsByLayer['extrude'][prevZ]){ // if(speedsByLayer['extrude'][prevZ]){
speedIndex = speeds['extrude'].indexOf(cmds[i].speed); speedIndex = speeds['extrude'].indexOf(cmds[i].speed);
// speedIndex = GCODE.ui.ArrayIndexOf(speedsByLayer['extrude'][prevZ], function(obj) {return obj.speed === cmds[i].speed;}); // speedIndex = GCODE.ui.ArrayIndexOf(speedsByLayer['extrude'][prevZ], function(obj) {return obj.speed === cmds[i].speed;});
// } else { // } else {
// speedIndex = -1; // speedIndex = -1;
// } // }
if(speedIndex === -1){ if(speedIndex === -1){
speedIndex = 0; speedIndex = 0;
}else if(speedIndex > renderOptions["colorLine"].length -1){ }else if(speedIndex > renderOptions["colorLine"].length -1){
speedIndex = speedIndex % (renderOptions["colorLine"].length-1); speedIndex = speedIndex % (renderOptions["colorLine"].length-1);
// console.log("Too much colors"); // console.log("Too much colors");
} }
}else if(renderOptions['showNextLayer']&&isNextLayer){ }else if(renderOptions['showNextLayer']&&isNextLayer){
speedIndex=3; speedIndex=3;
}else{ }else{
speedIndex=0; speedIndex=0;
} }
if(!cmds[i].extrude&&!cmds[i].noMove){ if(!cmds[i].extrude&&!cmds[i].noMove){
// ctx.stroke(); // ctx.stroke();
if(cmds[i].retract == -1){ if(cmds[i].retract == -1){
if(renderOptions["showRetracts"]){ if(renderOptions["showRetracts"]){
ctx.strokeStyle = renderOptions["colorRetract"]; ctx.strokeStyle = renderOptions["colorRetract"];
ctx.fillStyle = renderOptions["colorRetract"]; ctx.fillStyle = renderOptions["colorRetract"];
ctx.beginPath(); ctx.beginPath();
ctx.arc(prevX, prevY, renderOptions["sizeRetractSpot"], 0, Math.PI*2, true); ctx.arc(prevX, prevY, renderOptions["sizeRetractSpot"], 0, Math.PI*2, true);
ctx.stroke(); ctx.stroke();
ctx.fill(); ctx.fill();
} }
} }
if(renderOptions["showMoves"]){ if(renderOptions["showMoves"]){
ctx.strokeStyle = renderOptions["colorMove"]; ctx.strokeStyle = renderOptions["colorMove"];
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(prevX, prevY); ctx.moveTo(prevX, prevY);
ctx.lineTo(x*zoomFactor,y*zoomFactor); ctx.lineTo(x*zoomFactor,y*zoomFactor);
ctx.stroke(); ctx.stroke();
} }
// ctx.strokeStyle = renderOptions["colorLine"][0]; // ctx.strokeStyle = renderOptions["colorLine"][0];
// ctx.beginPath(); // ctx.beginPath();
// console.log("moveto: "+cmds[i].x+":"+cmds[i].y) // console.log("moveto: "+cmds[i].x+":"+cmds[i].y)
// ctx.moveTo(cmds[i].x*zoomFactor,cmds[i].y*zoomFactor); // ctx.moveTo(cmds[i].x*zoomFactor,cmds[i].y*zoomFactor);
} }
else if(cmds[i].extrude){ else if(cmds[i].extrude){
if(cmds[i].retract==0){ if(cmds[i].retract==0){
ctx.strokeStyle = renderOptions["colorLine"][speedIndex]; ctx.strokeStyle = renderOptions["colorLine"][speedIndex];
ctx.lineWidth = renderOptions['extrusionWidth']; ctx.lineWidth = renderOptions['extrusionWidth'];
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(prevX, prevY); ctx.moveTo(prevX, prevY);
ctx.lineTo(x*zoomFactor,y*zoomFactor); ctx.lineTo(x*zoomFactor,y*zoomFactor);
ctx.stroke(); ctx.stroke();
}else { }else {
if(renderOptions["showRetracts"]){ if(renderOptions["showRetracts"]){
// ctx.stroke(); // ctx.stroke();
ctx.strokeStyle = renderOptions["colorRestart"]; ctx.strokeStyle = renderOptions["colorRestart"];
ctx.fillStyle = renderOptions["colorRestart"]; ctx.fillStyle = renderOptions["colorRestart"];
ctx.beginPath(); ctx.beginPath();
ctx.arc(prevX, prevY, renderOptions["sizeRetractSpot"], 0, Math.PI*2, true); ctx.arc(prevX, prevY, renderOptions["sizeRetractSpot"], 0, Math.PI*2, true);
ctx.stroke(); ctx.stroke();
ctx.fill(); ctx.fill();
// ctx.strokeStyle = renderOptions["colorLine"][0]; // ctx.strokeStyle = renderOptions["colorLine"][0];
// ctx.beginPath(); // ctx.beginPath();
} }
} }
} }
prevX = x*zoomFactor; prevX = x*zoomFactor;
prevY = y*zoomFactor; prevY = y*zoomFactor;
} }
ctx.stroke(); ctx.stroke();
}; };
// ***** PUBLIC ******* // ***** PUBLIC *******
return { return {
init: function(){ init: function(){
startCanvas(); startCanvas();
initialized = true; initialized = true;
ctx.translate(10,gridSizeY*zoomFactor+20); ctx.translate(10,gridSizeY*zoomFactor+20);
}, },
setOption: function(options){ setOption: function(options){
for(var opt in options){ for(var opt in options){
if(options.hasOwnProperty(opt))renderOptions[opt] = options[opt]; if(options.hasOwnProperty(opt))renderOptions[opt] = options[opt];
}; };
if(initialized)reRender(); if(initialized)reRender();
}, },
getOptions: function(){ getOptions: function(){
return renderOptions; return renderOptions;
}, },
debugGetModel: function(){ debugGetModel: function(){
return model; return model;
}, },
render: function(layerNum, fromProgress, toProgress){ render: function(layerNum, fromProgress, toProgress){
if(!initialized)this.init(); if(!initialized)this.init();
if(!model){ if(!model){
drawGrid(); drawGrid();
}else{ }else{
if(layerNum < model.length){ if(layerNum < model.length){
var p1 = ctx.transformedPoint(0,0); var p1 = ctx.transformedPoint(0,0);
var p2 = ctx.transformedPoint(canvas.width,canvas.height); var p2 = ctx.transformedPoint(canvas.width,canvas.height);
ctx.clearRect(p1.x,p1.y,p2.x-p1.x,p2.y-p1.y); ctx.clearRect(p1.x,p1.y,p2.x-p1.x,p2.y-p1.y);
drawGrid(); drawGrid();
// ctx.globalAlpha = 0.5; // ctx.globalAlpha = 0.5;
if(renderOptions['showNextLayer'] && layerNum < model.length - 1) { if(renderOptions['showNextLayer'] && layerNum < model.length - 1) {
drawLayer(layerNum+1, 0, this.getLayerNumSegments(layerNum+1), true); drawLayer(layerNum+1, 0, this.getLayerNumSegments(layerNum+1), true);
} }
drawLayer(layerNum, fromProgress, toProgress); drawLayer(layerNum, fromProgress, toProgress);
}else{ }else{
console.log("Got request to render non-existent layer!!"); console.log("Got request to render non-existent layer!!");
} }
} }
}, },
getModelNumLayers: function(){ getModelNumLayers: function(){
return model?model.length:1; return model?model.length:1;
}, },
getLayerNumSegments: function(layer){ getLayerNumSegments: function(layer){
if(model){ if(model){
return model[layer]?model[layer].length:1; return model[layer]?model[layer].length:1;
}else{ }else{
return 1; return 1;
} }
}, },
doRender: function(mdl, layerNum){ doRender: function(mdl, layerNum){
var mdlInfo; var mdlInfo;
model = mdl; model = mdl;
prevX=0; prevX=0;
prevY=0; prevY=0;
if(!initialized)this.init(); if(!initialized)this.init();
mdlInfo = GCODE.gCodeReader.getModelInfo(); mdlInfo = GCODE.gCodeReader.getModelInfo();
speeds = mdlInfo.speeds; speeds = mdlInfo.speeds;
speedsByLayer = mdlInfo.speedsByLayer; speedsByLayer = mdlInfo.speedsByLayer;
// console.log(speeds); // console.log(speeds);
// console.log(mdlInfo.min.x + ' ' + mdlInfo.modelSize.x); // console.log(mdlInfo.min.x + ' ' + mdlInfo.modelSize.x);
offsetModelX = (gridSizeX/2-(mdlInfo.min.x+mdlInfo.modelSize.x/2))*zoomFactor; offsetModelX = (gridSizeX/2-(mdlInfo.min.x+mdlInfo.modelSize.x/2))*zoomFactor;
offsetModelY = (mdlInfo.min.y+mdlInfo.modelSize.y/2)*zoomFactor-gridSizeY/2*zoomFactor; offsetModelY = (mdlInfo.min.y+mdlInfo.modelSize.y/2)*zoomFactor-gridSizeY/2*zoomFactor;
if(ctx)ctx.translate(offsetModelX, offsetModelY); if(ctx)ctx.translate(offsetModelX, offsetModelY);
this.render(layerNum, 0, model[layerNum].length); this.render(layerNum, 0, model[layerNum].length);
}, },
getZ: function(layerNum){ getZ: function(layerNum){
if(!model&&!model[layerNum]){ if(!model&&!model[layerNum]){
return '-1'; return '-1';
} }
var cmds = model[layerNum]; var cmds = model[layerNum];
for(var i=0;i<cmds.length;i++){ for(var i=0;i<cmds.length;i++){
if(cmds[i].prevZ!==undefined)return cmds[i].prevZ; if(cmds[i].prevZ!==undefined)return cmds[i].prevZ;
} }
return '-1'; return '-1';
} }
} }
}()); }());

View file

@ -1,345 +1,345 @@
/** /**
* User: hudbrog (hudbrog@gmail.com) * User: hudbrog (hudbrog@gmail.com)
* Date: 10/21/12 * Date: 10/21/12
* Time: 7:45 AM * Time: 7:45 AM
*/ */
var GCODE = {}; var GCODE = {};
GCODE.ui = (function(){ GCODE.ui = (function(){
var reader; var reader;
var myCodeMirror; var myCodeMirror;
var sliderVer; var sliderVer;
var sliderHor; var sliderHor;
var gCodeLines = {first: 0, last: 0}; var gCodeLines = {first: 0, last: 0};
var showGCode = false; var showGCode = false;
var setProgress = function(id, progress){ var setProgress = function(id, progress){
$('#'+id).width(parseInt(progress)+'%'); $('#'+id).width(parseInt(progress)+'%');
$('#'+id).text(parseInt(progress)+'%'); $('#'+id).text(parseInt(progress)+'%');
}; };
var chooseAccordion = function(id){ var chooseAccordion = function(id){
// debugger; // debugger;
$('#'+id).collapse("show"); $('#'+id).collapse("show");
}; };
var setLinesColor = function(toggle){ var setLinesColor = function(toggle){
// var i=0; // var i=0;
// for(i=gCodeLines.first;i<gCodeLines.last; i++){ // for(i=gCodeLines.first;i<gCodeLines.last; i++){
// if(toggle){ // if(toggle){
// myCodeMirror.setLineClass(Number(i), null, "activeline"); // myCodeMirror.setLineClass(Number(i), null, "activeline");
// }else{ // }else{
// myCodeMirror.setLineClass(Number(i), null, null); // myCodeMirror.setLineClass(Number(i), null, null);
// } // }
// } // }
} }
var printLayerInfo = function(layerNum){ var printLayerInfo = function(layerNum){
var z = GCODE.renderer.getZ(layerNum); var z = GCODE.renderer.getZ(layerNum);
var segments = GCODE.renderer.getLayerNumSegments(layerNum); var segments = GCODE.renderer.getLayerNumSegments(layerNum);
var filament = GCODE.gCodeReader.getLayerFilament(z); var filament = GCODE.gCodeReader.getLayerFilament(z);
var layerSpeeds = GCODE.gCodeReader.getModelInfo().speedsByLayer; var layerSpeeds = GCODE.gCodeReader.getModelInfo().speedsByLayer;
var renderOptions = GCODE.renderer.getOptions(); var renderOptions = GCODE.renderer.getOptions();
var colors = renderOptions["colorLine"]; var colors = renderOptions["colorLine"];
var speedIndex = 0; var speedIndex = 0;
var keys, type; var keys, type;
var showMove=false; var showMove=false;
var i = 0; var i = 0;
var output = []; var output = [];
output.push("Layer number: " + layerNum); output.push("Layer number: " + layerNum);
output.push("Layer height (mm): " + z); output.push("Layer height (mm): " + z);
output.push("GCODE commands in layer: " + segments); output.push("GCODE commands in layer: " + segments);
output.push("Filament used by layer (mm): " + filament.toFixed(2)); 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("Print time for layer: " + parseFloat(GCODE.gCodeReader.getModelInfo().printTimeByLayer[z]).toFixed(1) + "sec");
output.push("Extrude speeds:"); output.push("Extrude speeds:");
for(i=0;i<layerSpeeds['extrude'][z].length;i++){ for(i=0;i<layerSpeeds['extrude'][z].length;i++){
if(typeof(layerSpeeds['extrude'][z][i])==='undefined'){continue;} if(typeof(layerSpeeds['extrude'][z][i])==='undefined'){continue;}
speedIndex = i; speedIndex = i;
if(speedIndex > colors.length -1){speedIndex = speedIndex % (colors.length-1);} 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"); 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'){ if(typeof(layerSpeeds['move'][z]) !== 'undefined'){
output.push("Move speeds:"); output.push("Move speeds:");
for(i=0;i<layerSpeeds['move'][z].length;i++){ for(i=0;i<layerSpeeds['move'][z].length;i++){
if(typeof(layerSpeeds['move'][z][i])==='undefined'){continue;} if(typeof(layerSpeeds['move'][z][i])==='undefined'){continue;}
speedIndex = i; speedIndex = i;
if(speedIndex > colors.length -1){speedIndex = speedIndex % (colors.length-1);} 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"); 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'){ if(typeof(layerSpeeds['retract'][z]) !== 'undefined'){
output.push("Retract speeds:"); output.push("Retract speeds:");
for(i=0;i<layerSpeeds['retract'][z].length;i++){ for(i=0;i<layerSpeeds['retract'][z].length;i++){
if(typeof(layerSpeeds['retract'][z][i])==='undefined'){continue;} if(typeof(layerSpeeds['retract'][z][i])==='undefined'){continue;}
speedIndex = i; speedIndex = i;
if(speedIndex > colors.length -1){speedIndex = speedIndex % (colors.length-1);} 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"); 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");
} }
} }
$('#layerInfo').html(output.join('<br>')); $('#layerInfo').html(output.join('<br>'));
// chooseAccordion('layerAccordionTab'); // chooseAccordion('layerAccordionTab');
}; };
var handleFileSelect = function(evt) { var handleFileSelect = function(evt) {
// console.log("handleFileSelect"); // console.log("handleFileSelect");
evt.stopPropagation(); evt.stopPropagation();
evt.preventDefault(); evt.preventDefault();
var files = evt.dataTransfer?evt.dataTransfer.files:evt.target.files; // FileList object. var files = evt.dataTransfer?evt.dataTransfer.files:evt.target.files; // FileList object.
var output = []; var output = [];
for (var i = 0, f; f = files[i]; i++) { for (var i = 0, f; f = files[i]; i++) {
if(f.name.toLowerCase().match(/^.*\.(?:gcode|g|txt)$/)){ if(f.name.toLowerCase().match(/^.*\.(?:gcode|g|txt)$/)){
output.push('<li>File extensions suggests GCODE</li>'); output.push('<li>File extensions suggests GCODE</li>');
}else{ }else{
output.push('<li><strong>You should only upload *.gcode files! I will not work with this one!</strong></li>'); output.push('<li><strong>You should only upload *.gcode files! I will not work with this one!</strong></li>');
document.getElementById('errorList').innerHTML = '<ul>' + output.join('') + '</ul>'; document.getElementById('errorList').innerHTML = '<ul>' + output.join('') + '</ul>';
return; return;
} }
reader = new FileReader(); reader = new FileReader();
reader.onload = function(theFile){ reader.onload = function(theFile){
chooseAccordion('progressAccordionTab'); chooseAccordion('progressAccordionTab');
setProgress('loadProgress', 0); setProgress('loadProgress', 0);
setProgress('analyzeProgress', 0); setProgress('analyzeProgress', 0);
// myCodeMirror.setValue(theFile.target.result); // myCodeMirror.setValue(theFile.target.result);
GCODE.gCodeReader.loadFile(theFile); GCODE.gCodeReader.loadFile(theFile);
if(showGCode){ if(showGCode){
myCodeMirror.setValue(theFile.target.result); myCodeMirror.setValue(theFile.target.result);
}else{ }else{
myCodeMirror.setValue("GCode view is disabled. You can enable it in 'GCode analyzer options' section.") myCodeMirror.setValue("GCode view is disabled. You can enable it in 'GCode analyzer options' section.")
} }
}; };
reader.readAsText(f); reader.readAsText(f);
} }
}; };
var handleDragOver = function(evt) { var handleDragOver = function(evt) {
evt.stopPropagation(); evt.stopPropagation();
evt.preventDefault(); evt.preventDefault();
evt.target.dropEffect = 'copy'; // Explicitly show this is a copy. evt.target.dropEffect = 'copy'; // Explicitly show this is a copy.
}; };
var initSliders = function(){ var initSliders = function(){
var prevX=0; var prevX=0;
var prevY=0; var prevY=0;
var handle; var handle;
sliderVer = $( "#slider-vertical" ); sliderVer = $( "#slider-vertical" );
sliderHor = $( "#slider-horizontal" ); sliderHor = $( "#slider-horizontal" );
var onLayerChange = function(val){ var onLayerChange = function(val){
var progress = GCODE.renderer.getLayerNumSegments(val)-1; var progress = GCODE.renderer.getLayerNumSegments(val)-1;
GCODE.renderer.render(val,0, progress); GCODE.renderer.render(val,0, progress);
sliderHor.slider({max: progress, values: [0,progress]}); sliderHor.slider({max: progress, values: [0,progress]});
setLinesColor(false); //clear current selection setLinesColor(false); //clear current selection
gCodeLines = GCODE.gCodeReader.getGCodeLines(val, sliderHor.slider("values",0), sliderHor.slider("values",1)); gCodeLines = GCODE.gCodeReader.getGCodeLines(val, sliderHor.slider("values",0), sliderHor.slider("values",1));
setLinesColor(true); // highlight lines setLinesColor(true); // highlight lines
printLayerInfo(val); printLayerInfo(val);
}; };
sliderVer.slider({ sliderVer.slider({
orientation: "vertical", orientation: "vertical",
range: "min", range: "min",
min: 0, min: 0,
max: GCODE.renderer.getModelNumLayers()-1, max: GCODE.renderer.getModelNumLayers()-1,
value: 0, value: 0,
slide: function( event, ui ) { slide: function( event, ui ) {
onLayerChange(ui.value); onLayerChange(ui.value);
} }
}); });
//this stops slider reacting to arrow keys, since we do it below manually //this stops slider reacting to arrow keys, since we do it below manually
$( "#slider-vertical .ui-slider-handle" ).unbind('keydown'); $( "#slider-vertical .ui-slider-handle" ).unbind('keydown');
sliderHor.slider({ sliderHor.slider({
orientation: "horizontal", orientation: "horizontal",
range: "min", range: "min",
min: 0, min: 0,
max: GCODE.renderer.getLayerNumSegments(0)-1, max: GCODE.renderer.getLayerNumSegments(0)-1,
values: [0,GCODE.renderer.getLayerNumSegments(0)-1], values: [0,GCODE.renderer.getLayerNumSegments(0)-1],
slide: function( event, ui ) { slide: function( event, ui ) {
setLinesColor(false); //clear current selection setLinesColor(false); //clear current selection
gCodeLines = GCODE.gCodeReader.getGCodeLines(sliderVer.slider("value"),ui.values[0], ui.values[1]); gCodeLines = GCODE.gCodeReader.getGCodeLines(sliderVer.slider("value"),ui.values[0], ui.values[1]);
setLinesColor(true); // highlight lines setLinesColor(true); // highlight lines
GCODE.renderer.render(sliderVer.slider("value"), ui.values[0], ui.values[1]); GCODE.renderer.render(sliderVer.slider("value"), ui.values[0], ui.values[1]);
} }
}); });
window.onkeydown = function (event){ window.onkeydown = function (event){
if(event.keyCode === 38 || event.keyCode === 33){ if(event.keyCode === 38 || event.keyCode === 33){
if(sliderVer.slider('value') < sliderVer.slider('option', 'max')){ if(sliderVer.slider('value') < sliderVer.slider('option', 'max')){
sliderVer.slider('value', sliderVer.slider('value')+1); sliderVer.slider('value', sliderVer.slider('value')+1);
onLayerChange(sliderVer.slider('value')); onLayerChange(sliderVer.slider('value'));
} }
}else if(event.keyCode === 40 || event.keyCode === 34){ }else if(event.keyCode === 40 || event.keyCode === 34){
if(sliderVer.slider('value') > 0){ if(sliderVer.slider('value') > 0){
sliderVer.slider('value', sliderVer.slider('value')-1); sliderVer.slider('value', sliderVer.slider('value')-1);
onLayerChange(sliderVer.slider('value')); onLayerChange(sliderVer.slider('value'));
} }
} }
event.stopPropagation() event.stopPropagation()
} }
}; };
var processMessage = function(e){ var processMessage = function(e){
var data = e.data; var data = e.data;
switch (data.cmd) { switch (data.cmd) {
case 'returnModel': case 'returnModel':
setProgress('loadProgress', 100); setProgress('loadProgress', 100);
worker.postMessage({ worker.postMessage({
"cmd":"analyzeModel", "cmd":"analyzeModel",
"msg":{ "msg":{
} }
} }
); );
break; break;
case 'analyzeDone': case 'analyzeDone':
var resultSet = []; var resultSet = [];
setProgress('analyzeProgress',100); setProgress('analyzeProgress',100);
GCODE.gCodeReader.processAnalyzeModelDone(data.msg); GCODE.gCodeReader.processAnalyzeModelDone(data.msg);
GCODE.gCodeReader.passDataToRenderer(); GCODE.gCodeReader.passDataToRenderer();
initSliders(); 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("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("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("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("Estimated layer height: " + data.msg.layerHeight.toFixed(2) + "mm<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(''); document.getElementById('list').innerHTML = resultSet.join('');
chooseAccordion('infoAccordionTab'); chooseAccordion('infoAccordionTab');
$('#myTab a[href="#tab2d"]').tab('show'); $('#myTab a[href="#tab2d"]').tab('show');
break; break;
case 'returnLayer': case 'returnLayer':
GCODE.gCodeReader.processLayerFromWorker(data.msg); GCODE.gCodeReader.processLayerFromWorker(data.msg);
setProgress('loadProgress',data.msg.progress); setProgress('loadProgress',data.msg.progress);
break; break;
case 'returnMultiLayer': case 'returnMultiLayer':
GCODE.gCodeReader.processMultiLayerFromWorker(data.msg); GCODE.gCodeReader.processMultiLayerFromWorker(data.msg);
setProgress('loadProgress',data.msg.progress); setProgress('loadProgress',data.msg.progress);
break; break;
case "analyzeProgress": case "analyzeProgress":
setProgress('analyzeProgress',data.msg.progress); setProgress('analyzeProgress',data.msg.progress);
break; break;
default: default:
console.log("default msg received" + data.cmd); console.log("default msg received" + data.cmd);
} }
}; };
var checkCapabilities = function(){ var checkCapabilities = function(){
var warnings = []; var warnings = [];
var fatal = []; var fatal = [];
Modernizr.addTest('filereader', function () { Modernizr.addTest('filereader', function () {
return !!(window.File && window.FileList && window.FileReader); return !!(window.File && window.FileList && window.FileReader);
}); });
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.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.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.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>"); if(!Modernizr.svg)fatal.push("<li>Your browser doesn't seem to support HTML5 SVG, this application won't work without it.</li>");
if(fatal.length>0){ if(fatal.length>0){
document.getElementById('errorList').innerHTML = '<ul>' + fatal.join('') + '</ul>'; document.getElementById('errorList').innerHTML = '<ul>' + fatal.join('') + '</ul>';
console.log("Initialization failed: unsupported browser.") console.log("Initialization failed: unsupported browser.")
return false; return false;
} }
if(!Modernizr.webgl && GCODE.renderer3d){ if(!Modernizr.webgl && GCODE.renderer3d){
warnings.push("<li>Your browser doesn't seem to support HTML5 Web GL, 3d mode is not recommended, going to be SLOW!</li>"); warnings.push("<li>Your browser doesn't seem to support HTML5 Web GL, 3d mode is not recommended, going to be SLOW!</li>");
GCODE.renderer3d.setOption({rendererType: "canvas"}); GCODE.renderer3d.setOption({rendererType: "canvas"});
} }
if(!Modernizr.draganddrop)warnings.push("<li>Your browser doesn't seem to support HTML5 Drag'n'Drop, Drop area will not work.</li>"); if(!Modernizr.draganddrop)warnings.push("<li>Your browser doesn't seem to support HTML5 Drag'n'Drop, Drop area will not work.</li>");
if(warnings.length>0){ if(warnings.length>0){
document.getElementById('errorList').innerHTML = '<ul>' + wanings.join('') + '</ul>'; document.getElementById('errorList').innerHTML = '<ul>' + wanings.join('') + '</ul>';
console.log("Initialization succeeded with warnings.") console.log("Initialization succeeded with warnings.")
} }
return true; return true;
}; };
return { return {
worker: undefined, worker: undefined,
initHandlers: function(){ initHandlers: function(){
var capabilitiesResult = checkCapabilities(); var capabilitiesResult = checkCapabilities();
if(!capabilitiesResult){ if(!capabilitiesResult){
return; return;
} }
setProgress('loadProgress', 0); setProgress('loadProgress', 0);
setProgress('analyzeProgress', 0); setProgress('analyzeProgress', 0);
worker = new Worker('static/gcodeviewer/js/Worker.js'); worker = new Worker('static/gcodeviewer/js/Worker.js');
worker.addEventListener('message', processMessage, false); worker.addEventListener('message', processMessage, false);
GCODE.ui.processOptions(); GCODE.ui.processOptions();
GCODE.renderer.render(0,0); GCODE.renderer.render(0,0);
console.log("Application initialized"); console.log("Application initialized");
}, },
ArrayIndexOf: function(a, fnc) { ArrayIndexOf: function(a, fnc) {
if (!fnc || typeof (fnc) != 'function') { if (!fnc || typeof (fnc) != 'function') {
return -1; return -1;
} }
if (!a || !a.length || a.length < 1) return -1; if (!a || !a.length || a.length < 1) return -1;
for (var i = 0; i < a.length; i++) { for (var i = 0; i < a.length; i++) {
if(!a[i]) continue; if(!a[i]) continue;
if (fnc(a[i])) return i; if (fnc(a[i])) return i;
} }
return -1; return -1;
}, },
updateLayerInfo: function(layerNum){ updateLayerInfo: function(layerNum){
printLayerInfo(layerNum); printLayerInfo(layerNum);
}, },
processOptions: function(){ processOptions: function(){
if(document.getElementById('sortLayersCheckbox').checked)GCODE.gCodeReader.setOption({sortLayers: true}); if(document.getElementById('sortLayersCheckbox').checked)GCODE.gCodeReader.setOption({sortLayers: true});
else GCODE.gCodeReader.setOption({sortLayers: false}); else GCODE.gCodeReader.setOption({sortLayers: false});
if(document.getElementById('purgeEmptyLayersCheckbox').checked)GCODE.gCodeReader.setOption({purgeEmptyLayers: true}); if(document.getElementById('purgeEmptyLayersCheckbox').checked)GCODE.gCodeReader.setOption({purgeEmptyLayers: true});
else GCODE.gCodeReader.setOption({purgeEmptyLayers: false}); else GCODE.gCodeReader.setOption({purgeEmptyLayers: false});
if(document.getElementById('showGCodeCheckbox').checked)showGCode = true; if(document.getElementById('showGCodeCheckbox').checked)showGCode = true;
else showGCode = false; else showGCode = false;
// if(document.getElementById('sortLayersCheckbox').checked) worker.postMessage({"cmd":"setOption", "msg":{sortLayers: true}}); // if(document.getElementById('sortLayersCheckbox').checked) worker.postMessage({"cmd":"setOption", "msg":{sortLayers: true}});
// else worker.postMessage({"cmd":"setOption", "msg":{sortLayers: false}}); // else worker.postMessage({"cmd":"setOption", "msg":{sortLayers: false}});
// //
// if(document.getElementById('purgeEmptyLayersCheckbox').checked)worker.postMessage({"cmd":"setOption", "msg":{purgeEmptyLayers: true}}); // if(document.getElementById('purgeEmptyLayersCheckbox').checked)worker.postMessage({"cmd":"setOption", "msg":{purgeEmptyLayers: true}});
// else worker.postMessage({"cmd":"setOption", "msg":{purgeEmptyLayers: false}}); // else worker.postMessage({"cmd":"setOption", "msg":{purgeEmptyLayers: false}});
// if(document.getElementById('analyzeModelCheckbox').checked)worker.postMessage({"cmd":"setOption", "msg":{analyzeModel: true}}); // if(document.getElementById('analyzeModelCheckbox').checked)worker.postMessage({"cmd":"setOption", "msg":{analyzeModel: true}});
// else worker.postMessage({"cmd":"setOption", "msg":{analyzeModel: false}}); // else worker.postMessage({"cmd":"setOption", "msg":{analyzeModel: false}});
if(document.getElementById('moveModelCheckbox').checked)GCODE.renderer.setOption({moveModel: true}); if(document.getElementById('moveModelCheckbox').checked)GCODE.renderer.setOption({moveModel: true});
else GCODE.renderer.setOption({moveModel: false}); else GCODE.renderer.setOption({moveModel: false});
if(document.getElementById('showMovesCheckbox').checked)GCODE.renderer.setOption({showMoves: true}); if(document.getElementById('showMovesCheckbox').checked)GCODE.renderer.setOption({showMoves: true});
else GCODE.renderer.setOption({showMoves: false}); else GCODE.renderer.setOption({showMoves: false});
if(document.getElementById('showRetractsCheckbox').checked)GCODE.renderer.setOption({showRetracts: true}); if(document.getElementById('showRetractsCheckbox').checked)GCODE.renderer.setOption({showRetracts: true});
else GCODE.renderer.setOption({showRetracts: false}); else GCODE.renderer.setOption({showRetracts: false});
if(document.getElementById('differentiateColorsCheckbox').checked)GCODE.renderer.setOption({differentiateColors: true}); if(document.getElementById('differentiateColorsCheckbox').checked)GCODE.renderer.setOption({differentiateColors: true});
else GCODE.renderer.setOption({differentiateColors: false}); else GCODE.renderer.setOption({differentiateColors: false});
var widthMod = 2; var widthMod = 2;
if(Number($('#widthModifier').attr('value'))) {widthMod = Number($('#widthModifier').attr('value'));} if(Number($('#widthModifier').attr('value'))) {widthMod = Number($('#widthModifier').attr('value'));}
if(document.getElementById('thickExtrusionCheckbox').checked)GCODE.renderer.setOption({extrusionWidth: widthMod}); if(document.getElementById('thickExtrusionCheckbox').checked)GCODE.renderer.setOption({extrusionWidth: widthMod});
else GCODE.renderer.setOption({extrusionWidth: 1}); else GCODE.renderer.setOption({extrusionWidth: 1});
if(document.getElementById('showNextLayer').checked)GCODE.renderer.setOption({showNextLayer: true}); if(document.getElementById('showNextLayer').checked)GCODE.renderer.setOption({showNextLayer: true});
else GCODE.renderer.setOption({showNextLayer: false}); else GCODE.renderer.setOption({showNextLayer: false});
} }
} }
}()); }());

View file

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View file

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View file

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 197 B

View file

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

View file

Before

Width:  |  Height:  |  Size: 780 B

After

Width:  |  Height:  |  Size: 780 B

View file

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

Before

Width:  |  Height:  |  Size: 721 B

After

Width:  |  Height:  |  Size: 721 B

View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

Before

Width:  |  Height:  |  Size: 815 B

After

Width:  |  Height:  |  Size: 815 B

View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Some files were not shown because too many files have changed in this diff Show more