Merge pull request #73 from mrbeam/mrbeam-dev-textInSvg

Mrbeam dev text in svg
This commit is contained in:
Clem 2016-07-01 10:10:31 +02:00 committed by GitHub
commit 75f69dd0df
7 changed files with 98 additions and 46 deletions

View file

@ -357,6 +357,8 @@ class SvgToGcodePlugin(octoprint.plugin.SlicerPlugin,
converter_path = '/home/teja/workspace/mrbeam-inkscape-ext' converter_path = '/home/teja/workspace/mrbeam-inkscape-ext'
elif("denkbrett" in hostname): elif("denkbrett" in hostname):
converter_path = '/home/flo/mrbeam/git/mrbeam-inkscape-ext' converter_path = '/home/flo/mrbeam/git/mrbeam-inkscape-ext'
elif ("clems-Air" in hostname):
converter_path = '/Users/clem/Dropbox/mrBeam/mrbeam-inkscape-ext'
import sys import sys
sys.path.append(converter_path) sys.path.append(converter_path)

View file

@ -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 = {

View file

@ -41,8 +41,10 @@ $(function(){
// image engraving stuff // image engraving stuff
// preset values are a good start for wood engraving // preset values are a good start for wood engraving
self.images_placed = ko.observable(false); self.images_placed = ko.observable(false);
self.text_placed = ko.observable(false);
self.show_image_parameters = ko.computed(function(){ self.show_image_parameters = ko.computed(function(){
return self.images_placed() || (self.fill_areas() && self.show_vector_parameters()); return (self.images_placed() || self.text_placed()
|| (self.fill_areas() && self.show_vector_parameters()));
}); });
self.imgIntensityWhite = ko.observable(0); self.imgIntensityWhite = ko.observable(0);
self.imgIntensityBlack = ko.observable(500); self.imgIntensityBlack = ko.observable(500);
@ -85,6 +87,7 @@ $(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()){

View file

@ -30,8 +30,12 @@ Snap.plugin(function (Snap, Element, Paper, global) {
*/ */
Element.prototype.bake = function (toCubics, dec) { Element.prototype.bake = function (toCubics, dec) {
var elem = this; var elem = this;
if (!elem || !elem.paper) // don't handle unplaced elements. this causes double handling.
console.log("ElemType: "+elem.type+" "+elem.id+" Children: "+elem.children().length);
if (!elem || !elem.paper || elem.type !== "text" || elem.type !== "#text" || elem.type !== "tspan"){
console.log("Skip not on paper!");
return; return;
} // don't handle unplaced elements. this causes double handling.
if (typeof (toCubics) === 'undefined') if (typeof (toCubics) === 'undefined')
toCubics = false; toCubics = false;
@ -42,9 +46,10 @@ Snap.plugin(function (Snap, Element, Paper, global) {
if (children.length > 0) { if (children.length > 0) {
for (var i = 0; i < children.length; i++) { for (var i = 0; i < children.length; i++) {
var child = children[i]; var child = children[i];
console.log("ChildType "+i+": "+child.type+" "+child.id+" Children: "+child.children().length);
child.bake(toCubics, dec); child.bake(toCubics, dec);
} }
elem.attr({transform: ''}); /*if(child.type !== "#text") */elem.attr({transform: ''});
return; return;
} }
if (elem.type !== "circle" && if (elem.type !== "circle" &&
@ -54,14 +59,44 @@ 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" &&
elem.type !== "#text"){
// if(elem.type !== 'g' && elem.type !== 'desc' && elem.type !== 'defs') // if(elem.type !== 'g' && elem.type !== 'desc' && elem.type !== 'defs')
// console.log('skipping unsupported element ', elem.type); // console.log('skipping unsupported element ', elem.type);
return; return;
} }
if (elem.type == 'image'){ // if (elem.type == "text" || elem.type == "#text"){
// var x = parseFloat(elem.attr('x')),
// y = parseFloat(elem.attr('y')),
// w = parseFloat(elem.attr('width')),
// h = parseFloat(elem.attr('height'));
//
// // Validity checks from http://www.w3.org/TR/SVG/shapes.html#RectElement:
// // If 'x' and 'y' are not specified, then set both to 0. // CorelDraw is creating that sometimes
// if (!isFinite(x)) {
// console.log('No attribute "x" in image tag. Assuming 0.')
// x = 0;
// }
// if (!isFinite(y)) {
// console.log('No attribute "y" in image tag. Assuming 0.')
// y = 0;
// }
// var transform = elem.transform();
// var matrix = transform['totalMatrix'];
// var transformedX = matrix.x(x, y);
// var transformedY = matrix.y(x, y);
// var transformedW = matrix.x(x+w, y+h) - transformedX;
// var transformedH = matrix.y(x+w, y+h) - transformedY;
//
// elem.attr({x: transformedX, y: transformedY, width: transformedW, height: transformedH});
// return;
// }
if (elem.type == 'image' || elem.type == "text" || elem.type == "#text"){
// TODO ... // TODO ...
var x = parseFloat(elem.attr('x')), var x = parseFloat(elem.attr('x')),
y = parseFloat(elem.attr('y')), y = parseFloat(elem.attr('y')),

View file

@ -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'){ if(elem.type === 'image' || elem.type === "text" || elem.type === "#text"){
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,14 +74,17 @@ 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;
@ -89,7 +92,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;
@ -113,9 +116,9 @@ 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;
@ -129,7 +132,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');

View file

@ -410,7 +410,7 @@ $(function(){
}; };
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/>Please convert them to paths.<br/>Otherwise they will be ignored.") + "</p>"; 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>";
//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",
@ -418,7 +418,6 @@ $(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){
@ -724,6 +723,16 @@ $(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) {
@ -846,7 +855,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') { if (item.type === 'image' || item.type === "text" || item.type === "#text") {
// remove filter effects on images for proper rendering // remove filter effects on images for proper rendering
var style = item.attr('style'); var style = item.attr('style');
if (style !== null) { if (style !== null) {

View file

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