Compare commits

..

11 commits

24 changed files with 2213 additions and 2306 deletions

View file

@ -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.
[![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)

File diff suppressed because it is too large Load diff

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))
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)

View file

@ -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
};

View file

@ -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/svg2gcode.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)

View file

@ -16,7 +16,7 @@ defaults = dict(
# general settings
svgDPI = 90,
pierce_time = 0,
# vector settings
speed = 300,
intensity = 500,
@ -24,7 +24,7 @@ defaults = dict(
cross_fill = False,
fill_angle = 0,
fill_spacing = 0.25,
# pixel settings
beam_diameter = 0.25,
intensity_white = 0,
@ -251,8 +251,8 @@ class Profile(object):
}
return settings
def convert_to_engine2(self):
settings = {

View file

@ -1160,7 +1160,6 @@ ul.dropdown-menu li a {
#control_zaxis {
display:inline-block;
width: 80px;
margin: 1em auto 0;
}
#control_zaxis_focus {
display:inline-block;
@ -1542,7 +1541,7 @@ td.settings_printerProfiles_profiles_action a.disabled {
.nav-pills>li>a,
select,
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,
.uneditable-input,
.input-append .add-on:last-child,

View file

@ -102,28 +102,3 @@ svg text {
.overrideSlider span {
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

@ -22,7 +22,7 @@ $(function(){
self.profiles = ko.observableArray();
self.defaultSlicer = undefined;
self.defaultProfile = undefined;
// expert settings
self.showHints = ko.observable(false);
self.showExpertSettings = ko.observable(false);
@ -37,27 +37,25 @@ $(function(){
self.minSpeed = ko.observable(20);
self.fill_areas = ko.observable(false);
self.show_fill_areas_checkbox = ko.observable(false);
// image engraving stuff
// preset values are a good start for wood engraving
self.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);
self.imgFeedrateWhite = ko.observable(1500);
self.imgFeedrateWhite = ko.observable(1500);
self.imgFeedrateBlack = ko.observable(250);
self.imgDithering = ko.observable(false);
self.imgSharpening = ko.observable(1);
self.imgContrast = ko.observable(1);
self.beamDiameter = ko.observable(0.2);
self.sharpeningMax = 25;
self.contrastMax = 2;
// preprocessing preview ... returns opacity 0.0 - 1.0
self.sharpenedPreview = ko.computed(function(){
if(self.imgDithering()) return 0;
@ -75,7 +73,6 @@ $(function(){
return contrastPercents - sharpeningPercents/2;
}
}, self);
self.maxSpeed.subscribe(function(val){
self._configureFeedrateSlider();
@ -87,14 +84,13 @@ $(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()){
if(self.laserIntensity() === undefined){
var intensity = self.settings.settings.plugins.svgtogcode.defaultIntensity();
self.laserIntensity(intensity);
}
}
if(self.laserSpeed() === undefined){
var speed = self.settings.settings.plugins.svgtogcode.defaultFeedrate();
self.laserSpeed(speed);
@ -110,7 +106,7 @@ $(function(){
self.convert();
}
};
self.cancel_conversion = function(){
if(self.slicing_in_progress()){
//console.log('cancel slicing', self.slicing_in_progress());
@ -142,14 +138,14 @@ $(function(){
if(uniqueDesigns > 1){
gcode_name += "_"+(uniqueDesigns-1)+"more";
}
return gcode_name;
} else {
} else {
console.error("no designs placed.");
return;
}
};
self.settingsString = ko.computed(function(){
var intensity = self.laserIntensity();
var feedrate = self.laserSpeed();
@ -251,7 +247,7 @@ $(function(){
} else {
self.slicing_in_progress(true);
self.workingArea.getCompositionSVG(self.fill_areas(), function(composition){
self.svg = composition;
self.svg = composition;
var filename = self.gcodeFilename() + self.settingsString() + '.gco';
var gcodeFilename = self._sanitize(filename);
@ -282,6 +278,10 @@ $(function(){
data.gcodeFilesToAppend = self.gcodeFilesToAppend;
}
var snapelement = snap.select("#userContent");
snapelement.bake(false, 5);
data.gcodedata = snapelement.toGcode(self.laserSpeed(), self.laserIntensity(), self.pierceTime());
$.ajax({
url: API_BASEURL + "files/convert",
type: "POST",
@ -289,7 +289,6 @@ $(function(){
contentType: "application/json; charset=UTF-8",
data: JSON.stringify(data)
});
});
}
};
@ -306,7 +305,7 @@ $(function(){
self._configureFeedrateSlider();
self._configureImgSliders();
};
self.onSlicingProgress = function(slicer, model_path, machinecode_path, progress){
self.slicing_progress(progress);
};
@ -392,7 +391,7 @@ $(function(){
self._calcRealSpeed = function(sliderVal){
return Math.round(self.minSpeed() + sliderVal/100 * (self.maxSpeed() - self.minSpeed()));
};
self._configureImgSliders = function() {
self.contrastSlider = $("#svgtogcode_contrast_slider").slider({
step: .1,
@ -403,7 +402,7 @@ $(function(){
}).on("slide", function(ev){
self.imgContrast(ev.value);
});
self.sharpeningSlider = $("#svgtogcode_sharpening_slider").slider({
step: 1,
min: 1,
@ -422,9 +421,9 @@ $(function(){
});
}
ADDITIONAL_VIEWMODELS.push([VectorConversionViewModel,
["loginStateViewModel", "settingsViewModel", "printerStateViewModel", "workingAreaViewModel", "gcodeFilesViewModel"],
ADDITIONAL_VIEWMODELS.push([VectorConversionViewModel,
["loginStateViewModel", "settingsViewModel", "printerStateViewModel", "workingAreaViewModel", "gcodeFilesViewModel"],
document.getElementById("dialog_vector_graphics_conversion")]);
});

View file

@ -1,8 +1,8 @@
// Drag, Scale & Rotate - a snapsvg.io plugin to free transform objects in an svg.
// Copyright (C) 2015 Teja Philipp <osd@tejaphilipp.de>
//
//
// heavily inspired by http://svg.dabbles.info
//
//
// 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
@ -19,10 +19,10 @@
Snap.plugin(function (Snap, Element, Paper, global) {
/**
*
*
*
*
* @returns {undefined}
*/
Element.prototype.transformable = function () {
@ -35,13 +35,13 @@ Snap.plugin(function (Snap, Element, Paper, global) {
elem.click(function(){ elem.ftCreateHandles() });
return elem;
};
/**
* Adds transparent fill if not present.
* This is useful for dragging the element around.
*
* Adds transparent fill if not present.
* This is useful for dragging the element around.
*
* @returns {path}
*/
Element.prototype.add_fill = function(){
@ -67,7 +67,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
});
/**
* Free transform plugin heavily inspired by http://svg.dabbles.info
*/
@ -79,13 +79,13 @@ Snap.plugin(function (Snap, Element, Paper, global) {
handleFill: "red",
handleStrokeDashPreset: [5,5],
handleStrokeWidth: 2,
handleLength: 18,
handleRadius: 16,
handleLength: 10,
handleRadius: 16,
unscale: 1,
handleStrokeDash: "5,5",
};
Element.prototype.ftToggleHandles = function(){
Element.prototype.ftToggleHandles = function(){
if(this.data('handlesGroup')){
this.ftRemoveHandles();
} else {
@ -97,10 +97,10 @@ Snap.plugin(function (Snap, Element, Paper, global) {
this.ftInit();
var freetransEl = this;
var bb = freetransEl.getBBox();
var rotateDragger = this.paper.select('#userContent').circle(bb.cx + bb.width/2 + ftOption.handleLength * ftOption.unscale, bb.cy, ftOption.handleRadius * ftOption.unscale ).attr({ fill: ftOption.handleFill });
var translateDragger = this.paper.select('#userContent').circle(bb.cx, bb.cy, ftOption.handleRadius * ftOption.unscale).attr({ fill: ftOption.handleFill });
var joinLine = freetransEl.ftDrawJoinLine( rotateDragger, ftOption.handleStrokeWidth * ftOption.unscale);
var handlesGroup = this.paper.select('#userContent').g( joinLine, rotateDragger, translateDragger );
@ -109,19 +109,19 @@ Snap.plugin(function (Snap, Element, Paper, global) {
freetransEl.data( "scaleFactor", calcDistance( bb.cx, bb.cy, rotateDragger.attr('cx'), rotateDragger.attr('cy') ) );
translateDragger.drag(
elementDragMove.bind( translateDragger, freetransEl ),
translateDragger.drag(
elementDragMove.bind( translateDragger, freetransEl ),
elementDragStart.bind( translateDragger, freetransEl ),
elementDragEnd.bind( translateDragger, freetransEl )
elementDragEnd.bind( translateDragger, freetransEl )
);
freetransEl.unclick();
freetransEl.data("click", freetransEl.click( function() { this.ftRemoveHandles() } ) );
rotateDragger.drag(
dragHandleRotateMove.bind( rotateDragger, freetransEl ),
rotateDragger.drag(
dragHandleRotateMove.bind( rotateDragger, freetransEl ),
dragHandleRotateStart.bind( rotateDragger, freetransEl ),
dragHandleRotateEnd.bind( rotateDragger, freetransEl )
dragHandleRotateEnd.bind( rotateDragger, freetransEl )
);
freetransEl.ftStoreInitialTransformMatrix();
freetransEl.ftHighlightBB();
@ -134,8 +134,8 @@ Snap.plugin(function (Snap, Element, Paper, global) {
this.data("tx", 0);
this.data("ty", 0);
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);
ftOption.handleStrokeDash = ftOption.handleStrokeDashPreset.map(function(v){ return v*ftOption.unscale; }).join(',');
return this;
@ -153,11 +153,11 @@ Snap.plugin(function (Snap, Element, Paper, global) {
this.data('ocy', this.attr('cy') );
return this;
}
Element.prototype.ftStoreInitialTransformMatrix = function() {
this.data('initialTransformMatrix', this.transform().localMatrix );
return this;
};
};
Element.prototype.ftGetInitialTransformMatrix = function() {
return this.data('initialTransformMatrix');
@ -191,10 +191,10 @@ Snap.plugin(function (Snap, Element, Paper, global) {
return this;
};
Element.prototype.ftUpdateTransform = function() {
//console.log("translate: ", this.data('tx'), this.data('ty'), 'rotate: ', this.data('angle'), 'scale: ', this.data('scale'));
var tstring = "t" + this.data("tx") + "," + this.data("ty") + this.ftGetInitialTransformMatrix().toTransformString() + "r" + this.data("angle") + 'S' + this.data("scale" );
var tstring = "t" + this.data("tx") + "," + this.data("ty") + this.ftGetInitialTransformMatrix().toTransformString() + "r" + this.data("angle") + 'S' + this.data("scale" );
this.attr({ transform: tstring });
this.data("bbT") && this.ftHighlightBB(this.paper.select('#userContent'));
this.ftReportTransformation();
@ -204,17 +204,17 @@ Snap.plugin(function (Snap, Element, Paper, global) {
Element.prototype.ftHighlightBB = function() {
this.data("bbT") && this.data("bbT").remove();
this.data("bb") && this.data("bb").remove();
// transformed bbox
this.data("bbT", this.paper.rect( rectObjFromBB( this.getBBox(1) ) )
.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
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;
};
Element.prototype.ftReportTransformation = function(){
if(this.data('ftCallbacks') && this.data('ftCallbacks').length > 0){
for (var idx = 0; idx < this.data('ftCallbacks').length; idx++) {
@ -230,9 +230,9 @@ Snap.plugin(function (Snap, Element, Paper, global) {
this.data('ftCallbacks').push(callback);
}
};
Element.prototype.ftDisableRotate = function(){
this.data('block_rotation', true);
this.data('block_rotation', true);
};
});
@ -254,7 +254,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
var dragHandle = this;
var unscale = mainEl.data('unscale');
var bb = mainEl.data('obb');
var udx = dx*unscale;
var udy = dy*unscale;
@ -287,22 +287,22 @@ Snap.plugin(function (Snap, Element, Paper, global) {
function dragHandleRotateEnd( mainElement ) {
};
function dragHandleRotateMove( mainEl, dx, dy, x, y, event ) {
var handle = this;
var mainBB = mainEl.getBBox();
var unscale = mainEl.data('unscale');
handle.attr({ cx: +handle.data('ocx') + dx*unscale, cy: +handle.data('ocy') + dy*unscale });
if(!mainEl.data('block_rotation')){
var angle = Snap.angle( mainBB.cx, mainBB.cy, handle.attr('cx'), handle.attr('cy') ) - 180;
if(event.shiftKey){
angle = Math.round(angle/30) * 30;
}
angle = Math.round(angle/15) * 15;
}
mainEl.data("angle", angle );
}
var distance = calcDistance( mainBB.cx, mainBB.cy, handle.attr('cx'), handle.attr('cy') );
var scale = distance / mainEl.data("scaleFactor");
if(event.shiftKey){
@ -311,7 +311,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
mainEl.data("scale", scale );
mainEl.ftUpdateTransform();
mainEl.ftDrawJoinLine( handle );
mainEl.ftDrawJoinLine( handle );
};
function calcDistance(x1,y1,x2,y2) {

View file

@ -1,7 +1,7 @@
// Matrix Oven - a snapsvg.io plugin to apply & remove transformations from svg files.
// Copyright (C) 2015 Teja Philipp <osd@tejaphilipp.de>
//
// based on work by https://gist.github.com/timo22345/9413158
//
// based on work by https://gist.github.com/timo22345/9413158
// and https://github.com/duopixel/Method-Draw/blob/master/editor/src/svgcanvas.js
//
// This program is free software: you can redistribute it and/or modify
@ -20,25 +20,24 @@
Snap.plugin(function (Snap, Element, Paper, global) {
/**
* bakes transformations of the element and all sub-elements into coordinates
*
*
* @param {boolean} toCubics : use only cubic path segments
* @param {integer} dec : number of digits after decimal separator. defaults to 5
* @returns {undefined}
*/
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,16 +54,15 @@ 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"){
// TODO ...
if (elem.type == 'image'){
// TODO ...
var x = parseFloat(elem.attr('x')),
y = parseFloat(elem.attr('y')),
w = parseFloat(elem.attr('width')),
@ -86,11 +84,12 @@ Snap.plugin(function (Snap, Element, Paper, global) {
var transformedY = matrix.y(x, y);
var transformedW = matrix.x(x+w, y+h) - transformedX;
var transformedH = matrix.y(x+w, y+h) - transformedY;
elem.attr({x: transformedX, y: transformedY, width: transformedW, height: transformedH});
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)
@ -102,7 +101,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
} else {
dec = false;
}
function r(num) {
if (dec !== false) {
return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
@ -115,8 +114,8 @@ Snap.plugin(function (Snap, Element, Paper, global) {
var d = path_elem.attr('d');
d = (d || "").trim();
var arr_orig;
arr = Snap.parsePathString(d);
if (!toCubics) {
arr = Snap.parsePathString(d);
if (!toCubics) {
arr_orig = arr;
arr = Snap.path.toAbsolute(arr);
} else {
@ -129,7 +128,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
var matrix = transform['totalMatrix'];
// apply the matrix transformation on the path segments
var j;
var j;
var m = arr.length;
var letter = '';
var letter_orig = '';
@ -137,8 +136,8 @@ Snap.plugin(function (Snap, Element, Paper, global) {
var y = 0;
var new_segments = [];
var pt = {x: 0, y: 0};
var pt_baked = {};
var subpath_start = {};
var pt_baked = {};
var subpath_start = {};
var prevX = 0;
var prevY = 0;
subpath_start.x = null;
@ -156,7 +155,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
pt.x = arr[i][6];
pt.y = arr[i][7];
new_segments[i] = _arc_transform(arr[i][1], arr[i][2], arr[i][3], arr[i][4], arr[i][5], pt, matrix);
} else if (letter !== 'Z') {
// parse other segs than Z and A
for (j = 1; j < arr[i].length; j = j + 2) {
@ -192,7 +191,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
y = subpath_start.y;
}
}
// Convert all that was relative back to relative
// This could be combined to above, but to make code more readable
// this is made separately.
@ -262,7 +261,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
//console.log("baked matrix ", matrix, " of ", path_elem.attr('id'));
};
/**
* Helper to apply matrix transformations to arcs.
* From flatten.js (https://gist.github.com/timo22345/9413158), modified a bit.
@ -270,7 +269,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
* @param {type} a_rh : r1 of the ellipsis in degree
* @param {type} a_rv : r2 of the ellipsis in degree
* @param {type} a_offsetrot : x-axis rotation in degree
* @param {type} large_arc_flag : 0 or 1
* @param {type} large_arc_flag : 0 or 1
* @param {int} sweep_flag : 0 or 1
* @param {object} endpoint with properties x and y
* @param {type} matrix : transformation matrix
@ -312,12 +311,12 @@ Snap.plugin(function (Snap, Element, Paper, global) {
// convert implicit equation to angle and halfaxis:
// disabled intentionally
if (false && NEARZERO(B)) { // there is a bug in this optimization: does not work for path below
a_offsetrot = 0;
// d="M0,350 l 50,-25
// a25,25 -30 0,1 50,-25 l 50,-25
// a25,50 -30 0,1 50,-25 l 50,-25
// a25,75 -30 0,1 50,-25 l 50,-25
if (false && NEARZERO(B)) { // there is a bug in this optimization: does not work for path below
a_offsetrot = 0;
// d="M0,350 l 50,-25
// a25,25 -30 0,1 50,-25 l 50,-25
// a25,50 -30 0,1 50,-25 l 50,-25
// a25,75 -30 0,1 50,-25 l 50,-25
// a25,100 -30 0,1 50,-25 l 50,-25"
// with matrix transform="scale(0.5,2.0)"
A2 = A;
@ -333,7 +332,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
// Clamp (precision issues might need this.. not likely, but better save than sorry)
K = (K < 0) ? 0 : Math.sqrt(K);
A2 = 0.5 * (A + C + K * ac);
C2 = 0.5 * (A + C - K * ac);
a_offsetrot = 0.5 * Math.atan2(B, ac);
@ -354,7 +353,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
a_rh = A2;
}
// If the transformation matrix contain a mirror-component
// If the transformation matrix contain a mirror-component
// winding order of the ellise needs to be changed.
if ((matrix.a * matrix.d) - (matrix.b * matrix.c) < 0){
sweep_flag = !sweep_flag ? 1 : 0;
@ -377,30 +376,30 @@ Snap.plugin(function (Snap, Element, Paper, global) {
var _convertToString = function (arr) {
return arr.join(',').replace(_p2s, '$1');
};
/**
* Replaces an element with a path of same shape.
* Supports rect, ellipse, circle, line, polyline, polygon and of course path
* The element will be replaced by the path with same id.
*
* The element will be replaced by the path with same id.
*
* @returns {path}
*/
Element.prototype.convertToPath = function(){
var old_element = this;
var path = old_element.toPath();
old_element.before(path);
old_element.remove();
old_element.remove();
return path;
};
/**
* Creates a path in the same shape as the origin element
* Supports rect, ellipse, circle, line, polyline, polygon and of course path
*
* based on
*
* based on
* https://github.com/duopixel/Method-Draw/blob/master/editor/src/svgcanvas.js
* Modifications: Timo (https://github.com/timo22345)
*
*
* @returns {path} path element
*/
Element.prototype.toPath = function () {
@ -431,7 +430,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
var validRadius = function (val) {
return (isFinite(val) && (val >= 0));
};
var validCoordinate = function (val) {
return (isFinite(val));
};
@ -439,19 +438,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':
@ -462,13 +448,13 @@ Snap.plugin(function (Snap, Element, Paper, global) {
if (tag === 'circle') {
rx = ry = +old_element.attr('r');
}
// If 'x' and 'y' are not specified, then set both to 0. // CorelDraw is creating that sometimes
if (!validCoordinate(cx))
cx = 0;
if (!validCoordinate(cy))
cy = 0;
d += _convertToString([
['M', (cx - rx), (cy)],
['C', (cx - rx), (cy - ry / num), (cx - rx / num), (cy - ry), (cx), (cy - ry)],
@ -495,7 +481,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
d = 'M' + old_element.attr('points') + 'Z';
break;
case 'rect':
// TODO ...
// TODO ...
var rx = parseFloat(old_element.attr('rx')),
ry = parseFloat(old_element.attr('ry')),
x = parseFloat(old_element.attr('x')),

View file

@ -1,7 +1,7 @@
// render_fills.js - a snapsvg.io plugin to render the infill of svg files into a bitmap.
// Copyright (C) 2015 Teja Philipp <osd@tejaphilipp.de>
//
// based on work by http://davidwalsh.name/convert-canvas-image
//
// based on work by http://davidwalsh.name/convert-canvas-image
// and http://getcontext.net/read/svg-images-on-a-html5-canvas
//
// This program is free software: you can redistribute it and/or modify
@ -20,12 +20,12 @@
Snap.plugin(function (Snap, Element, Paper, global) {
/**
* @param {elem} elem start point
*
*
* @returns {path}
*/
@ -34,7 +34,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
var selection = [];
var children = elem.children();
if (children.length > 0) {
var goRecursive = (elem.type !== "defs" && // ignore these tags
elem.type !== "clipPath" &&
@ -42,7 +42,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
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];
@ -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()){
@ -65,7 +65,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
Element.prototype.is_filled = function(){
var elem = this;
// TODO text support
// TODO opacity support
if (elem.type !== "circle" &&
@ -74,17 +74,14 @@ 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;
}
var fill = elem.attr('fill');
var opacity = elem.attr('fill-opacity');
if(fill !== 'none'){
if(opacity === null || opacity > 0){
return true;
@ -92,7 +89,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
}
return false;
};
Element.prototype.embedImage = function(callback){
var elem = this;
if(elem.type !== 'image') return;
@ -116,15 +113,15 @@ Snap.plugin(function (Snap, Element, Paper, global) {
};
image.src = url;
};
Element.prototype.renderPNG = function (wMM, hMM, pxPerMM, callback) {
var elem = this;
// 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;
@ -132,7 +129,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
var renderCanvas = document.createElement('canvas');
renderCanvas.id = "renderCanvas";
renderCanvas.width = wMM * pxPerMM;
renderCanvas.height = hMM * pxPerMM;
renderCanvas.height = hMM * pxPerMM;
document.getElementsByTagName('body')[0].appendChild(renderCanvas);
var renderCanvasContext = renderCanvas.getContext('2d');

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(){
// 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;
@ -79,7 +64,8 @@ $(function(){
// matrix scales svg units to display_pixels
self.scaleMatrix = ko.computed(function(){
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)){
m.scale(factor);
return m;
@ -107,7 +93,6 @@ $(function(){
self.clear = function(){
snap.selectAll('#userContent>*').remove();
snap.selectAll('#placedGcodes>*').remove();
snap.selectAll('rect:not(#coordGrid)').remove();
self.placedDesigns([]);
};
@ -118,34 +103,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 +128,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 +218,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 +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
var scale = self.svgDPI()/25.4;
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]/scale,mat[0][1],mat[1][0],mat[1][1]/scale,mat[0][2],mat[1][2]).toTransformString();
newSvgAttrs['transform'] = scaleMatrixStr;
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){
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 +376,7 @@ $(function(){
type: "warn",
hide: false
});
svg.selectAll('text,tspan').remove();
};
self.svg_misfitting_warning = function(svg, misfitting){
@ -461,12 +401,12 @@ $(function(){
var wpx = this.width;
var hpx = this.height;
var dimPT = self.getUsefulDimensions(wpx, hpx);
var wPT = dimPT[0];
var hPT = dimPT[1];
var dimMM = self.getUsefulDimensions(wpx, hpx);
var wMM = dimMM[0];
var hMM = dimMM[1];
var y = self.mm2svgUnits(self.workingAreaHeightMM()) - hPT;
var newImg = snap.image(url, 0, y, wPT, hPT);
var y = self.workingAreaHeightMM() - hMM;
var newImg = snap.image(url, 0, y, wMM, hMM);
var id = self.getEntryId(file);
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});
@ -498,9 +438,7 @@ $(function(){
} else {
destHeightMM = destWidthMM / aspectRatio;
}
var destWidthPT = self.mm2svgUnits(destWidthMM);
var destHeightPT = self.mm2svgUnits(destHeightMM);
return [destWidthPT, destHeightPT];
return [destWidthMM, destHeightMM];
};
self.getDocumentDimensionsInPt = function(doc_width, doc_height, doc_viewbox){
@ -641,18 +579,17 @@ $(function(){
self.draw_coord_grid = function(){
var grid = snap.select('#coordGrid');
if(grid.attr('fill') === 'none'){
var w = self.mm2svgUnits(self.workingAreaWidthMM());
var h = self.mm2svgUnits(self.workingAreaHeightMM());
var w = self.workingAreaWidthMM();
var h = self.workingAreaHeightMM();
var max_lines = 20;
var linedistMM = Math.floor(Math.max(self.workingAreaWidthMM(), self.workingAreaHeightMM()) / (max_lines * 10))*10;
var yPatternOffset = self.mm2svgUnits(self.workingAreaHeightMM() % linedistMM);
var linedist = self.mm2svgUnits(linedistMM);
var yPatternOffset = self.workingAreaHeightMM() % 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",
stroke: "none",
strokeWidth: 1
stroke: "none"
});
// dot pattern
@ -742,16 +679,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) {
@ -874,7 +801,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) {

View file

@ -18,7 +18,7 @@
</div>
<div class="controls alert alert-info hint" data-bind="visible: showHints">
<span class="icon icon-question-sign" aria-hidden="true"></span>
Sets the intensity of the laser. The more intensity the deeper the effect on the material.
Sets the intensity of the laser. The more intensity the deeper the effect on the material.
Cutting needs higher intensities than engraving.
The effect in general is dependent from the material and its color and surface.
</div>
@ -33,8 +33,8 @@
</div>
<div class="controls alert alert-info hint" data-bind="visible: showHints">
<span class="icon icon-question-sign" aria-hidden="true"></span>
Sets the velocity of the laser head. The slower the movement the deeper the effect on the material.
Cutting needs slower movement than engraving.
Sets the velocity of the laser head. The slower the movement the deeper the effect on the material.
Cutting needs slower movement than engraving.
The effect in general is dependent from the material and its color and surface.
</div>
</div>
@ -56,11 +56,11 @@
<div class="controls alert alert-info hint" data-bind="visible: showHints">
<span class="icon icon-question-sign" aria-hidden="true"></span>
Some (especially bright) materials require the laser to dwell a little until the surface has absorbed enough energy to be affected.
This parameter sets the amount of time in milliseconds the movement is paused after the laser is switched on.
This parameter sets the amount of time in milliseconds the movement is paused after the laser is switched on.
If the result shows gaps in lines for example increase this value carefully. The higher the value the higher the risk of material ignition.
</div>
</div>
<div data-bind="visible: show_image_parameters ">
<p>{{ _('Image engraving parameters:') }}</p>
<div class="control-group" >
@ -103,10 +103,10 @@
<div class="controls alert alert-info hint" data-bind="visible: showHints">
<span class="icon icon-question-sign" aria-hidden="true"></span>
Pixel / raster engravings are done line by line. This sets the distance between the single lines.
Smaller values allow finer engravings but require a more precise focus and are slower.
Smaller values allow finer engravings but require a more precise focus and are slower.
</div>
<p >{{ _('Image Preprocessing') }}</p>
<div class="controls">
<div class="img_preprocessing_preview before" style="background-image:url(/plugin/svgtogcode/static/img/kitty_grayscale.png);" >before</div>
@ -114,22 +114,22 @@
<div class="img_preprocessing_preview contrast" style="background-image:url(/plugin/svgtogcode/static/img/kitty_contrast.png);" data-bind="style: { opacity: contrastPreview }" ></div>
<div class="img_preprocessing_preview sharpened" style="background-image:url(/plugin/svgtogcode/static/img/kitty_sharpened.png);" data-bind="style: { opacity: sharpenedPreview }" ></div>
<div class="img_preprocessing_preview dithered" style="background-image:url(/plugin/svgtogcode/static/img/kitty_dithered_150.png);" data-bind="visible: imgDithering"></div>
</div>
<div class="photo_attribution"><a href="http://www.christianholmer.com" target="_blank">Photo: Christian Holmér</a></div>
</div>
<div data-bind="disable:imgDithering ">
<label class="control-label">{{ _('Contrast') }}</label>
<div class="controls img_slider">
<input id="svgtogcode_contrast_slider" type="text" data-bind="value: imgContrast" >
</div>
<div style="clear:both"></div>
<div style="clear:both"></div>
<div class="controls alert alert-info hint" data-bind="visible: showHints">
<span class="icon icon-question-sign" aria-hidden="true"></span>
Increases the image contrast before converting to gcode.
Increases the image contrast before converting to gcode.
</div>
<label class="control-label">{{ _('Sharpening') }}</label>
<div class="controls img_slider">
<input id="svgtogcode_sharpening_slider" class="uninitialized" type="text" data-bind="value: imgSharpening">
@ -137,10 +137,10 @@
<div style="clear:both"></div>
<div class="controls alert alert-info hint" data-bind="visible: showHints">
<span class="icon icon-question-sign" aria-hidden="true"></span>
Sharpens the image before converting to gcode.
Sharpens the image before converting to gcode.
</div>
</div>
<label class="control-label">{{ _('Dithering') }}</label>
<div class="controls">
<label class="checkbox">
@ -149,8 +149,8 @@
</div>
<div class="controls alert alert-info hint" data-bind="visible: showHints">
<span class="icon icon-question-sign" aria-hidden="true"></span>
Converts the image to solely black and white pixels.
Use this if the laser effect on your material is not able to transfer grayscales.
Converts the image to solely black and white pixels.
Use this if the laser effect on your material is not able to transfer grayscales.
</div>
</div>
@ -185,4 +185,4 @@
<a href="#" class="btn" data-dismiss="modal" aria-hidden="true" data-bind="click: $root.cancel_conversion()">{{ _('Cancel') }}</a>
<a href="#" class="btn btn-primary" data-bind="click: function() { if ($root.enableConvertButton()) { $root.convert() } }, enabled: enableConvertButton, css: {disabled: !$root.enableConvertButton()}">{{ _('Convert') }}</a>
</div>
</div>
</div>

View file

@ -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)):
@ -433,22 +433,6 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback):
payload["origin"] = FileDestinations.SDCARD
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):
"""
Returns a human readable string corresponding to the current communication state.

View file

@ -419,7 +419,7 @@ def gcodeFileCommand(filename, target):
@restricted_access
def gcodeConvertCommand():
target = FileDestinations.LOCAL;
# valid file commands, dict mapping command name to mandatory parameters
valid_commands = {
"convert": []
@ -427,14 +427,14 @@ def gcodeConvertCommand():
command, data, response = get_json_command_from_request(request, valid_commands)
if response is not None:
return response
appendGcodeFiles = data['gcodeFilesToAppend']
del data['gcodeFilesToAppend']
# def appendCallback(location, path, sources, **kwargs):
# if '_error' in kwargs:
# result = kwargs['_error']
# return make_response("Could not slice: {result}".format(result=result), 500)
# return make_response("Could not slice: {result}".format(result=result), 500)
# else:
# output_path = fileManager.path_on_disk(location, path)
# # append additioal gcodes
@ -461,18 +461,16 @@ def gcodeConvertCommand():
# #r = make_response(jsonify(result), 202)
# #r.headers["Location"] = location
# #return r
if command == "convert":
# TODO stripping non-ascii is a hack - svg contains lots of non-ascii in <text> tags. Fix this!
import re
svg = ''.join(i for i in data['svg'] if ord(i)<128) # strip non-ascii chars like €
del data['svg']
svg = ''.join(i for i in data['svg'] if ord(i)<128) # strip non-ascii chars like €
del data['svg']
import os
name, _ = os.path.splitext(data['gcode'])
filename = target + "/temp.svg"
class Wrapper(object):
def __init__(self, filename, content):
@ -486,7 +484,7 @@ def gcodeConvertCommand():
fileObj = Wrapper(filename, svg)
fileManager.add_file(target, filename, fileObj, links=None, allow_overwrite=True)
slicer = "svgtogcode";
slicer_instance = slicingManager.get_slicer(slicer)
if slicer_instance.get_slicer_properties()["same_device"] and (printer.is_printing() or printer.is_paused()):
@ -500,7 +498,7 @@ def gcodeConvertCommand():
import os
name, _ = os.path.splitext(filename)
gcode_name = name + ".gco"
# append number if file exists
name, ext = os.path.splitext(gcode_name)
i = 1;
@ -518,7 +516,7 @@ def gcodeConvertCommand():
del data["profile"]
else:
profile = None
##
if "printerProfile" in data.keys() and data["printerProfile"]:
printerProfile = data["printerProfile"]
del data["printerProfile"]
@ -530,7 +528,7 @@ def gcodeConvertCommand():
del data["position"]
else:
position = None
select_after_slicing = False
if "select" in data.keys() and data["select"] in valid_boolean_trues:
if not printer.is_operational():
@ -548,34 +546,41 @@ def gcodeConvertCommand():
for key in override_keys:
overrides[key[len("profile."):]] = data[key]
def slicing_done(target, gcode_name, select_after_slicing, print_after_slicing, append_these_files):
# append additioal gcodes
if data.has_key('gcodedata'):
output_path = fileManager.path_on_disk(target, gcode_name)
with open(output_path,'ab') as wfd:
for f in append_these_files:
path = fileManager.path_on_disk(f['origin'], f['name'])
wfd.write( "\n; "+ f['name'] + "\n")
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):
# append additioal gcodes
output_path = fileManager.path_on_disk(target, gcode_name)
with open(output_path,'ab') as wfd:
for f in append_these_files:
path = fileManager.path_on_disk(f['origin'], f['name'])
wfd.write( "\n; "+ f['name'] + "\n")
with open(path,'rb') as fd:
shutil.copyfileobj(fd, wfd, 1024*1024*10)
with open(path,'rb') as fd:
shutil.copyfileobj(fd, wfd, 1024*1024*10)
wfd.write( "\nM05\n") # ensure that the laser is off.
wfd.write( "\nM05\n") # ensure that the laser is off.
if select_after_slicing or print_after_slicing:
sd = False
filenameToSelect = fileManager.path_on_disk(target, gcode_name)
printer.select_file(filenameToSelect, sd, True)
if select_after_slicing or print_after_slicing:
sd = False
filenameToSelect = fileManager.path_on_disk(target, gcode_name)
printer.select_file(filenameToSelect, sd, True)
try:
fileManager.slice(slicer, target, filename, target, gcode_name,
profile=profile,
printer_profile_id=printerProfile,
position=position,
overrides=overrides,
callback=slicing_done,
callback_args=[target, gcode_name, select_after_slicing, print_after_slicing, appendGcodeFiles])
except octoprint.slicing.UnknownProfile:
return make_response("Profile {profile} doesn't exist".format(**locals()), 400)
try:
fileManager.slice(slicer, target, filename, target, gcode_name,
profile=profile,
printer_profile_id=printerProfile,
position=position,
overrides=overrides,
callback=slicing_done,
callback_args=[target, gcode_name, select_after_slicing, print_after_slicing, appendGcodeFiles])
except octoprint.slicing.UnknownProfile:
return make_response("Profile {profile} doesn't exist".format(**locals()), 400)
files = {}
location = url_for(".readGcodeFile", target=target, filename=gcode_name, _external=True)
@ -593,7 +598,7 @@ def gcodeConvertCommand():
return r
return NO_CONTENT
@api.route("/files/<string:target>/<path:filename>", methods=["DELETE"])
@restricted_access

View file

@ -23,9 +23,7 @@ def controlJob():
"start": [],
"restart": [],
"pause": [],
"cancel": [],
"incpasses": [],
"degpasses": []
"cancel": []
}
command, data, response = get_json_command_from_request(request, valid_commands)
@ -50,15 +48,6 @@ def controlJob():
if not activePrintjob:
return make_response("Printer is neither printing nor paused, 'cancel' command cannot be performed", 409)
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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

View file

@ -404,11 +404,6 @@ $(function() {
self.onStartup = function () {
self.requestData();
self._configureJogDistanceSlider();
$('#manual_position').keyup(function(e) {
if (e.which === 13){ // 13 == enter
self.manualPosition();
}
});
};
self.updateRotatorWidth = function() {
@ -611,24 +606,6 @@ $(function() {
self.setCoordinateOrigin = function () {
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);

View file

@ -38,7 +38,6 @@ $(function() {
self.feedrateOverride = ko.observable(100);
self.intensityOverride.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_UNPAUSED = gettext("Starts the print job");
@ -217,8 +216,7 @@ $(function() {
$("#confirmation_dialog .confirmation_dialog_acknowledge").click(
function (e) {
if (typeof callback === 'function') {
self.resetOverrideSlider();
self.numberOfPasses(1);
self.onEventPrintDone();
callback(e);
$("#confirmation_dialog").modal("hide");
$("#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.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([

View file

@ -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') }}">
@ -16,7 +16,7 @@
<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') }}">
<img alt="Mr Beam Logo" src="{{ url_for('static', filename='img/mr-typo-red_x120.png') }}">
</a>
</div>
<!-- Navbar -->
@ -58,7 +58,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;'>
@ -123,10 +123,6 @@
<div class="distance">
<input type="text" id="jogDistance" />
</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>
@ -160,7 +156,7 @@
-->
{{ _('Approx. Total Job Time') }}: <strong data-bind="text: estimatedPrintTimeString"></strong><br>
<div data-bind="visible: isPrinting() || isPaused()">
<div class="progress">
<div class="bar" id="job_progressBar" data-bind="style: { width: progressString() + '%' }">&nbsp;{{ _('Processed') }} : <strong data-bind="text: byteString"></strong></div>
</div>
@ -172,19 +168,6 @@
<input id="feedrate_override_slider" type="text" data-bind="sliderValue: feedrateOverride">
<span data-bind="text:feedrateOverride()">100</span>% Feedrate
</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>
<!-- {{ _('Print Time') }}: <strong data-bind="text: printTimeString"></strong><br>
@ -304,6 +287,9 @@
backgroundPosition: crosshairX()+'px'+' '+crosshairY()+'px',
width: workingAreaWidthPx()+'px',
height: workingAreaHeightPx()+'px'
},
attr: {
viewBox: '0 0 '+workingAreaWidthMM()+' '+workingAreaHeightMM()
}
">
<filter id="grayscale_filter">
@ -321,25 +307,23 @@
<text
xml:space="preserve"
data-bind="visible: working_area_empty"
style="font-size:64px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#DDDDDD;fill-opacity:1;stroke:none;font-family:DIN-BoldAlternate, Helvetica, Arial, Sans-serif;"
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"
y="552.36218"
id="add_designs_hint"
>
<tspan
id="tspan2987" x="368.571426" y="532.36218"
style="text-anchor:middle;text-align:center">add designs via </tspan>
id="tspan2987" x="60" y="60"
style="text-anchor:left;text-align:center">add designs via </tspan>
<tspan
x="500" y="592.36218" id="tspan2989"
style="text-anchor:middle;text-align:center">the design library </tspan>
x="70" y="75" id="tspan2989"
style="text-anchor:left;text-align:center">the design library </tspan>
<tspan
x="568.571426" y="652.36218" id="tspan2993"
style="text-anchor:middle;text-align:center">or drag 'n' drop </tspan>
<tspan
x="368.571426" y="712.36218" id="tspan2991"
style="text-anchor:middle;text-align:center" /></text>
<g id="placedGcodes" data-bind="visible: !state.isPrinting() && !state.isPaused(), attr: { transform: scaleMatrixMMtoDisplay() }"></g>
<g id="gCodePreview" data-bind="visible: state.isPrinting() || state.isPaused(), attr: { transform: scaleMatrixMMtoDisplay() }"></g>
x="80" y="90" id="tspan2993"
style="text-anchor:left;text-align:center">or drag 'n' drop </tspan>
</text>
<g id="placedGcodes" data-bind="visible: !state.isPrinting() && !state.isPaused()"></g>
<g id="gCodePreview" data-bind="visible: state.isPrinting() || state.isPaused()"></g>
<rect data-bind="click: move_laser"
id="coordGrid" x="0" y="0" width="0" height="0"
stroke="none" fill="none"></rect>
@ -533,7 +517,7 @@
<i class="icon-camera icon-white"></i>
<span>{{ _('Photo') }}</span>
</a>
</div>
<div id="gcode_upload_progress" class="progress" style="width: 100%;">
<div class="bar" style="width: 0%"></div>
@ -657,10 +641,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>&RightArrow; Now enable the pen calibration mode</li>
<li>5. Adjust the pen until it touches the paper</li>
<li>&RightArrow; 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>&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>
<div style="text-align:center">
<div class="btn-group" role="group" aria-label="focus mode control" style="">

View file

@ -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"

View file

@ -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
@ -405,7 +394,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 +409,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:
@ -618,7 +600,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 +737,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
@ -849,8 +827,6 @@ class MachineCom(object):
# 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.
@ -921,14 +897,6 @@ class MachineCom(object):
self._send_event.set()
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):
if self._state == self.STATE_NONE:
return "Offline"
@ -1169,9 +1137,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 +1159,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 +1184,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 +1248,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*") \