2424
2525class Plotter (object ):
2626 def __init__ (self , xyMin = (7 ,8 ), xyMax = (204 ,178 ),
27- drawSpeed = 35 , moveSpeed = 40 , zSpeed = 5 , workZ = 14.5 , liftDeltaZ = 2.5 , safeDeltaZ = 20 ):
27+ drawSpeed = 35 , moveSpeed = 40 , zSpeed = 5 , workZ = 14.5 , liftDeltaZ = 2.5 , safeDeltaZ = 20 ,
28+ liftCommand = None , safeLiftCommand = None , downCommand = None , comment = ";" ):
2829 self .xyMin = xyMin
2930 self .xyMax = xyMax
3031 self .drawSpeed = drawSpeed
@@ -33,6 +34,9 @@ def __init__(self, xyMin=(7,8), xyMax=(204,178),
3334 self .liftDeltaZ = liftDeltaZ
3435 self .safeDeltaZ = safeDeltaZ
3536 self .zSpeed = zSpeed
37+ self .liftCommand = liftCommand
38+ self .safeLiftCommand = safeLiftCommand
39+ self .downCommand = downCommand
3640
3741 def inRange (self , point ):
3842 for i in range (2 ):
@@ -50,10 +54,10 @@ def penUpZ(self):
5054
5155def gcodeHeader (plotter ):
5256 gcode = []
53- gcode .append ('G0 S1; endstops' )
54- gcode .append ('G0 E0; no extrusion' )
55- gcode .append ('G1 S1; endstops' )
56- gcode .append ('G1 E0; no extrusion' )
57+ gcode .append ('G00 S1; endstops' )
58+ gcode .append ('G00 E0; no extrusion' )
59+ gcode .append ('G01 S1; endstops' )
60+ gcode .append ('G01 E0; no extrusion' )
5761 gcode .append ('G21; millimeters' )
5862 gcode .append ('G91 G0 F%.1f Z%.3f; pen park !!Zsafe' % (plotter .zSpeed * 60. , plotter .safeDeltaZ ))
5963 gcode .append ('G90; absolute' )
@@ -123,7 +127,7 @@ def scalePoint(self, point):
123127 return (point [0 ]* self .scale [0 ]+ self .offset [0 ], point [1 ]* self .scale [1 ]+ self .offset [1 ])
124128
125129def comparison (a ,b ):
126- return ( a > b ) - ( a < b )
130+ return 1 if a > b else ( - 1 if a < b else 0 )
127131
128132def safeSorted (data ,comparison = comparison ):
129133 """
@@ -134,8 +138,8 @@ def safeSorted(data,comparison=comparison):
134138 n = len (data )
135139 if n <= 1 :
136140 return list (data )
137- d1 = safeSorted (data [:n // 2 ])
138- d2 = safeSorted (data [n // 2 :])
141+ d1 = safeSorted (data [:n // 2 ], comparison = comparison )
142+ d2 = safeSorted (data [n // 2 :], comparison = comparison )
139143 i1 = 0
140144 i2 = 0
141145 out = []
@@ -345,12 +349,15 @@ def emitGcode(data, pens = {}, plotter=Plotter(), scalingMode=SCALE_NONE, align
345349
346350 def park ():
347351 if not simulation :
348- gcode .append ('G0 F%.1f Z%.3f; pen park !!Zpark' % (plotter .zSpeed * 60. , plotter .safeUpZ ))
352+ if plotter .safeLiftCommand :
353+ gcode .append (plotter .safeLiftCommand )
354+ else :
355+ gcode .append ('G00 F%.1f Z%.3f; pen park !!Zpark' % (plotter .zSpeed * 60. , plotter .safeUpZ ))
349356
350357 park ()
351358 if not simulation :
352- gcode .append ('G0 F%.1f Y%.3f; !!Ybottom' % (plotter .moveSpeed * 60. , plotter .xyMin [1 ]))
353- gcode .append ('G0 F%.1f X%.3f; !!Xleft' % (plotter .moveSpeed * 60. , plotter .xyMin [0 ]))
359+ gcode .append ('G00 F%.1f Y%.3f; !!Ybottom' % (plotter .moveSpeed * 60. , plotter .xyMin [1 ]))
360+ gcode .append ('G00 F%.1f X%.3f; !!Xleft' % (plotter .moveSpeed * 60. , plotter .xyMin [0 ]))
354361
355362 class State (object ):
356363 pass
@@ -365,17 +372,21 @@ def distance(a,b):
365372 return math .hypot (a [0 ]- b [0 ],a [1 ]- b [1 ])
366373
367374 def penUp (force = False ):
368- if state .curZ is None or state .curZ < plotter .penUpZ or force :
375+ if not simulation and plotter .liftCommand :
376+ gcode .append (plotter .liftCommand )
377+ elif state .curZ is None or state .curZ < plotter .penUpZ or force :
369378 if not simulation :
370- gcode .append ('G0 F%.1f Z%.3f; pen up !!Zup' % (plotter .zSpeed * 60. , plotter .penUpZ ))
379+ gcode .append ('G00 F%.1f Z%.3f; pen up !!Zup' % (plotter .zSpeed * 60. , plotter .penUpZ ))
371380 if state .curZ is not None :
372381 state .time += abs (plotter .penUpZ - state .curZ ) / plotter .zSpeed
373382 state .curZ = plotter .penUpZ
374383
375384 def penDown (force = False ):
385+ if not simulation and plotter .downCommand :
386+ gcode .append (plotter .downCommand )
376387 if state .curZ is None or state .curZ != plotter .workZ or force :
377388 if not simulation :
378- gcode .append ('G0 F%.1f Z%.3f; pen down !!Zwork' % (plotter .zSpeed * 60. , plotter .workZ ))
389+ gcode .append ('G00 F%.1f Z%.3f; pen down !!Zwork' % (plotter .zSpeed * 60. , plotter .workZ ))
379390 state .time += abs (state .curZ - plotter .workZ ) / plotter .zSpeed
380391 state .curZ = plotter .workZ
381392
@@ -392,7 +403,7 @@ def flip(y):
392403 else :
393404 penUp (force = force )
394405 if not simulation :
395- gcode .append ('G %d F%.1f X%.3f Y%.3f; %s !!Xleft+%.3f Ybottom+%.3f' % (
406+ gcode .append ('G0 %d F%.1f X%.3f Y%.3f; %s !!Xleft+%.3f Ybottom+%.3f' % (
396407 1 if down else 0 , speed * 60. , p [0 ], p [1 ], "draw" if down else "move" ,
397408 p [0 ]- plotter .xyMin [0 ], p [1 ]- plotter .xyMin [1 ]))
398409 else :
@@ -630,6 +641,21 @@ def directionalize(paths, angle, tolerance=1e-10):
630641 outPaths .append (list (reversed (path [startIndex :i ])))
631642
632643 return outPaths
644+
645+ def fixComments (plotter , data , comment = ";" ):
646+ if comment == ";" :
647+ return data
648+ out = []
649+ for line in data :
650+ ind = line .index (";" )
651+ if ind >= 0 :
652+ if not plotter .comment :
653+ out .append ( ind [:ind ].strip () )
654+ else :
655+ out .append ( ind [:ind ] + comment [0 ] + ind [ind + 1 :] + comment [1 :] )
656+ else :
657+ out .append (data )
658+ return out
633659
634660if __name__ == '__main__' :
635661
@@ -672,6 +698,7 @@ def help(error=False):
672698 -P|--pens=penfile: read output pens from penfile
673699 -U|--pause-at-start*: pause at start (can be included without any input file to manually move stuff)
674700 -R|--extract-color=c: extract color (specified in SVG format , e.g., rgb(1,0,0) or #ff0000 or red)
701+ --comment-delimiters=xy: one or two characters specifying comment delimiters, e.g., ";" or "()"
675702 --tool-offset=x: cutting tool offset (millimeters) [default 0.0]
676703 --overcut=x: overcut (millimeters) [default 0.0]
677704
@@ -705,6 +732,7 @@ def help(error=False):
705732 toolMode = "custom"
706733 booleanExtractColor = False
707734 quiet = False
735+ comments = ";"
708736 sendAndSave = False
709737 directionAngle = None
710738
@@ -957,6 +985,7 @@ def help(error=False):
957985 print ('overcut=%.3f' % overcut )
958986 print ('simulation' if svgSimulation else 'no-simulation' )
959987 print ('direction=' + ('none' if directionAngle is None else '%.3f' % directionAngle ))
988+ print ('comments=' + comments )
960989
961990 sys .exit (0 )
962991
@@ -1061,7 +1090,7 @@ def help(error=False):
10611090 if hpglOut :
10621091 sys .stdout .write (g )
10631092 else :
1064- print ('\n ' .join (g ))
1093+ print ('\n ' .join (fixComments ( plotter , g , comments = comments ) ))
10651094
10661095 else :
10671096 sys .stderr .write ("No points." )
0 commit comments