Merge branch 'stable-1.2.2' into camera_support

Conflicts:
	src/octoprint/templates/mrbeam_index.jinja2
This commit is contained in:
make-ing 2016-01-21 16:10:24 +01:00
commit 20906bca4d
20 changed files with 1619 additions and 211 deletions

View file

@ -86,9 +86,10 @@ class Events(object):
# Settings
SETTINGS_UPDATED = "SettingsUpdated"
# GRBL
LIMITS_HIT = "LimitsHit"
SOFT_RESET = "Soft-Reset"
RT_STATE = "RealTimeState"

View file

@ -204,23 +204,7 @@ class FileManager(object):
source_meta = self.get_metadata(source_location, source_path)
hash = source_meta["hash"]
#<<<<<<< HEAD
# class Wrapper(object):
# def __init__(self, stl_name, temp_path, hash):
# self.stl_name = stl_name
# self.temp_path = temp_path
# self.hash = hash
#
# def save(self, absolute_dest_path):
# with open(absolute_dest_path, "w") as d:
# d.write("; Generated from\n; {stl_name}\n; {hash}\r".format(**vars(self)))
# with open(tmp_path, "r") as s:
# import shutil
# shutil.copyfileobj(s, d)
#
#=======
import io
#>>>>>>> upstream/maintenance
links = [("model", dict(name=source_path))]
_, stl_name = self.split_path(source_location, source_path)
file_obj = StreamWrapper(os.path.basename(dest_path),

View file

@ -204,15 +204,17 @@ class LaserCutterProfilesPlugin(octoprint.plugin.SettingsPlugin,
if self._printer.is_locked() or self._printer.is_operational():
if "volume" in new_profile:
if "width" in new_profile["volume"]:
width = int(new_profile['volume']['width'])
width = float(new_profile['volume']['width'])
if identifier == "_mrbeam_senior":
width *= 2
width += float(new_profile['volume']['origin_offset_x'])
self._printer.commands('$130=' + str(width))
time.sleep(0.1) ### TODO find better solution then sleep
if "depth" in new_profile["volume"]:
depth = int(new_profile['volume']['depth'])
depth = float(new_profile['volume']['depth'])
if identifier == "_mrbeam_senior":
depth *= 2
depth += float(new_profile['volume']['origin_offset_y'])
self._printer.commands('$131=' + str(depth))
new_profile["id"] = identifier

View file

@ -29,9 +29,11 @@ class LaserCutterProfileManager(object):
name = "Mr Beam",
model = "Junior",
volume=dict(
width = 216,
depth = 297,
width = 217,
depth = 298,
height = 0,
origin_offset_x = 1.1,
origin_offset_y = 1.1,
),
zAxis = False,
axes=dict(

View file

@ -16,7 +16,9 @@ $(function() {
formFactor: "rectangular",
width: 216,
depth: 297,
height: 0
height: 0,
origin_offset_x: 1,
origin_offset_y: 1
},
zAxis: false,
axes: {
@ -108,8 +110,8 @@ $(function() {
self.currentProfile(currentProfile);
self.currentProfileData(currentProfileData);
self.workingarea.workingAreaWidthMM(self.currentProfileData().volume.width());
self.workingarea.workingAreaHeightMM(self.currentProfileData().volume.depth());
self.workingarea.workingAreaWidthMM(self.currentProfileData().volume.width() - self.currentProfileData().volume.origin_offset_x());
self.workingarea.workingAreaHeightMM(self.currentProfileData().volume.depth() - self.currentProfileData().volume.origin_offset_y());
var maxSpeed = Math.min(self.currentProfileData().axes.x.speed(), self.currentProfileData().axes.y.speed());
self.conversion.maxSpeed(maxSpeed);
};

View file

@ -1,6 +1,6 @@
table th.settings_plugin_svgtogcode_profiles_key,table td.settings_plugin_svgtogcode_profiles_key{text-overflow:ellipsis;text-align:left;width:200px}table th.settings_plugin_svgtogcode_profiles_name,table td.settings_plugin_svgtogcode_profiles_name{text-overflow:ellipsis;text-align:left}table th.settings_plugin_svgtogcode_profiles_actions,table td.settings_plugin_svgtogcode_profiles_actions{text-align:center;width:100px}table th.settings_plugin_svgtogcode_profiles_actions a,table td.settings_plugin_svgtogcode_profiles_actions a{text-decoration:none;color:#000}table th.settings_plugin_svgtogcode_profiles_actions a.disabled,table td.settings_plugin_svgtogcode_profiles_actions a.disabled{color:#ccc;cursor:default}
.slider_manual_input {
margin-left: 1.5em;
margin-left: 1.5em;
width: 2.5em;
}
@ -22,7 +22,7 @@ table th.settings_plugin_svgtogcode_profiles_key,table td.settings_plugin_svgtog
}
.svgtogcode_grayscale {
background-image: linear-gradient(90deg, #FFFFFF, #000000);
background-image: linear-gradient(90deg, #FFFFFF, #000000);
width:220px;
display: inline-block;
}
@ -37,7 +37,7 @@ svg text {
-ms-user-select: none;
cursor: default;
pointer-events: none;
}
.img_slider{
@ -60,8 +60,8 @@ svg text {
left:0;
}
.img_preprocessing_preview.after .contrast,
.img_preprocessing_preview.after .sharpened,
.img_preprocessing_preview.after .contrast,
.img_preprocessing_preview.after .sharpened,
.img_preprocessing_preview.after .sharpened_contrast {
opacity: 0;
}
@ -87,7 +87,18 @@ svg text {
}
#photo_preview {
width: 80vw;
height: 70vh;
width: 400px;
height: 300px;
margin: auto;
}
.overrideSlider {
margin-bottom: 8px;
}
.overrideSlider input {
width:45%;
}
.overrideSlider span {
padding-left: .6em;
}

View file

@ -35,10 +35,15 @@ $(function(){
self.laserSpeed = ko.observable(undefined);
self.maxSpeed = ko.observable(3000);
self.minSpeed = ko.observable(20);
self.fill_areas = ko.observable(false);
self.show_fill_areas_checkbox = ko.observable(false);
// image engraving stuff
// preset values are a good start for wood engraving
self.show_image_parameters = ko.observable(false);
self.images_placed = ko.observable(false);
self.show_image_parameters = ko.computed(function(){
return self.images_placed() || (self.fill_areas() && self.show_vector_parameters());
});
self.imgIntensityWhite = ko.observable(0);
self.imgIntensityBlack = ko.observable(500);
self.imgFeedrateWhite = ko.observable(1500);
@ -76,32 +81,38 @@ $(function(){
// shows conversion dialog and extracts svg first
self.show_conversion_dialog = function() {
self.workingArea.getCompositionSVG(function(composition){
self.svg = composition;
self.gcodeFilesToAppend = self.workingArea.getPlacedGcodes();
self.show_image_parameters(self.workingArea.getPlacedImages().length > 0);
self.show_vector_parameters(self.workingArea.getPlacedSvgs().length > 0);
self.gcodeFilesToAppend = self.workingArea.getPlacedGcodes();
self.show_vector_parameters(self.workingArea.getPlacedSvgs().length > 0);
self.show_fill_areas_checkbox(self.workingArea.hasFilledVectors())
self.images_placed(self.workingArea.getPlacedImages().length > 0);
//self.show_image_parameters(self.workingArea.getPlacedImages().length > 0);
if(self.svg !== undefined){
if(self.laserIntensity() === undefined){
var intensity = self.settings.settings.plugins.svgtogcode.defaultIntensity();
self.laserIntensity(intensity);
}
if(self.laserSpeed() === undefined){
var speed = self.settings.settings.plugins.svgtogcode.defaultFeedrate();
self.laserSpeed(speed);
}
var gcodeFile = self.create_gcode_filename(self.workingArea.placedDesigns());
self.gcodeFilename(gcodeFile);
self.title(gettext("Converting"));
$("#dialog_vector_graphics_conversion").modal("show"); // calls self.convert() afterwards
} else {
// just gcodes were placed. Start lasering right away.
self.convert();
if(self.show_vector_parameters() || self.show_image_parameters()){
if(self.laserIntensity() === undefined){
var intensity = self.settings.settings.plugins.svgtogcode.defaultIntensity();
self.laserIntensity(intensity);
}
if(self.laserSpeed() === undefined){
var speed = self.settings.settings.plugins.svgtogcode.defaultFeedrate();
self.laserSpeed(speed);
}
});
var gcodeFile = self.create_gcode_filename(self.workingArea.placedDesigns());
self.gcodeFilename(gcodeFile);
self.title(gettext("Converting"));
$("#dialog_vector_graphics_conversion").modal("show"); // calls self.convert() afterwards
} else {
// just gcodes were placed. Start lasering right away.
self.convert();
}
};
self.cancel_conversion = function(){
if(self.slicing_in_progress()){
//console.log('cancel slicing', self.slicing_in_progress());
// TODO cancel slicing properly
}
};
self.create_gcode_filename = function(placedDesigns){
@ -235,43 +246,48 @@ $(function(){
if(self.gcodeFilesToAppend.length === 1 && self.svg === undefined){
self.files.startGcodeWithSafetyWarning(self.gcodeFilesToAppend[0]);
} else {
var filename = self.gcodeFilename() + self.settingsString() + '.gco';
var gcodeFilename = self._sanitize(filename);
self.slicing_in_progress(true);
self.workingArea.getCompositionSVG(self.fill_areas(), function(composition){
self.svg = composition;
var filename = self.gcodeFilename() + self.settingsString() + '.gco';
var gcodeFilename = self._sanitize(filename);
var data = {
command: "convert",
"profile.speed": self.laserSpeed(),
"profile.intensity": self.laserIntensity(),
"profile.pierce_time": self.pierceTime(),
"profile.intensity_black" : self.imgIntensityBlack(),
"profile.intensity_white" : self.imgIntensityWhite(),
"profile.feedrate_black" : self.imgFeedrateBlack(),
"profile.feedrate_white" : self.imgFeedrateWhite(),
"profile.img_contrast" : self.imgContrast(),
"profile.img_sharpening" : self.imgSharpening(),
"profile.img_dithering" : self.imgDithering(),
"profile.beam_diameter" : self.beamDiameter(),
slicer: "svgtogcode",
gcode: gcodeFilename
};
var data = {
command: "convert",
"profile.speed": self.laserSpeed(),
"profile.intensity": self.laserIntensity(),
"profile.fill_areas": self.fill_areas(),
"profile.pierce_time": self.pierceTime(),
"profile.intensity_black" : self.imgIntensityBlack(),
"profile.intensity_white" : self.imgIntensityWhite(),
"profile.feedrate_black" : self.imgFeedrateBlack(),
"profile.feedrate_white" : self.imgFeedrateWhite(),
"profile.img_contrast" : self.imgContrast(),
"profile.img_sharpening" : self.imgSharpening(),
"profile.img_dithering" : self.imgDithering(),
"profile.beam_diameter" : self.beamDiameter(),
slicer: "svgtogcode",
gcode: gcodeFilename
};
if(self.svg !== undefined){
data.svg = self.svg;
} else {
data.svg = '<svg height="0" version="1.1" width="0" xmlns="http://www.w3.org/2000/svg"><defs/></svg>';
}
if(self.gcodeFilesToAppend !== undefined){
data.gcodeFilesToAppend = self.gcodeFilesToAppend;
}
if(self.svg !== undefined){
data.svg = self.svg;
} else {
data.svg = '<svg height="0" version="1.1" width="0" xmlns="http://www.w3.org/2000/svg"><defs/></svg>';
}
if(self.gcodeFilesToAppend !== undefined){
data.gcodeFilesToAppend = self.gcodeFilesToAppend;
}
$.ajax({
url: API_BASEURL + "files/convert",
type: "POST",
dataType: "json",
contentType: "application/json; charset=UTF-8",
data: JSON.stringify(data)
});
$.ajax({
url: API_BASEURL + "files/convert",
type: "POST",
dataType: "json",
contentType: "application/json; charset=UTF-8",
data: JSON.stringify(data)
});
}
};
@ -293,29 +309,29 @@ $(function(){
};
self.onEventSlicingStarted = function(payload){
self.slicing_in_progress(true);
console.log("onSlicingDone" , payload);
};
self.onEventSlicingDone = function(payload){
// payload
// gcode: "angelina_20091211_0193_11more_i1000s300.gco"
// gcode: "ex_11more_i1000s300.gco"
// gcode_location: "local"
// stl: "local/angelina_jolie_20091211_0193_11more_i1000s300.svg"
// stl: "local/ex_11more_i1000s300.svg"
// time: 30.612739086151123
self.gcodeFilename(undefined);
self.svg = undefined;
$("#dialog_vector_graphics_conversion").modal("hide");
self.slicing_in_progress(false);
//console.log("onSlicingDone" , payload);
};
self.onEventSlicingCancelled = function(payload){
self.gcodeFilename(undefined);
self.svg = undefined;
self.slicing_in_progress(false);
$("#dialog_vector_graphics_conversion").modal("hide");
console.log("onSlicingCancelled" , payload);
//console.log("onSlicingCancelled" , payload);
};
self.onEventSlicingFailed = function(payload){
self.slicing_in_progress(false);
console.log("onSlicingFailed" , payload);
//console.log("onSlicingFailed" , payload);
};
self._configureIntensitySlider = function() {

File diff suppressed because one or more lines are too long

View file

@ -398,9 +398,13 @@ Snap.plugin(function (Snap, Element, Paper, global) {
var d = '';
var valid = function (val) {
var validRadius = function (val) {
return (isFinite(val) && (val >= 0));
};
var validCoordinate = function (val) {
return (isFinite(val));
};
// Possibly the cubed root of 6, but 1.81 works best
var num = 1.81;
@ -415,7 +419,13 @@ Snap.plugin(function (Snap, Element, Paper, global) {
if (tag === 'circle') {
rx = ry = +old_element.attr('r');
}
// If 'x' and 'y' are not specified, then set both to 0. // CorelDraw is creating that sometimes
if (!validCoordinate(cx))
cx = 0;
if (!validCoordinate(cy))
cy = 0;
d += _convertToString([
['M', (cx - rx), (cy)],
['C', (cx - rx), (cy - ry / num), (cx - rx / num), (cy - ry), (cx), (cy - ry)],
@ -451,14 +461,19 @@ Snap.plugin(function (Snap, Element, Paper, global) {
h = parseFloat(old_element.attr('height'));
// Validity checks from http://www.w3.org/TR/SVG/shapes.html#RectElement:
// If 'x' and 'y' are not specified, then set both to 0. // CorelDraw is creating that sometimes
if (!validCoordinate(x))
x = 0;
if (!validCoordinate(y))
y = 0;
// If neither rx nor ry are properly specified, then set both rx and ry to 0. (This will result in square corners.)
if (!valid(rx) && !valid(ry)) {
if (!validRadius(rx) && !validRadius(ry)) {
rx = ry = 0;
// Otherwise, if a properly specified value is provided for rx, but not for ry, then set both rx and ry to the value of rx.
} else if (valid(rx) && !valid(ry)) {
} else if (validRadius(rx) && !validRadius(ry)) {
ry = rx;
// Otherwise, if a properly specified value is provided for ry, but not for rx, then set both rx and ry to the value of ry.
} else if (valid(ry) && !valid(rx)) {
} else if (validRadius(ry) && !validRadius(rx)) {
rx = ry;
} else { // cap values for rx/ry to half of w/h
rx = Math.min(rx, w/2);

View file

@ -29,7 +29,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
* @returns {path}
*/
Element.prototype.removeUnfilled = function(){
Element.prototype.removeUnfilled = function(fillPaths){
var elem = this;
var selection = [];
var children = elem.children();
@ -46,14 +46,18 @@ Snap.plugin(function (Snap, Element, Paper, global) {
if(goRecursive) {
for (var i = 0; i < children.length; i++) {
var child = children[i];
selection = selection.concat(child.removeUnfilled());
selection = selection.concat(child.removeUnfilled(fillPaths));
}
}
} else {
if(elem.is_filled()){
if(elem.type === 'image'){
selection.push(elem);
} else {
elem.remove();
if(fillPaths && elem.is_filled()){
selection.push(elem);
} else {
elem.remove();
}
}
}
return selection;
@ -70,16 +74,11 @@ Snap.plugin(function (Snap, Element, Paper, global) {
elem.type !== "line" &&
elem.type !== "polygon" &&
elem.type !== "polyline" &&
elem.type !== "path" &&
elem.type !== "image"){
elem.type !== "path" ){
return false;
}
if(elem.type === 'image'){
return true;
}
var fill = elem.attr('fill');
var opacity = elem.attr('fill-opacity');

View file

@ -109,6 +109,8 @@ $(function(){
if(self.state.isOperational() && !self.state.isPrinting()){
var x = self.px2mm(event.offsetX);
var y = self.px2mm(event.toElement.ownerSVGElement.offsetHeight - event.offsetY); // hopefully this works across browsers
x = Math.min(x, self.workingAreaWidthMM());
y = Math.min(y, self.workingAreaHeightMM());
$.ajax({
url: API_BASEURL + "printer/printhead",
type: "POST",
@ -335,7 +337,7 @@ $(function(){
var tooHigh = svgBB.h > waBB.h;
var scale = 1;
if(tooWide || tooHigh){
scale = Math.min(waBB.w / svgBB.w, waBB.h / svgBB.h) - 0.01; // scale minimal smaller to avoid rounding errors
scale = Math.min(waBB.w / svgBB.w, waBB.h / svgBB.h) - 0.0001; // scale minimal smaller to avoid rounding errors
}
var dx = 0;
@ -623,7 +625,7 @@ $(function(){
}
};
self.getCompositionSVG = function(callback){
self.getCompositionSVG = function(fillAreas, callback){
self.abortFreeTransforms();
var wMM = self.workingAreaWidthMM();
var hMM = self.workingAreaHeightMM();
@ -635,8 +637,8 @@ $(function(){
var userContent = snap.select("#userContent").clone();
compSvg.append(userContent);
self.renderInfill(compSvg, wMM, hMM, 10, function(){
callback( self._wrapInSvgAndScale(compSvg));
self.renderInfill(compSvg, fillAreas, wMM, hMM, 10, function(svgWithRenderedInfill){
callback( self._wrapInSvgAndScale(svgWithRenderedInfill));
$('#compSvg').remove();
});
};
@ -684,6 +686,19 @@ $(function(){
return gcodeFiles;
}, self);
self.hasFilledVectors = function(){
var el = snap.selectAll('#userContent *');
for (var i = 0; i < el.length; i++) {
var e = el[i];
var fill = e.attr('fill');
var op = e.attr('fill-opacity');
if(fill !== 'none' && op > 0){
return true;
}
}
return false;
};
self.draw_gcode = function(points, intensity, target){
var stroke_color = intensity === 0 ? '#BBBBBB' : '#FF0000';
@ -697,12 +712,6 @@ $(function(){
};
self.draw_gcode_img_placeholder = function(x,y,w,h,url, target){
var i = snap.rect(x,y,w,h).attr({
stroke: '#AAAAAA',
'stroke-width': 1,
fill: 'none'
});
snap.select(target).append(i);
if(url !== ""){
var p = snap.image(url,x,y,w,h).attr({
transform: 'matrix(1,0,0,-1,0,'+ String(h) +')',
@ -774,7 +783,7 @@ $(function(){
}
// render the infill and inject it as an image into the svg
self.renderInfill = function (svg, wMM, hMM, pxPerMM, callback) {
self.renderInfill = function (svg, fillAreas, wMM, hMM, pxPerMM, callback) {
var wPT = wMM * 90 / 25.4;
var hPT = hMM * 90 / 25.4;
var tmpSvg = Snap(wPT, hPT).attr('id', 'tmpSvg');
@ -782,16 +791,19 @@ $(function(){
var userContent = svg.clone();
tmpSvg.append(userContent);
self._embedAllImages(tmpSvg, function(){
var fillings = userContent.removeUnfilled();
var fillings = userContent.removeUnfilled(fillAreas);
for (var i = 0; i < fillings.length; i++) {
var item = fillings[i];
if (item.type === 'image') {
// remove filter effects on images for proper rendering
var style = item.attr('style');
if (style !== null) {
var strippedFilters = style.replace(/filter.+?;/, '');
item.attr('style', strippedFilters);
}
} else {
// remove stroke from other elements
//item.attr('fill', '#ff0000');
item.attr('stroke', 'none');
}
@ -799,6 +811,7 @@ $(function(){
var cb = function(result) {
if(fillings.length > 0){
// replace all images with the fill rendering
svg.selectAll('image').remove();
var waBB = snap.select('#coordGrid').getBBox();
var fillImage = snap.image(result, 0, 0, waBB.w, waBB.h);

View file

@ -38,6 +38,12 @@
The effect in general is dependent from the material and its color and surface.
</div>
</div>
<label class="control-label">{{ _('Filled areas') }}</label>
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: fill_areas">{{ _('Engrave Infills') }}
</label>
</div>
</div>
<div class="control-group" data-bind="visible: showExpertSettings ">
@ -176,7 +182,7 @@
</label>
</div>
<a href="#" class="btn" data-dismiss="modal" aria-hidden="true">{{ _('Cancel') }}</a>
<a href="#" class="btn" data-dismiss="modal" aria-hidden="true" data-bind="click: $root.cancel_conversion()">{{ _('Cancel') }}</a>
<a href="#" class="btn btn-primary" data-bind="click: function() { if ($root.enableConvertButton()) { $root.convert() } }, enabled: enableConvertButton, css: {disabled: !$root.enableConvertButton()}">{{ _('Convert') }}</a>
</div>
</div>

View file

@ -23,7 +23,7 @@ __copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms
import re
import octoprint.util.comm_acc as comm
import octoprint.util.comm_acc2 as comm
import octoprint.util as util
from octoprint.settings import settings

View file

@ -22,7 +22,7 @@ from octoprint.plugin import plugin_manager, ProgressPlugin
from octoprint.printer import PrinterInterface, PrinterCallback, UnknownScript
from octoprint.printer.estimation import TimeEstimationHelper
from octoprint.settings import settings
from octoprint.util import comm_acc as comm
from octoprint.util import comm_acc2 as comm
from octoprint.util import InvariantContainer

View file

@ -108,11 +108,11 @@ $(function() {
});
}
};
self.rerenderControls = function () {
var allControls = self.controlsFromServer.concat(self.additionalControls);
self.controls(self._processControls(allControls))
self.controls(self._processControls(allControls));
};
self.requestData = function () {

View file

@ -100,7 +100,7 @@ $(function() {
});
}
};
self.fromCurrentData = function(data) {
self._processStateData(data.state);
};
@ -138,7 +138,7 @@ $(function() {
}
});
};
self.fromResponse = function(response, filenameToFocus, locationToFocus) {
var files = response.files;
_.each(files, function(element, index, list) {
@ -267,7 +267,7 @@ $(function() {
return "files_template_dummy";
}
};
self.getEntryId = function(data) {
return "gcode_file_" + md5(data["origin"] + ":" + data["name"]);
};
@ -344,7 +344,7 @@ $(function() {
}
return output;
};
self.performSearch = function(e) {
if (e !== undefined) {
e.preventDefault();
@ -375,7 +375,7 @@ $(function() {
self.enableSVGConversion = function (data) {
return self.loginState.isUser() && !(self.isPrinting() || self.isPaused());
};
self.onStartup = function() {
$(".accordion-toggle[data-target='#files']").click(function() {
var files = $("#files");
@ -610,11 +610,13 @@ $(function() {
$('#take_photo_dialog').on('shown', function () {
$('#photo_preview').photobooth();
var w = $('#photo_preview').width();
var h = $('#photo_preview').height();
var w = $('#photo_preview').parent().width()*0.98;
var h = w*3.0/4.0;
$('#photo_preview').height(h);
$('#photo_preview').width(w);
$('#photo_preview').data('photobooth').resize(w, h);
});
$('#photo_preview').on("image", function (event, dataUrl) {
var photoBlob = self.dataUriToBlob(dataUrl);
var t = new Date();
@ -660,7 +662,7 @@ $(function() {
);
return !!fGetUserMedia;
};
self.dataUriToBlob = function(dataURI) {
// serialize the base64/URLEncoded data
var byteString;

View file

@ -34,6 +34,10 @@ $(function() {
self.currentHeight = ko.observable(undefined);
self.currentPos = ko.observable(undefined);
self.intensityOverride = ko.observable(100);
self.feedrateOverride = ko.observable(100);
self.intensityOverride.extend({ rateLimit: 500 });
self.feedrateOverride.extend({ rateLimit: 500 });
self.TITLE_PRINT_BUTTON_PAUSED = gettext("Restarts the print job from the beginning");
self.TITLE_PRINT_BUTTON_UNPAUSED = gettext("Starts the print job");
@ -281,6 +285,62 @@ $(function() {
self.onEventRealTimeState = function(payload){
self.currentPos({x: payload.wx, y: payload.wy});
};
self.intensityOverride.subscribe(function(factor){
self._overrideCommand("/intensity "+factor);
});
self.feedrateOverride.subscribe(function(factor){
self._overrideCommand("/feedrate "+factor);
});
self._overrideCommand = function(command, callback) {
$.ajax({
url: API_BASEURL + "printer/command",
type: "POST",
dataType: "json",
contentType: "application/json; charset=UTF-8",
data: JSON.stringify({command: command}),
success: function(response) {
if (callback != undefined) {
callback();
}
}
});
};
self._configureOverrideSliders = function() {
self.intensityOverrideSlider = $("#intensity_override_slider").slider({
step: 1,
min: 10,
max: 200,
value: 100,
// tooltip: 'hide'
}).on("slideStop", function(ev){
self.intensityOverride(ev.value);
});
self.feedrateOverrideSlider = $("#feedrate_override_slider").slider({
step: 1,
min: 10,
max: 200,
value: 100,
// tooltip: 'hide'
}).on("slideStop", function(ev){
self.feedrateOverride(ev.value);
});
};
self.onEventPrintDone = function(){
self.feedrateOverrideSlider.slider('setValue', 100);
self.intensityOverrideSlider.slider('setValue', 100);
self.intensityOverride(100);
self.feedrateOverride(100);
};
self.onStartup = function() {
self._configureOverrideSliders();
};
}
OCTOPRINT_VIEWMODELS.push([

View file

@ -155,8 +155,20 @@
{{ _('Timelapse') }}: <strong data-bind="text: timelapseString"></strong><br>
-->
{{ _('Approx. Total Job Time') }}: <strong data-bind="text: estimatedPrintTimeString"></strong><br>
<div class="progress" data-bind="visible: isPrinting() || isPaused()">
<div class="bar" id="job_progressBar" data-bind="style: { width: progressString() + '%' }">&nbsp;{{ _('Processed') }} : <strong data-bind="text: byteString"></strong></div>
<div data-bind="visible: isPrinting() || isPaused()">
<div class="progress">
<div class="bar" id="job_progressBar" data-bind="style: { width: progressString() + '%' }">&nbsp;{{ _('Processed') }} : <strong data-bind="text: byteString"></strong></div>
</div>
<div class="overrideSlider">
<input id="intensity_override_slider" type="text" data-bind="sliderValue: intensityOverride">
<span data-bind="text:intensityOverride()">100</span>% Intensity
</div>
<div class="overrideSlider">
<input id="feedrate_override_slider" type="text" data-bind="sliderValue: feedrateOverride">
<span data-bind="text:feedrateOverride()">100</span>% Feedrate
</div>
</div>
<!-- {{ _('Print Time') }}: <strong data-bind="text: printTimeString"></strong><br>
{{ _('Print Time Left') }}: <strong data-bind="text: printTimeLeftString"></strong><br>-->
@ -270,69 +282,70 @@
<!-- end sidebar -->
<div class="span8">
<div style="position:relative">
{% if webcamStream %}
<div id="webcam_container" tabindex="0"
style="position:absolute; top:0;left:0"
data-bind="style: {
width: workingAreaWidthPx()+'px'
}">
<div id="webcam_rotator" data-bind="css: { rotate90: settings.webcam_rotate90() }">
<img id="webcam_image"
data-bind="css: { flipH: settings.webcam_flipH(), flipV: settings.webcam_flipV() },
style: {
width: workingAreaWidthPx()+'px',
}"/>
</div>
</div>
{% endif %}
<svg id="area_preview" class="workingarea"
data-bind="style: {
backgroundPosition: crosshairX()+'px'+' '+crosshairY()+'px',
width: workingAreaWidthPx()+'px',
height: workingAreaHeightPx()+'px'
}
">
<filter id="grayscale_filter">
<feColorMatrix in="SourceGraphic" type="saturate" values="0"/>
</filter>
<filter id="gcimage_preview">
<feComponentTransfer>
<feFuncR type="table" tableValues="1"></feFuncR>
<feFuncG type="table" tableValues="0.2 1"></feFuncG>
<feFuncB type="table" tableValues="0.2 1"></feFuncB>
</feComponentTransfer>
</filter>
<g id="scaleGroup" data-bind="attr: { transform: scaleMatrix() }">
<rect data-bind="click: move_laser"
id="coordGrid" x="0" y="0" width="0" height="0"
stroke="none" fill="none"></rect>
<text
xml:space="preserve"
data-bind="visible: working_area_empty"
style="font-size:64px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#DDDDDD;fill-opacity:1;stroke:none;font-family:DIN-BoldAlternate;-inkscape-font-specification:DIN-BoldAlternate Bold"
x="396.81018"
y="552.36218"
id="add_designs_hint"
>
<tspan
id="tspan2987" x="368.571426" y="532.36218"
style="text-anchor:middle;text-align:center">add designs via </tspan>
<tspan
x="500" y="592.36218" id="tspan2989"
style="text-anchor:middle;text-align:center">the design library </tspan>
<tspan
x="568.571426" y="652.36218" id="tspan2993"
style="text-anchor:middle;text-align:center">or drag 'n' drop </tspan>
<tspan
x="368.571426" y="712.36218" id="tspan2991"
style="text-anchor:middle;text-align:center" /></text>
<g id="userContent" data-bind="visible: !state.isPrinting() && !state.isPaused()"></g>
<g id="placedGcodes" data-bind="visible: !state.isPrinting() && !state.isPaused(), attr: { transform: scaleMatrixMMtoDisplay() }"></g>
<g id="gCodePreview" data-bind="visible: state.isPrinting() || state.isPaused(), attr: { transform: scaleMatrixMMtoDisplay() }"></g>
</g>
</svg>
</div>
<div style="position:relative">
{% if webcamStream %}
<div id="webcam_container" tabindex="0"
style="position:absolute; top:0;left:0"
data-bind="style: {
width: workingAreaWidthPx()+'px'
}">
<div id="webcam_rotator" data-bind="css: { rotate90: settings.webcam_rotate90() }">
<img id="webcam_image"
data-bind="css: { flipH: settings.webcam_flipH(), flipV: settings.webcam_flipV() },
style: {
width: workingAreaWidthPx()+'px',
}"/>
</div>
</div>
{% endif %}
<svg id="area_preview" class="workingarea"
data-bind="style: {
backgroundPosition: crosshairX()+'px'+' '+crosshairY()+'px',
width: workingAreaWidthPx()+'px',
height: workingAreaHeightPx()+'px'
}
">
<filter id="grayscale_filter">
<feColorMatrix in="SourceGraphic" type="saturate" values="0"/>
</filter>
<filter id="gcimage_preview">
<feComponentTransfer>
<feFuncR type="table" tableValues="1"></feFuncR>
<feFuncG type="table" tableValues="0.2 1"></feFuncG>
<feFuncB type="table" tableValues="0.2 1"></feFuncB>
</feComponentTransfer>
</filter>
<g id="scaleGroup" data-bind="attr: { transform: scaleMatrix() }">
<text
xml:space="preserve"
data-bind="visible: working_area_empty"
style="font-size:64px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#DDDDDD;fill-opacity:1;stroke:none;font-family:DIN-BoldAlternate, Helvetica, Arial, Sans-serif;"
x="396.81018"
y="552.36218"
id="add_designs_hint"
>
<tspan
id="tspan2987" x="368.571426" y="532.36218"
style="text-anchor:middle;text-align:center">add designs via </tspan>
<tspan
x="500" y="592.36218" id="tspan2989"
style="text-anchor:middle;text-align:center">the design library </tspan>
<tspan
x="568.571426" y="652.36218" id="tspan2993"
style="text-anchor:middle;text-align:center">or drag 'n' drop </tspan>
<tspan
x="368.571426" y="712.36218" id="tspan2991"
style="text-anchor:middle;text-align:center" /></text>
<g id="placedGcodes" data-bind="visible: !state.isPrinting() && !state.isPaused(), attr: { transform: scaleMatrixMMtoDisplay() }"></g>
<g id="gCodePreview" data-bind="visible: state.isPrinting() || state.isPaused(), attr: { transform: scaleMatrixMMtoDisplay() }"></g>
<rect data-bind="click: move_laser"
id="coordGrid" x="0" y="0" width="0" height="0"
stroke="none" fill="none"></rect>
<g id="userContent" data-bind="visible: !state.isPrinting() && !state.isPaused()"></g>
</g>
</svg>
</div>
</div>
</div>
</div>

View file

@ -1888,22 +1888,34 @@ class MachineCom(object):
self._doSendWithoutChecksum(commandToSend)
def _doSendWithoutChecksum(self, cmd):
self._log("Send: %s" % cmd)
self.acc_line_lengths.append(len(cmd)+1) # Track number of characters in grbl serial read buffer
try:
self._serial.write(cmd + '\n')
except serial.SerialTimeoutException:
self._log("Serial timeout while writing to serial port, trying again.")
if cmd == "?":
try:
self._serial.write(cmd)
except serial.SerialTimeoutException:
self._log("Serial timeout while writing to serial port, trying again.")
try:
self._serial.write(cmd)
except:
self._log("Unexpected error while writing serial port: %s" % (get_exception_string()))
self._errorValue = get_exception_string()
self.close(True)
else:
self._log("Send: %s" % cmd)
self.acc_line_lengths.append(len(cmd)+1) # Track number of characters in grbl serial read buffer
try:
self._serial.write(cmd + '\n')
except serial.SerialTimeoutException:
self._log("Serial timeout while writing to serial port, trying again.")
try:
self._serial.write(cmd + '\n')
except:
self._log("Unexpected error while writing serial port: %s" % (get_exception_string()))
self._errorValue = get_exception_string()
self.close(True)
except:
self._log("Unexpected error while writing serial port: %s" % (get_exception_string()))
self._errorValue = get_exception_string()
self.close(True)
except:
self._log("Unexpected error while writing serial port: %s" % (get_exception_string()))
self._errorValue = get_exception_string()
self.close(True)
##~~ command handlers
def _gcode_H_sent(self, cmd, cmd_type=None):

File diff suppressed because it is too large Load diff