Merge branch 'devel' into events
commit
0e294ef8fd
|
@ -63,6 +63,8 @@ class GcodeManager:
|
|||
dirty = True
|
||||
if gcode.extrusionAmount:
|
||||
analysisResult["filament"] = "%.2fm" % (gcode.extrusionAmount / 1000)
|
||||
if gcode.extrusionVolume:
|
||||
analysisResult["filament"] += " / %.2fcm³" % gcode.extrusionVolume
|
||||
dirty = True
|
||||
|
||||
if dirty:
|
||||
|
|
|
@ -5,13 +5,48 @@ body {
|
|||
}
|
||||
|
||||
.navbar-inner-text (@base) {
|
||||
text-shadow: 0 1px 0 lighten(@base, 15%);
|
||||
color: contrast(@base, #333333, #f2f2f2);
|
||||
text-shadow: 0 1px 0 contrast(@base, lighten(@base, 15%), darken(@base, 15%));
|
||||
color: @text-color;
|
||||
@caret-color: average(@base, @text-color);
|
||||
@caret-hover-color: average(@caret-color, @text-color);
|
||||
|
||||
.caret {
|
||||
border-bottom-color: @caret-color;
|
||||
border-top-color: @caret-color;
|
||||
}
|
||||
|
||||
&:hover .caret, &:focus .caret {
|
||||
border-bottom-color: @caret-hover-color;
|
||||
border-top-color: @caret-hover-color;
|
||||
}
|
||||
}
|
||||
|
||||
.brand (@color, @dark, @light) when (@color = @dark) {
|
||||
span {
|
||||
background-image: url(../img/tentacle-20x20.png);
|
||||
|
||||
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
|
||||
background-image: url(../img/tentacle-20x20@2x.png);
|
||||
}
|
||||
}
|
||||
}
|
||||
.brand (@color, @dark, @light) when (@color = @light) {
|
||||
span {
|
||||
background-image: url(../img/tentacle-20x20-light.png);
|
||||
|
||||
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
|
||||
background-image: url(../img/tentacle-20x20-light@2x.png);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-inner-color (@base) {
|
||||
@top: lighten(@base, 25%);
|
||||
@bottom: darken(@base, 15%);
|
||||
|
||||
@text-color-light: #f2f2f2;
|
||||
@text-color-dark: #333333;
|
||||
@text-color: contrast(@base, @text-color-dark, @text-color-light);
|
||||
|
||||
background-color: @base; /* fallback color if gradients are not supported */
|
||||
background-image: -webkit-linear-gradient(top, @top, @bottom); /* For Chrome and Safari */
|
||||
|
@ -23,6 +58,10 @@ body {
|
|||
.brand, .nav>li>a {
|
||||
.navbar-inner-text(@base);
|
||||
}
|
||||
|
||||
.brand {
|
||||
.brand(@text-color, @text-color-dark, @text-color-light);
|
||||
}
|
||||
|
||||
.nav {
|
||||
li.dropdown.open>.dropdown-toggle, li.dropdown.active>.dropdown-toggle, li.dropdown.open.active>.dropdown-toggle {
|
||||
|
@ -65,9 +104,16 @@ body {
|
|||
@base: #7728FF;
|
||||
.navbar-inner-color(@base);
|
||||
}
|
||||
|
||||
.brand img {
|
||||
vertical-align: bottom;
|
||||
&.black {
|
||||
@base: #383838;
|
||||
.navbar-inner-color(@base);
|
||||
}
|
||||
|
||||
.brand span {
|
||||
background-size: 20px 20px;
|
||||
background-position: left center;
|
||||
padding-left: 24px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 780 B |
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
File diff suppressed because one or more lines are too long
|
@ -1299,7 +1299,7 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
|
|||
self.appearance_color = ko.observable(undefined);
|
||||
|
||||
/* I did attempt to allow arbitrary gradients but cross browser support via knockout or jquery was going to be horrible */
|
||||
self.appearance_available_colors = ko.observable(["default", "red", "orange", "yellow", "green", "blue", "violet"]);
|
||||
self.appearance_available_colors = ko.observable(["default", "red", "orange", "yellow", "green", "blue", "violet", "black"]);
|
||||
|
||||
self.printer_movementSpeedX = ko.observable(undefined);
|
||||
self.printer_movementSpeedY = ko.observable(undefined);
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
<div id="navbar" class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner" data-bind="css: appearance.color">
|
||||
<div class="container">
|
||||
<a class="brand" href="#"><img src="{{ url_for('static', filename='img/tentacle-20x20.png') }}"> <span data-bind="text: appearance.brand">OctoPrint</span></a>
|
||||
<a class="brand" href="#"> <span data-bind="text: appearance.brand">OctoPrint</span></a>
|
||||
<div class="nav-collapse">
|
||||
<ul class="nav pull-right">
|
||||
<li style="display: none;" data-bind="visible: loginState.isAdmin">
|
||||
|
@ -575,7 +575,8 @@
|
|||
{% include 'settings.jinja2' %}
|
||||
{% include 'dialogs.jinja2' %}
|
||||
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
|
||||
<!--<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>-->
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery/jquery.min.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/modernizr.custom.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/underscore.js') }}"></script>
|
||||
<script type="text/javascript" src="{{ url_for('static', filename='js/knockout.js') }}"></script>
|
||||
|
|
|
@ -4,6 +4,9 @@ import sys
|
|||
import math
|
||||
import re
|
||||
import os
|
||||
import base64
|
||||
import zlib
|
||||
import logging
|
||||
|
||||
from octoprint.util import util3d
|
||||
|
||||
|
@ -34,9 +37,12 @@ class gcodePath(object):
|
|||
|
||||
class gcode(object):
|
||||
def __init__(self):
|
||||
self._logger = logging.getLogger(__name__)
|
||||
|
||||
self.regMatch = {}
|
||||
self.layerList = []
|
||||
self.extrusionAmount = 0
|
||||
self.extrusionVolume = None
|
||||
self.totalMoveTimeMinute = 0
|
||||
self.progressCallback = None
|
||||
self._abort = False
|
||||
|
@ -64,13 +70,13 @@ class gcode(object):
|
|||
currentExtruder = 0
|
||||
extrudeAmountMultiply = 1.0
|
||||
totalMoveTimeMinute = 0.0
|
||||
filamentDiameter = 0.0
|
||||
scale = 1.0
|
||||
posAbs = True
|
||||
posAbsExtruder = True;
|
||||
feedRate = 3600
|
||||
layerThickness = 0.1
|
||||
pathType = 'CUSTOM';
|
||||
startCodeDone = False
|
||||
currentLayer = []
|
||||
unknownGcodes={}
|
||||
unknownMcodes={}
|
||||
|
@ -97,7 +103,7 @@ class gcode(object):
|
|||
startCodeDone = True
|
||||
|
||||
if ';' in line:
|
||||
#Slic3r GCode comment parser
|
||||
# Slic3r GCode comment parser
|
||||
comment = line[line.find(';')+1:].strip()
|
||||
if comment == 'fill':
|
||||
pathType = 'FILL'
|
||||
|
@ -105,11 +111,21 @@ class gcode(object):
|
|||
pathType = 'WALL-INNER'
|
||||
elif comment == 'skirt':
|
||||
pathType = 'SKIRT'
|
||||
elif comment.startswith("filament_diameter"):
|
||||
filamentDiameter = float(line.split("=", 1)[1].strip())
|
||||
|
||||
# Cura Gcode comment parser
|
||||
if comment.startswith('LAYER:'):
|
||||
self.layerList.append(currentLayer)
|
||||
currentLayer = []
|
||||
if pathType != "CUSTOM":
|
||||
startCodeDone = True
|
||||
elif comment.startswith("CURA_PROFILE_STRING"):
|
||||
curaOptions = self._parseCuraProfileString(comment)
|
||||
|
||||
if "filament_diameter" in curaOptions.keys():
|
||||
try:
|
||||
filamentDiameter = float(curaOptions["filament_diameter"])
|
||||
except:
|
||||
filamentDiameter = 0.0
|
||||
line = line[0:line.find(';')]
|
||||
T = self.getCodeInt(line, 'T')
|
||||
if T is not None:
|
||||
|
@ -223,7 +239,7 @@ class gcode(object):
|
|||
posOffset.z = pos.z - z
|
||||
else:
|
||||
if G not in unknownGcodes:
|
||||
print "Unknown G code:" + str(G)
|
||||
self._logger.info("Unknown G code: %r" % G)
|
||||
unknownGcodes[G] = True
|
||||
else:
|
||||
M = self.getCodeInt(line, 'M')
|
||||
|
@ -272,10 +288,12 @@ class gcode(object):
|
|||
extrudeAmountMultiply = s / 100.0
|
||||
else:
|
||||
if M not in unknownMcodes:
|
||||
print "Unknown M code:" + str(M)
|
||||
self._logger.info("Unknown M code: %r" % M)
|
||||
unknownMcodes[M] = True
|
||||
self.layerList.append(currentLayer)
|
||||
self.extrusionAmount = maxExtrusion
|
||||
if filamentDiameter is not None and filamentDiameter > 0:
|
||||
self.extrusionVolume = math.pi * math.pow(filamentDiameter / 2.0, 2) * maxExtrusion / 1000.0
|
||||
self.totalMoveTimeMinute = totalMoveTimeMinute
|
||||
|
||||
def getCodeInt(self, line, code):
|
||||
|
@ -300,6 +318,9 @@ class gcode(object):
|
|||
except:
|
||||
return None
|
||||
|
||||
def _parseCuraProfileString(self, comment):
|
||||
return {key: value for (key, value) in map(lambda x: x.split("=", 1), zlib.decompress(base64.b64decode(comment[len("CURA_PROFILE_STRING:"):])).split("\b"))}
|
||||
|
||||
if __name__ == '__main__':
|
||||
for filename in sys.argv[1:]:
|
||||
gcode().load(filename)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
flask==0.9
|
||||
werkzeug==0.8.3
|
||||
tornado>=2.4.1
|
||||
tornadio2>=0.0.4
|
||||
PyYAML>=3.10
|
||||
Flask-Login>=0.1.3
|
||||
Flask-Principal>=0.3.5
|
||||
tornado==3.0.2
|
||||
tornadio2==0.0.4
|
||||
PyYAML==3.10
|
||||
Flask-Login==0.2.2
|
||||
Flask-Principal==0.3.5
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
flask==0.9
|
||||
werkzeug==0.8.3
|
||||
tornado==3.0.2
|
||||
tornadio2==0.0.4
|
||||
PyYAML==3.10
|
||||
Flask-Login==0.2.2
|
||||
Flask-Principal==0.3.5
|
||||
numpy>=1.6.2
|
||||
pyserial>=2.6
|
||||
tornado>=2.4.1
|
||||
tornadio2>=0.0.4
|
||||
PyYAML>=3.10
|
||||
Flask-Login>=0.1.3
|
||||
Flask-Principal>=0.3.5
|
Loading…
Reference in New Issue