Click here to surface your spoil board with this one easy Python Script

OK, I don’t want to do that conversationally again, so I certainly want a generator. It’s probably quicker to write one than to search for one that works the way I want.

$ ./generate-surface.py --help
usage: generate-surface.py [-h] [--x-max X_MAX] [--y-max Y_MAX]
                           [--pitch PITCH] [--feed FEED] [--z-depth Z_DEPTH]
                           [--safe SAFE]

Generate gcode for spoilboard surfacing.

optional arguments:
  -h, --help            show this help message and exit
  --x-max X_MAX, -x X_MAX
                        X working width
  --y-max Y_MAX, -y Y_MAX
                        Y working width
  --pitch PITCH, -p PITCH
                        Pitch of passes/step over
  --feed FEED, -f FEED  Horizontal feed
  --z-depth Z_DEPTH, -z Z_DEPTH
                        Z depth to cut
  --safe SAFE, -s SAFE  Safe Z height
#!/usr/bin/python

import argparse

parser = argparse.ArgumentParser(description='Generate gcode for spoilboard surfacing.')
parser.add_argument('--x-max', '-x', type=int, help='X working width')
parser.add_argument('--y-max', '-y', type=int, help='Y working width')
parser.add_argument('--pitch', '-p', type=int, help='Pitch of passes/step over')
parser.add_argument('--feed', '-f', type=int, help='Horizontal feed')
parser.add_argument('--z-depth', '-z', type=float, help='Z depth to cut')
parser.add_argument('--safe', '-s', type=float, help='Safe Z height')
args = parser.parse_args()
v = vars(args)

def steps(end):
    s = [x for x in range(0, end, args.pitch)]
    if s[-1] != end:
        # end not a multiple of pitch
        s.append(end)
    return s

x_steps = steps(args.x_max)
y_steps = steps(args.y_max)

print('G0 Z{safe}'.format(**v))
print('G0 X0 Y0')
print('G1 Z{z_depth} X{pitch} F{feed}'.format(**v))
print('G1 Z{z_depth} X0'.format(**v))

for y in y_steps:
    print('G1 Y{}'.format(y))
    print('G1 X{x_max}'.format(**v))
    print('G0 X0')

print('G0 Y0')
for x in x_steps[1:]: # X0 step already effectively run
    print('G1 X{}'.format(x))
    print('G1 Y{y_max}'.format(**v))
    print('G0 Y0')

print('G0 Z{safe} X0'.format(**v))

This intentionally does rapids over already-cut surface. You can change a few G0 to G1 if you don’t like that and it will then honor the feed rate for everything. I didn’t add a vertical feed rate because the ease-down should be dominated by the pitch anyway, so plunge rate isn’t a concern. I think.

This rang bells, so I had to do a quick search… :grinning:

1 Like