2022-06-13 14:37:46 +02:00
#!/usr/bin/python
2022-06-13 12:45:47 +02:00
from __future__ import absolute_import
from __future__ import print_function
import sys
2022-06-13 14:37:46 +02:00
import os
2022-06-13 12:45:47 +02:00
import xml . etree . ElementTree as ET
import shapes as shapes_pkg
from shapes import point_generator
from config import *
2022-06-13 15:19:01 +02:00
debug = True
2022-06-13 22:48:51 +02:00
example_usage = " -i test_data/Test_H.svg -o test_data/test.gcode -fr 300 -mr 1200 -p 1 -lp 20 % "
2022-06-13 15:19:01 +02:00
svg_shapes = set ( [ ' rect ' , ' circle ' , ' ellipse ' , ' line ' , ' polyline ' , ' polygon ' , ' path ' ] )
2022-06-14 15:28:00 +02:00
global conf
2022-06-13 15:19:01 +02:00
2022-06-13 15:35:59 +02:00
def gcode_write ( gcode_file , gcode ) :
2022-06-13 15:19:01 +02:00
if ( debug ) :
for cmd in gcode . split ( " \n " ) :
if len ( cmd ) :
print ( " [GCODE] " + str ( cmd ) )
gcode_file . write ( gcode )
def close_on_failure ( ) :
os . remove ( gcode_file_path )
sys . exit ( 1 )
2022-06-13 14:37:46 +02:00
2022-06-14 15:28:00 +02:00
def laserpower_to_pwm ( percent ) :
if ( percent < = 1 ) :
return int ( percent * 255 )
else :
return 0
2022-06-13 14:37:46 +02:00
def read_input_file ( svg_file_path ) :
try :
tree = ET . parse ( svg_file_path )
return tree . getroot ( )
except Exception as e :
print ( " unable to read svg file: \n " + str ( e ) )
sys . exit ( 1 )
2022-06-13 15:35:59 +02:00
def generate_gcode ( svg_file_root_tree , gcode_file ) :
generated_points_count = 0
2022-06-13 14:37:46 +02:00
width = svg_file_root_tree . get ( ' width ' )
height = svg_file_root_tree . get ( ' height ' )
2022-06-13 12:45:47 +02:00
if width == None or height == None :
2022-06-13 14:37:46 +02:00
viewbox = svg_file_root_tree . get ( ' viewBox ' )
2022-06-13 12:45:47 +02:00
if viewbox :
2022-06-13 15:19:01 +02:00
if ( debug ) : print ( " Using viewbox size " )
2022-06-13 12:45:47 +02:00
_ , _ , width , height = viewbox . split ( )
if width == None or height == None :
print ( " Unable to get width and height for the svg " )
2022-06-13 15:19:01 +02:00
close_on_failure ( )
2022-06-13 12:45:47 +02:00
width = float ( width . split ( " mm " ) [ 0 ] )
height = float ( height . split ( " mm " ) [ 0 ] )
2022-06-13 15:19:01 +02:00
print ( " [SVG loaded] With: " + str ( width ) + " mm Height: " + str ( height ) + " mm " )
2022-06-13 14:37:46 +02:00
2022-06-13 15:19:01 +02:00
#generate start cmds's
2022-06-14 15:28:00 +02:00
gcode_write ( gcode_file , conf . preamble )
2022-06-13 14:37:46 +02:00
2022-06-13 15:35:59 +02:00
2022-06-13 14:37:46 +02:00
for elem in svg_file_root_tree . iter ( ) :
2022-06-13 12:45:47 +02:00
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 )
2022-06-13 15:35:59 +02:00
obj_path = shape_obj . d_path ( )
obj_trans_matrix = shape_obj . transformation_matrix ( )
2022-06-14 15:28:00 +02:00
gcode_write ( gcode_file , " G0 F " + str ( conf . moverate ) + " set the moverate to " + str ( conf . moverate ) + " mm/min; \n " )
2022-06-13 15:35:59 +02:00
if obj_path :
gcode_write ( gcode_file , " ; == Start of " + tag_suffix + " == \n " )
2022-06-14 15:28:00 +02:00
points = point_generator ( obj_path , obj_trans_matrix , conf . smoothness )
2022-06-13 15:35:59 +02:00
num_points = 0
for x , y in points :
if ( debug ) : print ( " [Point] X: " + str ( x ) + " Y: " + str ( y ) )
2022-06-14 15:28:00 +02:00
if x > 0 and x < conf . bedsizex and y > 0 and y < conf . bedsizey :
2022-06-13 15:35:59 +02:00
gcode_write ( gcode_file , " G1 X %0.001f Y %0.001f \n " % ( x , y ) )
2022-06-13 12:45:47 +02:00
num_points + = 1
2022-06-13 15:35:59 +02:00
if ( num_points == 1 ) :
2022-06-14 15:28:00 +02:00
gcode_write ( gcode_file , " G0 F " + str ( conf . feedrate ) + " set the feedrate to " + str ( conf . feedrate ) + " mm/min; \n " )
gcode_write ( gcode_file , " M3 I S " + str ( laserpower_to_pwm ( conf . laserpower ) ) + " ;start laser \n " )
2022-06-13 15:35:59 +02:00
elif ( debug ) :
2022-06-13 15:19:01 +02:00
print ( " \n ; Coordinates out of range: " , " G1 X %0.01f Y %0.01f " % ( x , y ) )
print ( " ; Raw: " , str ( x ) , str ( y ) , " \n Scaled: " , str ( x ) , str ( y ) , " \n " )
close_on_failure ( )
2022-06-13 15:35:59 +02:00
gcode_write ( gcode_file , " M5 ;stop laser \n " )
gcode_write ( gcode_file , " ; == End of " + tag_suffix + " == \n " )
generated_points_count + = num_points
2022-06-14 15:28:00 +02:00
gcode_write ( gcode_file , " G0 F " + str ( conf . moverate ) + " set the moverate to " + str ( conf . moverate ) + " mm/min; \n " )
gcode_write ( gcode_file , conf . postamble )
2022-06-13 15:35:59 +02:00
print ( " \n Generated " , generated_points_count , " points " )
2022-06-13 12:45:47 +02:00
if __name__ == " __main__ " :
2022-06-13 14:37:46 +02:00
sys . setrecursionlimit ( 20000 ) #needed for svg's with more indepented paths
2022-06-14 15:28:00 +02:00
conf = Config ( )
conf . parse_arguments ( )
2022-06-13 14:37:46 +02:00
try :
2022-06-14 15:28:00 +02:00
with open ( conf . gcode_file_path , ' w ' ) as gcode_file :
generate_gcode ( read_input_file ( conf . svg_file_path ) , gcode_file )
2022-06-13 14:37:46 +02:00
except Exception as e :
print ( " unable to create gcode file: \n " + str ( e ) )
2022-06-13 15:19:01 +02:00
close_on_failure ( )
2022-06-13 12:45:47 +02:00