Compare commits
6 commits
stable-1.2
...
mrbeam-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
21e7a885b4 | ||
|
|
08d023be53 | ||
|
|
89d493a33b | ||
|
|
d89ec331da | ||
|
|
f54d932928 | ||
|
|
14f83133b7 |
|
|
@ -1,6 +1,5 @@
|
|||
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.
|
||||
|
||||
[](https://flattr.com/submit/auto?user_id=foosel&url=https://github.com/foosel/OctoPrint&title=OctoPrint&language=&tags=github&category=software)
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
||||
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:
|
||||
raise RuntimeError("Could not update, \"git pull\" failed with returncode %d: %s" % (returncode, stdout))
|
||||
print(stdout)
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ $(function() {
|
|||
text += "<small>" + gettext("Those components marked with <i class=\"icon-ok\"></i> can be updated directly.") + "</small>";
|
||||
|
||||
var options = {
|
||||
title: gettext("Mr Beam Update Available"),
|
||||
title: gettext("Update Available"),
|
||||
text: text,
|
||||
hide: false
|
||||
};
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ class SvgToGcodePlugin(octoprint.plugin.SlicerPlugin,
|
|||
|
||||
def get_assets(self):
|
||||
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/extrude.js"],
|
||||
less=["less/svgtogcode.less"],
|
||||
css=["css/svgtogcode.css", "css/mrbeam.css"]
|
||||
)
|
||||
|
|
@ -270,7 +270,7 @@ class SvgToGcodePlugin(octoprint.plugin.SlicerPlugin,
|
|||
feedrate = max(1,data["defaultFeedrate"])
|
||||
s.set(["defaultFeedrate"], feedrate)
|
||||
if "svgDPI" in data and data["svgDPI"]:
|
||||
s.set_int(["svgDPI"], data["svgDPI"])
|
||||
s.set(["svgDPI"], data["svgDPI"])
|
||||
if "debug_logging" in data:
|
||||
old_debug_logging = s.get_boolean(["debug_logging"])
|
||||
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'
|
||||
elif("denkbrett" in hostname):
|
||||
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
|
||||
sys.path.append(converter_path)
|
||||
|
|
|
|||
BIN
src/octoprint/plugins/svgtogcode/static/img/wa_preview/0.jpg
Normal file
|
After Width: | Height: | Size: 184 KiB |
BIN
src/octoprint/plugins/svgtogcode/static/img/wa_preview/1.jpg
Normal file
|
After Width: | Height: | Size: 5 MiB |
BIN
src/octoprint/plugins/svgtogcode/static/img/wa_preview/10.jpg
Normal file
|
After Width: | Height: | Size: 5.9 MiB |
BIN
src/octoprint/plugins/svgtogcode/static/img/wa_preview/11.jpg
Normal file
|
After Width: | Height: | Size: 5.1 MiB |
BIN
src/octoprint/plugins/svgtogcode/static/img/wa_preview/12.jpg
Normal file
|
After Width: | Height: | Size: 4.4 MiB |
BIN
src/octoprint/plugins/svgtogcode/static/img/wa_preview/2.jpg
Normal file
|
After Width: | Height: | Size: 7.9 MiB |
BIN
src/octoprint/plugins/svgtogcode/static/img/wa_preview/3.jpg
Normal file
|
After Width: | Height: | Size: 8.3 MiB |
BIN
src/octoprint/plugins/svgtogcode/static/img/wa_preview/4.jpg
Normal file
|
After Width: | Height: | Size: 8.7 MiB |
BIN
src/octoprint/plugins/svgtogcode/static/img/wa_preview/5.jpg
Normal file
|
After Width: | Height: | Size: 8.3 MiB |
BIN
src/octoprint/plugins/svgtogcode/static/img/wa_preview/6.jpg
Normal file
|
After Width: | Height: | Size: 5.7 MiB |
BIN
src/octoprint/plugins/svgtogcode/static/img/wa_preview/7.jpg
Normal file
|
After Width: | Height: | Size: 7.4 MiB |
BIN
src/octoprint/plugins/svgtogcode/static/img/wa_preview/8.jpg
Normal file
|
After Width: | Height: | Size: 7.6 MiB |
BIN
src/octoprint/plugins/svgtogcode/static/img/wa_preview/9.jpg
Normal file
|
After Width: | Height: | Size: 8 MiB |
|
|
@ -41,10 +41,8 @@ $(function(){
|
|||
// image engraving stuff
|
||||
// preset values are a good start for wood engraving
|
||||
self.images_placed = ko.observable(false);
|
||||
self.text_placed = ko.observable(false);
|
||||
self.show_image_parameters = ko.computed(function(){
|
||||
return (self.images_placed() || self.text_placed()
|
||||
|| (self.fill_areas() && self.show_vector_parameters()));
|
||||
return self.images_placed() || (self.fill_areas() && self.show_vector_parameters());
|
||||
});
|
||||
self.imgIntensityWhite = ko.observable(0);
|
||||
self.imgIntensityBlack = ko.observable(500);
|
||||
|
|
@ -87,7 +85,6 @@ $(function(){
|
|||
self.show_vector_parameters(self.workingArea.getPlacedSvgs().length > 0);
|
||||
self.show_fill_areas_checkbox(self.workingArea.hasFilledVectors())
|
||||
self.images_placed(self.workingArea.getPlacedImages().length > 0);
|
||||
self.text_placed(self.workingArea.hasTextItems());
|
||||
//self.show_image_parameters(self.workingArea.getPlacedImages().length > 0);
|
||||
|
||||
if(self.show_vector_parameters() || self.show_image_parameters()){
|
||||
|
|
|
|||
158
src/octoprint/plugins/svgtogcode/static/js/extrude.js
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
// extrude.js - a snapsvg.io plugin to generate extrusion walls of svg paths.
|
||||
// Copyright (C) 2016 Teja Philipp <osd@tejaphilipp.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
Snap.plugin(function (Snap, Element, Paper, global) {
|
||||
|
||||
/**
|
||||
* @param {elem} elem start point
|
||||
*
|
||||
* @returns {path}
|
||||
*/
|
||||
|
||||
Element.prototype.extrude = function(height, perforation_curvature_threshold){
|
||||
var subdiv_length = 1;
|
||||
var material_thickness = 1;
|
||||
var perforation_curvature_threshold = perforation_curvature_threshold || 5;
|
||||
var elem = this;
|
||||
var walls = [];
|
||||
var children = elem.children();
|
||||
|
||||
if (children.length > 0) {
|
||||
var goRecursive = (elem.type !== "defs" && // ignore these tags
|
||||
elem.type !== "clipPath" &&
|
||||
elem.type !== "metadata" &&
|
||||
elem.type !== "rdf:rdf" &&
|
||||
elem.type !== "cc:work" &&
|
||||
elem.type !== "sodipodi:namedview");
|
||||
|
||||
if(goRecursive) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
var more = child.extrude(height);
|
||||
walls.push.apply(walls, more);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var e;
|
||||
if (elem.type !== "path"){
|
||||
console.log('converting element to path', elem.type);
|
||||
e = elem.toPath();
|
||||
} else {
|
||||
e = elem;
|
||||
}
|
||||
|
||||
var dOriginal = e.attr('d');
|
||||
var parts = Snap.path.toRelative(dOriginal).toString();
|
||||
var segments = parts.split('m');
|
||||
|
||||
console.log('d',dOriginal);
|
||||
for (var i = 0; i < segments.length; i++) {
|
||||
if(segments[i].trim() !== ''){
|
||||
var seg = 'M' + segments[i];
|
||||
var l = Snap.path.getTotalLength(seg);
|
||||
console.log("segment", seg, l);
|
||||
walls.push(createWrappingPath2(seg), height);
|
||||
}
|
||||
}
|
||||
|
||||
//walls.push( createWrappingPath(segments, height));
|
||||
}
|
||||
return walls;
|
||||
};
|
||||
|
||||
function createWrappingPath2(segment, height){
|
||||
var l = Snap.path.getTotalLength(segment);
|
||||
console.log(segment, l);
|
||||
|
||||
// create "rectangle"
|
||||
var rect_d = "m0,0 l"+l+',0' // top
|
||||
+ ' l0,'+height // right
|
||||
+ ' l-'+l+',0' // bottom
|
||||
+ ' l0,-'+height; // left
|
||||
|
||||
var perforations = getPerforations(segment, 5);
|
||||
var perf_d = [];
|
||||
for (var i = 0; i < perforations.length; i++) {
|
||||
var perf = perforations[i];
|
||||
var density = 0.8 * perf.curvature/90;
|
||||
perf_d.push(createVerticalPerforation(perf.loc,height,density, height/10));
|
||||
|
||||
}
|
||||
return rect_d+perf_d.join(',');
|
||||
|
||||
}
|
||||
|
||||
function getPerforations(d, perf_curvature_threshold){
|
||||
var stepSize = 1;
|
||||
var perfs = [];
|
||||
var e = snap.path(d)
|
||||
var l = e.getTotalLength();
|
||||
var i = 0;
|
||||
var last_alpha = -999;
|
||||
var curvature_sum = 0;
|
||||
while(i<l){
|
||||
var p = e.getPointAtLength(i);
|
||||
p.curvature = last_alpha - p.alpha;
|
||||
p.loc = i;
|
||||
curvature_sum += p.curvature;
|
||||
last_alpha = p.alpha;
|
||||
if(Math.abs(curvature_sum) > perf_curvature_threshold){
|
||||
perfs.push({loc:i, curve:p.curvature});
|
||||
curvature_sum = 0;
|
||||
}
|
||||
i+=stepSize;
|
||||
}
|
||||
return perfs;
|
||||
}
|
||||
|
||||
function createWrappingPath(divs, height){
|
||||
var upper_d = "M0,0";
|
||||
var lower_d = "M0,"+height;
|
||||
var verticals = ['M0,0l0,'+height];
|
||||
for (var i = 0; i < divs.length; i++) {
|
||||
var d = divs[i];
|
||||
var x = d.loc.toFixed(2);
|
||||
upper_d += 'L'+x+',0';
|
||||
lower_d += 'L'+x+','+height;
|
||||
var density = 0.8* d.curvature/180;
|
||||
verticals.push(createVerticalPerforation(x,height, density, height/15));
|
||||
}
|
||||
return upper_d+lower_d+verticals.join();
|
||||
}
|
||||
|
||||
function createVerticalPerforation(x, height, density, perfLength){
|
||||
var cut = (perfLength * (density)).toFixed(2);
|
||||
var gap = (perfLength - cut).toFixed(2);
|
||||
var d = 'M'+x+',0';
|
||||
var y = 0;
|
||||
while(y < height){
|
||||
d += 'l0,'+cut+'m0,'+gap;
|
||||
y += perfLength;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -30,15 +30,14 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
|||
*/
|
||||
Element.prototype.bake = function (toCubics, dec) {
|
||||
var elem = this;
|
||||
|
||||
if (!elem || !elem.paper || elem.type !== "text" || elem.type !== "#text" || elem.type !== "tspan"){
|
||||
if (!elem || !elem.paper) // don't handle unplaced elements. this causes double handling.
|
||||
return;
|
||||
} // don't handle unplaced elements. this causes double handling.
|
||||
|
||||
if (typeof (toCubics) === 'undefined')
|
||||
toCubics = false;
|
||||
if (typeof (dec) === 'undefined')
|
||||
dec = 5;
|
||||
//var children = elem.selectAll('*')
|
||||
var children = elem.children();
|
||||
if (children.length > 0) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
|
|
@ -55,15 +54,14 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
|||
elem.type !== "polygon" &&
|
||||
elem.type !== "polyline" &&
|
||||
elem.type !== "image" &&
|
||||
elem.type !== "path" &&
|
||||
elem.type !== "text" &&
|
||||
elem.type !== "tspan" &&
|
||||
elem.type !== "#text"){
|
||||
elem.type !== "path"){
|
||||
|
||||
// if(elem.type !== 'g' && elem.type !== 'desc' && elem.type !== 'defs')
|
||||
// console.log('skipping unsupported element ', elem.type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (elem.type == 'image' || elem.type == "text" || elem.type == "#text"){
|
||||
if (elem.type == 'image'){
|
||||
// TODO ...
|
||||
var x = parseFloat(elem.attr('x')),
|
||||
y = parseFloat(elem.attr('y')),
|
||||
|
|
@ -72,14 +70,12 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
|||
|
||||
// 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 (!isFinite(x)) {
|
||||
if (!isFinite(x))
|
||||
console.log('No attribute "x" in image tag. Assuming 0.')
|
||||
x = 0;
|
||||
}
|
||||
if (!isFinite(y)) {
|
||||
if (!isFinite(y))
|
||||
console.log('No attribute "y" in image tag. Assuming 0.')
|
||||
y = 0;
|
||||
}
|
||||
var transform = elem.transform();
|
||||
var matrix = transform['totalMatrix'];
|
||||
var transformedX = matrix.x(x, y);
|
||||
|
|
@ -91,6 +87,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
|||
return;
|
||||
}
|
||||
|
||||
//if(elem.type !== 'path') console.log("bake: converting " + elem.type + " to path");
|
||||
var path_elem = elem.convertToPath();
|
||||
|
||||
if (!path_elem || path_elem.attr('d') === '' || path_elem.attr('d') === null)
|
||||
|
|
@ -439,19 +436,6 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
|||
// Possibly the cubed root of 6, but 1.81 works best
|
||||
var num = 1.81;
|
||||
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) {
|
||||
case 'ellipse':
|
||||
case 'circle':
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if(elem.type === 'image' || elem.type === "text" || elem.type === "#text"){
|
||||
if(elem.type === 'image'){
|
||||
selection.push(elem);
|
||||
} else {
|
||||
if(fillPaths && elem.is_filled()){
|
||||
|
|
@ -74,10 +74,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
|||
elem.type !== "line" &&
|
||||
elem.type !== "polygon" &&
|
||||
elem.type !== "polyline" &&
|
||||
elem.type !== "path" //&&
|
||||
// elem.type !== "text" &&
|
||||
// elem.type !== "#text"
|
||||
){
|
||||
elem.type !== "path" ){
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -124,7 +121,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
|||
|
||||
// get svg as dataUrl
|
||||
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();
|
||||
source.src = svgDataUri;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,20 +1,5 @@
|
|||
$(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) {
|
||||
var self = this;
|
||||
|
||||
|
|
@ -107,7 +92,6 @@ $(function(){
|
|||
self.clear = function(){
|
||||
snap.selectAll('#userContent>*').remove();
|
||||
snap.selectAll('#placedGcodes>*').remove();
|
||||
snap.selectAll('rect:not(#coordGrid)').remove();
|
||||
self.placedDesigns([]);
|
||||
};
|
||||
|
||||
|
|
@ -118,34 +102,24 @@ $(function(){
|
|||
self.availableWidth($('#workingarea div.span8').innerWidth());
|
||||
};
|
||||
|
||||
self.move_laser = function(data, evt){
|
||||
self.move_laser = function(el){
|
||||
self.abortFreeTransforms();
|
||||
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({
|
||||
url: API_BASEURL + "printer/printhead",
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
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(){
|
||||
var pos = self.state.currentPos();
|
||||
|
|
@ -153,7 +127,7 @@ $(function(){
|
|||
|
||||
};
|
||||
self.crosshairY = function(){
|
||||
var h = Snap($('#area_preview')[0]).getBBox().height;
|
||||
var h = document.getElementById('area_preview').clientHeight;
|
||||
var pos = self.state.currentPos();
|
||||
return pos !== undefined ? (h - self.mm2px(pos.y) - 15) : -100; // subtract height/2;
|
||||
};
|
||||
|
|
@ -243,26 +217,11 @@ $(function(){
|
|||
var url = self._getSVGserveUrl(file);
|
||||
callback = function (f) {
|
||||
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_height = 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
|
||||
for(var i = 0; i < root_attrs.length; i++){
|
||||
var attr = root_attrs[i];
|
||||
|
|
@ -278,19 +237,9 @@ $(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
|
||||
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],mat[0][1],mat[1][0],mat[1][1],mat[0][2],mat[1][2]).scale(dpiscale).toTransformString();
|
||||
var scaleMatrixStr = new Snap.Matrix(mat[0][0],mat[0][1],mat[1][0],mat[1][1],mat[0][2],mat[1][2]).toTransformString();
|
||||
newSvgAttrs['transform'] = scaleMatrixStr;
|
||||
|
||||
var newSvg = snap.group(f.selectAll("svg>*"));
|
||||
|
|
@ -396,7 +345,7 @@ $(function(){
|
|||
dx = -svgBB.x + 0.01;
|
||||
outside = true;
|
||||
} else if(svgBB.x2 > waBB.x2){
|
||||
dx = -svgBB.x + 0.01;
|
||||
dx = -svgBB.x2 + waBB.x2 - 0.01;
|
||||
outside = true;
|
||||
}
|
||||
if(svgBB.y < waBB.y){
|
||||
|
|
@ -416,20 +365,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){
|
||||
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>");
|
||||
new PNotify({
|
||||
title: "Text elements found",
|
||||
|
|
@ -437,6 +374,7 @@ $(function(){
|
|||
type: "warn",
|
||||
hide: false
|
||||
});
|
||||
svg.selectAll('text,tspan').remove();
|
||||
};
|
||||
|
||||
self.svg_misfitting_warning = function(svg, misfitting){
|
||||
|
|
@ -488,16 +426,10 @@ $(function(){
|
|||
};
|
||||
|
||||
self.getUsefulDimensions = function(wpx, hpx){
|
||||
var maxWidthMM = wpx * 0.25; // TODO parametrize
|
||||
var maxHeightMM = hpx * 0.25; // TODO parametrize
|
||||
var aspectRatio = wpx / hpx;
|
||||
var destWidthMM = Math.min(self.workingAreaWidthMM() - 2, maxWidthMM);
|
||||
var destHeightMM = Math.min(self.workingAreaHeightMM() - 2, maxHeightMM);
|
||||
if ((destWidthMM / aspectRatio) > destHeightMM) {
|
||||
destWidthMM = destHeightMM * aspectRatio;
|
||||
} else {
|
||||
destHeightMM = destWidthMM / aspectRatio;
|
||||
}
|
||||
var maxWidthMM = wpx * 0.25; // TODO parametrize
|
||||
var aspectRatio = wpx / hpx;
|
||||
var destWidthMM = Math.min(self.workingAreaWidthMM() - 2, maxWidthMM);
|
||||
var destHeightMM = destWidthMM / aspectRatio;
|
||||
var destWidthPT = self.mm2svgUnits(destWidthMM);
|
||||
var destHeightPT = self.mm2svgUnits(destHeightMM);
|
||||
return [destWidthPT, destHeightPT];
|
||||
|
|
@ -742,16 +674,6 @@ $(function(){
|
|||
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() {
|
||||
var gcodeFiles = [];
|
||||
ko.utils.arrayForEach(self.placedDesigns(), function(design) {
|
||||
|
|
@ -836,12 +758,7 @@ $(function(){
|
|||
self._embedAllImages = function(svg, callback){
|
||||
|
||||
var allImages = svg.selectAll('image');
|
||||
var linkedImages = allImages.items.filter(function(i){
|
||||
if(i.attr('xlink:href') != null) {
|
||||
return !i.attr('xlink:href').startsWith('data:');
|
||||
} else if(i.attr('href') != null) {
|
||||
return !i.attr('href').startsWith('data:');
|
||||
}});
|
||||
var linkedImages = allImages.items.filter(function(i){ return !i.attr('href').startsWith('data:') });
|
||||
if(linkedImages.length > 0){
|
||||
var callbackCounter = linkedImages.length;
|
||||
for (var i = 0; i < linkedImages.length; i++) {
|
||||
|
|
@ -874,7 +791,7 @@ $(function(){
|
|||
for (var i = 0; i < fillings.length; 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
|
||||
var style = item.attr('style');
|
||||
if (style !== null) {
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback):
|
|||
def position(self, x, y):
|
||||
printer_profile = self._printerProfileManager.get_current_or_default()
|
||||
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):
|
||||
if not isinstance(factor, (int, float, long)):
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 6.7 KiB |
|
|
@ -217,8 +217,6 @@ $(function() {
|
|||
$("#confirmation_dialog .confirmation_dialog_acknowledge").click(
|
||||
function (e) {
|
||||
if (typeof callback === 'function') {
|
||||
self.resetOverrideSlider();
|
||||
self.numberOfPasses(1);
|
||||
callback(e);
|
||||
$("#confirmation_dialog").modal("hide");
|
||||
$("#confirmation_dialog .confirmation_dialog_message").html('');
|
||||
|
|
@ -289,12 +287,6 @@ $(function() {
|
|||
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({
|
||||
|
|
@ -317,9 +309,11 @@ $(function() {
|
|||
min: 10,
|
||||
max: 200,
|
||||
value: 100,
|
||||
// tooltip: 'hide'
|
||||
}).on("slideStop", function(ev){
|
||||
tooltip: 'hide'
|
||||
}).on("slide", function(ev){
|
||||
self.intensityOverride(ev.value);
|
||||
}).on("slideStop", function(ev){
|
||||
self._overrideCommand("/intensity "+self.intensityOverride());
|
||||
});
|
||||
|
||||
self.feedrateOverrideSlider = $("#feedrate_override_slider").slider({
|
||||
|
|
@ -327,9 +321,11 @@ $(function() {
|
|||
min: 10,
|
||||
max: 200,
|
||||
value: 100,
|
||||
// tooltip: 'hide'
|
||||
}).on("slideStop", function(ev){
|
||||
tooltip: 'hide'
|
||||
}).on("slide", function(ev){
|
||||
self.feedrateOverride(ev.value);
|
||||
}).on("slideStop", function(ev){
|
||||
self._overrideCommand("/feedrate "+self.feedrateOverride());
|
||||
});
|
||||
|
||||
};
|
||||
|
|
@ -345,19 +341,15 @@ $(function() {
|
|||
}
|
||||
|
||||
self.onEventPrintDone = function(){
|
||||
self.resetOverrideSlider();
|
||||
self.feedrateOverrideSlider.slider('setValue', 100);
|
||||
self.intensityOverrideSlider.slider('setValue', 100);
|
||||
self.intensityOverride(100);
|
||||
self.feedrateOverride(100);
|
||||
};
|
||||
|
||||
self.onStartup = function() {
|
||||
self._configureOverrideSliders();
|
||||
};
|
||||
|
||||
self.resetOverrideSlider = function() {
|
||||
self.feedrateOverrideSlider.slider('setValue', 100);
|
||||
self.intensityOverrideSlider.slider('setValue', 100);
|
||||
self.intensityOverride(100);
|
||||
self.feedrateOverride(100);
|
||||
};
|
||||
}
|
||||
|
||||
OCTOPRINT_VIEWMODELS.push([
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<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="apple-touch-icon" sizes="114x114" href="{{ url_for('static', filename='img/apple-touch-icon-114x114.png') }}">
|
||||
|
|
@ -9,14 +9,27 @@
|
|||
|
||||
{% include 'stylesheets.jinja2' %}
|
||||
{% include 'initscript.jinja2' %}
|
||||
|
||||
<script type="text/javascript" >
|
||||
function cycle_bg(){
|
||||
var path = $('#cam').attr('xlink:href');
|
||||
var m = path.match(/[0-9]+/);
|
||||
var number = 0;
|
||||
if(m.length > 0){
|
||||
number = (parseInt(m[0]) + 1) % 12;
|
||||
}
|
||||
var nPath = "/plugin/svgtogcode/static/img/wa_preview/" + number + ".jpg";
|
||||
$('#cam').attr('xlink:href', nPath);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container octoprint-container">
|
||||
<nav class="navbar navbar-default navbar-fixed-top" role="navigation" id="navbar">
|
||||
<div class="container">
|
||||
<div class="navbar-header brand" style="min-width: 272px;">
|
||||
<a class="navbar-brand" href="#">
|
||||
<img alt="Mr Draw Logo" src="{{ url_for('static', filename='img/mr-draw-red_x120.png') }}">
|
||||
<div class="navbar-header brand" style="min-width: 272px;" onclick="cycle_bg()">
|
||||
<a class="navbar-brand" href="#" >
|
||||
<img alt="Mr Beam Logo" src="{{ url_for('static', filename='img/mr-typo-red_x120.png') }}">
|
||||
</a>
|
||||
</div>
|
||||
<!-- Navbar -->
|
||||
|
|
@ -58,7 +71,7 @@
|
|||
|
||||
<div id="control" class="accordion-inner" data-bind="visible: isReady() || isLocked() || isFlashing()">
|
||||
<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.
|
||||
Then do a homing cycle.
|
||||
<div style='text-align: center; padding:.5em;'>
|
||||
|
|
@ -316,6 +329,9 @@
|
|||
<feFuncB type="table" tableValues="0.2 1"></feFuncB>
|
||||
</feComponentTransfer>
|
||||
</filter>
|
||||
<image id="cam" xlink:href="/plugin/svgtogcode/static/img/wa_preview/0.jpg" x="0" y="0"
|
||||
height="0px" width="0px" data-bind="attr: { width: workingAreaWidthPx()+'px', height: workingAreaHeightPx()+'px'}" />
|
||||
|
||||
<g id="scaleGroup" data-bind="attr: { transform: scaleMatrix() }">
|
||||
|
||||
<text
|
||||
|
|
@ -657,10 +673,12 @@
|
|||
<div class="span4">
|
||||
<ul class="focus_steps">
|
||||
<li>1. Place your material on the working area</li>
|
||||
<li>2. Move the pen over the material</li>
|
||||
<li>→ Now enable the pen calibration mode</li>
|
||||
<li>5. Adjust the pen until it touches the paper</li>
|
||||
<li>→ Disable the pen calibration mode. </li>
|
||||
<li>2. Move the laser over the material</li>
|
||||
<li>3. Put on your safety glasses</li>
|
||||
<li>4. Turn the laser safety switch to on</li>
|
||||
<li>→ Now enable the focus mode</li>
|
||||
<li>5. Adjust the focus until the laser beam is as small as possible</li>
|
||||
<li>→ Disable the focus mode. </li>
|
||||
</ul>
|
||||
<div style="text-align:center">
|
||||
<div class="btn-group" role="group" aria-label="focus mode control" style="">
|
||||
|
|
|
|||
|
|
@ -568,8 +568,8 @@ msgstr ""
|
|||
"aktualisiert werden."
|
||||
|
||||
#: src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js:131
|
||||
msgid "Mr Beam Update Available"
|
||||
msgstr "Mr Beam Aktualisierung verfügbar"
|
||||
msgid "Update Available"
|
||||
msgstr "Aktualisierung verfügbar"
|
||||
|
||||
#: src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js:143
|
||||
msgid "Ignore"
|
||||
|
|
|
|||
|
|
@ -84,11 +84,9 @@ class MachineCom(object):
|
|||
self._actual_intensity = None
|
||||
self._feedrate_dict = {}
|
||||
self._intensity_dict = {}
|
||||
self._passes = 1
|
||||
self._finished_passes = 0
|
||||
|
||||
# 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_intensity = re.compile("S\d+", re.IGNORECASE)
|
||||
|
||||
|
|
@ -147,7 +145,7 @@ class MachineCom(object):
|
|||
elif line.startswith('['): # feedback message
|
||||
self._handle_feedback_message(line)
|
||||
elif line.startswith('Grb'): # Grbl startup message
|
||||
self._handle_startup_message(line)
|
||||
self._handle_startup_message()
|
||||
except:
|
||||
self._logger.exception("Something crashed inside the monitoring loop, please report this to Mr. Beam")
|
||||
errorMsg = "See octoprint.log for details"
|
||||
|
|
@ -166,15 +164,8 @@ class MachineCom(object):
|
|||
if cmd is not None:
|
||||
self.sendCommand(cmd)
|
||||
self._callback.on_comm_progress()
|
||||
else:
|
||||
if self._finished_passes >= self._passes:
|
||||
if len(self._acc_line_buffer) == 0:
|
||||
self._set_print_finished()
|
||||
self._currentFile.resetToBeginning()
|
||||
cmd = self._getNext()
|
||||
if cmd is not None:
|
||||
self.sendCommand(cmd)
|
||||
self._callback.on_comm_progress()
|
||||
elif len(self._acc_line_buffer) == 0:
|
||||
self._set_print_finished()
|
||||
|
||||
self._sendCommand()
|
||||
self._send_event.wait(1)
|
||||
|
|
@ -320,9 +311,7 @@ class MachineCom(object):
|
|||
if self._finished_currentFile is False:
|
||||
line = self._currentFile.getNext()
|
||||
if line is None:
|
||||
self._finished_passes += 1
|
||||
if self._finished_passes >= self._passes:
|
||||
self._finished_currentFile = True
|
||||
self._finished_currentFile = True
|
||||
return line
|
||||
else:
|
||||
return None
|
||||
|
|
@ -358,6 +347,7 @@ class MachineCom(object):
|
|||
def _handle_ok_message(self):
|
||||
if self._state == self.STATE_HOMING:
|
||||
self._changeState(self.STATE_OPERATIONAL)
|
||||
self._onHomingDone()
|
||||
|
||||
def _handle_error_message(self, line):
|
||||
self._errorValue = line
|
||||
|
|
@ -405,7 +395,7 @@ class MachineCom(object):
|
|||
elif line[1:].startswith('Dis'): # [Disabled]
|
||||
pass
|
||||
|
||||
def _handle_startup_message(self, line):
|
||||
def _handle_startup_message(self):
|
||||
if self.isOperational():
|
||||
errorMsg = "Machine reset."
|
||||
self._cmd = None
|
||||
|
|
@ -420,14 +410,7 @@ class MachineCom(object):
|
|||
self._changeState(self.STATE_LOCKED)
|
||||
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:
|
||||
self._onConnected(self.STATE_LOCKED)
|
||||
self._onConnected(self.STATE_LOCKED)
|
||||
|
||||
def _update_grbl_pos(self, line):
|
||||
# line example:
|
||||
|
|
@ -557,6 +540,11 @@ class MachineCom(object):
|
|||
payload = dict(port=self._port, baudrate=self._baudrate)
|
||||
eventManager().fire(Events.CONNECTED, payload)
|
||||
|
||||
def _onHomingDone(self):
|
||||
self.sendCommand("G92X500Y0Z0")
|
||||
self.sendCommand("G90")
|
||||
self.sendCommand("G21")
|
||||
|
||||
def _detectPort(self, close):
|
||||
self._log("Serial port list: %s" % (str(serialList())))
|
||||
for p in serialList():
|
||||
|
|
@ -618,7 +606,7 @@ class MachineCom(object):
|
|||
params = ["avrdude", "-patmega328p", "-carduino", "-b" + str(self._baudrate), "-P" + str(self._port), "-D", "-Uflash:w:" + pathToGrblHex]
|
||||
rc = subprocesscall(params)
|
||||
|
||||
if rc == 0:
|
||||
if rc is False:
|
||||
self._log("successfully flashed new grbl version")
|
||||
self._openSerial()
|
||||
self._changeState(self.STATE_CONNECTING)
|
||||
|
|
@ -755,10 +743,6 @@ class MachineCom(object):
|
|||
self._changeState(self.STATE_HOMING)
|
||||
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):
|
||||
self._changeState(self.STATE_PAUSED)
|
||||
return cmd
|
||||
|
|
@ -846,12 +830,6 @@ class MachineCom(object):
|
|||
if self._currentFile is None:
|
||||
raise ValueError("No file selected for printing")
|
||||
|
||||
# reset feedrate and intesity factor in case they where changed in a previous run
|
||||
self._feedrate_factor = 1
|
||||
self._intensity_factor = 1
|
||||
self._passes = 1
|
||||
self._finished_passes = 0
|
||||
|
||||
try:
|
||||
# ensure fan is on whatever gcode follows.
|
||||
self.sendCommand("M08")
|
||||
|
|
@ -922,12 +900,10 @@ class MachineCom(object):
|
|||
eventManager().fire(Events.PRINT_PAUSED, payload)
|
||||
|
||||
def increasePasses(self):
|
||||
self._passes += 1
|
||||
self._log("increased Passes to %d" % self._passes)
|
||||
self._log("increase Passes")
|
||||
|
||||
def degreasePasses(self):
|
||||
self._passes -= 1
|
||||
self._log("degrease Passes to %d" % self._passes)
|
||||
self._log("degrease Passes")
|
||||
|
||||
def getStateString(self):
|
||||
if self._state == self.STATE_NONE:
|
||||
|
|
@ -1169,9 +1145,6 @@ class PrintingGcodeFileInformation(PrintingFileInformation):
|
|||
|
||||
if not os.path.exists(self._filename) or not os.path.isfile(self._filename):
|
||||
raise IOError("File %s does not exist" % self._filename)
|
||||
|
||||
self._stripCommments()
|
||||
|
||||
self._size = os.stat(self._filename).st_size
|
||||
self._pos = 0
|
||||
|
||||
|
|
@ -1194,12 +1167,6 @@ class PrintingGcodeFileInformation(PrintingFileInformation):
|
|||
pass
|
||||
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):
|
||||
"""
|
||||
Retrieves the next line for printing.
|
||||
|
|
@ -1225,16 +1192,6 @@ class PrintingGcodeFileInformation(PrintingFileInformation):
|
|||
self._logger.exception("Exception while processing line")
|
||||
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):
|
||||
triggers = {
|
||||
"enable": [],
|
||||
|
|
@ -1299,7 +1256,6 @@ def serialList():
|
|||
baselist = baselist \
|
||||
+ glob.glob("/dev/ttyUSB*") \
|
||||
+ glob.glob("/dev/ttyACM*") \
|
||||
+ glob.glob("/dev/ttyAMA*") \
|
||||
+ glob.glob("/dev/tty.usb*") \
|
||||
+ glob.glob("/dev/cu.*") \
|
||||
+ glob.glob("/dev/cuaU*") \
|
||||
|
|
|
|||