From 003109d59e969daeb06abe57d9f01c2fab5fcb8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Sun, 9 Jun 2013 14:00:15 +0200 Subject: [PATCH] Made gcode viewer capable of handling progress information GCode viewer now updates its visualization (during printing) based on the current progress percentage, not based on the current line (which will not be available any more as part of the progress tuple with gcode streaming) --- octoprint/static/gcodeviewer/js/Worker.js | 67 ++----- .../static/gcodeviewer/js/gCodeReader.js | 78 ++++---- octoprint/static/js/avltree.js | 169 ++++++++++++++++++ octoprint/static/js/ui.js | 15 +- octoprint/templates/index.jinja2 | 1 + 5 files changed, 242 insertions(+), 88 deletions(-) create mode 100644 octoprint/static/js/avltree.js diff --git a/octoprint/static/gcodeviewer/js/Worker.js b/octoprint/static/gcodeviewer/js/Worker.js index 98b39b22..feb4d953 100644 --- a/octoprint/static/gcodeviewer/js/Worker.js +++ b/octoprint/static/gcodeviewer/js/Worker.js @@ -223,42 +223,31 @@ var assumeNonDC = false; for(var i=0;i0&&prevRetract < 0){ prevRetract = 0; retract = 1; } else { - // prevRetract = retract; retract = 0; } prev_extrude[argChar] = numSlice; @@ -317,24 +301,24 @@ prev_extrude["abs"] = Math.sqrt((prevX-x)*(prevX-x)+(prevY-y)*(prevY-y)); } if(!model[layer])model[layer]=[]; - if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined'||retract!=0) model[layer][model[layer].length] = {x: Number(x), y: Number(y), z: Number(z), extrude: extrude, retract: Number(retract), noMove: false, extrusion: (extrude||retract)?Number(prev_extrude["abs"]):0, prevX: Number(prevX), prevY: Number(prevY), prevZ: Number(prevZ), speed: Number(lastF), gcodeLine: Number(i)}; + if(typeof(x) !== 'undefined' || typeof(y) !== 'undefined' ||typeof(z) !== 'undefined'||retract!=0) model[layer][model[layer].length] = {x: Number(x), y: Number(y), z: Number(z), extrude: extrude, retract: Number(retract), noMove: false, extrusion: (extrude||retract)?Number(prev_extrude["abs"]):0, prevX: Number(prevX), prevY: Number(prevY), prevZ: Number(prevZ), speed: Number(lastF), gcodeLine: Number(i), percentage: percentage}; //{x: x, y: y, z: z, extrude: extrude, retract: retract, noMove: false, extrusion: (extrude||retract)?prev_extrude["abs"]:0, prevX: prevX, prevY: prevY, prevZ: prevZ, speed: lastF, gcodeLine: i}; if(typeof(x) !== 'undefined') prevX = x; if(typeof(y) !== 'undefined') prevY = y; - } else if(gcode[i].match(/^(?:M82)/i)){ + } else if(line.match(/^(?:M82)/i)){ extrudeRelative = false; - }else if(gcode[i].match(/^(?:G91)/i)){ + }else if(line.match(/^(?:G91)/i)){ extrudeRelative=true; - }else if(gcode[i].match(/^(?:G90)/i)){ + }else if(line.match(/^(?:G90)/i)){ extrudeRelative=false; - }else if(gcode[i].match(/^(?:M83)/i)){ + }else if(line.match(/^(?:M83)/i)){ extrudeRelative=true; - }else if(gcode[i].match(/^(?:M101)/i)){ + }else if(line.match(/^(?:M101)/i)){ dcExtrude=true; - }else if(gcode[i].match(/^(?:M103)/i)){ + }else if(line.match(/^(?:M103)/i)){ dcExtrude=false; - }else if(gcode[i].match(/^(?:G92)/i)){ - var args = gcode[i].split(/\s/); + }else if(line.match(/^(?:G92)/i)){ + var args = line.split(/\s/); for(j=0;j gcode.length*0.02 && sendMultiLayer.length != 0){ lastSend = i; @@ -429,13 +406,7 @@ sendLayerZ = undefined; } } -// sendMultiLayer[sendMultiLayer.length] = layer; -// sendMultiLayerZ[sendMultiLayerZ.length] = z; sendMultiLayerToParent(sendMultiLayer, sendMultiLayerZ, i/gcode.length*100); - -// if(gCodeOptions["sortLayers"])sortLayers(); -// if(gCodeOptions["purgeEmptyLayers"])purgeLayers(); - }; diff --git a/octoprint/static/gcodeviewer/js/gCodeReader.js b/octoprint/static/gcodeviewer/js/gCodeReader.js index 190bc570..f30fdc69 100644 --- a/octoprint/static/gcodeviewer/js/gCodeReader.js +++ b/octoprint/static/gcodeviewer/js/gCodeReader.js @@ -23,57 +23,73 @@ GCODE.gCodeReader = (function(){ purgeEmptyLayers: true, analyzeModel: false }; - var linesCmdIndex = {}; - var prepareGCode = function(){ + var percentageTree = undefined; + + var prepareGCode = function(totalSize){ if(!lines)return; gcode = []; - var i, tmp; + var i, tmp, byteCount; + + byteCount = 0; for(i=0;i 1 || tmp === -1) { - gcode.push(lines[i]); + gcode.push({line: lines[i], percentage: byteCount * 100 / totalSize}); } } lines = []; -// console.log("GCode prepared"); }; var sortLayers = function(){ var sortedZ = []; var tmpModel = []; -// var cnt = 0; -// console.log(z_heights); + for(var layer in z_heights){ sortedZ[z_heights[layer]] = layer; -// cnt++; } -// console.log("cnt is " + cnt); + sortedZ.sort(function(a,b){ return a-b; }); -// console.log(sortedZ); -// console.log(model.length); + for(var i=0;i rdepth + 1) { + // LR or LL rotation + var lldepth = self.left.left == null ? 0 : self.left.left.depth; + var lrdepth = self.left.right == null ? 0 : self.left.right.depth; + + if (lldepth < lrdepth) { + // LR rotation consists of a RR rotation of the left child + self.left.rotateRR(); + // plus a LL rotation of self node, which happens anyway + } + self.rotateLL(); + } else if (ldepth + 1 < rdepth) { + // RR or RL rorarion + var rrdepth = self.right.right == null ? 0 : self.right.right.depth; + var rldepth = self.right.left == null ? 0 : self.right.left.depth; + + if (rldepth > rrdepth) { + // RR rotation consists of a LL rotation of the right child + self.right.rotateLL(); + // plus a RR rotation of self node, which happens anyway + } + self.rotateRR(); + } + } + + self.rotateLL = function() { + // the left side is too long => rotate from the left (_not_ leftwards) + var nodeBefore = self.node; + var elementsBefore = self.elements; + var rightBefore = self.right; + self.node = self.left.node; + self.elements = self.left.elements; + self.right = self.left; + self.left = self.left.left; + self.right.left = self.right.right; + self.right.right = rightBefore; + self.right.node = nodeBefore; + self.right.elements = elementsBefore; + self.right.updateInNewLocation(); + self.updateInNewLocation(); + } + + self.rotateRR = function() { + // the right side is too long => rotate from the right (_not_ rightwards) + var nodeBefore = self.node; + var elementsBefore = self.elements; + var leftBefore = self.left; + self.node = self.right.node; + self.elements = self.right.elements; + self.left = self.right; + self.right = self.right.right; + self.left.right = self.left.left; + self.left.left = leftBefore; + self.left.node = nodeBefore; + self.left.elements = elementsBefore; + self.left.updateInNewLocation(); + self.updateInNewLocation(); + } + + self.updateInNewLocation = function() { + self.getDepthFromChildren(); + } + + self.getDepthFromChildren = function() { + self.depth = self.node == null ? 0 : 1; + if (self.left != null) { + self.depth = self.left.depth + 1; + } + if (self.right != null && self.depth <= self.right.depth) { + self.depth = self.right.depth + 1; + } + } + + self.compare = function(n1, n2) { + var v1 = n1[self.attr]; + var v2 = n2[self.attr]; + if (v1 == v2) { + return 0; + } + if (v1 < v2) { + return -1; + } + return 1; + } + + self.add = function(n) { + var o = self.compare(n, self.node); + if (o == 0) { + self.elements.push(n); + return false; + } + + var ret = false; + if (o == -1) { + if (self.left == null) { + self.left = new AVLTree(n, self.attr); + ret = true; + } else { + ret = self.left.add(n); + if (ret) { + self.balance(); + } + } + } else if (o == 1) { + if (self.right == null) { + self.right = new AVLTree(n, self.attr); + ret = true; + } else { + ret = self.right.add(n); + if (ret) { + self.balance(); + } + } + } + + if (ret) { + self.getDepthFromChildren(); + } + return ret; + } + + self.findBest = function(value) { + if (value < self.node[self.attr]) { + if (self.left != null) { + return self.left.findBest(value); + } + } else if (value > self.node[self.attr]) { + if (self.right != null) { + return self.right.findBest(value); + } + } + + return self.elements; + } + + self.find = function(value) { + var elements = self.findBest(value); + for (var i = 0; i < elements.length; i++) { + if (elements[i][self.attr] == value) { + return elements; + } + } + + return false; + } +} diff --git a/octoprint/static/js/ui.js b/octoprint/static/js/ui.js index 01a01d8d..fc3c779d 100644 --- a/octoprint/static/js/ui.js +++ b/octoprint/static/js/ui.js @@ -1093,13 +1093,16 @@ function GcodeViewModel(loginStateViewModel) { } self._processData = function(data) { - if(!self.enabled)return; + if (!self.enabled) return; + if (!data.job.filename) return; - if(self.loadedFilename == data.job.filename) { - var cmdIndex = GCODE.gCodeReader.getLinesCmdIndex(data.progress.progress); - if(cmdIndex){ - GCODE.renderer.render(cmdIndex.layer, 0, cmdIndex.cmd); - GCODE.ui.updateLayerInfo(cmdIndex.layer); + if(self.loadedFilename && self.loadedFilename == data.job.filename) { + if (data.state.flags && (data.state.flags.printing || data.state.flags.paused)) { + var cmdIndex = GCODE.gCodeReader.getCmdIndexForPercentage(data.progress.progress * 100); + if(cmdIndex){ + GCODE.renderer.render(cmdIndex.layer, 0, cmdIndex.cmd); + GCODE.ui.updateLayerInfo(cmdIndex.layer); + } } self.errorCount = 0 } else if (data.job.filename) { diff --git a/octoprint/templates/index.jinja2 b/octoprint/templates/index.jinja2 index 7b3c28cb..d5530fe6 100644 --- a/octoprint/templates/index.jinja2 +++ b/octoprint/templates/index.jinja2 @@ -579,6 +579,7 @@ +