Compare commits
11 commits
stable-1.2
...
js2gcode
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb5ccf0c7a | ||
|
|
8820fe7cc7 | ||
|
|
114a7b8acd | ||
|
|
9099bdb303 | ||
|
|
5a62fc35c1 | ||
|
|
f63de0e630 | ||
|
|
22f474a029 | ||
|
|
7b88cddd3e | ||
|
|
ea591a954e | ||
|
|
fdbbf71cc7 | ||
|
|
753cb7845d |
24 changed files with 2213 additions and 2306 deletions
|
|
@ -1,6 +1,5 @@
|
||||||
OctoPrint
|
OctoPrint
|
||||||
=========
|
=========
|
||||||
What I did was take the MrBeam fork of Octoprint (because I have a MrBeam, and I like it) - and modify it for pen plotting with an axidraw v3 clone.
|
|
||||||
|
|
||||||
[](https://flattr.com/submit/auto?user_id=foosel&url=https://github.com/foosel/OctoPrint&title=OctoPrint&language=&tags=github&category=software)
|
[](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
|
|
@ -97,7 +97,7 @@ def update_source(git_executable, folder, target, force=False):
|
||||||
raise RuntimeError("Could not update, \"git reset --hard\" failed with returncode %d: %s" % (returncode, stdout))
|
raise RuntimeError("Could not update, \"git reset --hard\" failed with returncode %d: %s" % (returncode, stdout))
|
||||||
|
|
||||||
print(">>> Running: git pull")
|
print(">>> Running: git pull")
|
||||||
returncode, stdout = _git(["pull", "origin", "stable-1.2.2"], folder, git_executable=git_executable)
|
returncode, stdout = _git(["pull"], folder, git_executable=git_executable)
|
||||||
if returncode != 0:
|
if returncode != 0:
|
||||||
raise RuntimeError("Could not update, \"git pull\" failed with returncode %d: %s" % (returncode, stdout))
|
raise RuntimeError("Could not update, \"git pull\" failed with returncode %d: %s" % (returncode, stdout))
|
||||||
print(stdout)
|
print(stdout)
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ $(function() {
|
||||||
text += "<small>" + gettext("Those components marked with <i class=\"icon-ok\"></i> can be updated directly.") + "</small>";
|
text += "<small>" + gettext("Those components marked with <i class=\"icon-ok\"></i> can be updated directly.") + "</small>";
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
title: gettext("Mr Beam Update Available"),
|
title: gettext("Update Available"),
|
||||||
text: text,
|
text: text,
|
||||||
hide: false
|
hide: false
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ class SvgToGcodePlugin(octoprint.plugin.SlicerPlugin,
|
||||||
|
|
||||||
def get_assets(self):
|
def get_assets(self):
|
||||||
return dict(
|
return dict(
|
||||||
js=[ "js/convert.js", "js/working_area.js", "js/gcode_parser.js", "js/lib/snap.svg-min.js", "js/lib/photobooth_min.js", "js/matrix_oven.js", "js/render_fills.js", "js/drag_scale_rotate.js"],
|
js=[ "js/convert.js", "js/working_area.js", "js/gcode_parser.js", "js/lib/snap.svg-min.js", "js/lib/photobooth_min.js", "js/matrix_oven.js", "js/render_fills.js", "js/drag_scale_rotate.js", "js/svg2gcode.js"],
|
||||||
less=["less/svgtogcode.less"],
|
less=["less/svgtogcode.less"],
|
||||||
css=["css/svgtogcode.css", "css/mrbeam.css"]
|
css=["css/svgtogcode.css", "css/mrbeam.css"]
|
||||||
)
|
)
|
||||||
|
|
@ -270,7 +270,7 @@ class SvgToGcodePlugin(octoprint.plugin.SlicerPlugin,
|
||||||
feedrate = max(1,data["defaultFeedrate"])
|
feedrate = max(1,data["defaultFeedrate"])
|
||||||
s.set(["defaultFeedrate"], feedrate)
|
s.set(["defaultFeedrate"], feedrate)
|
||||||
if "svgDPI" in data and data["svgDPI"]:
|
if "svgDPI" in data and data["svgDPI"]:
|
||||||
s.set_int(["svgDPI"], data["svgDPI"])
|
s.set(["svgDPI"], data["svgDPI"])
|
||||||
if "debug_logging" in data:
|
if "debug_logging" in data:
|
||||||
old_debug_logging = s.get_boolean(["debug_logging"])
|
old_debug_logging = s.get_boolean(["debug_logging"])
|
||||||
new_debug_logging = data["debug_logging"] in octoprint.settings.valid_boolean_trues
|
new_debug_logging = data["debug_logging"] in octoprint.settings.valid_boolean_trues
|
||||||
|
|
@ -357,8 +357,6 @@ class SvgToGcodePlugin(octoprint.plugin.SlicerPlugin,
|
||||||
converter_path = '/home/teja/workspace/mrbeam-inkscape-ext'
|
converter_path = '/home/teja/workspace/mrbeam-inkscape-ext'
|
||||||
elif("denkbrett" in hostname):
|
elif("denkbrett" in hostname):
|
||||||
converter_path = '/home/flo/mrbeam/git/mrbeam-inkscape-ext'
|
converter_path = '/home/flo/mrbeam/git/mrbeam-inkscape-ext'
|
||||||
elif ("clems-Air" in hostname):
|
|
||||||
converter_path = '/Users/clem/Dropbox/mrBeam/mrbeam-inkscape-ext'
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
sys.path.append(converter_path)
|
sys.path.append(converter_path)
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ defaults = dict(
|
||||||
# general settings
|
# general settings
|
||||||
svgDPI = 90,
|
svgDPI = 90,
|
||||||
pierce_time = 0,
|
pierce_time = 0,
|
||||||
|
|
||||||
# vector settings
|
# vector settings
|
||||||
speed = 300,
|
speed = 300,
|
||||||
intensity = 500,
|
intensity = 500,
|
||||||
|
|
@ -24,7 +24,7 @@ defaults = dict(
|
||||||
cross_fill = False,
|
cross_fill = False,
|
||||||
fill_angle = 0,
|
fill_angle = 0,
|
||||||
fill_spacing = 0.25,
|
fill_spacing = 0.25,
|
||||||
|
|
||||||
# pixel settings
|
# pixel settings
|
||||||
beam_diameter = 0.25,
|
beam_diameter = 0.25,
|
||||||
intensity_white = 0,
|
intensity_white = 0,
|
||||||
|
|
@ -251,8 +251,8 @@ class Profile(object):
|
||||||
}
|
}
|
||||||
|
|
||||||
return settings
|
return settings
|
||||||
|
|
||||||
|
|
||||||
def convert_to_engine2(self):
|
def convert_to_engine2(self):
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
|
|
|
||||||
|
|
@ -1160,7 +1160,6 @@ ul.dropdown-menu li a {
|
||||||
#control_zaxis {
|
#control_zaxis {
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
width: 80px;
|
width: 80px;
|
||||||
margin: 1em auto 0;
|
|
||||||
}
|
}
|
||||||
#control_zaxis_focus {
|
#control_zaxis_focus {
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
|
|
@ -1542,7 +1541,7 @@ td.settings_printerProfiles_profiles_action a.disabled {
|
||||||
.nav-pills>li>a,
|
.nav-pills>li>a,
|
||||||
select,
|
select,
|
||||||
textarea,
|
textarea,
|
||||||
input, input[type="text"], input[type="password"], input[type="datetime"], input[type="datetime-local"], input[type="date"], input[type="month"], input[type="time"], input[type="week"], input[type="number"], input[type="email"], input[type="url"], input[type="search"], input[type="tel"], input[type="color"],
|
input,
|
||||||
input.search-query,
|
input.search-query,
|
||||||
.uneditable-input,
|
.uneditable-input,
|
||||||
.input-append .add-on:last-child,
|
.input-append .add-on:last-child,
|
||||||
|
|
|
||||||
|
|
@ -102,28 +102,3 @@ svg text {
|
||||||
.overrideSlider span {
|
.overrideSlider span {
|
||||||
padding-left: .6em;
|
padding-left: .6em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.repeatGcode .btn-group {
|
|
||||||
width: 145px;
|
|
||||||
}
|
|
||||||
.repeatGcode input, .repeatGcode button {
|
|
||||||
width: 33%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.repeatGcode input {
|
|
||||||
margin-bottom:0;
|
|
||||||
padding-left: 0;
|
|
||||||
padding-right: 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.repeatGcode>span {
|
|
||||||
padding-left: .6em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.manual_position_input {
|
|
||||||
padding-top: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#manual_position.warning {
|
|
||||||
color: #DD0000;
|
|
||||||
}
|
|
||||||
|
|
@ -22,7 +22,7 @@ $(function(){
|
||||||
self.profiles = ko.observableArray();
|
self.profiles = ko.observableArray();
|
||||||
self.defaultSlicer = undefined;
|
self.defaultSlicer = undefined;
|
||||||
self.defaultProfile = undefined;
|
self.defaultProfile = undefined;
|
||||||
|
|
||||||
// expert settings
|
// expert settings
|
||||||
self.showHints = ko.observable(false);
|
self.showHints = ko.observable(false);
|
||||||
self.showExpertSettings = ko.observable(false);
|
self.showExpertSettings = ko.observable(false);
|
||||||
|
|
@ -37,27 +37,25 @@ $(function(){
|
||||||
self.minSpeed = ko.observable(20);
|
self.minSpeed = ko.observable(20);
|
||||||
self.fill_areas = ko.observable(false);
|
self.fill_areas = ko.observable(false);
|
||||||
self.show_fill_areas_checkbox = ko.observable(false);
|
self.show_fill_areas_checkbox = ko.observable(false);
|
||||||
|
|
||||||
// image engraving stuff
|
// image engraving stuff
|
||||||
// preset values are a good start for wood engraving
|
// preset values are a good start for wood engraving
|
||||||
self.images_placed = ko.observable(false);
|
self.images_placed = ko.observable(false);
|
||||||
self.text_placed = ko.observable(false);
|
|
||||||
self.show_image_parameters = ko.computed(function(){
|
self.show_image_parameters = ko.computed(function(){
|
||||||
return (self.images_placed() || self.text_placed()
|
return self.images_placed() || (self.fill_areas() && self.show_vector_parameters());
|
||||||
|| (self.fill_areas() && self.show_vector_parameters()));
|
|
||||||
});
|
});
|
||||||
self.imgIntensityWhite = ko.observable(0);
|
self.imgIntensityWhite = ko.observable(0);
|
||||||
self.imgIntensityBlack = ko.observable(500);
|
self.imgIntensityBlack = ko.observable(500);
|
||||||
self.imgFeedrateWhite = ko.observable(1500);
|
self.imgFeedrateWhite = ko.observable(1500);
|
||||||
self.imgFeedrateBlack = ko.observable(250);
|
self.imgFeedrateBlack = ko.observable(250);
|
||||||
self.imgDithering = ko.observable(false);
|
self.imgDithering = ko.observable(false);
|
||||||
self.imgSharpening = ko.observable(1);
|
self.imgSharpening = ko.observable(1);
|
||||||
self.imgContrast = ko.observable(1);
|
self.imgContrast = ko.observable(1);
|
||||||
self.beamDiameter = ko.observable(0.2);
|
self.beamDiameter = ko.observable(0.2);
|
||||||
|
|
||||||
self.sharpeningMax = 25;
|
self.sharpeningMax = 25;
|
||||||
self.contrastMax = 2;
|
self.contrastMax = 2;
|
||||||
|
|
||||||
// preprocessing preview ... returns opacity 0.0 - 1.0
|
// preprocessing preview ... returns opacity 0.0 - 1.0
|
||||||
self.sharpenedPreview = ko.computed(function(){
|
self.sharpenedPreview = ko.computed(function(){
|
||||||
if(self.imgDithering()) return 0;
|
if(self.imgDithering()) return 0;
|
||||||
|
|
@ -75,7 +73,6 @@ $(function(){
|
||||||
return contrastPercents - sharpeningPercents/2;
|
return contrastPercents - sharpeningPercents/2;
|
||||||
}
|
}
|
||||||
}, self);
|
}, self);
|
||||||
|
|
||||||
|
|
||||||
self.maxSpeed.subscribe(function(val){
|
self.maxSpeed.subscribe(function(val){
|
||||||
self._configureFeedrateSlider();
|
self._configureFeedrateSlider();
|
||||||
|
|
@ -87,14 +84,13 @@ $(function(){
|
||||||
self.show_vector_parameters(self.workingArea.getPlacedSvgs().length > 0);
|
self.show_vector_parameters(self.workingArea.getPlacedSvgs().length > 0);
|
||||||
self.show_fill_areas_checkbox(self.workingArea.hasFilledVectors())
|
self.show_fill_areas_checkbox(self.workingArea.hasFilledVectors())
|
||||||
self.images_placed(self.workingArea.getPlacedImages().length > 0);
|
self.images_placed(self.workingArea.getPlacedImages().length > 0);
|
||||||
self.text_placed(self.workingArea.hasTextItems());
|
|
||||||
//self.show_image_parameters(self.workingArea.getPlacedImages().length > 0);
|
//self.show_image_parameters(self.workingArea.getPlacedImages().length > 0);
|
||||||
|
|
||||||
if(self.show_vector_parameters() || self.show_image_parameters()){
|
if(self.show_vector_parameters() || self.show_image_parameters()){
|
||||||
if(self.laserIntensity() === undefined){
|
if(self.laserIntensity() === undefined){
|
||||||
var intensity = self.settings.settings.plugins.svgtogcode.defaultIntensity();
|
var intensity = self.settings.settings.plugins.svgtogcode.defaultIntensity();
|
||||||
self.laserIntensity(intensity);
|
self.laserIntensity(intensity);
|
||||||
}
|
}
|
||||||
if(self.laserSpeed() === undefined){
|
if(self.laserSpeed() === undefined){
|
||||||
var speed = self.settings.settings.plugins.svgtogcode.defaultFeedrate();
|
var speed = self.settings.settings.plugins.svgtogcode.defaultFeedrate();
|
||||||
self.laserSpeed(speed);
|
self.laserSpeed(speed);
|
||||||
|
|
@ -110,7 +106,7 @@ $(function(){
|
||||||
self.convert();
|
self.convert();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.cancel_conversion = function(){
|
self.cancel_conversion = function(){
|
||||||
if(self.slicing_in_progress()){
|
if(self.slicing_in_progress()){
|
||||||
//console.log('cancel slicing', self.slicing_in_progress());
|
//console.log('cancel slicing', self.slicing_in_progress());
|
||||||
|
|
@ -142,14 +138,14 @@ $(function(){
|
||||||
if(uniqueDesigns > 1){
|
if(uniqueDesigns > 1){
|
||||||
gcode_name += "_"+(uniqueDesigns-1)+"more";
|
gcode_name += "_"+(uniqueDesigns-1)+"more";
|
||||||
}
|
}
|
||||||
|
|
||||||
return gcode_name;
|
return gcode_name;
|
||||||
} else {
|
} else {
|
||||||
console.error("no designs placed.");
|
console.error("no designs placed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.settingsString = ko.computed(function(){
|
self.settingsString = ko.computed(function(){
|
||||||
var intensity = self.laserIntensity();
|
var intensity = self.laserIntensity();
|
||||||
var feedrate = self.laserSpeed();
|
var feedrate = self.laserSpeed();
|
||||||
|
|
@ -251,7 +247,7 @@ $(function(){
|
||||||
} else {
|
} else {
|
||||||
self.slicing_in_progress(true);
|
self.slicing_in_progress(true);
|
||||||
self.workingArea.getCompositionSVG(self.fill_areas(), function(composition){
|
self.workingArea.getCompositionSVG(self.fill_areas(), function(composition){
|
||||||
self.svg = composition;
|
self.svg = composition;
|
||||||
var filename = self.gcodeFilename() + self.settingsString() + '.gco';
|
var filename = self.gcodeFilename() + self.settingsString() + '.gco';
|
||||||
var gcodeFilename = self._sanitize(filename);
|
var gcodeFilename = self._sanitize(filename);
|
||||||
|
|
||||||
|
|
@ -282,6 +278,10 @@ $(function(){
|
||||||
data.gcodeFilesToAppend = self.gcodeFilesToAppend;
|
data.gcodeFilesToAppend = self.gcodeFilesToAppend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var snapelement = snap.select("#userContent");
|
||||||
|
snapelement.bake(false, 5);
|
||||||
|
data.gcodedata = snapelement.toGcode(self.laserSpeed(), self.laserIntensity(), self.pierceTime());
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: API_BASEURL + "files/convert",
|
url: API_BASEURL + "files/convert",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
|
|
@ -289,7 +289,6 @@ $(function(){
|
||||||
contentType: "application/json; charset=UTF-8",
|
contentType: "application/json; charset=UTF-8",
|
||||||
data: JSON.stringify(data)
|
data: JSON.stringify(data)
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -306,7 +305,7 @@ $(function(){
|
||||||
self._configureFeedrateSlider();
|
self._configureFeedrateSlider();
|
||||||
self._configureImgSliders();
|
self._configureImgSliders();
|
||||||
};
|
};
|
||||||
|
|
||||||
self.onSlicingProgress = function(slicer, model_path, machinecode_path, progress){
|
self.onSlicingProgress = function(slicer, model_path, machinecode_path, progress){
|
||||||
self.slicing_progress(progress);
|
self.slicing_progress(progress);
|
||||||
};
|
};
|
||||||
|
|
@ -392,7 +391,7 @@ $(function(){
|
||||||
self._calcRealSpeed = function(sliderVal){
|
self._calcRealSpeed = function(sliderVal){
|
||||||
return Math.round(self.minSpeed() + sliderVal/100 * (self.maxSpeed() - self.minSpeed()));
|
return Math.round(self.minSpeed() + sliderVal/100 * (self.maxSpeed() - self.minSpeed()));
|
||||||
};
|
};
|
||||||
|
|
||||||
self._configureImgSliders = function() {
|
self._configureImgSliders = function() {
|
||||||
self.contrastSlider = $("#svgtogcode_contrast_slider").slider({
|
self.contrastSlider = $("#svgtogcode_contrast_slider").slider({
|
||||||
step: .1,
|
step: .1,
|
||||||
|
|
@ -403,7 +402,7 @@ $(function(){
|
||||||
}).on("slide", function(ev){
|
}).on("slide", function(ev){
|
||||||
self.imgContrast(ev.value);
|
self.imgContrast(ev.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.sharpeningSlider = $("#svgtogcode_sharpening_slider").slider({
|
self.sharpeningSlider = $("#svgtogcode_sharpening_slider").slider({
|
||||||
step: 1,
|
step: 1,
|
||||||
min: 1,
|
min: 1,
|
||||||
|
|
@ -422,9 +421,9 @@ $(function(){
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ADDITIONAL_VIEWMODELS.push([VectorConversionViewModel,
|
ADDITIONAL_VIEWMODELS.push([VectorConversionViewModel,
|
||||||
["loginStateViewModel", "settingsViewModel", "printerStateViewModel", "workingAreaViewModel", "gcodeFilesViewModel"],
|
["loginStateViewModel", "settingsViewModel", "printerStateViewModel", "workingAreaViewModel", "gcodeFilesViewModel"],
|
||||||
document.getElementById("dialog_vector_graphics_conversion")]);
|
document.getElementById("dialog_vector_graphics_conversion")]);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
// Drag, Scale & Rotate - a snapsvg.io plugin to free transform objects in an svg.
|
// Drag, Scale & Rotate - a snapsvg.io plugin to free transform objects in an svg.
|
||||||
// Copyright (C) 2015 Teja Philipp <osd@tejaphilipp.de>
|
// Copyright (C) 2015 Teja Philipp <osd@tejaphilipp.de>
|
||||||
//
|
//
|
||||||
// heavily inspired by http://svg.dabbles.info
|
// heavily inspired by http://svg.dabbles.info
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
// it under the terms of the GNU Affero General Public License as
|
// it under the terms of the GNU Affero General Public License as
|
||||||
// published by the Free Software Foundation, either version 3 of the
|
// published by the Free Software Foundation, either version 3 of the
|
||||||
|
|
@ -19,10 +19,10 @@
|
||||||
|
|
||||||
|
|
||||||
Snap.plugin(function (Snap, Element, Paper, global) {
|
Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @returns {undefined}
|
* @returns {undefined}
|
||||||
*/
|
*/
|
||||||
Element.prototype.transformable = function () {
|
Element.prototype.transformable = function () {
|
||||||
|
|
@ -35,13 +35,13 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
elem.click(function(){ elem.ftCreateHandles() });
|
elem.click(function(){ elem.ftCreateHandles() });
|
||||||
return elem;
|
return elem;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds transparent fill if not present.
|
* Adds transparent fill if not present.
|
||||||
* This is useful for dragging the element around.
|
* This is useful for dragging the element around.
|
||||||
*
|
*
|
||||||
* @returns {path}
|
* @returns {path}
|
||||||
*/
|
*/
|
||||||
Element.prototype.add_fill = function(){
|
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
|
* Free transform plugin heavily inspired by http://svg.dabbles.info
|
||||||
*/
|
*/
|
||||||
|
|
@ -79,13 +79,13 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
handleFill: "red",
|
handleFill: "red",
|
||||||
handleStrokeDashPreset: [5,5],
|
handleStrokeDashPreset: [5,5],
|
||||||
handleStrokeWidth: 2,
|
handleStrokeWidth: 2,
|
||||||
handleLength: 18,
|
handleLength: 10,
|
||||||
handleRadius: 16,
|
handleRadius: 16,
|
||||||
unscale: 1,
|
unscale: 1,
|
||||||
handleStrokeDash: "5,5",
|
handleStrokeDash: "5,5",
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.ftToggleHandles = function(){
|
Element.prototype.ftToggleHandles = function(){
|
||||||
if(this.data('handlesGroup')){
|
if(this.data('handlesGroup')){
|
||||||
this.ftRemoveHandles();
|
this.ftRemoveHandles();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -97,10 +97,10 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
this.ftInit();
|
this.ftInit();
|
||||||
var freetransEl = this;
|
var freetransEl = this;
|
||||||
var bb = freetransEl.getBBox();
|
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 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 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 joinLine = freetransEl.ftDrawJoinLine( rotateDragger, ftOption.handleStrokeWidth * ftOption.unscale);
|
||||||
var handlesGroup = this.paper.select('#userContent').g( joinLine, rotateDragger, translateDragger );
|
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') ) );
|
freetransEl.data( "scaleFactor", calcDistance( bb.cx, bb.cy, rotateDragger.attr('cx'), rotateDragger.attr('cy') ) );
|
||||||
|
|
||||||
translateDragger.drag(
|
translateDragger.drag(
|
||||||
elementDragMove.bind( translateDragger, freetransEl ),
|
elementDragMove.bind( translateDragger, freetransEl ),
|
||||||
elementDragStart.bind( translateDragger, freetransEl ),
|
elementDragStart.bind( translateDragger, freetransEl ),
|
||||||
elementDragEnd.bind( translateDragger, freetransEl )
|
elementDragEnd.bind( translateDragger, freetransEl )
|
||||||
);
|
);
|
||||||
|
|
||||||
freetransEl.unclick();
|
freetransEl.unclick();
|
||||||
freetransEl.data("click", freetransEl.click( function() { this.ftRemoveHandles() } ) );
|
freetransEl.data("click", freetransEl.click( function() { this.ftRemoveHandles() } ) );
|
||||||
|
|
||||||
rotateDragger.drag(
|
rotateDragger.drag(
|
||||||
dragHandleRotateMove.bind( rotateDragger, freetransEl ),
|
dragHandleRotateMove.bind( rotateDragger, freetransEl ),
|
||||||
dragHandleRotateStart.bind( rotateDragger, freetransEl ),
|
dragHandleRotateStart.bind( rotateDragger, freetransEl ),
|
||||||
dragHandleRotateEnd.bind( rotateDragger, freetransEl )
|
dragHandleRotateEnd.bind( rotateDragger, freetransEl )
|
||||||
);
|
);
|
||||||
freetransEl.ftStoreInitialTransformMatrix();
|
freetransEl.ftStoreInitialTransformMatrix();
|
||||||
freetransEl.ftHighlightBB();
|
freetransEl.ftHighlightBB();
|
||||||
|
|
@ -134,8 +134,8 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
this.data("tx", 0);
|
this.data("tx", 0);
|
||||||
this.data("ty", 0);
|
this.data("ty", 0);
|
||||||
this.attr({class:'_freeTransformInProgress'});
|
this.attr({class:'_freeTransformInProgress'});
|
||||||
|
|
||||||
ftOption.unscale = 1 / this.paper.select('#scaleGroup').transform().localMatrix.a;
|
ftOption.unscale = 1 / this.paper.select('#scaleGroup').transform().globalMatrix.a;
|
||||||
this.data('unscale', ftOption.unscale);
|
this.data('unscale', ftOption.unscale);
|
||||||
ftOption.handleStrokeDash = ftOption.handleStrokeDashPreset.map(function(v){ return v*ftOption.unscale; }).join(',');
|
ftOption.handleStrokeDash = ftOption.handleStrokeDashPreset.map(function(v){ return v*ftOption.unscale; }).join(',');
|
||||||
return this;
|
return this;
|
||||||
|
|
@ -153,11 +153,11 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
this.data('ocy', this.attr('cy') );
|
this.data('ocy', this.attr('cy') );
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Element.prototype.ftStoreInitialTransformMatrix = function() {
|
Element.prototype.ftStoreInitialTransformMatrix = function() {
|
||||||
this.data('initialTransformMatrix', this.transform().localMatrix );
|
this.data('initialTransformMatrix', this.transform().localMatrix );
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.ftGetInitialTransformMatrix = function() {
|
Element.prototype.ftGetInitialTransformMatrix = function() {
|
||||||
return this.data('initialTransformMatrix');
|
return this.data('initialTransformMatrix');
|
||||||
|
|
@ -191,10 +191,10 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.ftUpdateTransform = function() {
|
Element.prototype.ftUpdateTransform = function() {
|
||||||
//console.log("translate: ", this.data('tx'), this.data('ty'), 'rotate: ', this.data('angle'), 'scale: ', this.data('scale'));
|
//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.attr({ transform: tstring });
|
||||||
this.data("bbT") && this.ftHighlightBB(this.paper.select('#userContent'));
|
this.data("bbT") && this.ftHighlightBB(this.paper.select('#userContent'));
|
||||||
this.ftReportTransformation();
|
this.ftReportTransformation();
|
||||||
|
|
@ -204,17 +204,17 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
Element.prototype.ftHighlightBB = function() {
|
Element.prototype.ftHighlightBB = function() {
|
||||||
this.data("bbT") && this.data("bbT").remove();
|
this.data("bbT") && this.data("bbT").remove();
|
||||||
this.data("bb") && this.data("bb").remove();
|
this.data("bb") && this.data("bb").remove();
|
||||||
|
|
||||||
// transformed bbox
|
// transformed bbox
|
||||||
this.data("bbT", this.paper.rect( rectObjFromBB( this.getBBox(1) ) )
|
this.data("bbT", this.paper.rect( rectObjFromBB( this.getBBox(1) ) )
|
||||||
.attr({ fill: "none", stroke: ftOption.handleFill, strokeWidth: ftOption.handleStrokeWidth, strokeDasharray: ftOption.handleStrokeDashPreset.join(',') })
|
.attr({ fill: "none", stroke: ftOption.handleFill, strokeWidth: ftOption.handleStrokeWidth, strokeDasharray: ftOption.handleStrokeDashPreset.join(',') })
|
||||||
.transform( this.transform().global.toString() ) );
|
.transform( this.transform().local.toString() ) );
|
||||||
// outer bbox
|
// outer bbox
|
||||||
this.data("bb", this.paper.select('#userContent').rect( rectObjFromBB( this.getBBox() ) )
|
this.data("bb", this.paper.select('#userContent').rect( rectObjFromBB( this.getBBox() ) )
|
||||||
.attr({ fill: "none", stroke: 'gray', strokeWidth: ftOption.handleStrokeWidth, strokeDasharray: ftOption.handleStrokeDash }) );
|
.attr({ fill: "none", stroke: 'gray', strokeWidth: 0.6, strokeDasharray: [2,2] }) );
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.ftReportTransformation = function(){
|
Element.prototype.ftReportTransformation = function(){
|
||||||
if(this.data('ftCallbacks') && this.data('ftCallbacks').length > 0){
|
if(this.data('ftCallbacks') && this.data('ftCallbacks').length > 0){
|
||||||
for (var idx = 0; idx < this.data('ftCallbacks').length; idx++) {
|
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);
|
this.data('ftCallbacks').push(callback);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.ftDisableRotate = function(){
|
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 dragHandle = this;
|
||||||
var unscale = mainEl.data('unscale');
|
var unscale = mainEl.data('unscale');
|
||||||
var bb = mainEl.data('obb');
|
var bb = mainEl.data('obb');
|
||||||
|
|
||||||
var udx = dx*unscale;
|
var udx = dx*unscale;
|
||||||
var udy = dy*unscale;
|
var udy = dy*unscale;
|
||||||
|
|
||||||
|
|
@ -287,22 +287,22 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
|
|
||||||
function dragHandleRotateEnd( mainElement ) {
|
function dragHandleRotateEnd( mainElement ) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function dragHandleRotateMove( mainEl, dx, dy, x, y, event ) {
|
function dragHandleRotateMove( mainEl, dx, dy, x, y, event ) {
|
||||||
var handle = this;
|
var handle = this;
|
||||||
var mainBB = mainEl.getBBox();
|
var mainBB = mainEl.getBBox();
|
||||||
var unscale = mainEl.data('unscale');
|
var unscale = mainEl.data('unscale');
|
||||||
handle.attr({ cx: +handle.data('ocx') + dx*unscale, cy: +handle.data('ocy') + dy*unscale });
|
handle.attr({ cx: +handle.data('ocx') + dx*unscale, cy: +handle.data('ocy') + dy*unscale });
|
||||||
|
|
||||||
if(!mainEl.data('block_rotation')){
|
if(!mainEl.data('block_rotation')){
|
||||||
var angle = Snap.angle( mainBB.cx, mainBB.cy, handle.attr('cx'), handle.attr('cy') ) - 180;
|
var angle = Snap.angle( mainBB.cx, mainBB.cy, handle.attr('cx'), handle.attr('cy') ) - 180;
|
||||||
if(event.shiftKey){
|
if(event.shiftKey){
|
||||||
angle = Math.round(angle/30) * 30;
|
angle = Math.round(angle/15) * 15;
|
||||||
}
|
}
|
||||||
mainEl.data("angle", angle );
|
mainEl.data("angle", angle );
|
||||||
}
|
}
|
||||||
|
|
||||||
var distance = calcDistance( mainBB.cx, mainBB.cy, handle.attr('cx'), handle.attr('cy') );
|
var distance = calcDistance( mainBB.cx, mainBB.cy, handle.attr('cx'), handle.attr('cy') );
|
||||||
var scale = distance / mainEl.data("scaleFactor");
|
var scale = distance / mainEl.data("scaleFactor");
|
||||||
if(event.shiftKey){
|
if(event.shiftKey){
|
||||||
|
|
@ -311,7 +311,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
mainEl.data("scale", scale );
|
mainEl.data("scale", scale );
|
||||||
|
|
||||||
mainEl.ftUpdateTransform();
|
mainEl.ftUpdateTransform();
|
||||||
mainEl.ftDrawJoinLine( handle );
|
mainEl.ftDrawJoinLine( handle );
|
||||||
};
|
};
|
||||||
|
|
||||||
function calcDistance(x1,y1,x2,y2) {
|
function calcDistance(x1,y1,x2,y2) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// Matrix Oven - a snapsvg.io plugin to apply & remove transformations from svg files.
|
// Matrix Oven - a snapsvg.io plugin to apply & remove transformations from svg files.
|
||||||
// Copyright (C) 2015 Teja Philipp <osd@tejaphilipp.de>
|
// 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
|
// 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
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
|
@ -20,25 +20,24 @@
|
||||||
|
|
||||||
|
|
||||||
Snap.plugin(function (Snap, Element, Paper, global) {
|
Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bakes transformations of the element and all sub-elements into coordinates
|
* bakes transformations of the element and all sub-elements into coordinates
|
||||||
*
|
*
|
||||||
* @param {boolean} toCubics : use only cubic path segments
|
* @param {boolean} toCubics : use only cubic path segments
|
||||||
* @param {integer} dec : number of digits after decimal separator. defaults to 5
|
* @param {integer} dec : number of digits after decimal separator. defaults to 5
|
||||||
* @returns {undefined}
|
* @returns {undefined}
|
||||||
*/
|
*/
|
||||||
Element.prototype.bake = function (toCubics, dec) {
|
Element.prototype.bake = function (toCubics, dec) {
|
||||||
var elem = this;
|
var elem = this;
|
||||||
|
if (!elem || !elem.paper) // don't handle unplaced elements. this causes double handling.
|
||||||
if (!elem || !elem.paper || elem.type !== "text" || elem.type !== "#text" || elem.type !== "tspan"){
|
|
||||||
return;
|
return;
|
||||||
} // don't handle unplaced elements. this causes double handling.
|
|
||||||
|
|
||||||
if (typeof (toCubics) === 'undefined')
|
if (typeof (toCubics) === 'undefined')
|
||||||
toCubics = false;
|
toCubics = false;
|
||||||
if (typeof (dec) === 'undefined')
|
if (typeof (dec) === 'undefined')
|
||||||
dec = 5;
|
dec = 5;
|
||||||
|
//var children = elem.selectAll('*')
|
||||||
var children = elem.children();
|
var children = elem.children();
|
||||||
if (children.length > 0) {
|
if (children.length > 0) {
|
||||||
for (var i = 0; i < children.length; i++) {
|
for (var i = 0; i < children.length; i++) {
|
||||||
|
|
@ -55,16 +54,15 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
elem.type !== "polygon" &&
|
elem.type !== "polygon" &&
|
||||||
elem.type !== "polyline" &&
|
elem.type !== "polyline" &&
|
||||||
elem.type !== "image" &&
|
elem.type !== "image" &&
|
||||||
elem.type !== "path" &&
|
elem.type !== "path"){
|
||||||
elem.type !== "text" &&
|
|
||||||
elem.type !== "tspan" &&
|
// if(elem.type !== 'g' && elem.type !== 'desc' && elem.type !== 'defs')
|
||||||
elem.type !== "#text"){
|
// console.log('skipping unsupported element ', elem.type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (elem.type == 'image' || elem.type == "text" || elem.type == "#text"){
|
if (elem.type == 'image'){
|
||||||
// TODO ...
|
// TODO ...
|
||||||
var x = parseFloat(elem.attr('x')),
|
var x = parseFloat(elem.attr('x')),
|
||||||
y = parseFloat(elem.attr('y')),
|
y = parseFloat(elem.attr('y')),
|
||||||
w = parseFloat(elem.attr('width')),
|
w = parseFloat(elem.attr('width')),
|
||||||
|
|
@ -86,11 +84,12 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
var transformedY = matrix.y(x, y);
|
var transformedY = matrix.y(x, y);
|
||||||
var transformedW = matrix.x(x+w, y+h) - transformedX;
|
var transformedW = matrix.x(x+w, y+h) - transformedX;
|
||||||
var transformedH = matrix.y(x+w, y+h) - transformedY;
|
var transformedH = matrix.y(x+w, y+h) - transformedY;
|
||||||
|
|
||||||
elem.attr({x: transformedX, y: transformedY, width: transformedW, height: transformedH});
|
elem.attr({x: transformedX, y: transformedY, width: transformedW, height: transformedH});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if(elem.type !== 'path') console.log("bake: converting " + elem.type + " to path");
|
||||||
var path_elem = elem.convertToPath();
|
var path_elem = elem.convertToPath();
|
||||||
|
|
||||||
if (!path_elem || path_elem.attr('d') === '' || path_elem.attr('d') === null)
|
if (!path_elem || path_elem.attr('d') === '' || path_elem.attr('d') === null)
|
||||||
|
|
@ -102,7 +101,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
} else {
|
} else {
|
||||||
dec = false;
|
dec = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function r(num) {
|
function r(num) {
|
||||||
if (dec !== false) {
|
if (dec !== false) {
|
||||||
return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
|
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');
|
var d = path_elem.attr('d');
|
||||||
d = (d || "").trim();
|
d = (d || "").trim();
|
||||||
var arr_orig;
|
var arr_orig;
|
||||||
arr = Snap.parsePathString(d);
|
arr = Snap.parsePathString(d);
|
||||||
if (!toCubics) {
|
if (!toCubics) {
|
||||||
arr_orig = arr;
|
arr_orig = arr;
|
||||||
arr = Snap.path.toAbsolute(arr);
|
arr = Snap.path.toAbsolute(arr);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -129,7 +128,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
var matrix = transform['totalMatrix'];
|
var matrix = transform['totalMatrix'];
|
||||||
|
|
||||||
// apply the matrix transformation on the path segments
|
// apply the matrix transformation on the path segments
|
||||||
var j;
|
var j;
|
||||||
var m = arr.length;
|
var m = arr.length;
|
||||||
var letter = '';
|
var letter = '';
|
||||||
var letter_orig = '';
|
var letter_orig = '';
|
||||||
|
|
@ -137,8 +136,8 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
var y = 0;
|
var y = 0;
|
||||||
var new_segments = [];
|
var new_segments = [];
|
||||||
var pt = {x: 0, y: 0};
|
var pt = {x: 0, y: 0};
|
||||||
var pt_baked = {};
|
var pt_baked = {};
|
||||||
var subpath_start = {};
|
var subpath_start = {};
|
||||||
var prevX = 0;
|
var prevX = 0;
|
||||||
var prevY = 0;
|
var prevY = 0;
|
||||||
subpath_start.x = null;
|
subpath_start.x = null;
|
||||||
|
|
@ -156,7 +155,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
pt.x = arr[i][6];
|
pt.x = arr[i][6];
|
||||||
pt.y = arr[i][7];
|
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);
|
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') {
|
} else if (letter !== 'Z') {
|
||||||
// parse other segs than Z and A
|
// parse other segs than Z and A
|
||||||
for (j = 1; j < arr[i].length; j = j + 2) {
|
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;
|
y = subpath_start.y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert all that was relative back to relative
|
// Convert all that was relative back to relative
|
||||||
// This could be combined to above, but to make code more readable
|
// This could be combined to above, but to make code more readable
|
||||||
// this is made separately.
|
// 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'));
|
//console.log("baked matrix ", matrix, " of ", path_elem.attr('id'));
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to apply matrix transformations to arcs.
|
* Helper to apply matrix transformations to arcs.
|
||||||
* From flatten.js (https://gist.github.com/timo22345/9413158), modified a bit.
|
* 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_rh : r1 of the ellipsis in degree
|
||||||
* @param {type} a_rv : r2 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} 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 {int} sweep_flag : 0 or 1
|
||||||
* @param {object} endpoint with properties x and y
|
* @param {object} endpoint with properties x and y
|
||||||
* @param {type} matrix : transformation matrix
|
* @param {type} matrix : transformation matrix
|
||||||
|
|
@ -312,12 +311,12 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
|
|
||||||
// convert implicit equation to angle and halfaxis:
|
// convert implicit equation to angle and halfaxis:
|
||||||
// disabled intentionally
|
// disabled intentionally
|
||||||
if (false && NEARZERO(B)) { // there is a bug in this optimization: does not work for path below
|
if (false && NEARZERO(B)) { // there is a bug in this optimization: does not work for path below
|
||||||
a_offsetrot = 0;
|
a_offsetrot = 0;
|
||||||
// d="M0,350 l 50,-25
|
// d="M0,350 l 50,-25
|
||||||
// a25,25 -30 0,1 50,-25 l 50,-25
|
// a25,25 -30 0,1 50,-25 l 50,-25
|
||||||
// a25,50 -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,75 -30 0,1 50,-25 l 50,-25
|
||||||
// a25,100 -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)"
|
// with matrix transform="scale(0.5,2.0)"
|
||||||
A2 = A;
|
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)
|
// Clamp (precision issues might need this.. not likely, but better save than sorry)
|
||||||
K = (K < 0) ? 0 : Math.sqrt(K);
|
K = (K < 0) ? 0 : Math.sqrt(K);
|
||||||
|
|
||||||
A2 = 0.5 * (A + C + K * ac);
|
A2 = 0.5 * (A + C + K * ac);
|
||||||
C2 = 0.5 * (A + C - K * ac);
|
C2 = 0.5 * (A + C - K * ac);
|
||||||
a_offsetrot = 0.5 * Math.atan2(B, ac);
|
a_offsetrot = 0.5 * Math.atan2(B, ac);
|
||||||
|
|
@ -354,7 +353,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
a_rh = A2;
|
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.
|
// winding order of the ellise needs to be changed.
|
||||||
if ((matrix.a * matrix.d) - (matrix.b * matrix.c) < 0){
|
if ((matrix.a * matrix.d) - (matrix.b * matrix.c) < 0){
|
||||||
sweep_flag = !sweep_flag ? 1 : 0;
|
sweep_flag = !sweep_flag ? 1 : 0;
|
||||||
|
|
@ -377,30 +376,30 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
var _convertToString = function (arr) {
|
var _convertToString = function (arr) {
|
||||||
return arr.join(',').replace(_p2s, '$1');
|
return arr.join(',').replace(_p2s, '$1');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replaces an element with a path of same shape.
|
* Replaces an element with a path of same shape.
|
||||||
* Supports rect, ellipse, circle, line, polyline, polygon and of course path
|
* 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}
|
* @returns {path}
|
||||||
*/
|
*/
|
||||||
Element.prototype.convertToPath = function(){
|
Element.prototype.convertToPath = function(){
|
||||||
var old_element = this;
|
var old_element = this;
|
||||||
var path = old_element.toPath();
|
var path = old_element.toPath();
|
||||||
old_element.before(path);
|
old_element.before(path);
|
||||||
old_element.remove();
|
old_element.remove();
|
||||||
return path;
|
return path;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a path in the same shape as the origin element
|
* Creates a path in the same shape as the origin element
|
||||||
* Supports rect, ellipse, circle, line, polyline, polygon and of course path
|
* 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
|
* https://github.com/duopixel/Method-Draw/blob/master/editor/src/svgcanvas.js
|
||||||
* Modifications: Timo (https://github.com/timo22345)
|
* Modifications: Timo (https://github.com/timo22345)
|
||||||
*
|
*
|
||||||
* @returns {path} path element
|
* @returns {path} path element
|
||||||
*/
|
*/
|
||||||
Element.prototype.toPath = function () {
|
Element.prototype.toPath = function () {
|
||||||
|
|
@ -431,7 +430,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
var validRadius = function (val) {
|
var validRadius = function (val) {
|
||||||
return (isFinite(val) && (val >= 0));
|
return (isFinite(val) && (val >= 0));
|
||||||
};
|
};
|
||||||
|
|
||||||
var validCoordinate = function (val) {
|
var validCoordinate = function (val) {
|
||||||
return (isFinite(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
|
// Possibly the cubed root of 6, but 1.81 works best
|
||||||
var num = 1.81;
|
var num = 1.81;
|
||||||
var tag = old_element.type;
|
var tag = old_element.type;
|
||||||
|
|
||||||
var convertMMtoPixel = function (val) {
|
|
||||||
attrList = ['rx','ry','r','cx','cy','x1','x2','y1','y2','x','y','width','height'];
|
|
||||||
for(var attrIdx in attrList) {
|
|
||||||
if(val.attr(attrList[attrIdx]) != null && val.attr(attrList[attrIdx]).indexOf('mm') > -1) {
|
|
||||||
var tmp = parseFloat(val.attr(attrList[attrIdx])) * 3.5433;
|
|
||||||
val.attr(attrList[attrIdx], tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
convertMMtoPixel(old_element);
|
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case 'ellipse':
|
case 'ellipse':
|
||||||
case 'circle':
|
case 'circle':
|
||||||
|
|
@ -462,13 +448,13 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
if (tag === 'circle') {
|
if (tag === 'circle') {
|
||||||
rx = ry = +old_element.attr('r');
|
rx = ry = +old_element.attr('r');
|
||||||
}
|
}
|
||||||
|
|
||||||
// If 'x' and 'y' are not specified, then set both to 0. // CorelDraw is creating that sometimes
|
// If 'x' and 'y' are not specified, then set both to 0. // CorelDraw is creating that sometimes
|
||||||
if (!validCoordinate(cx))
|
if (!validCoordinate(cx))
|
||||||
cx = 0;
|
cx = 0;
|
||||||
if (!validCoordinate(cy))
|
if (!validCoordinate(cy))
|
||||||
cy = 0;
|
cy = 0;
|
||||||
|
|
||||||
d += _convertToString([
|
d += _convertToString([
|
||||||
['M', (cx - rx), (cy)],
|
['M', (cx - rx), (cy)],
|
||||||
['C', (cx - rx), (cy - ry / num), (cx - rx / num), (cy - ry), (cx), (cy - ry)],
|
['C', (cx - rx), (cy - ry / num), (cx - rx / num), (cy - ry), (cx), (cy - ry)],
|
||||||
|
|
@ -495,7 +481,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
d = 'M' + old_element.attr('points') + 'Z';
|
d = 'M' + old_element.attr('points') + 'Z';
|
||||||
break;
|
break;
|
||||||
case 'rect':
|
case 'rect':
|
||||||
// TODO ...
|
// TODO ...
|
||||||
var rx = parseFloat(old_element.attr('rx')),
|
var rx = parseFloat(old_element.attr('rx')),
|
||||||
ry = parseFloat(old_element.attr('ry')),
|
ry = parseFloat(old_element.attr('ry')),
|
||||||
x = parseFloat(old_element.attr('x')),
|
x = parseFloat(old_element.attr('x')),
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// render_fills.js - a snapsvg.io plugin to render the infill of svg files into a bitmap.
|
// 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>
|
// 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
|
// and http://getcontext.net/read/svg-images-on-a-html5-canvas
|
||||||
//
|
//
|
||||||
// This program is free software: you can redistribute it and/or modify
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
|
@ -20,12 +20,12 @@
|
||||||
|
|
||||||
|
|
||||||
Snap.plugin(function (Snap, Element, Paper, global) {
|
Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {elem} elem start point
|
* @param {elem} elem start point
|
||||||
*
|
*
|
||||||
* @returns {path}
|
* @returns {path}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
var selection = [];
|
var selection = [];
|
||||||
var children = elem.children();
|
var children = elem.children();
|
||||||
|
|
||||||
|
|
||||||
if (children.length > 0) {
|
if (children.length > 0) {
|
||||||
var goRecursive = (elem.type !== "defs" && // ignore these tags
|
var goRecursive = (elem.type !== "defs" && // ignore these tags
|
||||||
elem.type !== "clipPath" &&
|
elem.type !== "clipPath" &&
|
||||||
|
|
@ -42,7 +42,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
elem.type !== "rdf:rdf" &&
|
elem.type !== "rdf:rdf" &&
|
||||||
elem.type !== "cc:work" &&
|
elem.type !== "cc:work" &&
|
||||||
elem.type !== "sodipodi:namedview");
|
elem.type !== "sodipodi:namedview");
|
||||||
|
|
||||||
if(goRecursive) {
|
if(goRecursive) {
|
||||||
for (var i = 0; i < children.length; i++) {
|
for (var i = 0; i < children.length; i++) {
|
||||||
var child = children[i];
|
var child = children[i];
|
||||||
|
|
@ -50,7 +50,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(elem.type === 'image' || elem.type === "text" || elem.type === "#text"){
|
if(elem.type === 'image'){
|
||||||
selection.push(elem);
|
selection.push(elem);
|
||||||
} else {
|
} else {
|
||||||
if(fillPaths && elem.is_filled()){
|
if(fillPaths && elem.is_filled()){
|
||||||
|
|
@ -65,7 +65,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
|
|
||||||
Element.prototype.is_filled = function(){
|
Element.prototype.is_filled = function(){
|
||||||
var elem = this;
|
var elem = this;
|
||||||
|
|
||||||
// TODO text support
|
// TODO text support
|
||||||
// TODO opacity support
|
// TODO opacity support
|
||||||
if (elem.type !== "circle" &&
|
if (elem.type !== "circle" &&
|
||||||
|
|
@ -74,17 +74,14 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
elem.type !== "line" &&
|
elem.type !== "line" &&
|
||||||
elem.type !== "polygon" &&
|
elem.type !== "polygon" &&
|
||||||
elem.type !== "polyline" &&
|
elem.type !== "polyline" &&
|
||||||
elem.type !== "path" //&&
|
elem.type !== "path" ){
|
||||||
// elem.type !== "text" &&
|
|
||||||
// elem.type !== "#text"
|
|
||||||
){
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var fill = elem.attr('fill');
|
var fill = elem.attr('fill');
|
||||||
var opacity = elem.attr('fill-opacity');
|
var opacity = elem.attr('fill-opacity');
|
||||||
|
|
||||||
if(fill !== 'none'){
|
if(fill !== 'none'){
|
||||||
if(opacity === null || opacity > 0){
|
if(opacity === null || opacity > 0){
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -92,7 +89,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.embedImage = function(callback){
|
Element.prototype.embedImage = function(callback){
|
||||||
var elem = this;
|
var elem = this;
|
||||||
if(elem.type !== 'image') return;
|
if(elem.type !== 'image') return;
|
||||||
|
|
@ -116,15 +113,15 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
};
|
};
|
||||||
|
|
||||||
image.src = url;
|
image.src = url;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Element.prototype.renderPNG = function (wMM, hMM, pxPerMM, callback) {
|
Element.prototype.renderPNG = function (wMM, hMM, pxPerMM, callback) {
|
||||||
var elem = this;
|
var elem = this;
|
||||||
|
|
||||||
// get svg as dataUrl
|
// get svg as dataUrl
|
||||||
var svgStr = elem.outerSVG();
|
var svgStr = elem.outerSVG();
|
||||||
var svgDataUri = 'data:image/svg+xml;base64,' + window.btoa(unescape(encodeURIComponent(svgStr))); //deprecated unescape needed!
|
var svgDataUri = 'data:image/svg+xml;base64,' + window.btoa(svgStr);
|
||||||
var source = new Image();
|
var source = new Image();
|
||||||
source.src = svgDataUri;
|
source.src = svgDataUri;
|
||||||
|
|
||||||
|
|
@ -132,7 +129,7 @@ Snap.plugin(function (Snap, Element, Paper, global) {
|
||||||
var renderCanvas = document.createElement('canvas');
|
var renderCanvas = document.createElement('canvas');
|
||||||
renderCanvas.id = "renderCanvas";
|
renderCanvas.id = "renderCanvas";
|
||||||
renderCanvas.width = wMM * pxPerMM;
|
renderCanvas.width = wMM * pxPerMM;
|
||||||
renderCanvas.height = hMM * pxPerMM;
|
renderCanvas.height = hMM * pxPerMM;
|
||||||
document.getElementsByTagName('body')[0].appendChild(renderCanvas);
|
document.getElementsByTagName('body')[0].appendChild(renderCanvas);
|
||||||
var renderCanvasContext = renderCanvas.getContext('2d');
|
var renderCanvasContext = renderCanvas.getContext('2d');
|
||||||
|
|
||||||
|
|
|
||||||
154
src/octoprint/plugins/svgtogcode/static/js/svg2gcode.js
Normal file
154
src/octoprint/plugins/svgtogcode/static/js/svg2gcode.js
Normal 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");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -1,20 +1,5 @@
|
||||||
$(function(){
|
$(function(){
|
||||||
|
|
||||||
// Opera 8.0+
|
|
||||||
var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
|
|
||||||
// Firefox 1.0+
|
|
||||||
var isFirefox = typeof InstallTrigger !== 'undefined';
|
|
||||||
// At least Safari 3+: "[object HTMLElementConstructor]"
|
|
||||||
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
|
|
||||||
// Internet Explorer 6-11
|
|
||||||
var isIE = /*@cc_on!@*/false || !!document.documentMode;
|
|
||||||
// Edge 20+
|
|
||||||
var isEdge = !isIE && !!window.StyleMedia;
|
|
||||||
// Chrome 1+
|
|
||||||
var isChrome = !!window.chrome && !!window.chrome.webstore;
|
|
||||||
// Blink engine detection
|
|
||||||
var isBlink = (isChrome || isOpera) && !!window.CSS;
|
|
||||||
|
|
||||||
function WorkingAreaViewModel(params) {
|
function WorkingAreaViewModel(params) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
|
@ -79,7 +64,8 @@ $(function(){
|
||||||
// matrix scales svg units to display_pixels
|
// matrix scales svg units to display_pixels
|
||||||
self.scaleMatrix = ko.computed(function(){
|
self.scaleMatrix = ko.computed(function(){
|
||||||
var m = new Snap.Matrix();
|
var m = new Snap.Matrix();
|
||||||
var factor = 25.4/self.svgDPI() * 1/self.px2mm_factor();
|
//var factor = 25.4/self.svgDPI() * 1/self.px2mm_factor();
|
||||||
|
var factor = 1;
|
||||||
if(!isNaN(factor)){
|
if(!isNaN(factor)){
|
||||||
m.scale(factor);
|
m.scale(factor);
|
||||||
return m;
|
return m;
|
||||||
|
|
@ -107,7 +93,6 @@ $(function(){
|
||||||
self.clear = function(){
|
self.clear = function(){
|
||||||
snap.selectAll('#userContent>*').remove();
|
snap.selectAll('#userContent>*').remove();
|
||||||
snap.selectAll('#placedGcodes>*').remove();
|
snap.selectAll('#placedGcodes>*').remove();
|
||||||
snap.selectAll('rect:not(#coordGrid)').remove();
|
|
||||||
self.placedDesigns([]);
|
self.placedDesigns([]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -118,34 +103,24 @@ $(function(){
|
||||||
self.availableWidth($('#workingarea div.span8').innerWidth());
|
self.availableWidth($('#workingarea div.span8').innerWidth());
|
||||||
};
|
};
|
||||||
|
|
||||||
self.move_laser = function(data, evt){
|
self.move_laser = function(el){
|
||||||
self.abortFreeTransforms();
|
self.abortFreeTransforms();
|
||||||
if(self.state.isOperational() && !self.state.isPrinting()){
|
if(self.state.isOperational() && !self.state.isPrinting()){
|
||||||
var coord = self.getXYCoord(evt);
|
var x = self.px2mm(event.offsetX);
|
||||||
|
var y = self.px2mm(event.toElement.ownerSVGElement.offsetHeight - event.offsetY); // hopefully this works across browsers
|
||||||
|
x = Math.min(x, self.workingAreaWidthMM());
|
||||||
|
y = Math.min(y, self.workingAreaHeightMM());
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: API_BASEURL + "printer/printhead",
|
url: API_BASEURL + "printer/printhead",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
contentType: "application/json; charset=UTF8",
|
contentType: "application/json; charset=UTF8",
|
||||||
data: JSON.stringify({"command": "position", x:coord.x, y:coord.y})
|
data: JSON.stringify({"command": "position", x:x, y:y})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getXYCoord = function(evt){
|
|
||||||
if(/firefox/.test(navigator.userAgent.toLowerCase())) {
|
|
||||||
var scale = evt.target.parentElement.transform.baseVal[0].matrix.a;
|
|
||||||
var x = self.px2mm(evt.offsetX) * scale;
|
|
||||||
var y = self.px2mm(parseFloat(evt.target.attributes.height.value) - evt.offsetY) * scale;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
var x = self.px2mm(evt.offsetX);
|
|
||||||
var y = self.px2mm(parseFloat(evt.target.farthestViewportElement.clientHeight) - evt.offsetY);
|
|
||||||
}
|
|
||||||
x = Math.min(x, self.workingAreaWidthMM());
|
|
||||||
y = Math.min(y, self.workingAreaHeightMM());
|
|
||||||
return {x:x, y:y};
|
|
||||||
}
|
|
||||||
|
|
||||||
self.crosshairX = function(){
|
self.crosshairX = function(){
|
||||||
var pos = self.state.currentPos();
|
var pos = self.state.currentPos();
|
||||||
|
|
@ -153,7 +128,7 @@ $(function(){
|
||||||
|
|
||||||
};
|
};
|
||||||
self.crosshairY = function(){
|
self.crosshairY = function(){
|
||||||
var h = Snap($('#area_preview')[0]).getBBox().height;
|
var h = document.getElementById('area_preview').clientHeight;
|
||||||
var pos = self.state.currentPos();
|
var pos = self.state.currentPos();
|
||||||
return pos !== undefined ? (h - self.mm2px(pos.y) - 15) : -100; // subtract height/2;
|
return pos !== undefined ? (h - self.mm2px(pos.y) - 15) : -100; // subtract height/2;
|
||||||
};
|
};
|
||||||
|
|
@ -243,26 +218,11 @@ $(function(){
|
||||||
var url = self._getSVGserveUrl(file);
|
var url = self._getSVGserveUrl(file);
|
||||||
callback = function (f) {
|
callback = function (f) {
|
||||||
var newSvgAttrs = {};
|
var newSvgAttrs = {};
|
||||||
if(f.select('svg') == null){
|
var root_attrs = f.select('svg').node.attributes;
|
||||||
root_attrs = f.node.attributes;
|
|
||||||
} else {
|
|
||||||
var root_attrs = f.select('svg').node.attributes;
|
|
||||||
}
|
|
||||||
var doc_width = null;
|
var doc_width = null;
|
||||||
var doc_height = null;
|
var doc_height = null;
|
||||||
var doc_viewbox = null;
|
var doc_viewbox = null;
|
||||||
|
|
||||||
// find clippath elements
|
|
||||||
var clipPathEl = f.selectAll('clipPath');
|
|
||||||
if(clipPathEl.length != 0){
|
|
||||||
console.warn("Warning: removed unsupported clipPath element in SVG");
|
|
||||||
self.svg_contains_clipPath_warning();
|
|
||||||
clipPathEl.remove()
|
|
||||||
}
|
|
||||||
|
|
||||||
// find all elements with "display=none" and remove them
|
|
||||||
f.selectAll("[display=none]").remove()
|
|
||||||
|
|
||||||
// iterate svg tag attributes
|
// iterate svg tag attributes
|
||||||
for(var i = 0; i < root_attrs.length; i++){
|
for(var i = 0; i < root_attrs.length; i++){
|
||||||
var attr = root_attrs[i];
|
var attr = root_attrs[i];
|
||||||
|
|
@ -278,19 +238,10 @@ $(function(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// find Illustrator comment and notify
|
|
||||||
f.node.childNodes.forEach(function(entry) {
|
|
||||||
if(entry.nodeType == 8) { // Nodetype 8 = comment
|
|
||||||
if(entry.textContent.indexOf('Illustrator') > -1) {
|
|
||||||
new PNotify({title: gettext("Illustrator SVG Detected"), text: "Illustrator SVG detected! To preserve coorect scale, please go to the \'Settings\' menu and change the \'SVG dpi\' field under \'Plugins/Svg Conversion\' according to your file. And add it again.", type: "info", hide: false});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// scale matrix
|
// scale matrix
|
||||||
|
var scale = self.svgDPI()/25.4;
|
||||||
var mat = self.getDocumentViewBoxMatrix(doc_width, doc_height, doc_viewbox);
|
var mat = self.getDocumentViewBoxMatrix(doc_width, doc_height, doc_viewbox);
|
||||||
var dpiscale = 90 / self.settings.settings.plugins.svgtogcode.svgDPI();
|
var scaleMatrixStr = new Snap.Matrix(mat[0][0]/scale,mat[0][1],mat[1][0],mat[1][1]/scale,mat[0][2],mat[1][2]).toTransformString();
|
||||||
var scaleMatrixStr = new Snap.Matrix(mat[0][0],mat[0][1],mat[1][0],mat[1][1],mat[0][2],mat[1][2]).scale(dpiscale).toTransformString();
|
|
||||||
newSvgAttrs['transform'] = scaleMatrixStr;
|
newSvgAttrs['transform'] = scaleMatrixStr;
|
||||||
|
|
||||||
var newSvg = snap.group(f.selectAll("svg>*"));
|
var newSvg = snap.group(f.selectAll("svg>*"));
|
||||||
|
|
@ -416,20 +367,8 @@ $(function(){
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
self.svg_contains_clipPath_warning = function(){
|
|
||||||
var error = "<p>" + gettext("The SVG file contains clipPath elements.<br/>clipPath is not supported yet and has been removed from file.") + "</p>";
|
|
||||||
//error += pnotifyAdditionalInfo("<pre>" + data.jqXHR.responseText + "</pre>");
|
|
||||||
new PNotify({
|
|
||||||
title: "clipPath elements removed",
|
|
||||||
text: error,
|
|
||||||
type: "warn",
|
|
||||||
hide: false
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
self.svg_contains_text_warning = function(svg){
|
self.svg_contains_text_warning = function(svg){
|
||||||
var error = "<p>" + gettext("The SVG file contains text elements.<br/>If you want to laser just their outlines,<br/>please convert them to paths.<br/>Otherwise they will be engraved with infill.") + "</p>";
|
var error = "<p>" + gettext("The svg file contains text elements.<br/>Please convert them to paths.<br/>Otherwise they will be ignored.") + "</p>";
|
||||||
//error += pnotifyAdditionalInfo("<pre>" + data.jqXHR.responseText + "</pre>");
|
//error += pnotifyAdditionalInfo("<pre>" + data.jqXHR.responseText + "</pre>");
|
||||||
new PNotify({
|
new PNotify({
|
||||||
title: "Text elements found",
|
title: "Text elements found",
|
||||||
|
|
@ -437,6 +376,7 @@ $(function(){
|
||||||
type: "warn",
|
type: "warn",
|
||||||
hide: false
|
hide: false
|
||||||
});
|
});
|
||||||
|
svg.selectAll('text,tspan').remove();
|
||||||
};
|
};
|
||||||
|
|
||||||
self.svg_misfitting_warning = function(svg, misfitting){
|
self.svg_misfitting_warning = function(svg, misfitting){
|
||||||
|
|
@ -461,12 +401,12 @@ $(function(){
|
||||||
var wpx = this.width;
|
var wpx = this.width;
|
||||||
var hpx = this.height;
|
var hpx = this.height;
|
||||||
|
|
||||||
var dimPT = self.getUsefulDimensions(wpx, hpx);
|
var dimMM = self.getUsefulDimensions(wpx, hpx);
|
||||||
var wPT = dimPT[0];
|
var wMM = dimMM[0];
|
||||||
var hPT = dimPT[1];
|
var hMM = dimMM[1];
|
||||||
|
|
||||||
var y = self.mm2svgUnits(self.workingAreaHeightMM()) - hPT;
|
var y = self.workingAreaHeightMM() - hMM;
|
||||||
var newImg = snap.image(url, 0, y, wPT, hPT);
|
var newImg = snap.image(url, 0, y, wMM, hMM);
|
||||||
var id = self.getEntryId(file);
|
var id = self.getEntryId(file);
|
||||||
var previewId = self.generateUniqueId(id); // appends # if multiple times the same design is placed.
|
var previewId = self.generateUniqueId(id); // appends # if multiple times the same design is placed.
|
||||||
newImg.attr({id: previewId, filter: 'url(#grayscale_filter)', 'data-serveurl': url});
|
newImg.attr({id: previewId, filter: 'url(#grayscale_filter)', 'data-serveurl': url});
|
||||||
|
|
@ -498,9 +438,7 @@ $(function(){
|
||||||
} else {
|
} else {
|
||||||
destHeightMM = destWidthMM / aspectRatio;
|
destHeightMM = destWidthMM / aspectRatio;
|
||||||
}
|
}
|
||||||
var destWidthPT = self.mm2svgUnits(destWidthMM);
|
return [destWidthMM, destHeightMM];
|
||||||
var destHeightPT = self.mm2svgUnits(destHeightMM);
|
|
||||||
return [destWidthPT, destHeightPT];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.getDocumentDimensionsInPt = function(doc_width, doc_height, doc_viewbox){
|
self.getDocumentDimensionsInPt = function(doc_width, doc_height, doc_viewbox){
|
||||||
|
|
@ -641,18 +579,17 @@ $(function(){
|
||||||
self.draw_coord_grid = function(){
|
self.draw_coord_grid = function(){
|
||||||
var grid = snap.select('#coordGrid');
|
var grid = snap.select('#coordGrid');
|
||||||
if(grid.attr('fill') === 'none'){
|
if(grid.attr('fill') === 'none'){
|
||||||
var w = self.mm2svgUnits(self.workingAreaWidthMM());
|
var w = self.workingAreaWidthMM();
|
||||||
var h = self.mm2svgUnits(self.workingAreaHeightMM());
|
var h = self.workingAreaHeightMM();
|
||||||
var max_lines = 20;
|
var max_lines = 20;
|
||||||
|
|
||||||
var linedistMM = Math.floor(Math.max(self.workingAreaWidthMM(), self.workingAreaHeightMM()) / (max_lines * 10))*10;
|
var linedistMM = Math.floor(Math.max(self.workingAreaWidthMM(), self.workingAreaHeightMM()) / (max_lines * 10))*10;
|
||||||
var yPatternOffset = self.mm2svgUnits(self.workingAreaHeightMM() % linedistMM);
|
var yPatternOffset = self.workingAreaHeightMM() % linedistMM;
|
||||||
var linedist = self.mm2svgUnits(linedistMM);
|
var linedist = linedistMM;
|
||||||
|
|
||||||
var marker = snap.circle(linedist/2, linedist/2, 1).attr({
|
var marker = snap.circle(linedist/2, linedist/2, 0.3).attr({
|
||||||
fill: "#000000",
|
fill: "#000000",
|
||||||
stroke: "none",
|
stroke: "none"
|
||||||
strokeWidth: 1
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// dot pattern
|
// dot pattern
|
||||||
|
|
@ -742,16 +679,6 @@ $(function(){
|
||||||
return snap.selectAll("#userContent image");
|
return snap.selectAll("#userContent image");
|
||||||
};
|
};
|
||||||
|
|
||||||
self.hasTextItems = function () {
|
|
||||||
if(snap.selectAll("#userContent tspan").length > 0 ||
|
|
||||||
snap.selectAll("#userContent text").length > 0 ||
|
|
||||||
snap.selectAll("userContent #text").length > 0) {
|
|
||||||
return true
|
|
||||||
}else{
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.getPlacedGcodes = ko.computed(function() {
|
self.getPlacedGcodes = ko.computed(function() {
|
||||||
var gcodeFiles = [];
|
var gcodeFiles = [];
|
||||||
ko.utils.arrayForEach(self.placedDesigns(), function(design) {
|
ko.utils.arrayForEach(self.placedDesigns(), function(design) {
|
||||||
|
|
@ -874,7 +801,7 @@ $(function(){
|
||||||
for (var i = 0; i < fillings.length; i++) {
|
for (var i = 0; i < fillings.length; i++) {
|
||||||
var item = fillings[i];
|
var item = fillings[i];
|
||||||
|
|
||||||
if (item.type === 'image' || item.type === "text" || item.type === "#text") {
|
if (item.type === 'image') {
|
||||||
// remove filter effects on images for proper rendering
|
// remove filter effects on images for proper rendering
|
||||||
var style = item.attr('style');
|
var style = item.attr('style');
|
||||||
if (style !== null) {
|
if (style !== null) {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
||||||
<span class="icon icon-question-sign" aria-hidden="true"></span>
|
<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.
|
Cutting needs higher intensities than engraving.
|
||||||
The effect in general is dependent from the material and its color and surface.
|
The effect in general is dependent from the material and its color and surface.
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -33,8 +33,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
||||||
<span class="icon icon-question-sign" aria-hidden="true"></span>
|
<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.
|
Sets the velocity of the laser head. The slower the movement the deeper the effect on the material.
|
||||||
Cutting needs slower movement than engraving.
|
Cutting needs slower movement than engraving.
|
||||||
The effect in general is dependent from the material and its color and surface.
|
The effect in general is dependent from the material and its color and surface.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -56,11 +56,11 @@
|
||||||
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
||||||
<span class="icon icon-question-sign" aria-hidden="true"></span>
|
<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.
|
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.
|
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>
|
</div>
|
||||||
|
|
||||||
<div data-bind="visible: show_image_parameters ">
|
<div data-bind="visible: show_image_parameters ">
|
||||||
<p>{{ _('Image engraving parameters:') }}</p>
|
<p>{{ _('Image engraving parameters:') }}</p>
|
||||||
<div class="control-group" >
|
<div class="control-group" >
|
||||||
|
|
@ -103,10 +103,10 @@
|
||||||
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
||||||
<span class="icon icon-question-sign" aria-hidden="true"></span>
|
<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.
|
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>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<p >{{ _('Image Preprocessing') }}</p>
|
<p >{{ _('Image Preprocessing') }}</p>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<div class="img_preprocessing_preview before" style="background-image:url(/plugin/svgtogcode/static/img/kitty_grayscale.png);" >before</div>
|
<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 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 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 class="img_preprocessing_preview dithered" style="background-image:url(/plugin/svgtogcode/static/img/kitty_dithered_150.png);" data-bind="visible: imgDithering"></div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="photo_attribution"><a href="http://www.christianholmer.com" target="_blank">Photo: Christian Holmér</a></div>
|
<div class="photo_attribution"><a href="http://www.christianholmer.com" target="_blank">Photo: Christian Holmér</a></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-bind="disable:imgDithering ">
|
<div data-bind="disable:imgDithering ">
|
||||||
<label class="control-label">{{ _('Contrast') }}</label>
|
<label class="control-label">{{ _('Contrast') }}</label>
|
||||||
<div class="controls img_slider">
|
<div class="controls img_slider">
|
||||||
<input id="svgtogcode_contrast_slider" type="text" data-bind="value: imgContrast" >
|
<input id="svgtogcode_contrast_slider" type="text" data-bind="value: imgContrast" >
|
||||||
</div>
|
</div>
|
||||||
<div style="clear:both"></div>
|
<div style="clear:both"></div>
|
||||||
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
||||||
<span class="icon icon-question-sign" aria-hidden="true"></span>
|
<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>
|
</div>
|
||||||
|
|
||||||
<label class="control-label">{{ _('Sharpening') }}</label>
|
<label class="control-label">{{ _('Sharpening') }}</label>
|
||||||
<div class="controls img_slider">
|
<div class="controls img_slider">
|
||||||
<input id="svgtogcode_sharpening_slider" class="uninitialized" type="text" data-bind="value: imgSharpening">
|
<input id="svgtogcode_sharpening_slider" class="uninitialized" type="text" data-bind="value: imgSharpening">
|
||||||
|
|
@ -137,10 +137,10 @@
|
||||||
<div style="clear:both"></div>
|
<div style="clear:both"></div>
|
||||||
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
||||||
<span class="icon icon-question-sign" aria-hidden="true"></span>
|
<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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label class="control-label">{{ _('Dithering') }}</label>
|
<label class="control-label">{{ _('Dithering') }}</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
|
|
@ -149,8 +149,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
<div class="controls alert alert-info hint" data-bind="visible: showHints">
|
||||||
<span class="icon icon-question-sign" aria-hidden="true"></span>
|
<span class="icon icon-question-sign" aria-hidden="true"></span>
|
||||||
Converts the image to solely black and white pixels.
|
Converts the image to solely black and white pixels.
|
||||||
Use this if the laser effect on your material is not able to transfer grayscales.
|
Use this if the laser effect on your material is not able to transfer grayscales.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</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" data-dismiss="modal" aria-hidden="true" data-bind="click: $root.cancel_conversion()">{{ _('Cancel') }}</a>
|
||||||
<a href="#" class="btn btn-primary" data-bind="click: function() { if ($root.enableConvertButton()) { $root.convert() } }, enabled: enableConvertButton, css: {disabled: !$root.enableConvertButton()}">{{ _('Convert') }}</a>
|
<a href="#" class="btn btn-primary" data-bind="click: function() { if ($root.enableConvertButton()) { $root.convert() } }, enabled: enableConvertButton, css: {disabled: !$root.enableConvertButton()}">{{ _('Convert') }}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -331,7 +331,7 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback):
|
||||||
def position(self, x, y):
|
def position(self, x, y):
|
||||||
printer_profile = self._printerProfileManager.get_current_or_default()
|
printer_profile = self._printerProfileManager.get_current_or_default()
|
||||||
movement_speed = min(printer_profile["axes"]["x"]["speed"], printer_profile["axes"]["y"]["speed"])
|
movement_speed = min(printer_profile["axes"]["x"]["speed"], printer_profile["axes"]["y"]["speed"])
|
||||||
self.commands(["G90", "G0 X%.3f Y%.3f F%d" % (x, y, movement_speed)])
|
self.commands(["G90", "G0 X%.3f Y%.3f F%d" % (x, y, movement_speed), "?"])
|
||||||
|
|
||||||
def _convert_rate_value(self, factor, min=0, max=200):
|
def _convert_rate_value(self, factor, min=0, max=200):
|
||||||
if not isinstance(factor, (int, float, long)):
|
if not isinstance(factor, (int, float, long)):
|
||||||
|
|
@ -433,22 +433,6 @@ class Printer(PrinterInterface, comm.MachineComPrintCallback):
|
||||||
payload["origin"] = FileDestinations.SDCARD
|
payload["origin"] = FileDestinations.SDCARD
|
||||||
eventManager().fire(Events.PRINT_FAILED, payload)
|
eventManager().fire(Events.PRINT_FAILED, payload)
|
||||||
|
|
||||||
def increase_passes(self):
|
|
||||||
"""
|
|
||||||
increase the number of passes by one.
|
|
||||||
"""
|
|
||||||
if self._comm is None:
|
|
||||||
return
|
|
||||||
self._comm.increasePasses()
|
|
||||||
|
|
||||||
def degrease_passes(self):
|
|
||||||
"""
|
|
||||||
degrease the number of passes by one.
|
|
||||||
"""
|
|
||||||
if self._comm is None:
|
|
||||||
return
|
|
||||||
self._comm.degreasePasses()
|
|
||||||
|
|
||||||
def get_state_string(self):
|
def get_state_string(self):
|
||||||
"""
|
"""
|
||||||
Returns a human readable string corresponding to the current communication state.
|
Returns a human readable string corresponding to the current communication state.
|
||||||
|
|
|
||||||
|
|
@ -419,7 +419,7 @@ def gcodeFileCommand(filename, target):
|
||||||
@restricted_access
|
@restricted_access
|
||||||
def gcodeConvertCommand():
|
def gcodeConvertCommand():
|
||||||
target = FileDestinations.LOCAL;
|
target = FileDestinations.LOCAL;
|
||||||
|
|
||||||
# valid file commands, dict mapping command name to mandatory parameters
|
# valid file commands, dict mapping command name to mandatory parameters
|
||||||
valid_commands = {
|
valid_commands = {
|
||||||
"convert": []
|
"convert": []
|
||||||
|
|
@ -427,14 +427,14 @@ def gcodeConvertCommand():
|
||||||
command, data, response = get_json_command_from_request(request, valid_commands)
|
command, data, response = get_json_command_from_request(request, valid_commands)
|
||||||
if response is not None:
|
if response is not None:
|
||||||
return response
|
return response
|
||||||
|
|
||||||
appendGcodeFiles = data['gcodeFilesToAppend']
|
appendGcodeFiles = data['gcodeFilesToAppend']
|
||||||
del data['gcodeFilesToAppend']
|
del data['gcodeFilesToAppend']
|
||||||
|
|
||||||
# def appendCallback(location, path, sources, **kwargs):
|
# def appendCallback(location, path, sources, **kwargs):
|
||||||
# if '_error' in kwargs:
|
# if '_error' in kwargs:
|
||||||
# result = kwargs['_error']
|
# 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:
|
# else:
|
||||||
# output_path = fileManager.path_on_disk(location, path)
|
# output_path = fileManager.path_on_disk(location, path)
|
||||||
# # append additioal gcodes
|
# # append additioal gcodes
|
||||||
|
|
@ -461,18 +461,16 @@ def gcodeConvertCommand():
|
||||||
# #r = make_response(jsonify(result), 202)
|
# #r = make_response(jsonify(result), 202)
|
||||||
# #r.headers["Location"] = location
|
# #r.headers["Location"] = location
|
||||||
# #return r
|
# #return r
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if command == "convert":
|
if command == "convert":
|
||||||
# TODO stripping non-ascii is a hack - svg contains lots of non-ascii in <text> tags. Fix this!
|
# TODO stripping non-ascii is a hack - svg contains lots of non-ascii in <text> tags. Fix this!
|
||||||
import re
|
import re
|
||||||
svg = ''.join(i for i in data['svg'] if ord(i)<128) # strip non-ascii chars like €
|
svg = ''.join(i for i in data['svg'] if ord(i)<128) # strip non-ascii chars like €
|
||||||
del data['svg']
|
del data['svg']
|
||||||
|
|
||||||
import os
|
import os
|
||||||
name, _ = os.path.splitext(data['gcode'])
|
name, _ = os.path.splitext(data['gcode'])
|
||||||
|
|
||||||
filename = target + "/temp.svg"
|
filename = target + "/temp.svg"
|
||||||
class Wrapper(object):
|
class Wrapper(object):
|
||||||
def __init__(self, filename, content):
|
def __init__(self, filename, content):
|
||||||
|
|
@ -486,7 +484,7 @@ def gcodeConvertCommand():
|
||||||
|
|
||||||
fileObj = Wrapper(filename, svg)
|
fileObj = Wrapper(filename, svg)
|
||||||
fileManager.add_file(target, filename, fileObj, links=None, allow_overwrite=True)
|
fileManager.add_file(target, filename, fileObj, links=None, allow_overwrite=True)
|
||||||
|
|
||||||
slicer = "svgtogcode";
|
slicer = "svgtogcode";
|
||||||
slicer_instance = slicingManager.get_slicer(slicer)
|
slicer_instance = slicingManager.get_slicer(slicer)
|
||||||
if slicer_instance.get_slicer_properties()["same_device"] and (printer.is_printing() or printer.is_paused()):
|
if slicer_instance.get_slicer_properties()["same_device"] and (printer.is_printing() or printer.is_paused()):
|
||||||
|
|
@ -500,7 +498,7 @@ def gcodeConvertCommand():
|
||||||
import os
|
import os
|
||||||
name, _ = os.path.splitext(filename)
|
name, _ = os.path.splitext(filename)
|
||||||
gcode_name = name + ".gco"
|
gcode_name = name + ".gco"
|
||||||
|
|
||||||
# append number if file exists
|
# append number if file exists
|
||||||
name, ext = os.path.splitext(gcode_name)
|
name, ext = os.path.splitext(gcode_name)
|
||||||
i = 1;
|
i = 1;
|
||||||
|
|
@ -518,7 +516,7 @@ def gcodeConvertCommand():
|
||||||
del data["profile"]
|
del data["profile"]
|
||||||
else:
|
else:
|
||||||
profile = None
|
profile = None
|
||||||
##
|
|
||||||
if "printerProfile" in data.keys() and data["printerProfile"]:
|
if "printerProfile" in data.keys() and data["printerProfile"]:
|
||||||
printerProfile = data["printerProfile"]
|
printerProfile = data["printerProfile"]
|
||||||
del data["printerProfile"]
|
del data["printerProfile"]
|
||||||
|
|
@ -530,7 +528,7 @@ def gcodeConvertCommand():
|
||||||
del data["position"]
|
del data["position"]
|
||||||
else:
|
else:
|
||||||
position = None
|
position = None
|
||||||
|
|
||||||
select_after_slicing = False
|
select_after_slicing = False
|
||||||
if "select" in data.keys() and data["select"] in valid_boolean_trues:
|
if "select" in data.keys() and data["select"] in valid_boolean_trues:
|
||||||
if not printer.is_operational():
|
if not printer.is_operational():
|
||||||
|
|
@ -548,34 +546,41 @@ def gcodeConvertCommand():
|
||||||
for key in override_keys:
|
for key in override_keys:
|
||||||
overrides[key[len("profile."):]] = data[key]
|
overrides[key[len("profile."):]] = data[key]
|
||||||
|
|
||||||
def slicing_done(target, gcode_name, select_after_slicing, print_after_slicing, append_these_files):
|
if data.has_key('gcodedata'):
|
||||||
# append additioal gcodes
|
|
||||||
output_path = fileManager.path_on_disk(target, gcode_name)
|
output_path = fileManager.path_on_disk(target, gcode_name)
|
||||||
with open(output_path,'ab') as wfd:
|
with open(output_path,'wb') as wfd:
|
||||||
for f in append_these_files:
|
for line in data['gcodedata']:
|
||||||
path = fileManager.path_on_disk(f['origin'], f['name'])
|
wfd.write(line)
|
||||||
wfd.write( "\n; "+ f['name'] + "\n")
|
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:
|
with open(path,'rb') as fd:
|
||||||
shutil.copyfileobj(fd, wfd, 1024*1024*10)
|
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:
|
if select_after_slicing or print_after_slicing:
|
||||||
sd = False
|
sd = False
|
||||||
filenameToSelect = fileManager.path_on_disk(target, gcode_name)
|
filenameToSelect = fileManager.path_on_disk(target, gcode_name)
|
||||||
printer.select_file(filenameToSelect, sd, True)
|
printer.select_file(filenameToSelect, sd, True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fileManager.slice(slicer, target, filename, target, gcode_name,
|
fileManager.slice(slicer, target, filename, target, gcode_name,
|
||||||
profile=profile,
|
profile=profile,
|
||||||
printer_profile_id=printerProfile,
|
printer_profile_id=printerProfile,
|
||||||
position=position,
|
position=position,
|
||||||
overrides=overrides,
|
overrides=overrides,
|
||||||
callback=slicing_done,
|
callback=slicing_done,
|
||||||
callback_args=[target, gcode_name, select_after_slicing, print_after_slicing, appendGcodeFiles])
|
callback_args=[target, gcode_name, select_after_slicing, print_after_slicing, appendGcodeFiles])
|
||||||
except octoprint.slicing.UnknownProfile:
|
except octoprint.slicing.UnknownProfile:
|
||||||
return make_response("Profile {profile} doesn't exist".format(**locals()), 400)
|
return make_response("Profile {profile} doesn't exist".format(**locals()), 400)
|
||||||
|
|
||||||
files = {}
|
files = {}
|
||||||
location = url_for(".readGcodeFile", target=target, filename=gcode_name, _external=True)
|
location = url_for(".readGcodeFile", target=target, filename=gcode_name, _external=True)
|
||||||
|
|
@ -593,7 +598,7 @@ def gcodeConvertCommand():
|
||||||
return r
|
return r
|
||||||
|
|
||||||
return NO_CONTENT
|
return NO_CONTENT
|
||||||
|
|
||||||
|
|
||||||
@api.route("/files/<string:target>/<path:filename>", methods=["DELETE"])
|
@api.route("/files/<string:target>/<path:filename>", methods=["DELETE"])
|
||||||
@restricted_access
|
@restricted_access
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,7 @@ def controlJob():
|
||||||
"start": [],
|
"start": [],
|
||||||
"restart": [],
|
"restart": [],
|
||||||
"pause": [],
|
"pause": [],
|
||||||
"cancel": [],
|
"cancel": []
|
||||||
"incpasses": [],
|
|
||||||
"degpasses": []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
command, data, response = get_json_command_from_request(request, valid_commands)
|
command, data, response = get_json_command_from_request(request, valid_commands)
|
||||||
|
|
@ -50,15 +48,6 @@ def controlJob():
|
||||||
if not activePrintjob:
|
if not activePrintjob:
|
||||||
return make_response("Printer is neither printing nor paused, 'cancel' command cannot be performed", 409)
|
return make_response("Printer is neither printing nor paused, 'cancel' command cannot be performed", 409)
|
||||||
printer.cancel_print()
|
printer.cancel_print()
|
||||||
elif command == "incpasses":
|
|
||||||
if not activePrintjob:
|
|
||||||
return make_response("Printer is neither printing nor paused, 'incpasses' command cannot be performed", 409)
|
|
||||||
printer.increase_passes()
|
|
||||||
elif command == "degpasses":
|
|
||||||
if not activePrintjob:
|
|
||||||
return make_response("Printer is neither printing nor paused, 'degpasses' command cannot be performed", 409)
|
|
||||||
printer.degrease_passes()
|
|
||||||
|
|
||||||
return NO_CONTENT
|
return NO_CONTENT
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.7 KiB |
|
|
@ -404,11 +404,6 @@ $(function() {
|
||||||
self.onStartup = function () {
|
self.onStartup = function () {
|
||||||
self.requestData();
|
self.requestData();
|
||||||
self._configureJogDistanceSlider();
|
self._configureJogDistanceSlider();
|
||||||
$('#manual_position').keyup(function(e) {
|
|
||||||
if (e.which === 13){ // 13 == enter
|
|
||||||
self.manualPosition();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.updateRotatorWidth = function() {
|
self.updateRotatorWidth = function() {
|
||||||
|
|
@ -611,24 +606,6 @@ $(function() {
|
||||||
self.setCoordinateOrigin = function () {
|
self.setCoordinateOrigin = function () {
|
||||||
self.sendCustomCommand({type: 'command', command: "G92 X0 Y0"});
|
self.sendCustomCommand({type: 'command', command: "G92 X0 Y0"});
|
||||||
};
|
};
|
||||||
|
|
||||||
self.manualPosition = function(){
|
|
||||||
$('#manual_position').removeClass('warning');
|
|
||||||
var s = $('#manual_position').val();
|
|
||||||
var tmp = s.split(/[^0-9.,-\\+]+/);
|
|
||||||
if (tmp.length === 2) {
|
|
||||||
var x = parseFloat(tmp[0]);
|
|
||||||
var y = parseFloat(tmp[1]);
|
|
||||||
if(!isNaN(x) && !isNaN(y)) {
|
|
||||||
self.sendCustomCommand({type: 'command', command: "G0X"+x+"Y"+y});
|
|
||||||
$('#manual_position').val('');
|
|
||||||
} else {
|
|
||||||
$('#manual_position').addClass('warning');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$('#manual_position').addClass('warning');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.jogDistanceInMM = ko.observable(undefined);
|
self.jogDistanceInMM = ko.observable(undefined);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ $(function() {
|
||||||
self.feedrateOverride = ko.observable(100);
|
self.feedrateOverride = ko.observable(100);
|
||||||
self.intensityOverride.extend({ rateLimit: 500 });
|
self.intensityOverride.extend({ rateLimit: 500 });
|
||||||
self.feedrateOverride.extend({ rateLimit: 500 });
|
self.feedrateOverride.extend({ rateLimit: 500 });
|
||||||
self.numberOfPasses = ko.observable(1);
|
|
||||||
|
|
||||||
self.TITLE_PRINT_BUTTON_PAUSED = gettext("Restarts the print job from the beginning");
|
self.TITLE_PRINT_BUTTON_PAUSED = gettext("Restarts the print job from the beginning");
|
||||||
self.TITLE_PRINT_BUTTON_UNPAUSED = gettext("Starts the print job");
|
self.TITLE_PRINT_BUTTON_UNPAUSED = gettext("Starts the print job");
|
||||||
|
|
@ -217,8 +216,7 @@ $(function() {
|
||||||
$("#confirmation_dialog .confirmation_dialog_acknowledge").click(
|
$("#confirmation_dialog .confirmation_dialog_acknowledge").click(
|
||||||
function (e) {
|
function (e) {
|
||||||
if (typeof callback === 'function') {
|
if (typeof callback === 'function') {
|
||||||
self.resetOverrideSlider();
|
self.onEventPrintDone();
|
||||||
self.numberOfPasses(1);
|
|
||||||
callback(e);
|
callback(e);
|
||||||
$("#confirmation_dialog").modal("hide");
|
$("#confirmation_dialog").modal("hide");
|
||||||
$("#confirmation_dialog .confirmation_dialog_message").html('');
|
$("#confirmation_dialog .confirmation_dialog_message").html('');
|
||||||
|
|
@ -334,30 +332,16 @@ $(function() {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.increasePasses = function(){
|
|
||||||
self.numberOfPasses(self.numberOfPasses()+1);
|
|
||||||
self._jobCommand("incpasses");
|
|
||||||
}
|
|
||||||
self.decreasePasses = function(){
|
|
||||||
var passes = Math.max(self.numberOfPasses()-1, 1);
|
|
||||||
self.numberOfPasses(passes);
|
|
||||||
self._jobCommand("degpasses");
|
|
||||||
}
|
|
||||||
|
|
||||||
self.onEventPrintDone = function(){
|
self.onEventPrintDone = function(){
|
||||||
self.resetOverrideSlider();
|
self.feedrateOverrideSlider.slider('setValue', 100);
|
||||||
|
self.intensityOverrideSlider.slider('setValue', 100);
|
||||||
|
self.intensityOverride(100);
|
||||||
|
self.feedrateOverride(100);
|
||||||
};
|
};
|
||||||
|
|
||||||
self.onStartup = function() {
|
self.onStartup = function() {
|
||||||
self._configureOverrideSliders();
|
self._configureOverrideSliders();
|
||||||
};
|
};
|
||||||
|
|
||||||
self.resetOverrideSlider = function() {
|
|
||||||
self.feedrateOverrideSlider.slider('setValue', 100);
|
|
||||||
self.intensityOverrideSlider.slider('setValue', 100);
|
|
||||||
self.intensityOverride(100);
|
|
||||||
self.feedrateOverride(100);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OCTOPRINT_VIEWMODELS.push([
|
OCTOPRINT_VIEWMODELS.push([
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title data-bind="text: title">Mr Draw</title>
|
<title data-bind="text: title">Mr Beam</title>
|
||||||
|
|
||||||
<link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.png') }}">
|
<link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.png') }}">
|
||||||
<link rel="apple-touch-icon" sizes="114x114" href="{{ url_for('static', filename='img/apple-touch-icon-114x114.png') }}">
|
<link rel="apple-touch-icon" sizes="114x114" href="{{ url_for('static', filename='img/apple-touch-icon-114x114.png') }}">
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="navbar-header brand" style="min-width: 272px;">
|
<div class="navbar-header brand" style="min-width: 272px;">
|
||||||
<a class="navbar-brand" href="#">
|
<a class="navbar-brand" href="#">
|
||||||
<img alt="Mr Draw Logo" src="{{ url_for('static', filename='img/mr-draw-red_x120.png') }}">
|
<img alt="Mr Beam Logo" src="{{ url_for('static', filename='img/mr-typo-red_x120.png') }}">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<!-- Navbar -->
|
<!-- Navbar -->
|
||||||
|
|
@ -58,7 +58,7 @@
|
||||||
|
|
||||||
<div id="control" class="accordion-inner" data-bind="visible: isReady() || isLocked() || isFlashing()">
|
<div id="control" class="accordion-inner" data-bind="visible: isReady() || isLocked() || isFlashing()">
|
||||||
<div data-bind="visible: isLocked ">
|
<div data-bind="visible: isLocked ">
|
||||||
Mr Draw is in a locked state as it does not know its position.
|
Mr Beam is in a locked state as it does not know its position.
|
||||||
First remove any objects blocking the gantry's travel range.
|
First remove any objects blocking the gantry's travel range.
|
||||||
Then do a homing cycle.
|
Then do a homing cycle.
|
||||||
<div style='text-align: center; padding:.5em;'>
|
<div style='text-align: center; padding:.5em;'>
|
||||||
|
|
@ -123,10 +123,6 @@
|
||||||
<div class="distance">
|
<div class="distance">
|
||||||
<input type="text" id="jogDistance" />
|
<input type="text" id="jogDistance" />
|
||||||
</div>
|
</div>
|
||||||
<div class="input-append manual_position_input">
|
|
||||||
<input id="manual_position" placeholder="x.xx y.yy" onsubmit="manualPosition"/>
|
|
||||||
<button class="" data-bind="click: manualPosition">Go</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -160,7 +156,7 @@
|
||||||
-->
|
-->
|
||||||
{{ _('Approx. Total Job Time') }}: <strong data-bind="text: estimatedPrintTimeString"></strong><br>
|
{{ _('Approx. Total Job Time') }}: <strong data-bind="text: estimatedPrintTimeString"></strong><br>
|
||||||
<div data-bind="visible: isPrinting() || isPaused()">
|
<div data-bind="visible: isPrinting() || isPaused()">
|
||||||
|
|
||||||
<div class="progress">
|
<div class="progress">
|
||||||
<div class="bar" id="job_progressBar" data-bind="style: { width: progressString() + '%' }"> {{ _('Processed') }} : <strong data-bind="text: byteString"></strong></div>
|
<div class="bar" id="job_progressBar" data-bind="style: { width: progressString() + '%' }"> {{ _('Processed') }} : <strong data-bind="text: byteString"></strong></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -172,19 +168,6 @@
|
||||||
<input id="feedrate_override_slider" type="text" data-bind="sliderValue: feedrateOverride">
|
<input id="feedrate_override_slider" type="text" data-bind="sliderValue: feedrateOverride">
|
||||||
<span data-bind="text:feedrateOverride()">100</span>% Feedrate
|
<span data-bind="text:feedrateOverride()">100</span>% Feedrate
|
||||||
</div>
|
</div>
|
||||||
<div class="repeatGcode">
|
|
||||||
<div class="btn-group">
|
|
||||||
<button type="button" class="btn btn-default btn-number" data-bind="enable: numberOfPasses() > 1, click:decreasePasses">
|
|
||||||
<span class="icon-minus"></span>
|
|
||||||
</button>
|
|
||||||
<input type="text" class="input-mini text-right" value="1" min="1" max="10" data-bind="value:numberOfPasses()">
|
|
||||||
<button type="button" class="btn btn-default btn-number" data-bind="click:increasePasses">
|
|
||||||
<span class="icon-plus"></span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<span>Passes</span>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- {{ _('Print Time') }}: <strong data-bind="text: printTimeString"></strong><br>
|
<!-- {{ _('Print Time') }}: <strong data-bind="text: printTimeString"></strong><br>
|
||||||
|
|
@ -304,6 +287,9 @@
|
||||||
backgroundPosition: crosshairX()+'px'+' '+crosshairY()+'px',
|
backgroundPosition: crosshairX()+'px'+' '+crosshairY()+'px',
|
||||||
width: workingAreaWidthPx()+'px',
|
width: workingAreaWidthPx()+'px',
|
||||||
height: workingAreaHeightPx()+'px'
|
height: workingAreaHeightPx()+'px'
|
||||||
|
},
|
||||||
|
attr: {
|
||||||
|
viewBox: '0 0 '+workingAreaWidthMM()+' '+workingAreaHeightMM()
|
||||||
}
|
}
|
||||||
">
|
">
|
||||||
<filter id="grayscale_filter">
|
<filter id="grayscale_filter">
|
||||||
|
|
@ -321,25 +307,23 @@
|
||||||
<text
|
<text
|
||||||
xml:space="preserve"
|
xml:space="preserve"
|
||||||
data-bind="visible: working_area_empty"
|
data-bind="visible: working_area_empty"
|
||||||
style="font-size:64px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#DDDDDD;fill-opacity:1;stroke:none;font-family:DIN-BoldAlternate, Helvetica, Arial, Sans-serif;"
|
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#DDDDDD;fill-opacity:1;stroke:none;font-family:DIN-BoldAlternate, Helvetica, Arial, Sans-serif;"
|
||||||
x="396.81018"
|
x="396.81018"
|
||||||
y="552.36218"
|
y="552.36218"
|
||||||
id="add_designs_hint"
|
id="add_designs_hint"
|
||||||
>
|
>
|
||||||
<tspan
|
<tspan
|
||||||
id="tspan2987" x="368.571426" y="532.36218"
|
id="tspan2987" x="60" y="60"
|
||||||
style="text-anchor:middle;text-align:center">add designs via </tspan>
|
style="text-anchor:left;text-align:center">add designs via </tspan>
|
||||||
<tspan
|
<tspan
|
||||||
x="500" y="592.36218" id="tspan2989"
|
x="70" y="75" id="tspan2989"
|
||||||
style="text-anchor:middle;text-align:center">the design library </tspan>
|
style="text-anchor:left;text-align:center">the design library </tspan>
|
||||||
<tspan
|
<tspan
|
||||||
x="568.571426" y="652.36218" id="tspan2993"
|
x="80" y="90" id="tspan2993"
|
||||||
style="text-anchor:middle;text-align:center">or drag 'n' drop </tspan>
|
style="text-anchor:left;text-align:center">or drag 'n' drop </tspan>
|
||||||
<tspan
|
</text>
|
||||||
x="368.571426" y="712.36218" id="tspan2991"
|
<g id="placedGcodes" data-bind="visible: !state.isPrinting() && !state.isPaused()"></g>
|
||||||
style="text-anchor:middle;text-align:center" /></text>
|
<g id="gCodePreview" data-bind="visible: state.isPrinting() || state.isPaused()"></g>
|
||||||
<g id="placedGcodes" data-bind="visible: !state.isPrinting() && !state.isPaused(), attr: { transform: scaleMatrixMMtoDisplay() }"></g>
|
|
||||||
<g id="gCodePreview" data-bind="visible: state.isPrinting() || state.isPaused(), attr: { transform: scaleMatrixMMtoDisplay() }"></g>
|
|
||||||
<rect data-bind="click: move_laser"
|
<rect data-bind="click: move_laser"
|
||||||
id="coordGrid" x="0" y="0" width="0" height="0"
|
id="coordGrid" x="0" y="0" width="0" height="0"
|
||||||
stroke="none" fill="none"></rect>
|
stroke="none" fill="none"></rect>
|
||||||
|
|
@ -533,7 +517,7 @@
|
||||||
<i class="icon-camera icon-white"></i>
|
<i class="icon-camera icon-white"></i>
|
||||||
<span>{{ _('Photo') }}</span>
|
<span>{{ _('Photo') }}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div id="gcode_upload_progress" class="progress" style="width: 100%;">
|
<div id="gcode_upload_progress" class="progress" style="width: 100%;">
|
||||||
<div class="bar" style="width: 0%"></div>
|
<div class="bar" style="width: 0%"></div>
|
||||||
|
|
@ -657,10 +641,12 @@
|
||||||
<div class="span4">
|
<div class="span4">
|
||||||
<ul class="focus_steps">
|
<ul class="focus_steps">
|
||||||
<li>1. Place your material on the working area</li>
|
<li>1. Place your material on the working area</li>
|
||||||
<li>2. Move the pen over the material</li>
|
<li>2. Move the laser over the material</li>
|
||||||
<li>→ Now enable the pen calibration mode</li>
|
<li>3. Put on your safety glasses</li>
|
||||||
<li>5. Adjust the pen until it touches the paper</li>
|
<li>4. Turn the laser safety switch to on</li>
|
||||||
<li>→ Disable the pen calibration mode. </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>
|
</ul>
|
||||||
<div style="text-align:center">
|
<div style="text-align:center">
|
||||||
<div class="btn-group" role="group" aria-label="focus mode control" style="">
|
<div class="btn-group" role="group" aria-label="focus mode control" style="">
|
||||||
|
|
|
||||||
|
|
@ -568,8 +568,8 @@ msgstr ""
|
||||||
"aktualisiert werden."
|
"aktualisiert werden."
|
||||||
|
|
||||||
#: src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js:131
|
#: src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js:131
|
||||||
msgid "Mr Beam Update Available"
|
msgid "Update Available"
|
||||||
msgstr "Mr Beam Aktualisierung verfügbar"
|
msgstr "Aktualisierung verfügbar"
|
||||||
|
|
||||||
#: src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js:143
|
#: src/octoprint/plugins/softwareupdate/static/js/softwareupdate.js:143
|
||||||
msgid "Ignore"
|
msgid "Ignore"
|
||||||
|
|
|
||||||
|
|
@ -84,11 +84,9 @@ class MachineCom(object):
|
||||||
self._actual_intensity = None
|
self._actual_intensity = None
|
||||||
self._feedrate_dict = {}
|
self._feedrate_dict = {}
|
||||||
self._intensity_dict = {}
|
self._intensity_dict = {}
|
||||||
self._passes = 1
|
|
||||||
self._finished_passes = 0
|
|
||||||
|
|
||||||
# regular expressions
|
# regular expressions
|
||||||
self._regex_command = re.compile("^\s*\$?([GM]\d+|[THX])")
|
self._regex_command = re.compile("^\s*\$?([GM]\d+|[TH])")
|
||||||
self._regex_feedrate = re.compile("F\d+", re.IGNORECASE)
|
self._regex_feedrate = re.compile("F\d+", re.IGNORECASE)
|
||||||
self._regex_intensity = re.compile("S\d+", re.IGNORECASE)
|
self._regex_intensity = re.compile("S\d+", re.IGNORECASE)
|
||||||
|
|
||||||
|
|
@ -147,7 +145,7 @@ class MachineCom(object):
|
||||||
elif line.startswith('['): # feedback message
|
elif line.startswith('['): # feedback message
|
||||||
self._handle_feedback_message(line)
|
self._handle_feedback_message(line)
|
||||||
elif line.startswith('Grb'): # Grbl startup message
|
elif line.startswith('Grb'): # Grbl startup message
|
||||||
self._handle_startup_message(line)
|
self._handle_startup_message()
|
||||||
except:
|
except:
|
||||||
self._logger.exception("Something crashed inside the monitoring loop, please report this to Mr. Beam")
|
self._logger.exception("Something crashed inside the monitoring loop, please report this to Mr. Beam")
|
||||||
errorMsg = "See octoprint.log for details"
|
errorMsg = "See octoprint.log for details"
|
||||||
|
|
@ -166,15 +164,8 @@ class MachineCom(object):
|
||||||
if cmd is not None:
|
if cmd is not None:
|
||||||
self.sendCommand(cmd)
|
self.sendCommand(cmd)
|
||||||
self._callback.on_comm_progress()
|
self._callback.on_comm_progress()
|
||||||
else:
|
elif len(self._acc_line_buffer) == 0:
|
||||||
if self._finished_passes >= self._passes:
|
self._set_print_finished()
|
||||||
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()
|
|
||||||
|
|
||||||
self._sendCommand()
|
self._sendCommand()
|
||||||
self._send_event.wait(1)
|
self._send_event.wait(1)
|
||||||
|
|
@ -320,9 +311,7 @@ class MachineCom(object):
|
||||||
if self._finished_currentFile is False:
|
if self._finished_currentFile is False:
|
||||||
line = self._currentFile.getNext()
|
line = self._currentFile.getNext()
|
||||||
if line is None:
|
if line is None:
|
||||||
self._finished_passes += 1
|
self._finished_currentFile = True
|
||||||
if self._finished_passes >= self._passes:
|
|
||||||
self._finished_currentFile = True
|
|
||||||
return line
|
return line
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
@ -405,7 +394,7 @@ class MachineCom(object):
|
||||||
elif line[1:].startswith('Dis'): # [Disabled]
|
elif line[1:].startswith('Dis'): # [Disabled]
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _handle_startup_message(self, line):
|
def _handle_startup_message(self):
|
||||||
if self.isOperational():
|
if self.isOperational():
|
||||||
errorMsg = "Machine reset."
|
errorMsg = "Machine reset."
|
||||||
self._cmd = None
|
self._cmd = None
|
||||||
|
|
@ -420,14 +409,7 @@ class MachineCom(object):
|
||||||
self._changeState(self.STATE_LOCKED)
|
self._changeState(self.STATE_LOCKED)
|
||||||
eventManager().fire(Events.ERROR, {"error": self.getErrorString()})
|
eventManager().fire(Events.ERROR, {"error": self.getErrorString()})
|
||||||
else:
|
else:
|
||||||
versionMatch = re.search("Grbl (?P<grbl>.+?)(_(?P<git>[0-9a-f]{7})(?P<dirty>-dirty)?)? \[.+\]", line)
|
self._onConnected(self.STATE_LOCKED)
|
||||||
if versionMatch:
|
|
||||||
versionDict = versionMatch.groupdict()
|
|
||||||
self._writeGrblVersionToFile(versionDict)
|
|
||||||
if self._compareGrblVersion(versionDict) is False:
|
|
||||||
self._flashGrbl()
|
|
||||||
else:
|
|
||||||
self._onConnected(self.STATE_LOCKED)
|
|
||||||
|
|
||||||
def _update_grbl_pos(self, line):
|
def _update_grbl_pos(self, line):
|
||||||
# line example:
|
# 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]
|
params = ["avrdude", "-patmega328p", "-carduino", "-b" + str(self._baudrate), "-P" + str(self._port), "-D", "-Uflash:w:" + pathToGrblHex]
|
||||||
rc = subprocesscall(params)
|
rc = subprocesscall(params)
|
||||||
|
|
||||||
if rc == 0:
|
if rc is False:
|
||||||
self._log("successfully flashed new grbl version")
|
self._log("successfully flashed new grbl version")
|
||||||
self._openSerial()
|
self._openSerial()
|
||||||
self._changeState(self.STATE_CONNECTING)
|
self._changeState(self.STATE_CONNECTING)
|
||||||
|
|
@ -755,10 +737,6 @@ class MachineCom(object):
|
||||||
self._changeState(self.STATE_HOMING)
|
self._changeState(self.STATE_HOMING)
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
def _gcode_X_sent(self, cmd, cmd_type=None):
|
|
||||||
self._changeState(self.STATE_HOMING) # TODO: maybe change to seperate $X mode
|
|
||||||
return cmd
|
|
||||||
|
|
||||||
def _gcode_Hold_sent(self, cmd, cmd_type=None):
|
def _gcode_Hold_sent(self, cmd, cmd_type=None):
|
||||||
self._changeState(self.STATE_PAUSED)
|
self._changeState(self.STATE_PAUSED)
|
||||||
return cmd
|
return cmd
|
||||||
|
|
@ -849,8 +827,6 @@ class MachineCom(object):
|
||||||
# reset feedrate and intesity factor in case they where changed in a previous run
|
# reset feedrate and intesity factor in case they where changed in a previous run
|
||||||
self._feedrate_factor = 1
|
self._feedrate_factor = 1
|
||||||
self._intensity_factor = 1
|
self._intensity_factor = 1
|
||||||
self._passes = 1
|
|
||||||
self._finished_passes = 0
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# ensure fan is on whatever gcode follows.
|
# ensure fan is on whatever gcode follows.
|
||||||
|
|
@ -921,14 +897,6 @@ class MachineCom(object):
|
||||||
self._send_event.set()
|
self._send_event.set()
|
||||||
eventManager().fire(Events.PRINT_PAUSED, payload)
|
eventManager().fire(Events.PRINT_PAUSED, payload)
|
||||||
|
|
||||||
def increasePasses(self):
|
|
||||||
self._passes += 1
|
|
||||||
self._log("increased Passes to %d" % self._passes)
|
|
||||||
|
|
||||||
def degreasePasses(self):
|
|
||||||
self._passes -= 1
|
|
||||||
self._log("degrease Passes to %d" % self._passes)
|
|
||||||
|
|
||||||
def getStateString(self):
|
def getStateString(self):
|
||||||
if self._state == self.STATE_NONE:
|
if self._state == self.STATE_NONE:
|
||||||
return "Offline"
|
return "Offline"
|
||||||
|
|
@ -1169,9 +1137,6 @@ class PrintingGcodeFileInformation(PrintingFileInformation):
|
||||||
|
|
||||||
if not os.path.exists(self._filename) or not os.path.isfile(self._filename):
|
if not os.path.exists(self._filename) or not os.path.isfile(self._filename):
|
||||||
raise IOError("File %s does not exist" % self._filename)
|
raise IOError("File %s does not exist" % self._filename)
|
||||||
|
|
||||||
self._stripCommments()
|
|
||||||
|
|
||||||
self._size = os.stat(self._filename).st_size
|
self._size = os.stat(self._filename).st_size
|
||||||
self._pos = 0
|
self._pos = 0
|
||||||
|
|
||||||
|
|
@ -1194,12 +1159,6 @@ class PrintingGcodeFileInformation(PrintingFileInformation):
|
||||||
pass
|
pass
|
||||||
self._handle = None
|
self._handle = None
|
||||||
|
|
||||||
def resetToBeginning(self):
|
|
||||||
"""
|
|
||||||
resets the file handle so you can read from the beginning again.
|
|
||||||
"""
|
|
||||||
self._handle = open(self._filename, "r")
|
|
||||||
|
|
||||||
def getNext(self):
|
def getNext(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the next line for printing.
|
Retrieves the next line for printing.
|
||||||
|
|
@ -1225,16 +1184,6 @@ class PrintingGcodeFileInformation(PrintingFileInformation):
|
||||||
self._logger.exception("Exception while processing line")
|
self._logger.exception("Exception while processing line")
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
def _stripCommments(self):
|
|
||||||
dir = os.path.dirname(os.path.abspath(self._filename))
|
|
||||||
tmpfile = open(dir + '/gcode.tmp', 'w')
|
|
||||||
with open(self._filename, "r") as fileobject:
|
|
||||||
for line in fileobject:
|
|
||||||
if process_gcode_line(line) is not None:
|
|
||||||
tmpfile.write(line)
|
|
||||||
tmpfile.close()
|
|
||||||
self._filename = dir + '/gcode.tmp'
|
|
||||||
|
|
||||||
def convert_pause_triggers(configured_triggers):
|
def convert_pause_triggers(configured_triggers):
|
||||||
triggers = {
|
triggers = {
|
||||||
"enable": [],
|
"enable": [],
|
||||||
|
|
@ -1299,7 +1248,6 @@ def serialList():
|
||||||
baselist = baselist \
|
baselist = baselist \
|
||||||
+ glob.glob("/dev/ttyUSB*") \
|
+ glob.glob("/dev/ttyUSB*") \
|
||||||
+ glob.glob("/dev/ttyACM*") \
|
+ glob.glob("/dev/ttyACM*") \
|
||||||
+ glob.glob("/dev/ttyAMA*") \
|
|
||||||
+ glob.glob("/dev/tty.usb*") \
|
+ glob.glob("/dev/tty.usb*") \
|
||||||
+ glob.glob("/dev/cu.*") \
|
+ glob.glob("/dev/cu.*") \
|
||||||
+ glob.glob("/dev/cuaU*") \
|
+ glob.glob("/dev/cuaU*") \
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue