Compare commits

..

11 commits

24 changed files with 2213 additions and 2306 deletions

View file

@ -1,6 +1,5 @@
OctoPrint OctoPrint
========= =========
What I did was take the MrBeam fork of Octoprint (because I have a MrBeam, and I like it) - and modify it for pen plotting with an axidraw v3 clone.
[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=foosel&url=https://github.com/foosel/OctoPrint&title=OctoPrint&language=&tags=github&category=software) [![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=foosel&url=https://github.com/foosel/OctoPrint&title=OctoPrint&language=&tags=github&category=software)

View file

@ -97,7 +97,7 @@ def update_source(git_executable, folder, target, force=False):
raise RuntimeError("Could not update, \"git reset --hard\" failed with returncode %d: %s" % (returncode, stdout)) raise RuntimeError("Could not update, \"git reset --hard\" failed with returncode %d: %s" % (returncode, stdout))
print(">>> Running: git pull") print(">>> Running: git pull")
returncode, stdout = _git(["pull", "origin", "stable-1.2.2"], folder, git_executable=git_executable) returncode, stdout = _git(["pull"], folder, git_executable=git_executable)
if returncode != 0: if returncode != 0:
raise RuntimeError("Could not update, \"git pull\" failed with returncode %d: %s" % (returncode, stdout)) raise RuntimeError("Could not update, \"git pull\" failed with returncode %d: %s" % (returncode, stdout))
print(stdout) print(stdout)

View file

@ -158,7 +158,7 @@ $(function() {
text += "<small>" + gettext("Those components marked with <i class=\"icon-ok\"></i> can be updated directly.") + "</small>"; text += "<small>" + gettext("Those components marked with <i class=\"icon-ok\"></i> can be updated directly.") + "</small>";
var options = { var options = {
title: gettext("Mr Beam Update Available"), title: gettext("Update Available"),
text: text, text: text,
hide: false hide: false
}; };

View file

@ -235,7 +235,7 @@ class SvgToGcodePlugin(octoprint.plugin.SlicerPlugin,
def get_assets(self): def get_assets(self):
return dict( return dict(
js=[ "js/convert.js", "js/working_area.js", "js/gcode_parser.js", "js/lib/snap.svg-min.js", "js/lib/photobooth_min.js", "js/matrix_oven.js", "js/render_fills.js", "js/drag_scale_rotate.js"], js=[ "js/convert.js", "js/working_area.js", "js/gcode_parser.js", "js/lib/snap.svg-min.js", "js/lib/photobooth_min.js", "js/matrix_oven.js", "js/render_fills.js", "js/drag_scale_rotate.js", "js/svg2gcode.js"],
less=["less/svgtogcode.less"], less=["less/svgtogcode.less"],
css=["css/svgtogcode.css", "css/mrbeam.css"] css=["css/svgtogcode.css", "css/mrbeam.css"]
) )
@ -270,7 +270,7 @@ class SvgToGcodePlugin(octoprint.plugin.SlicerPlugin,
feedrate = max(1,data["defaultFeedrate"]) feedrate = max(1,data["defaultFeedrate"])
s.set(["defaultFeedrate"], feedrate) s.set(["defaultFeedrate"], feedrate)
if "svgDPI" in data and data["svgDPI"]: if "svgDPI" in data and data["svgDPI"]:
s.set_int(["svgDPI"], data["svgDPI"]) s.set(["svgDPI"], data["svgDPI"])
if "debug_logging" in data: if "debug_logging" in data:
old_debug_logging = s.get_boolean(["debug_logging"]) old_debug_logging = s.get_boolean(["debug_logging"])
new_debug_logging = data["debug_logging"] in octoprint.settings.valid_boolean_trues new_debug_logging = data["debug_logging"] in octoprint.settings.valid_boolean_trues
@ -357,8 +357,6 @@ class SvgToGcodePlugin(octoprint.plugin.SlicerPlugin,
converter_path = '/home/teja/workspace/mrbeam-inkscape-ext' converter_path = '/home/teja/workspace/mrbeam-inkscape-ext'
elif("denkbrett" in hostname): elif("denkbrett" in hostname):
converter_path = '/home/flo/mrbeam/git/mrbeam-inkscape-ext' converter_path = '/home/flo/mrbeam/git/mrbeam-inkscape-ext'
elif ("clems-Air" in hostname):
converter_path = '/Users/clem/Dropbox/mrBeam/mrbeam-inkscape-ext'
import sys import sys
sys.path.append(converter_path) sys.path.append(converter_path)

View file

@ -1160,7 +1160,6 @@ ul.dropdown-menu li a {
#control_zaxis { #control_zaxis {
display:inline-block; display:inline-block;
width: 80px; width: 80px;
margin: 1em auto 0;
} }
#control_zaxis_focus { #control_zaxis_focus {
display:inline-block; display:inline-block;
@ -1542,7 +1541,7 @@ td.settings_printerProfiles_profiles_action a.disabled {
.nav-pills>li>a, .nav-pills>li>a,
select, select,
textarea, textarea,
input, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"], input,
input.search-query, input.search-query,
.uneditable-input, .uneditable-input,
.input-append .add-on:last-child, .input-append .add-on:last-child,

View file

@ -102,28 +102,3 @@ svg text {
.overrideSlider span { .overrideSlider span {
padding-left: .6em; padding-left: .6em;
} }
.repeatGcode .btn-group {
width: 145px;
}
.repeatGcode input, .repeatGcode button {
width: 33%;
}
.repeatGcode input {
margin-bottom:0;
padding-left: 0;
padding-right: 0;
text-align: center;
}
.repeatGcode>span {
padding-left: .6em;
}
.manual_position_input {
padding-top: 12px;
}
#manual_position.warning {
color: #DD0000;
}

View file

@ -41,10 +41,8 @@ $(function(){
// 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.images_placed = ko.observable(false); self.images_placed = ko.observable(false);
self.text_placed = ko.observable(false);
self.show_image_parameters = ko.computed(function(){ self.show_image_parameters = ko.computed(function(){
return (self.images_placed() || self.text_placed() return self.images_placed() || (self.fill_areas() && self.show_vector_parameters());
|| (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);
@ -76,7 +74,6 @@ $(function(){
} }
}, self); }, self);
self.maxSpeed.subscribe(function(val){ self.maxSpeed.subscribe(function(val){
self._configureFeedrateSlider(); self._configureFeedrateSlider();
}); });
@ -87,7 +84,6 @@ $(function(){
self.show_vector_parameters(self.workingArea.getPlacedSvgs().length > 0); self.show_vector_parameters(self.workingArea.getPlacedSvgs().length > 0);
self.show_fill_areas_checkbox(self.workingArea.hasFilledVectors()) self.show_fill_areas_checkbox(self.workingArea.hasFilledVectors())
self.images_placed(self.workingArea.getPlacedImages().length > 0); self.images_placed(self.workingArea.getPlacedImages().length > 0);
self.text_placed(self.workingArea.hasTextItems());
//self.show_image_parameters(self.workingArea.getPlacedImages().length > 0); //self.show_image_parameters(self.workingArea.getPlacedImages().length > 0);
if(self.show_vector_parameters() || self.show_image_parameters()){ if(self.show_vector_parameters() || self.show_image_parameters()){
@ -282,6 +278,10 @@ $(function(){
data.gcodeFilesToAppend = self.gcodeFilesToAppend; data.gcodeFilesToAppend = self.gcodeFilesToAppend;
} }
var snapelement = snap.select("#userContent");
snapelement.bake(false, 5);
data.gcodedata = snapelement.toGcode(self.laserSpeed(), self.laserIntensity(), self.pierceTime());
$.ajax({ $.ajax({
url: API_BASEURL + "files/convert", url: API_BASEURL + "files/convert",
type: "POST", type: "POST",
@ -289,7 +289,6 @@ $(function(){
contentType: "application/json; charset=UTF-8", contentType: "application/json; charset=UTF-8",
data: JSON.stringify(data) data: JSON.stringify(data)
}); });
}); });
} }
}; };

View file

@ -79,7 +79,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
handleFill: "red", handleFill: "red",
handleStrokeDashPreset: [5,5], handleStrokeDashPreset: [5,5],
handleStrokeWidth: 2, handleStrokeWidth: 2,
handleLength: 18, handleLength: 10,
handleRadius: 16, handleRadius: 16,
unscale: 1, unscale: 1,
handleStrokeDash: "5,5", handleStrokeDash: "5,5",
@ -135,7 +135,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
this.data("ty", 0); this.data("ty", 0);
this.attr({class:'_freeTransformInProgress'}); this.attr({class:'_freeTransformInProgress'});
ftOption.unscale = 1 / this.paper.select('#scaleGroup').transform().localMatrix.a; ftOption.unscale = 1 / this.paper.select('#scaleGroup').transform().globalMatrix.a;
this.data('unscale', ftOption.unscale); this.data('unscale', ftOption.unscale);
ftOption.handleStrokeDash = ftOption.handleStrokeDashPreset.map(function(v){ return v*ftOption.unscale; }).join(','); ftOption.handleStrokeDash = ftOption.handleStrokeDashPreset.map(function(v){ return v*ftOption.unscale; }).join(',');
return this; return this;
@ -208,10 +208,10 @@ Snap.plugin(function (Snap, Element, Paper, global) {
// transformed bbox // transformed bbox
this.data("bbT", this.paper.rect( rectObjFromBB( this.getBBox(1) ) ) this.data("bbT", this.paper.rect( rectObjFromBB( this.getBBox(1) ) )
.attr({ fill: "none", stroke: ftOption.handleFill, strokeWidth: ftOption.handleStrokeWidth, strokeDasharray: ftOption.handleStrokeDashPreset.join(',') }) .attr({ fill: "none", stroke: ftOption.handleFill, strokeWidth: ftOption.handleStrokeWidth, strokeDasharray: ftOption.handleStrokeDashPreset.join(',') })
.transform( this.transform().global.toString() ) ); .transform( this.transform().local.toString() ) );
// outer bbox // outer bbox
this.data("bb", this.paper.select('#userContent').rect( rectObjFromBB( this.getBBox() ) ) this.data("bb", this.paper.select('#userContent').rect( rectObjFromBB( this.getBBox() ) )
.attr({ fill: "none", stroke: 'gray', strokeWidth: ftOption.handleStrokeWidth, strokeDasharray: ftOption.handleStrokeDash }) ); .attr({ fill: "none", stroke: 'gray', strokeWidth: 0.6, strokeDasharray: [2,2] }) );
return this; return this;
}; };
@ -298,7 +298,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
if(!mainEl.data('block_rotation')){ if(!mainEl.data('block_rotation')){
var angle = Snap.angle( mainBB.cx, mainBB.cy, handle.attr('cx'), handle.attr('cy') ) - 180; var angle = Snap.angle( mainBB.cx, mainBB.cy, handle.attr('cx'), handle.attr('cy') ) - 180;
if(event.shiftKey){ if(event.shiftKey){
angle = Math.round(angle/30) * 30; angle = Math.round(angle/15) * 15;
} }
mainEl.data("angle", angle ); mainEl.data("angle", angle );
} }

View file

@ -30,15 +30,14 @@ Snap.plugin(function (Snap, Element, Paper, global) {
*/ */
Element.prototype.bake = function (toCubics, dec) { Element.prototype.bake = function (toCubics, dec) {
var elem = this; var elem = this;
if (!elem || !elem.paper) // don't handle unplaced elements. this causes double handling.
if (!elem || !elem.paper || elem.type !== "text" || elem.type !== "#text" || elem.type !== "tspan"){
return; return;
} // don't handle unplaced elements. this causes double handling.
if (typeof (toCubics) === 'undefined') if (typeof (toCubics) === 'undefined')
toCubics = false; toCubics = false;
if (typeof (dec) === 'undefined') if (typeof (dec) === 'undefined')
dec = 5; dec = 5;
//var children = elem.selectAll('*')
var children = elem.children(); var children = elem.children();
if (children.length > 0) { if (children.length > 0) {
for (var i = 0; i < children.length; i++) { for (var i = 0; i < children.length; i++) {
@ -55,15 +54,14 @@ Snap.plugin(function (Snap, Element, Paper, global) {
elem.type !== "polygon" && elem.type !== "polygon" &&
elem.type !== "polyline" && elem.type !== "polyline" &&
elem.type !== "image" && elem.type !== "image" &&
elem.type !== "path" && elem.type !== "path"){
elem.type !== "text" &&
elem.type !== "tspan" && // if(elem.type !== 'g' && elem.type !== 'desc' && elem.type !== 'defs')
elem.type !== "#text"){ // console.log('skipping unsupported element ', elem.type);
return; return;
} }
if (elem.type == 'image'){
if (elem.type == 'image' || elem.type == "text" || elem.type == "#text"){
// TODO ... // TODO ...
var x = parseFloat(elem.attr('x')), var x = parseFloat(elem.attr('x')),
y = parseFloat(elem.attr('y')), y = parseFloat(elem.attr('y')),
@ -91,6 +89,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
return; return;
} }
//if(elem.type !== 'path') console.log("bake: converting " + elem.type + " to path");
var path_elem = elem.convertToPath(); var path_elem = elem.convertToPath();
if (!path_elem || path_elem.attr('d') === '' || path_elem.attr('d') === null) if (!path_elem || path_elem.attr('d') === '' || path_elem.attr('d') === null)
@ -439,19 +438,6 @@ Snap.plugin(function (Snap, Element, Paper, global) {
// 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;
var tag = old_element.type; var tag = old_element.type;
var convertMMtoPixel = function (val) {
attrList = ['rx','ry','r','cx','cy','x1','x2','y1','y2','x','y','width','height'];
for(var attrIdx in attrList) {
if(val.attr(attrList[attrIdx]) != null && val.attr(attrList[attrIdx]).indexOf('mm') > -1) {
var tmp = parseFloat(val.attr(attrList[attrIdx])) * 3.5433;
val.attr(attrList[attrIdx], tmp);
}
}
}
convertMMtoPixel(old_element);
switch (tag) { switch (tag) {
case 'ellipse': case 'ellipse':
case 'circle': case 'circle':

View file

@ -50,7 +50,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
} }
} }
} else { } else {
if(elem.type === 'image' || elem.type === "text" || elem.type === "#text"){ if(elem.type === 'image'){
selection.push(elem); selection.push(elem);
} else { } else {
if(fillPaths && elem.is_filled()){ if(fillPaths && elem.is_filled()){
@ -74,10 +74,7 @@ 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 !== "text" &&
// elem.type !== "#text"
){
return false; return false;
} }
@ -124,7 +121,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
// get svg as dataUrl // get svg as dataUrl
var svgStr = elem.outerSVG(); var svgStr = elem.outerSVG();
var svgDataUri = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgStr))); //deprecated unescape needed! var svgDataUri = 'data:image/svg+xml;base64,' + window.btoa(svgStr);
var source = new Image(); var source = new Image();
source.src = svgDataUri; source.src = svgDataUri;

View file

@ -0,0 +1,154 @@
Snap.plugin(function (Snap, Element, Paper, global) {
/**
* generates and returns the svg as gcode
*
* @param {integer} laserSpeed : value for laser speed
* @param {integer} laserIntensity : value for laser intensity
* @param {integer} pierceTime : value for pierce time
* @returns {list}
*/
Element.prototype.toGcode = function (laserSpeed, laserIntensity, pierceTime) {
var gCodeList = [];
gCodeList.push(";Generated with svg2gcode Version 0.1\n");
gCodeList.push("G21\n");
//gCodeList.push("G1F" + laserSpeed + "\n");
svgWidth = this.paper.attr('viewBox').width;
svgHeight = this.paper.attr('viewBox').height;
feedrateSet = 0;
var elem = this.selectAll("path");
for (var i = 0; i < elem.length; i++) {
gCodeList.push(elem[i].pathStringToGCode(laserIntensity, laserSpeed, pierceTime));
}
// Always append a M5 command to be sure the Laser is OFF
gCodeList.push("\nM5");
return gCodeList;
}
Element.prototype.pathStringToGCode = function (laserIntensity, laserSpeed, pierceTime) {
if (this.type !== "path") {
return this;
}
var gcode = [];
var startP = [0, 0];
var lastP = [0, 0];
var lastXstr = "";
var lastYstr = "";
var xStr = "";
var yStr = "";
var laser = 0;
var arr = Snap.parsePathString(Snap.path.toAbsolute(this.realPath));
gcode.push(";NEW PATH STRING")
for (var i = 0; i < arr.length; i++) {
if (arr[i][0] == "M") {
xStr = Math.round(arr[i][1] * 100) / 100;
yStr = Math.round((svgHeight - arr[i][2]) * 100) / 100;
if (laser == 1) {
gcode.push("M3S0");
}
if (xStr != lastXstr && yStr != lastYstr) {
gcode.push("G0X" + xStr + "Y" + yStr);
lastXstr = xStr;
lastYstr = yStr;
} else if (xStr != lastXstr) {
gcode.push("G0X" + xStr);
lastXstr = xStr;
} else if (yStr != lastYstr) {
gcode.push("G0Y" + yStr);
lastYstr = yStr;
}
if (feedrateSet == 0) {
gcode.push("G1F" + laserSpeed);
feedrateSet = 1;
}
gcode.push("M3S" + laserIntensity);
laser = 1
if (pierceTime != 0) {
gcode.push("G4P" + pierceTime);
}
startP = [arr[i][1], (svgHeight - arr[i][2])];
lastP = startP;
} else if (arr[i][0] == "L") {
xStr = Math.round(arr[i][1] * 100) / 100;
yStr = Math.round((svgHeight - arr[i][2]) * 100) / 100;
if (xStr != lastXstr && yStr != lastYstr) {
gcode.push("G1X" + xStr + "Y" + yStr);
lastXstr = xStr;
lastYstr = yStr;
} else if (xStr != lastXstr) {
gcode.push("G1X" + xStr);
lastXstr = xStr;
} else if (yStr != lastYstr) {
gcode.push("G1Y" + yStr);
lastYstr = yStr;
}
lastP = [arr[i][1], (svgHeight - arr[i][2])];
} else if (arr[i][0] == "H") {
xStr = Math.round(arr[i][1] * 100) / 100;
gcode.push("G1X" + xStr);
lastXstr = xStr;
lastP = [arr[i][1], lastP[1]];
} else if (arr[i][0] == "V") {
yStr = Math.round((svgHeight - arr[i][1]) * 100) / 100;
gcode.push("G1Y" + yStr);
lastYstr = yStr;
lastP = [lastP[0], (svgHeight - arr[i][1])];
} else if (arr[i][0] == "C") {
var x0 = lastP[0];
var y0 = lastP[1];
var x1 = arr[i][1];
var y1 = (svgHeight - arr[i][2]);
var x2 = arr[i][3];
var y2 = (svgHeight - arr[i][4]);
var x3 = arr[i][5];
var y3 = (svgHeight - arr[i][6]);
var tmp = Snap.path.getTotalLength("M" + lastP[0] + "," + lastP[1] + "C" + x1 + "," + y1 + "," + x2 + "," + y2 + "," + x3 + "," + y3);
var range = Math.round(tmp) * 10;
for (var t = 1; t <= range; t++) {
obj = Snap.path.findDotsAtSegment(x0, y0, x1, y1, x2, y2, x3, y3, t / range)
xStr = Math.round(obj.x * 100) / 100;
yStr = Math.round(obj.y * 100) / 100;
if (xStr != lastXstr && yStr != lastYstr) {
gcode.push("G1X" + xStr + "Y" + yStr);
lastXstr = xStr;
lastYstr = yStr;
} else if (xStr != lastXstr) {
gcode.push("G1X" + xStr);
lastXstr = xStr;
} else if (yStr != lastYstr) {
gcode.push("G1Y" + yStr);
lastYstr = yStr;
}
}
lastP = [x3, y3];
} else if (arr[i][0] == "Q") {
// TODO implement Q path element
gcode.push("NOT_IMPLEMENTED");
} else if (arr[i][0] == "A") {
// TODO implement A path element
gcode.push("NOT_IMPLEMENTED");
} else if (arr[i][0] == "Z") {
xStr = Math.round(startP[0] * 100) / 100;
yStr = Math.round(startP[1] * 100) / 100;
if (xStr != lastXstr && yStr != lastYstr) {
gcode.push("G1X" + xStr + "Y" + yStr);
lastXstr = xStr;
lastYstr = yStr;
} else if (xStr != lastXstr) {
gcode.push("G1X" + xStr);
lastXstr = xStr;
} else if (yStr != lastYstr) {
gcode.push("G1Y" + yStr);
lastYstr = yStr;
}
}
}
gcode.push("M3S0\n")
//console.log(gcode.join("\n").length)
return gcode.join("\n");
}
});

View file

@ -1,20 +1,5 @@
$(function(){ $(function(){
// Opera 8.0+
var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
// Firefox 1.0+
var isFirefox = typeof InstallTrigger !== 'undefined';
// At least Safari 3+: "[object HTMLElementConstructor]"
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
// Internet Explorer 6-11
var isIE = /*@cc_on!@*/false || !!document.documentMode;
// Edge 20+
var isEdge = !isIE && !!window.StyleMedia;
// Chrome 1+
var isChrome = !!window.chrome && !!window.chrome.webstore;
// Blink engine detection
var isBlink = (isChrome || isOpera) && !!window.CSS;
function WorkingAreaViewModel(params) { function WorkingAreaViewModel(params) {
var self = this; var self = this;
@ -79,7 +64,8 @@ $(function(){
// matrix scales svg units to display_pixels // matrix scales svg units to display_pixels
self.scaleMatrix = ko.computed(function(){ self.scaleMatrix = ko.computed(function(){
var m = new Snap.Matrix(); var m = new Snap.Matrix();
var factor = 25.4/self.svgDPI() * 1/self.px2mm_factor(); //var factor = 25.4/self.svgDPI() * 1/self.px2mm_factor();
var factor = 1;
if(!isNaN(factor)){ if(!isNaN(factor)){
m.scale(factor); m.scale(factor);
return m; return m;
@ -107,7 +93,6 @@ $(function(){
self.clear = function(){ self.clear = function(){
snap.selectAll('#userContent>*').remove(); snap.selectAll('#userContent>*').remove();
snap.selectAll('#placedGcodes>*').remove(); snap.selectAll('#placedGcodes>*').remove();
snap.selectAll('rect:not(#coordGrid)').remove();
self.placedDesigns([]); self.placedDesigns([]);
}; };
@ -118,34 +103,24 @@ $(function(){
self.availableWidth($('#workingarea div.span8').innerWidth()); self.availableWidth($('#workingarea div.span8').innerWidth());
}; };
self.move_laser = function(data, evt){ self.move_laser = function(el){
self.abortFreeTransforms(); self.abortFreeTransforms();
if(self.state.isOperational() && !self.state.isPrinting()){ if(self.state.isOperational() && !self.state.isPrinting()){
var coord = self.getXYCoord(evt); 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({ $.ajax({
url: API_BASEURL + "printer/printhead", url: API_BASEURL + "printer/printhead",
type: "POST", type: "POST",
dataType: "json", dataType: "json",
contentType: "application/json; charset=UTF8", contentType: "application/json; charset=UTF8",
data: JSON.stringify({"command": "position", x:coord.x, y:coord.y}) data: JSON.stringify({"command": "position", x:x, y:y})
}); });
} }
}; };
self.getXYCoord = function(evt){
if(/firefox/.test(navigator.userAgent.toLowerCase())) {
var scale = evt.target.parentElement.transform.baseVal[0].matrix.a;
var x = self.px2mm(evt.offsetX) * scale;
var y = self.px2mm(parseFloat(evt.target.attributes.height.value) - evt.offsetY) * scale;
} else
{
var x = self.px2mm(evt.offsetX);
var y = self.px2mm(parseFloat(evt.target.farthestViewportElement.clientHeight) - evt.offsetY);
}
x = Math.min(x, self.workingAreaWidthMM());
y = Math.min(y, self.workingAreaHeightMM());
return {x:x, y:y};
}
self.crosshairX = function(){ self.crosshairX = function(){
var pos = self.state.currentPos(); var pos = self.state.currentPos();
@ -153,7 +128,7 @@ $(function(){
}; };
self.crosshairY = function(){ self.crosshairY = function(){
var h = Snap($('#area_preview')[0]).getBBox().height; var h = document.getElementById('area_preview').clientHeight;
var pos = self.state.currentPos(); var pos = self.state.currentPos();
return pos !== undefined ? (h - self.mm2px(pos.y) - 15) : -100; // subtract height/2; return pos !== undefined ? (h - self.mm2px(pos.y) - 15) : -100; // subtract height/2;
}; };
@ -243,26 +218,11 @@ $(function(){
var url = self._getSVGserveUrl(file); var url = self._getSVGserveUrl(file);
callback = function (f) { callback = function (f) {
var newSvgAttrs = {}; var newSvgAttrs = {};
if(f.select('svg') == null){
root_attrs = f.node.attributes;
} else {
var root_attrs = f.select('svg').node.attributes; var root_attrs = f.select('svg').node.attributes;
}
var doc_width = null; var doc_width = null;
var doc_height = null; var doc_height = null;
var doc_viewbox = null; var doc_viewbox = null;
// find clippath elements
var clipPathEl = f.selectAll('clipPath');
if(clipPathEl.length != 0){
console.warn("Warning: removed unsupported clipPath element in SVG");
self.svg_contains_clipPath_warning();
clipPathEl.remove()
}
// find all elements with "display=none" and remove them
f.selectAll("[display=none]").remove()
// iterate svg tag attributes // iterate svg tag attributes
for(var i = 0; i < root_attrs.length; i++){ for(var i = 0; i < root_attrs.length; i++){
var attr = root_attrs[i]; var attr = root_attrs[i];
@ -278,19 +238,10 @@ $(function(){
} }
} }
// find Illustrator comment and notify
f.node.childNodes.forEach(function(entry) {
if(entry.nodeType == 8) { // Nodetype 8 = comment
if(entry.textContent.indexOf('Illustrator') > -1) {
new PNotify({title: gettext("Illustrator SVG Detected"), text: "Illustrator SVG detected! To preserve coorect scale, please go to the \'Settings\' menu and change the \'SVG dpi\' field under \'Plugins/Svg Conversion\' according to your file. And add it again.", type: "info", hide: false});
}
}
});
// scale matrix // scale matrix
var scale = self.svgDPI()/25.4;
var mat = self.getDocumentViewBoxMatrix(doc_width, doc_height, doc_viewbox); var mat = self.getDocumentViewBoxMatrix(doc_width, doc_height, doc_viewbox);
var dpiscale = 90 / self.settings.settings.plugins.svgtogcode.svgDPI(); var scaleMatrixStr = new Snap.Matrix(mat[0][0]/scale,mat[0][1],mat[1][0],mat[1][1]/scale,mat[0][2],mat[1][2]).toTransformString();
var scaleMatrixStr = new Snap.Matrix(mat[0][0],mat[0][1],mat[1][0],mat[1][1],mat[0][2],mat[1][2]).scale(dpiscale).toTransformString();
newSvgAttrs['transform'] = scaleMatrixStr; newSvgAttrs['transform'] = scaleMatrixStr;
var newSvg = snap.group(f.selectAll("svg>*")); var newSvg = snap.group(f.selectAll("svg>*"));
@ -416,20 +367,8 @@ $(function(){
}; };
}; };
self.svg_contains_clipPath_warning = function(){
var error = "<p>" + gettext("The SVG file contains clipPath elements.<br/>clipPath is not supported yet and has been removed from file.") + "</p>";
//error += pnotifyAdditionalInfo("<pre>" + data.jqXHR.responseText + "</pre>");
new PNotify({
title: "clipPath elements removed",
text: error,
type: "warn",
hide: false
});
};
self.svg_contains_text_warning = function(svg){ self.svg_contains_text_warning = function(svg){
var error = "<p>" + gettext("The SVG file contains text elements.<br/>If you want to laser just their outlines,<br/>please convert them to paths.<br/>Otherwise they will be engraved with infill.") + "</p>"; var error = "<p>" + gettext("The svg file contains text elements.<br/>Please convert them to paths.<br/>Otherwise they will be ignored.") + "</p>";
//error += pnotifyAdditionalInfo("<pre>" + data.jqXHR.responseText + "</pre>"); //error += pnotifyAdditionalInfo("<pre>" + data.jqXHR.responseText + "</pre>");
new PNotify({ new PNotify({
title: "Text elements found", title: "Text elements found",
@ -437,6 +376,7 @@ $(function(){
type: "warn", type: "warn",
hide: false hide: false
}); });
svg.selectAll('text,tspan').remove();
}; };
self.svg_misfitting_warning = function(svg, misfitting){ self.svg_misfitting_warning = function(svg, misfitting){
@ -461,12 +401,12 @@ $(function(){
var wpx = this.width; var wpx = this.width;
var hpx = this.height; var hpx = this.height;
var dimPT = self.getUsefulDimensions(wpx, hpx); var dimMM = self.getUsefulDimensions(wpx, hpx);
var wPT = dimPT[0]; var wMM = dimMM[0];
var hPT = dimPT[1]; var hMM = dimMM[1];
var y = self.mm2svgUnits(self.workingAreaHeightMM()) - hPT; var y = self.workingAreaHeightMM() - hMM;
var newImg = snap.image(url, 0, y, wPT, hPT); var newImg = snap.image(url, 0, y, wMM, hMM);
var id = self.getEntryId(file); var id = self.getEntryId(file);
var previewId = self.generateUniqueId(id); // appends # if multiple times the same design is placed. var previewId = self.generateUniqueId(id); // appends # if multiple times the same design is placed.
newImg.attr({id: previewId, filter: 'url(#grayscale_filter)', 'data-serveurl': url}); newImg.attr({id: previewId, filter: 'url(#grayscale_filter)', 'data-serveurl': url});
@ -498,9 +438,7 @@ $(function(){
} else { } else {
destHeightMM = destWidthMM / aspectRatio; destHeightMM = destWidthMM / aspectRatio;
} }
var destWidthPT = self.mm2svgUnits(destWidthMM); return [destWidthMM, destHeightMM];
var destHeightPT = self.mm2svgUnits(destHeightMM);
return [destWidthPT, destHeightPT];
}; };
self.getDocumentDimensionsInPt = function(doc_width, doc_height, doc_viewbox){ self.getDocumentDimensionsInPt = function(doc_width, doc_height, doc_viewbox){
@ -641,18 +579,17 @@ $(function(){
self.draw_coord_grid = function(){ self.draw_coord_grid = function(){
var grid = snap.select('#coordGrid'); var grid = snap.select('#coordGrid');
if(grid.attr('fill') === 'none'){ if(grid.attr('fill') === 'none'){
var w = self.mm2svgUnits(self.workingAreaWidthMM()); var w = self.workingAreaWidthMM();
var h = self.mm2svgUnits(self.workingAreaHeightMM()); var h = self.workingAreaHeightMM();
var max_lines = 20; var max_lines = 20;
var linedistMM = Math.floor(Math.max(self.workingAreaWidthMM(), self.workingAreaHeightMM()) / (max_lines * 10))*10; var linedistMM = Math.floor(Math.max(self.workingAreaWidthMM(), self.workingAreaHeightMM()) / (max_lines * 10))*10;
var yPatternOffset = self.mm2svgUnits(self.workingAreaHeightMM() % linedistMM); var yPatternOffset = self.workingAreaHeightMM() % linedistMM;
var linedist = self.mm2svgUnits(linedistMM); var linedist = linedistMM;
var marker = snap.circle(linedist/2, linedist/2, 1).attr({ var marker = snap.circle(linedist/2, linedist/2, 0.3).attr({
fill: "#000000", fill: "#000000",
stroke: "none", stroke: "none"
strokeWidth: 1
}); });
// dot pattern // dot pattern
@ -742,16 +679,6 @@ $(function(){
return snap.selectAll("#userContent image"); return snap.selectAll("#userContent image");
}; };
self.hasTextItems = function () {
if(snap.selectAll("#userContent tspan").length > 0 ||
snap.selectAll("#userContent text").length > 0 ||
snap.selectAll("userContent #text").length > 0) {
return true
}else{
return false
}
};
self.getPlacedGcodes = ko.computed(function() { self.getPlacedGcodes = ko.computed(function() {
var gcodeFiles = []; var gcodeFiles = [];
ko.utils.arrayForEach(self.placedDesigns(), function(design) { ko.utils.arrayForEach(self.placedDesigns(), function(design) {
@ -874,7 +801,7 @@ $(function(){
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' || item.type === "text" || item.type === "#text") { if (item.type === 'image') {
// remove filter effects on images for proper rendering // remove filter effects on images for proper rendering
var style = item.attr('style'); var style = item.attr('style');
if (style !== null) { if (style !== null) {

View file

@ -331,7 +331,7 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback):
def position(self, x, y): def position(self, x, y):
printer_profile = self._printerProfileManager.get_current_or_default() printer_profile = self._printerProfileManager.get_current_or_default()
movement_speed = min(printer_profile["axes"]["x"]["speed"], printer_profile["axes"]["y"]["speed"]) movement_speed = min(printer_profile["axes"]["x"]["speed"], printer_profile["axes"]["y"]["speed"])
self.commands(["G90", "G0 X%.3f Y%.3f F%d" % (x, y, movement_speed)]) self.commands(["G90", "G0 X%.3f Y%.3f F%d" % (x, y, movement_speed), "?"])
def _convert_rate_value(self, factor, min=0, max=200): def _convert_rate_value(self, factor, min=0, max=200):
if not isinstance(factor, (int, float, long)): if not isinstance(factor, (int, float, long)):
@ -433,22 +433,6 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback):
payload["origin"] = FileDestinations.SDCARD payload["origin"] = FileDestinations.SDCARD
eventManager().fire(Events.PRINT_FAILED, payload) eventManager().fire(Events.PRINT_FAILED, payload)
def increase_passes(self):
"""
increase the number of passes by one.
"""
if self._comm is None:
return
self._comm.increasePasses()
def degrease_passes(self):
"""
degrease the number of passes by one.
"""
if self._comm is None:
return
self._comm.degreasePasses()
def get_state_string(self): def get_state_string(self):
""" """
Returns a human readable string corresponding to the current communication state. Returns a human readable string corresponding to the current communication state.

View file

@ -462,8 +462,6 @@ def gcodeConvertCommand():
# #r.headers["Location"] = location # #r.headers["Location"] = location
# #return r # #return r
if command == "convert": if command == "convert":
# TODO stripping non-ascii is a hack - svg contains lots of non-ascii in <text> tags. Fix this! # TODO stripping non-ascii is a hack - svg contains lots of non-ascii in <text> tags. Fix this!
import re import re
@ -518,7 +516,7 @@ def gcodeConvertCommand():
del data["profile"] del data["profile"]
else: else:
profile = None profile = None
##
if "printerProfile" in data.keys() and data["printerProfile"]: if "printerProfile" in data.keys() and data["printerProfile"]:
printerProfile = data["printerProfile"] printerProfile = data["printerProfile"]
del data["printerProfile"] del data["printerProfile"]
@ -548,6 +546,13 @@ def gcodeConvertCommand():
for key in override_keys: for key in override_keys:
overrides[key[len("profile."):]] = data[key] overrides[key[len("profile."):]] = data[key]
if data.has_key('gcodedata'):
output_path = fileManager.path_on_disk(target, gcode_name)
with open(output_path,'wb') as wfd:
for line in data['gcodedata']:
wfd.write(line)
eventManager.fire(Events.SLICING_DONE, {"stl": filename, "gcode": gcode_name, "gcode_location": target, "time": 1.0})
else:
def slicing_done(target, gcode_name, select_after_slicing, print_after_slicing, append_these_files): def slicing_done(target, gcode_name, select_after_slicing, print_after_slicing, append_these_files):
# append additioal gcodes # append additioal gcodes
output_path = fileManager.path_on_disk(target, gcode_name) output_path = fileManager.path_on_disk(target, gcode_name)

View file

@ -23,9 +23,7 @@ def controlJob():
"start": [], "start": [],
"restart": [], "restart": [],
"pause": [], "pause": [],
"cancel": [], "cancel": []
"incpasses": [],
"degpasses": []
} }
command, data, response = get_json_command_from_request(request, valid_commands) command, data, response = get_json_command_from_request(request, valid_commands)
@ -50,15 +48,6 @@ def controlJob():
if not activePrintjob: if not activePrintjob:
return make_response("Printer is neither printing nor paused, 'cancel' command cannot be performed", 409) return make_response("Printer is neither printing nor paused, 'cancel' command cannot be performed", 409)
printer.cancel_print() printer.cancel_print()
elif command == "incpasses":
if not activePrintjob:
return make_response("Printer is neither printing nor paused, 'incpasses' command cannot be performed", 409)
printer.increase_passes()
elif command == "degpasses":
if not activePrintjob:
return make_response("Printer is neither printing nor paused, 'degpasses' command cannot be performed", 409)
printer.degrease_passes()
return NO_CONTENT return NO_CONTENT

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

View file

@ -404,11 +404,6 @@ $(function() {
self.onStartup = function () { self.onStartup = function () {
self.requestData(); self.requestData();
self._configureJogDistanceSlider(); self._configureJogDistanceSlider();
$('#manual_position').keyup(function(e) {
if (e.which === 13){ // 13 == enter
self.manualPosition();
}
});
}; };
self.updateRotatorWidth = function() { self.updateRotatorWidth = function() {
@ -612,24 +607,6 @@ $(function() {
self.sendCustomCommand({type: 'command', command: "G92 X0 Y0"}); self.sendCustomCommand({type: 'command', command: "G92 X0 Y0"});
}; };
self.manualPosition = function(){
$('#manual_position').removeClass('warning');
var s = $('#manual_position').val();
var tmp = s.split(/[^0-9.,-\\+]+/);
if (tmp.length === 2) {
var x = parseFloat(tmp[0]);
var y = parseFloat(tmp[1]);
if(!isNaN(x) && !isNaN(y)) {
self.sendCustomCommand({type: 'command', command: "G0X"+x+"Y"+y});
$('#manual_position').val('');
} else {
$('#manual_position').addClass('warning');
}
} else {
$('#manual_position').addClass('warning');
}
};
self.jogDistanceInMM = ko.observable(undefined); self.jogDistanceInMM = ko.observable(undefined);
self.focus_on = function () { self.focus_on = function () {

View file

@ -38,7 +38,6 @@ $(function() {
self.feedrateOverride = ko.observable(100); self.feedrateOverride = ko.observable(100);
self.intensityOverride.extend({ rateLimit: 500 }); self.intensityOverride.extend({ rateLimit: 500 });
self.feedrateOverride.extend({ rateLimit: 500 }); self.feedrateOverride.extend({ rateLimit: 500 });
self.numberOfPasses = ko.observable(1);
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");
@ -217,8 +216,7 @@ $(function() {
$("#confirmation_dialog .confirmation_dialog_acknowledge").click( $("#confirmation_dialog .confirmation_dialog_acknowledge").click(
function (e) { function (e) {
if (typeof callback === 'function') { if (typeof callback === 'function') {
self.resetOverrideSlider(); self.onEventPrintDone();
self.numberOfPasses(1);
callback(e); callback(e);
$("#confirmation_dialog").modal("hide"); $("#confirmation_dialog").modal("hide");
$("#confirmation_dialog .confirmation_dialog_message").html(''); $("#confirmation_dialog .confirmation_dialog_message").html('');
@ -334,30 +332,16 @@ $(function() {
}; };
self.increasePasses = function(){
self.numberOfPasses(self.numberOfPasses()+1);
self._jobCommand("incpasses");
}
self.decreasePasses = function(){
var passes = Math.max(self.numberOfPasses()-1, 1);
self.numberOfPasses(passes);
self._jobCommand("degpasses");
}
self.onEventPrintDone = function(){ self.onEventPrintDone = function(){
self.resetOverrideSlider();
};
self.onStartup = function() {
self._configureOverrideSliders();
};
self.resetOverrideSlider = function() {
self.feedrateOverrideSlider.slider('setValue', 100); self.feedrateOverrideSlider.slider('setValue', 100);
self.intensityOverrideSlider.slider('setValue', 100); self.intensityOverrideSlider.slider('setValue', 100);
self.intensityOverride(100); self.intensityOverride(100);
self.feedrateOverride(100); self.feedrateOverride(100);
}; };
self.onStartup = function() {
self._configureOverrideSliders();
};
} }
OCTOPRINT_VIEWMODELS.push([ OCTOPRINT_VIEWMODELS.push([

View file

@ -1,7 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title data-bind="text: title">Mr Draw</title> <title data-bind="text: title">Mr Beam</title>
<link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.png') }}"> <link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.png') }}">
<link rel="apple-touch-icon" sizes="114x114" href="{{ url_for('static', filename='img/apple-touch-icon-114x114.png') }}"> <link rel="apple-touch-icon" sizes="114x114" href="{{ url_for('static', filename='img/apple-touch-icon-114x114.png') }}">
@ -16,7 +16,7 @@
<div class="container"> <div class="container">
<div class="navbar-header brand" style="min-width: 272px;"> <div class="navbar-header brand" style="min-width: 272px;">
<a class="navbar-brand" href="#"> <a class="navbar-brand" href="#">
<img alt="Mr Draw Logo" src="{{ url_for('static', filename='img/mr-draw-red_x120.png') }}"> <img alt="Mr Beam Logo" src="{{ url_for('static', filename='img/mr-typo-red_x120.png') }}">
</a> </a>
</div> </div>
<!-- Navbar --> <!-- Navbar -->
@ -58,7 +58,7 @@
<div id="control" class="accordion-inner" data-bind="visible: isReady() || isLocked() || isFlashing()"> <div id="control" class="accordion-inner" data-bind="visible: isReady() || isLocked() || isFlashing()">
<div data-bind="visible: isLocked "> <div data-bind="visible: isLocked ">
Mr Draw is in a locked state as it does not know its position. Mr Beam is in a locked state as it does not know its position.
First remove any objects blocking the gantry's travel range. First remove any objects blocking the gantry's travel range.
Then do a homing cycle. Then do a homing cycle.
<div style='text-align: center; padding:.5em;'> <div style='text-align: center; padding:.5em;'>
@ -123,10 +123,6 @@
<div class="distance"> <div class="distance">
<input type="text" id="jogDistance" /> <input type="text" id="jogDistance" />
</div> </div>
<div class="input-append manual_position_input">
<input id="manual_position" placeholder="x.xx y.yy" onsubmit="manualPosition"/>
<button class="" data-bind="click: manualPosition">Go</button>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -172,19 +168,6 @@
<input id="feedrate_override_slider" type="text" data-bind="sliderValue: feedrateOverride"> <input id="feedrate_override_slider" type="text" data-bind="sliderValue: feedrateOverride">
<span data-bind="text:feedrateOverride()">100</span>% Feedrate <span data-bind="text:feedrateOverride()">100</span>% Feedrate
</div> </div>
<div class="repeatGcode">
<div class="btn-group">
<button type="button" class="btn btn-default btn-number" data-bind="enable: numberOfPasses() > 1, click:decreasePasses">
<span class="icon-minus"></span>
</button>
<input type="text" class="input-mini text-right" value="1" min="1" max="10" data-bind="value:numberOfPasses()">
<button type="button" class="btn btn-default btn-number" data-bind="click:increasePasses">
<span class="icon-plus"></span>
</button>
</div>
<span>Passes</span>
</div>
</div> </div>
<!-- {{ _('Print Time') }}: <strong data-bind="text: printTimeString"></strong><br> <!-- {{ _('Print Time') }}: <strong data-bind="text: printTimeString"></strong><br>
@ -304,6 +287,9 @@
backgroundPosition: crosshairX()+'px'+' '+crosshairY()+'px', backgroundPosition: crosshairX()+'px'+' '+crosshairY()+'px',
width: workingAreaWidthPx()+'px', width: workingAreaWidthPx()+'px',
height: workingAreaHeightPx()+'px' height: workingAreaHeightPx()+'px'
},
attr: {
viewBox: '0 0 '+workingAreaWidthMM()+' '+workingAreaHeightMM()
} }
"> ">
<filter id="grayscale_filter"> <filter id="grayscale_filter">
@ -321,25 +307,23 @@
<text <text
xml:space="preserve" xml:space="preserve"
data-bind="visible: working_area_empty" 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;" style="font-size:12px;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" x="396.81018"
y="552.36218" y="552.36218"
id="add_designs_hint" id="add_designs_hint"
> >
<tspan <tspan
id="tspan2987" x="368.571426" y="532.36218" id="tspan2987" x="60" y="60"
style="text-anchor:middle;text-align:center">add designs via </tspan> style="text-anchor:left;text-align:center">add designs via </tspan>
<tspan <tspan
x="500" y="592.36218" id="tspan2989" x="70" y="75" id="tspan2989"
style="text-anchor:middle;text-align:center">the design library </tspan> style="text-anchor:left;text-align:center">the design library </tspan>
<tspan <tspan
x="568.571426" y="652.36218" id="tspan2993" x="80" y="90" id="tspan2993"
style="text-anchor:middle;text-align:center">or drag 'n' drop </tspan> style="text-anchor:left;text-align:center">or drag 'n' drop </tspan>
<tspan </text>
x="368.571426" y="712.36218" id="tspan2991" <g id="placedGcodes" data-bind="visible: !state.isPrinting() && !state.isPaused()"></g>
style="text-anchor:middle;text-align:center" /></text> <g id="gCodePreview" 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>
<rect data-bind="click: move_laser" <rect data-bind="click: move_laser"
id="coordGrid" x="0" y="0" width="0" height="0" id="coordGrid" x="0" y="0" width="0" height="0"
stroke="none" fill="none"></rect> stroke="none" fill="none"></rect>
@ -657,10 +641,12 @@
<div class="span4"> <div class="span4">
<ul class="focus_steps"> <ul class="focus_steps">
<li>1. Place your material on the working area</li> <li>1. Place your material on the working area</li>
<li>2. Move the pen over the material</li> <li>2. Move the laser over the material</li>
<li>&RightArrow; Now enable the pen calibration mode</li> <li>3. Put on your safety glasses</li>
<li>5. Adjust the pen until it touches the paper</li> <li>4. Turn the laser safety switch to on</li>
<li>&RightArrow; Disable the pen calibration mode. </li> <li>&RightArrow; Now enable the focus mode</li>
<li>5. Adjust the focus until the laser beam is as small as possible</li>
<li>&RightArrow; Disable the focus mode. </li>
</ul> </ul>
<div style="text-align:center"> <div style="text-align:center">
<div class="btn-group" role="group" aria-label="focus mode control" style=""> <div class="btn-group" role="group" aria-label="focus mode control" style="">

View file

@ -568,8 +568,8 @@ msgstr ""
"aktualisiert werden." "aktualisiert werden."
#: src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js:131 #: src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js:131
msgid "Mr Beam Update Available" msgid "Update Available"
msgstr "Mr Beam Aktualisierung verfügbar" msgstr "Aktualisierung verfügbar"
#: src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js:143 #: src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js:143
msgid "Ignore" msgid "Ignore"

View file

@ -84,11 +84,9 @@ class MachineCom(object):
self._actual_intensity = None self._actual_intensity = None
self._feedrate_dict = {} self._feedrate_dict = {}
self._intensity_dict = {} self._intensity_dict = {}
self._passes = 1
self._finished_passes = 0
# regular expressions # regular expressions
self._regex_command = re.compile("^\s*\$?([GM]\d+|[THX])") self._regex_command = re.compile("^\s*\$?([GM]\d+|[TH])")
self._regex_feedrate = re.compile("F\d+", re.IGNORECASE) self._regex_feedrate = re.compile("F\d+", re.IGNORECASE)
self._regex_intensity = re.compile("S\d+", re.IGNORECASE) self._regex_intensity = re.compile("S\d+", re.IGNORECASE)
@ -147,7 +145,7 @@ class MachineCom(object):
elif line.startswith('['): # feedback message elif line.startswith('['): # feedback message
self._handle_feedback_message(line) self._handle_feedback_message(line)
elif line.startswith('Grb'): # Grbl startup message elif line.startswith('Grb'): # Grbl startup message
self._handle_startup_message(line) self._handle_startup_message()
except: except:
self._logger.exception("Something crashed inside the monitoring loop, please report this to Mr. Beam") self._logger.exception("Something crashed inside the monitoring loop, please report this to Mr. Beam")
errorMsg = "See octoprint.log for details" errorMsg = "See octoprint.log for details"
@ -166,15 +164,8 @@ class MachineCom(object):
if cmd is not None: if cmd is not None:
self.sendCommand(cmd) self.sendCommand(cmd)
self._callback.on_comm_progress() self._callback.on_comm_progress()
else: elif len(self._acc_line_buffer) == 0:
if self._finished_passes >= self._passes:
if len(self._acc_line_buffer) == 0:
self._set_print_finished() self._set_print_finished()
self._currentFile.resetToBeginning()
cmd = self._getNext()
if cmd is not None:
self.sendCommand(cmd)
self._callback.on_comm_progress()
self._sendCommand() self._sendCommand()
self._send_event.wait(1) self._send_event.wait(1)
@ -320,8 +311,6 @@ class MachineCom(object):
if self._finished_currentFile is False: if self._finished_currentFile is False:
line = self._currentFile.getNext() line = self._currentFile.getNext()
if line is None: if line is None:
self._finished_passes += 1
if self._finished_passes >= self._passes:
self._finished_currentFile = True self._finished_currentFile = True
return line return line
else: else:
@ -405,7 +394,7 @@ class MachineCom(object):
elif line[1:].startswith('Dis'): # [Disabled] elif line[1:].startswith('Dis'): # [Disabled]
pass pass
def _handle_startup_message(self, line): def _handle_startup_message(self):
if self.isOperational(): if self.isOperational():
errorMsg = "Machine reset." errorMsg = "Machine reset."
self._cmd = None self._cmd = None
@ -419,13 +408,6 @@ class MachineCom(object):
self._errorValue = errorMsg self._errorValue = errorMsg
self._changeState(self.STATE_LOCKED) self._changeState(self.STATE_LOCKED)
eventManager().fire(Events.ERROR, {"error": self.getErrorString()}) eventManager().fire(Events.ERROR, {"error": self.getErrorString()})
else:
versionMatch = re.search("Grbl (?P<grbl>.+?)(_(?P<git>[0-9a-f]{7})(?P<dirty>-dirty)?)? \[.+\]", line)
if versionMatch:
versionDict = versionMatch.groupdict()
self._writeGrblVersionToFile(versionDict)
if self._compareGrblVersion(versionDict) is False:
self._flashGrbl()
else: else:
self._onConnected(self.STATE_LOCKED) self._onConnected(self.STATE_LOCKED)
@ -618,7 +600,7 @@ class MachineCom(object):
params = ["avrdude", "-patmega328p", "-carduino", "-b" + str(self._baudrate), "-P" + str(self._port), "-D", "-Uflash:w:" + pathToGrblHex] params = ["avrdude", "-patmega328p", "-carduino", "-b" + str(self._baudrate), "-P" + str(self._port), "-D", "-Uflash:w:" + pathToGrblHex]
rc = subprocesscall(params) rc = subprocesscall(params)
if rc == 0: if rc is False:
self._log("successfully flashed new grbl version") self._log("successfully flashed new grbl version")
self._openSerial() self._openSerial()
self._changeState(self.STATE_CONNECTING) self._changeState(self.STATE_CONNECTING)
@ -755,10 +737,6 @@ class MachineCom(object):
self._changeState(self.STATE_HOMING) self._changeState(self.STATE_HOMING)
return cmd return cmd
def _gcode_X_sent(self, cmd, cmd_type=None):
self._changeState(self.STATE_HOMING) # TODO: maybe change to seperate $X mode
return cmd
def _gcode_Hold_sent(self, cmd, cmd_type=None): def _gcode_Hold_sent(self, cmd, cmd_type=None):
self._changeState(self.STATE_PAUSED) self._changeState(self.STATE_PAUSED)
return cmd return cmd
@ -849,8 +827,6 @@ class MachineCom(object):
# reset feedrate and intesity factor in case they where changed in a previous run # reset feedrate and intesity factor in case they where changed in a previous run
self._feedrate_factor = 1 self._feedrate_factor = 1
self._intensity_factor = 1 self._intensity_factor = 1
self._passes = 1
self._finished_passes = 0
try: try:
# ensure fan is on whatever gcode follows. # ensure fan is on whatever gcode follows.
@ -921,14 +897,6 @@ class MachineCom(object):
self._send_event.set() self._send_event.set()
eventManager().fire(Events.PRINT_PAUSED, payload) eventManager().fire(Events.PRINT_PAUSED, payload)
def increasePasses(self):
self._passes += 1
self._log("increased Passes to %d" % self._passes)
def degreasePasses(self):
self._passes -= 1
self._log("degrease Passes to %d" % self._passes)
def getStateString(self): def getStateString(self):
if self._state == self.STATE_NONE: if self._state == self.STATE_NONE:
return "Offline" return "Offline"
@ -1169,9 +1137,6 @@ class PrintingGcodeFileInformation(PrintingFileInformation):
if not os.path.exists(self._filename) or not os.path.isfile(self._filename): if not os.path.exists(self._filename) or not os.path.isfile(self._filename):
raise IOError("File %s does not exist" % self._filename) raise IOError("File %s does not exist" % self._filename)
self._stripCommments()
self._size = os.stat(self._filename).st_size self._size = os.stat(self._filename).st_size
self._pos = 0 self._pos = 0
@ -1194,12 +1159,6 @@ class PrintingGcodeFileInformation(PrintingFileInformation):
pass pass
self._handle = None self._handle = None
def resetToBeginning(self):
"""
resets the file handle so you can read from the beginning again.
"""
self._handle = open(self._filename, "r")
def getNext(self): def getNext(self):
""" """
Retrieves the next line for printing. Retrieves the next line for printing.
@ -1225,16 +1184,6 @@ class PrintingGcodeFileInformation(PrintingFileInformation):
self._logger.exception("Exception while processing line") self._logger.exception("Exception while processing line")
raise e raise e
def _stripCommments(self):
dir = os.path.dirname(os.path.abspath(self._filename))
tmpfile = open(dir + '/gcode.tmp', 'w')
with open(self._filename, "r") as fileobject:
for line in fileobject:
if process_gcode_line(line) is not None:
tmpfile.write(line)
tmpfile.close()
self._filename = dir + '/gcode.tmp'
def convert_pause_triggers(configured_triggers): def convert_pause_triggers(configured_triggers):
triggers = { triggers = {
"enable": [], "enable": [],
@ -1299,7 +1248,6 @@ def serialList():
baselist = baselist \ baselist = baselist \
+ glob.glob("/dev/ttyUSB*") \ + glob.glob("/dev/ttyUSB*") \
+ glob.glob("/dev/ttyACM*") \ + glob.glob("/dev/ttyACM*") \
+ glob.glob("/dev/ttyAMA*") \
+ glob.glob("/dev/tty.usb*") \ + glob.glob("/dev/tty.usb*") \
+ glob.glob("/dev/cu.*") \ + glob.glob("/dev/cu.*") \
+ glob.glob("/dev/cuaU*") \ + glob.glob("/dev/cuaU*") \