--- a/printrun-src/printrun/laser.py Thu Jul 07 11:58:38 2016 +0200 +++ b/printrun-src/printrun/laser.py Fri Jul 28 15:56:52 2017 +0200 @@ -1,6 +1,6 @@ """ Lasercutter library -2015/2016 by NeoSoft, Malte Bayer +2015-2016 by NeoSoft, Malte Di Donato Intended to use standalone or implemented in Pronterface/Printrun """ @@ -301,31 +301,75 @@ tree = ET.parse(filename) root = tree.getroot() - width = root.get('width') - height = root.get('height') - if width == None or height == None: - viewbox = root.get('viewBox') - if viewbox: - _, _, width, height = viewbox.split() + # Todo: force viewbox values configurable? + #width = root.get('width') + #height = root.get('height') + # if width == None or height == None: + viewbox = root.get('viewBox') + if viewbox: + _, _, width, height = viewbox.split() if width == None or height == None: self.log("Unable to get width and height for the svg!") return False + else: + self.log("SVG Dimensions are %s x %s" % (width, height)) # TODO: use cm or mm as absolute dimensions! width = float(width.replace("px", "").replace("pt", "").replace("mm", "")) height = float(height.replace("px", "").replace("pt", "").replace("mm", "")) + smoothness = self.settings.lc_svg_smoothness if smoothness < 0.1: smoothness = 0.1 + # get the minimum x and y values to get an offset to 0,0 + ofs_x = 99999999999.0 + ofs_y = 99999999999.0 + max_x = -99999999999.0 + max_y = -99999999999.0 + for elem in root.iter(): + try: + _, tag_suffix = elem.tag.split('}') + except ValueError: + continue + if tag_suffix in svg_shapes: + shape_class = getattr(shapes_pkg, tag_suffix) + shape_obj = shape_class(elem) + d = shape_obj.d_path() + m = shape_obj.transformation_matrix() + + if d: + p = point_generator(d, m, smoothness) + start = True + for x,y,pen in p: + if x < ofs_x: + ofs_x = x + if y < ofs_y: + ofs_y = y + if x > max_x: + max_x = x + if y > max_y: + max_y = y + ofs_x *= -1 + ofs_y *= -1 + max_x += ofs_x + max_y += ofs_y + self.log("Calculated Offset to 0,0 is %f,%f" % (ofs_x, ofs_y)) + + """ + self.log("Calculated Dimension is %f,%f" % (max_x, max_y)) + width = max_x + height = max_y + """ + bed_max_x = self.settings.lc_svg_width bed_max_y = self.settings.lc_svg_height if self.settings.lc_svg_scalemode == "scale": scale_x = scale_y = min(bed_max_x, bed_max_y) / max(width, height) else: - scale_x = bed_max_x / max(width, height) - scale_y = bed_max_y / max(width, height) + scale_x = bed_max_x / width + scale_y = bed_max_y / height self.log("Scaling factor: %.2f, %.2f" % (scale_x,scale_y)) @@ -335,6 +379,7 @@ travel_speed = self.settings.lc_travel_speed * 60 engrave_speed = self.settings.lc_engrave_speed * 60 * self.settings.lc_svg_speed_factor + for elem in root.iter(): try: _, tag_suffix = elem.tag.split('}') @@ -342,6 +387,7 @@ continue if tag_suffix in svg_shapes: + self.log("Parsing shape: %s" % tag_suffix) shape_class = getattr(shapes_pkg, tag_suffix) shape_obj = shape_class(elem) d = shape_obj.d_path() @@ -356,13 +402,15 @@ p = point_generator(d, m, smoothness) start = True for x,y,pen in p: - y = height - y + x += ofs_x + y += ofs_y + y = height - y # invert the bed xs = scale_x * x ys = scale_y * y if xo == xs and yo == ys: continue if not pen: start = True - if xs >= 0 and xs <= bed_max_x and ys >= 0 and ys <= bed_max_y: + if xs >= 0 and xs <= bed_max_x+0.1 and ys >= 0 and ys <= bed_max_y+0.1: if start: fo.write("G0 X%0.2f Y%0.2f F%.4f ; Move to start of shape\n" % ( xs, ys, travel_speed)) @@ -378,8 +426,8 @@ E = E + (e_distance) fo.write("G1 X%0.2f Y%0.2f E%.4f F%.4f\n" % ( xs, ys, E * E_FACTOR, engrave_speed)) - #else: - # self.log("Position outside print dimension: %d, %d" % (xs, ys)) + else: + self.log("Position outside print dimension: %d, %d" % (xs, ys)) if shape_obj.xml_node.get('fill'): # Close the polygon