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
SETTINGS_UPDATED = "SettingsUpdated" SETTINGS_UPDATED = "SettingsUpdated"
# GRBL # GRBL
LIMITS_HIT = "LimitsHit" LIMITS_HIT = "LimitsHit"
SOFT_RESET = "Soft-Reset"
RT_STATE = "RealTimeState" RT_STATE = "RealTimeState"

View file

@ -204,23 +204,7 @@ class FileManager(object):
source_meta = self.get_metadata(source_location, source_path) source_meta = self.get_metadata(source_location, source_path)
hash = source_meta["hash"] 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 import io
#>>>>>>> upstream/maintenance
links = [("model", dict(name=source_path))] links = [("model", dict(name=source_path))]
_, stl_name = self.split_path(source_location, source_path) _, stl_name = self.split_path(source_location, source_path)
file_obj = StreamWrapper(os.path.basename(dest_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 self._printer.is_locked() or self._printer.is_operational():
if "volume" in new_profile: if "volume" in new_profile:
if "width" in new_profile["volume"]: if "width" in new_profile["volume"]:
width = int(new_profile['volume']['width']) width = float(new_profile['volume']['width'])
if identifier == "_mrbeam_senior": if identifier == "_mrbeam_senior":
width *= 2 width *= 2
width += float(new_profile['volume']['origin_offset_x'])
self._printer.commands('$130=' + str(width)) self._printer.commands('$130=' + str(width))
time.sleep(0.1) ### TODO find better solution then sleep time.sleep(0.1) ### TODO find better solution then sleep
if "depth" in new_profile["volume"]: if "depth" in new_profile["volume"]:
depth = int(new_profile['volume']['depth']) depth = float(new_profile['volume']['depth'])
if identifier == "_mrbeam_senior": if identifier == "_mrbeam_senior":
depth *= 2 depth *= 2
depth += float(new_profile['volume']['origin_offset_y'])
self._printer.commands('$131=' + str(depth)) self._printer.commands('$131=' + str(depth))
new_profile["id"] = identifier new_profile["id"] = identifier

View file

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

View file

@ -16,7 +16,9 @@ $(function() {
formFactor: "rectangular", formFactor: "rectangular",
width: 216, width: 216,
depth: 297, depth: 297,
height: 0 height: 0,
origin_offset_x: 1,
origin_offset_y: 1
}, },
zAxis: false, zAxis: false,
axes: { axes: {
@ -108,8 +110,8 @@ $(function() {
self.currentProfile(currentProfile); self.currentProfile(currentProfile);
self.currentProfileData(currentProfileData); self.currentProfileData(currentProfileData);
self.workingarea.workingAreaWidthMM(self.currentProfileData().volume.width()); self.workingarea.workingAreaWidthMM(self.currentProfileData().volume.width() - self.currentProfileData().volume.origin_offset_x());
self.workingarea.workingAreaHeightMM(self.currentProfileData().volume.depth()); 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()); var maxSpeed = Math.min(self.currentProfileData().axes.x.speed(), self.currentProfileData().axes.y.speed());
self.conversion.maxSpeed(maxSpeed); 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} 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 { .slider_manual_input {
margin-left: 1.5em; margin-left: 1.5em;
width: 2.5em; width: 2.5em;
} }
@ -22,7 +22,7 @@ table th.settings_plugin_svgtogcode_profiles_key,table td.settings_plugin_svgtog
} }
.svgtogcode_grayscale { .svgtogcode_grayscale {
background-image: linear-gradient(90deg, #FFFFFF, #000000); background-image: linear-gradient(90deg, #FFFFFF, #000000);
width:220px; width:220px;
display: inline-block; display: inline-block;
} }
@ -37,7 +37,7 @@ svg text {
-ms-user-select: none; -ms-user-select: none;
cursor: default; cursor: default;
pointer-events: none; pointer-events: none;
} }
.img_slider{ .img_slider{
@ -60,8 +60,8 @@ svg text {
left:0; left:0;
} }
.img_preprocessing_preview.after .contrast, .img_preprocessing_preview.after .contrast,
.img_preprocessing_preview.after .sharpened, .img_preprocessing_preview.after .sharpened,
.img_preprocessing_preview.after .sharpened_contrast { .img_preprocessing_preview.after .sharpened_contrast {
opacity: 0; opacity: 0;
} }
@ -87,7 +87,18 @@ svg text {
} }
#photo_preview { #photo_preview {
width: 80vw; width: 400px;
height: 70vh; height: 300px;
margin: auto; 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.laserSpeed = ko.observable(undefined);
self.maxSpeed = ko.observable(3000); self.maxSpeed = ko.observable(3000);
self.minSpeed = ko.observable(20); self.minSpeed = ko.observable(20);
self.fill_areas = ko.observable(false);
self.show_fill_areas_checkbox = ko.observable(false);
// image engraving stuff // image engraving stuff
// preset values are a good start for wood engraving // 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.imgIntensityWhite = ko.observable(0);
self.imgIntensityBlack = ko.observable(500); self.imgIntensityBlack = ko.observable(500);
self.imgFeedrateWhite = ko.observable(1500); self.imgFeedrateWhite = ko.observable(1500);
@ -76,32 +81,38 @@ $(function(){
// shows conversion dialog and extracts svg first // shows conversion dialog and extracts svg first
self.show_conversion_dialog = function() { self.show_conversion_dialog = function() {
self.workingArea.getCompositionSVG(function(composition){ self.gcodeFilesToAppend = self.workingArea.getPlacedGcodes();
self.svg = composition; self.show_vector_parameters(self.workingArea.getPlacedSvgs().length > 0);
self.gcodeFilesToAppend = self.workingArea.getPlacedGcodes(); self.show_fill_areas_checkbox(self.workingArea.hasFilledVectors())
self.show_image_parameters(self.workingArea.getPlacedImages().length > 0); self.images_placed(self.workingArea.getPlacedImages().length > 0);
self.show_vector_parameters(self.workingArea.getPlacedSvgs().length > 0); //self.show_image_parameters(self.workingArea.getPlacedImages().length > 0);
if(self.svg !== undefined){ if(self.show_vector_parameters() || self.show_image_parameters()){
if(self.laserIntensity() === undefined){ if(self.laserIntensity() === undefined){
var intensity = self.settings.settings.plugins.svgtogcode.defaultIntensity(); var intensity = self.settings.settings.plugins.svgtogcode.defaultIntensity();
self.laserIntensity(intensity); self.laserIntensity(intensity);
} }
if(self.laserSpeed() === undefined){ if(self.laserSpeed() === undefined){
var speed = self.settings.settings.plugins.svgtogcode.defaultFeedrate(); var speed = self.settings.settings.plugins.svgtogcode.defaultFeedrate();
self.laserSpeed(speed); 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();
} }
});
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){ self.create_gcode_filename = function(placedDesigns){
@ -235,43 +246,48 @@ $(function(){
if(self.gcodeFilesToAppend.length === 1 && self.svg === undefined){ if(self.gcodeFilesToAppend.length === 1 && self.svg === undefined){
self.files.startGcodeWithSafetyWarning(self.gcodeFilesToAppend[0]); self.files.startGcodeWithSafetyWarning(self.gcodeFilesToAppend[0]);
} else { } else {
var filename = self.gcodeFilename() + self.settingsString() + '.gco'; self.slicing_in_progress(true);
var gcodeFilename = self._sanitize(filename); 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 = { var data = {
command: "convert", command: "convert",
"profile.speed": self.laserSpeed(), "profile.speed": self.laserSpeed(),
"profile.intensity": self.laserIntensity(), "profile.intensity": self.laserIntensity(),
"profile.pierce_time": self.pierceTime(), "profile.fill_areas": self.fill_areas(),
"profile.intensity_black" : self.imgIntensityBlack(), "profile.pierce_time": self.pierceTime(),
"profile.intensity_white" : self.imgIntensityWhite(), "profile.intensity_black" : self.imgIntensityBlack(),
"profile.feedrate_black" : self.imgFeedrateBlack(), "profile.intensity_white" : self.imgIntensityWhite(),
"profile.feedrate_white" : self.imgFeedrateWhite(), "profile.feedrate_black" : self.imgFeedrateBlack(),
"profile.img_contrast" : self.imgContrast(), "profile.feedrate_white" : self.imgFeedrateWhite(),
"profile.img_sharpening" : self.imgSharpening(), "profile.img_contrast" : self.imgContrast(),
"profile.img_dithering" : self.imgDithering(), "profile.img_sharpening" : self.imgSharpening(),
"profile.beam_diameter" : self.beamDiameter(), "profile.img_dithering" : self.imgDithering(),
slicer: "svgtogcode", "profile.beam_diameter" : self.beamDiameter(),
gcode: gcodeFilename slicer: "svgtogcode",
}; gcode: gcodeFilename
};
if(self.svg !== undefined){ if(self.svg !== undefined){
data.svg = self.svg; data.svg = self.svg;
} else { } else {
data.svg = '<svg height="0" version="1.1" width="0" xmlns="http://www.w3.org/2000/svg"><defs/></svg>'; data.svg = '<svg height="0" version="1.1" width="0" xmlns="http://www.w3.org/2000/svg"><defs/></svg>';
} }
if(self.gcodeFilesToAppend !== undefined){ if(self.gcodeFilesToAppend !== undefined){
data.gcodeFilesToAppend = self.gcodeFilesToAppend; 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.onEventSlicingStarted = function(payload){
self.slicing_in_progress(true); self.slicing_in_progress(true);
console.log("onSlicingDone" , payload);
}; };
self.onEventSlicingDone = function(payload){ self.onEventSlicingDone = function(payload){
// payload // payload
// gcode: "angelina_20091211_0193_11more_i1000s300.gco" // gcode: "ex_11more_i1000s300.gco"
// gcode_location: "local" // gcode_location: "local"
// stl: "local/angelina_jolie_20091211_0193_11more_i1000s300.svg" // stl: "local/ex_11more_i1000s300.svg"
// time: 30.612739086151123 // time: 30.612739086151123
self.gcodeFilename(undefined); self.gcodeFilename(undefined);
self.svg = undefined; self.svg = undefined;
$("#dialog_vector_graphics_conversion").modal("hide"); $("#dialog_vector_graphics_conversion").modal("hide");
self.slicing_in_progress(false); self.slicing_in_progress(false);
//console.log("onSlicingDone" , payload);
}; };
self.onEventSlicingCancelled = function(payload){ self.onEventSlicingCancelled = function(payload){
self.gcodeFilename(undefined); self.gcodeFilename(undefined);
self.svg = undefined; self.svg = undefined;
self.slicing_in_progress(false); self.slicing_in_progress(false);
$("#dialog_vector_graphics_conversion").modal("hide"); $("#dialog_vector_graphics_conversion").modal("hide");
console.log("onSlicingCancelled" , payload); //console.log("onSlicingCancelled" , payload);
}; };
self.onEventSlicingFailed = function(payload){ self.onEventSlicingFailed = function(payload){
self.slicing_in_progress(false); self.slicing_in_progress(false);
console.log("onSlicingFailed" , payload); //console.log("onSlicingFailed" , payload);
}; };
self._configureIntensitySlider = function() { 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 d = '';
var valid = function (val) { var validRadius = function (val) {
return (isFinite(val) && (val >= 0)); return (isFinite(val) && (val >= 0));
}; };
var validCoordinate = function (val) {
return (isFinite(val));
};
// Possibly the cubed root of 6, but 1.81 works best // Possibly the cubed root of 6, but 1.81 works best
var num = 1.81; var num = 1.81;
@ -415,7 +419,13 @@ Snap.plugin(function (Snap, Element, Paper, global) {
if (tag === 'circle') { if (tag === 'circle') {
rx = ry = +old_element.attr('r'); 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([ d += _convertToString([
['M', (cx - rx), (cy)], ['M', (cx - rx), (cy)],
['C', (cx - rx), (cy - ry / num), (cx - rx / num), (cy - ry), (cx), (cy - ry)], ['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')); h = parseFloat(old_element.attr('height'));
// Validity checks from http://www.w3.org/TR/SVG/shapes.html#RectElement: // 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 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; 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. // 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; 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. // 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; rx = ry;
} else { // cap values for rx/ry to half of w/h } else { // cap values for rx/ry to half of w/h
rx = Math.min(rx, w/2); rx = Math.min(rx, w/2);

View file

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

View file

@ -109,6 +109,8 @@ $(function(){
if(self.state.isOperational() && !self.state.isPrinting()){ if(self.state.isOperational() && !self.state.isPrinting()){
var x = self.px2mm(event.offsetX); var x = self.px2mm(event.offsetX);
var y = self.px2mm(event.toElement.ownerSVGElement.offsetHeight - event.offsetY); // hopefully this works across browsers 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({ $.ajax({
url: API_BASEURL + "printer/printhead", url: API_BASEURL + "printer/printhead",
type: "POST", type: "POST",
@ -335,7 +337,7 @@ $(function(){
var tooHigh = svgBB.h > waBB.h; var tooHigh = svgBB.h > waBB.h;
var scale = 1; var scale = 1;
if(tooWide || tooHigh){ 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; var dx = 0;
@ -623,7 +625,7 @@ $(function(){
} }
}; };
self.getCompositionSVG = function(callback){ self.getCompositionSVG = function(fillAreas, callback){
self.abortFreeTransforms(); self.abortFreeTransforms();
var wMM = self.workingAreaWidthMM(); var wMM = self.workingAreaWidthMM();
var hMM = self.workingAreaHeightMM(); var hMM = self.workingAreaHeightMM();
@ -635,8 +637,8 @@ $(function(){
var userContent = snap.select("#userContent").clone(); var userContent = snap.select("#userContent").clone();
compSvg.append(userContent); compSvg.append(userContent);
self.renderInfill(compSvg, wMM, hMM, 10, function(){ self.renderInfill(compSvg, fillAreas, wMM, hMM, 10, function(svgWithRenderedInfill){
callback( self._wrapInSvgAndScale(compSvg)); callback( self._wrapInSvgAndScale(svgWithRenderedInfill));
$('#compSvg').remove(); $('#compSvg').remove();
}); });
}; };
@ -684,6 +686,19 @@ $(function(){
return gcodeFiles; return gcodeFiles;
}, self); }, 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){ self.draw_gcode = function(points, intensity, target){
var stroke_color = intensity === 0 ? '#BBBBBB' : '#FF0000'; var stroke_color = intensity === 0 ? '#BBBBBB' : '#FF0000';
@ -697,12 +712,6 @@ $(function(){
}; };
self.draw_gcode_img_placeholder = function(x,y,w,h,url, target){ 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 !== ""){ if(url !== ""){
var p = snap.image(url,x,y,w,h).attr({ var p = snap.image(url,x,y,w,h).attr({
transform: 'matrix(1,0,0,-1,0,'+ String(h) +')', 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 // 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 wPT = wMM * 90 / 25.4;
var hPT = hMM * 90 / 25.4; var hPT = hMM * 90 / 25.4;
var tmpSvg = Snap(wPT, hPT).attr('id', 'tmpSvg'); var tmpSvg = Snap(wPT, hPT).attr('id', 'tmpSvg');
@ -782,16 +791,19 @@ $(function(){
var userContent = svg.clone(); var userContent = svg.clone();
tmpSvg.append(userContent); tmpSvg.append(userContent);
self._embedAllImages(tmpSvg, function(){ self._embedAllImages(tmpSvg, function(){
var fillings = userContent.removeUnfilled(); var fillings = userContent.removeUnfilled(fillAreas);
for (var i = 0; i < fillings.length; i++) { for (var i = 0; i < fillings.length; i++) {
var item = fillings[i]; var item = fillings[i];
if (item.type === 'image') { if (item.type === 'image') {
// remove filter effects on images for proper rendering
var style = item.attr('style'); var style = item.attr('style');
if (style !== null) { if (style !== null) {
var strippedFilters = style.replace(/filter.+?;/, ''); var strippedFilters = style.replace(/filter.+?;/, '');
item.attr('style', strippedFilters); item.attr('style', strippedFilters);
} }
} else { } else {
// remove stroke from other elements
//item.attr('fill', '#ff0000'); //item.attr('fill', '#ff0000');
item.attr('stroke', 'none'); item.attr('stroke', 'none');
} }
@ -799,6 +811,7 @@ $(function(){
var cb = function(result) { var cb = function(result) {
if(fillings.length > 0){ if(fillings.length > 0){
// replace all images with the fill rendering
svg.selectAll('image').remove(); svg.selectAll('image').remove();
var waBB = snap.select('#coordGrid').getBBox(); var waBB = snap.select('#coordGrid').getBBox();
var fillImage = snap.image(result, 0, 0, waBB.w, waBB.h); 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. The effect in general is dependent from the material and its color and surface.
</div> </div>
</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>
<div class="control-group" data-bind="visible: showExpertSettings "> <div class="control-group" data-bind="visible: showExpertSettings ">
@ -176,7 +182,7 @@
</label> </label>
</div> </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> <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>
</div> </div>

View file

@ -23,7 +23,7 @@ __copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms
import re import re
import octoprint.util.comm_acc as comm import octoprint.util.comm_acc2 as comm
import octoprint.util as util import octoprint.util as util
from octoprint.settings import settings 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 import PrinterInterface, PrinterCallback, UnknownScript
from octoprint.printer.estimation import TimeEstimationHelper from octoprint.printer.estimation import TimeEstimationHelper
from octoprint.settings import settings 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 from octoprint.util import InvariantContainer

View file

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

View file

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

View file

@ -34,6 +34,10 @@ $(function() {
self.currentHeight = ko.observable(undefined); self.currentHeight = ko.observable(undefined);
self.currentPos = 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_PAUSED = gettext("Restarts the print job from the beginning");
self.TITLE_PRINT_BUTTON_UNPAUSED = gettext("Starts the print job"); self.TITLE_PRINT_BUTTON_UNPAUSED = gettext("Starts the print job");
@ -281,6 +285,62 @@ $(function() {
self.onEventRealTimeState = function(payload){ self.onEventRealTimeState = function(payload){
self.currentPos({x: payload.wx, y: payload.wy}); 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([ OCTOPRINT_VIEWMODELS.push([

View file

@ -155,8 +155,20 @@
{{ _('Timelapse') }}: <strong data-bind="text: timelapseString"></strong><br> {{ _('Timelapse') }}: <strong data-bind="text: timelapseString"></strong><br>
--> -->
{{ _('Approx. Total Job Time') }}: <strong data-bind="text: estimatedPrintTimeString"></strong><br> {{ _('Approx. Total Job Time') }}: <strong data-bind="text: estimatedPrintTimeString"></strong><br>
<div class="progress" data-bind="visible: isPrinting() || isPaused()"> <div 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 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> </div>
<!-- {{ _('Print Time') }}: <strong data-bind="text: printTimeString"></strong><br> <!-- {{ _('Print Time') }}: <strong data-bind="text: printTimeString"></strong><br>
{{ _('Print Time Left') }}: <strong data-bind="text: printTimeLeftString"></strong><br>--> {{ _('Print Time Left') }}: <strong data-bind="text: printTimeLeftString"></strong><br>-->
@ -270,69 +282,70 @@
<!-- end sidebar --> <!-- end sidebar -->
<div class="span8"> <div class="span8">
<div style="position:relative"> <div style="position:relative">
{% if webcamStream %} {% if webcamStream %}
<div id="webcam_container" tabindex="0" <div id="webcam_container" tabindex="0"
style="position:absolute; top:0;left:0" style="position:absolute; top:0;left:0"
data-bind="style: { data-bind="style: {
width: workingAreaWidthPx()+'px' width: workingAreaWidthPx()+'px'
}"> }">
<div id="webcam_rotator" data-bind="css: { rotate90: settings.webcam_rotate90() }"> <div id="webcam_rotator" data-bind="css: { rotate90: settings.webcam_rotate90() }">
<img id="webcam_image" <img id="webcam_image"
data-bind="css: { flipH: settings.webcam_flipH(), flipV: settings.webcam_flipV() }, data-bind="css: { flipH: settings.webcam_flipH(), flipV: settings.webcam_flipV() },
style: { style: {
width: workingAreaWidthPx()+'px', width: workingAreaWidthPx()+'px',
}"/> }"/>
</div> </div>
</div> </div>
{% endif %} {% endif %}
<svg id="area_preview" class="workingarea" <svg id="area_preview" class="workingarea"
data-bind="style: { data-bind="style: {
backgroundPosition: crosshairX()+'px'+' '+crosshairY()+'px', backgroundPosition: crosshairX()+'px'+' '+crosshairY()+'px',
width: workingAreaWidthPx()+'px', width: workingAreaWidthPx()+'px',
height: workingAreaHeightPx()+'px' height: workingAreaHeightPx()+'px'
} }
"> ">
<filter id="grayscale_filter"> <filter id="grayscale_filter">
<feColorMatrix in="SourceGraphic" type="saturate" values="0"/> <feColorMatrix in="SourceGraphic" type="saturate" values="0"/>
</filter> </filter>
<filter id="gcimage_preview"> <filter id="gcimage_preview">
<feComponentTransfer> <feComponentTransfer>
<feFuncR type="table" tableValues="1"></feFuncR> <feFuncR type="table" tableValues="1"></feFuncR>
<feFuncG type="table" tableValues="0.2 1"></feFuncG> <feFuncG type="table" tableValues="0.2 1"></feFuncG>
<feFuncB type="table" tableValues="0.2 1"></feFuncB> <feFuncB type="table" tableValues="0.2 1"></feFuncB>
</feComponentTransfer> </feComponentTransfer>
</filter> </filter>
<g id="scaleGroup" data-bind="attr: { transform: scaleMatrix() }"> <g id="scaleGroup" data-bind="attr: { transform: scaleMatrix() }">
<rect data-bind="click: move_laser"
id="coordGrid" x="0" y="0" width="0" height="0" <text
stroke="none" fill="none"></rect> xml:space="preserve"
<text data-bind="visible: working_area_empty"
xml:space="preserve" 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;"
data-bind="visible: working_area_empty" x="396.81018"
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" y="552.36218"
x="396.81018" id="add_designs_hint"
y="552.36218" >
id="add_designs_hint" <tspan
> id="tspan2987" x="368.571426" y="532.36218"
<tspan style="text-anchor:middle;text-align:center">add designs via </tspan>
id="tspan2987" x="368.571426" y="532.36218" <tspan
style="text-anchor:middle;text-align:center">add designs via </tspan> x="500" y="592.36218" id="tspan2989"
<tspan style="text-anchor:middle;text-align:center">the design library </tspan>
x="500" y="592.36218" id="tspan2989" <tspan
style="text-anchor:middle;text-align:center">the design library </tspan> x="568.571426" y="652.36218" id="tspan2993"
<tspan style="text-anchor:middle;text-align:center">or drag 'n' drop </tspan>
x="568.571426" y="652.36218" id="tspan2993" <tspan
style="text-anchor:middle;text-align:center">or drag 'n' drop </tspan> x="368.571426" y="712.36218" id="tspan2991"
<tspan style="text-anchor:middle;text-align:center" /></text>
x="368.571426" y="712.36218" id="tspan2991" <g id="placedGcodes" data-bind="visible: !state.isPrinting() && !state.isPaused(), attr: { transform: scaleMatrixMMtoDisplay() }"></g>
style="text-anchor:middle;text-align:center" /></text> <g id="gCodePreview" data-bind="visible: state.isPrinting() || state.isPaused(), attr: { transform: scaleMatrixMMtoDisplay() }"></g>
<g id="userContent" data-bind="visible: !state.isPrinting() && !state.isPaused()"></g> <rect data-bind="click: move_laser"
<g id="placedGcodes" data-bind="visible: !state.isPrinting() && !state.isPaused(), attr: { transform: scaleMatrixMMtoDisplay() }"></g> id="coordGrid" x="0" y="0" width="0" height="0"
<g id="gCodePreview" data-bind="visible: state.isPrinting() || state.isPaused(), attr: { transform: scaleMatrixMMtoDisplay() }"></g> stroke="none" fill="none"></rect>
</g> <g id="userContent" data-bind="visible: !state.isPrinting() && !state.isPaused()"></g>
</svg> </g>
</div> </svg>
</div>
</div> </div>
</div> </div>
</div> </div>

View file

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

File diff suppressed because it is too large Load diff