-
Notifications
You must be signed in to change notification settings - Fork 23
/
M144
executable file
·152 lines (126 loc) · 3.88 KB
/
M144
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env python
import os, sys, time, glob
from subprocess import *
from itertools import *
from PIL import Image
from raster_utils import *
from raster_gui import *
import linuxcnc
P, Q = map(lambda x: float(x), sys.argv[1:])
try:
INI_FILE_NAME = os.environ['INI_FILE_NAME']
except KeyError:
INI_FILE_NAME = '2x_Laser.ini'
try:
ini = linuxcnc.ini(INI_FILE_NAME)
except linuxcnc.error:
fatal('Expected LinuxCNC configuration in %s' % INI_FILE_NAME)
linuxcnc.nmlfile = ini.find('EMC', 'NML_FILE')
if linuxcnc.nmlfile is None:
fatal('Expected [EMC]NML_FILE in INI')
axis = ini.find('RASTER', 'AXIS')
if axis is None:
axis = 0
stat = linuxcnc.stat()
# Get the G92 and G5x work offsets so we can translate
stat.poll()
origin = stat.g5x_offset[axis] + stat.g92_offset[axis]
if stat.current_line < 0:
fatal('cannot execute M144 from MDI')
if False:
# Unfortunately when M144 is invoked from inside O145 the stat.file
# is the 145.ngc file rather than the original source. Previously
# there was clever code to extract the filename from the comment on
# the M144 line.
image_name = get_comment(stat.file, stat.current_line)
dirname = os.path.dirname(stat.file)
image_name = os.path.normpath(os.path.join(dirname, image_name))
else:
IMAGE_PATH = ini.find('RASTER', 'IMAGE_PATH')
if IMAGE_PATH is None:
IMAGE_PATH = os.environ['HOME']
IMAGE_PATH = IMAGE_PATH.split(os.path.pathsep)
image_name = None
for dir in IMAGE_PATH:
images = glob.glob(os.path.join(dir, '*-%u.*' % int(P)))
if images:
image_name = images[0]
if image_name is None:
image_name = image_not_found(int(P))
print 'image = %s' % image_name
if os.fork():
# parent must wait until child is ready, then exit
#...
time.sleep(1)
sys.exit(0)
else:
os.setsid()
streamer = Popen(['halstreamer'], stdin=PIPE)
stream = streamer.stdin
image = Image.open(image_name)
# wait for M145 to send us the image info
X, Y = recv_params()
W, ROWS = recv_params()
XSCANGAP, YSCANGAP = recv_params()
# program units are 1:inch, 2:mm, while linear_units are 0:inch, 1:mm
if stat.program_units == 1 and stat.linear_units == 1:
scale = 25.4
elif stat.program_units == 2 and stat.linear_units == 0:
scale = 1/25.4
else:
scale = 1
X *= scale
Y *= scale
W *= scale
#H *= scale
XSCANGAP *= scale
YSCANGAP *= scale
x_mmpd = XSCANGAP
y_mmpd = YSCANGAP
origin += X
pix_w = int(W / x_mmpd)
pix_h = int(ROWS + 0.5)
W = pix_w * x_mmpd
reverse_fudge = 0.0
print 'rescaling to %u,%u' % (pix_w, pix_h)
#XXX
image = image.resize((pix_w, pix_h), Image.BICUBIC).convert('1')
#image = image.resize((pix_w, pix_h), Image.NEAREST).convert('1')
image.save('actual.png')
# XXX possibly rotate based on axis
pix = list(image.getdata())
for y in xrange(0,pix_h):
forward = (y & 1) == 0
# laser is off until cued for this line:
if forward:
stream.write('0 1 %0.3f\n' % (origin))
else:
stream.write('0 0 %0.3f\n' % (origin + W + x_mmpd))
row = pix[y * pix_w:(y + 1) * pix_w]
groups = map(lambda (v,run): (v, len(list(run))), groupby(row))
if forward:
x = 0
else:
groups.reverse()
x = pix_w
for v, run in groups:
if (v <= 127):
# off until we hit start / on until end
if forward:
stream.write('0 0 %0.3f\n' % (origin + x * x_mmpd))
stream.write('1 0 %0.3f\n' % (origin + (x + run) * x_mmpd))
else:
stream.write('0 1 %0.3f\n' % (origin + x * x_mmpd + reverse_fudge))
stream.write('1 1 %0.3f\n' % (origin + (x - run) * x_mmpd + reverse_fudge))
if forward:
x += run
else:
x -= run
# finally: laser is off once clearing raster area
if forward:
stream.write('0 0 %0.3f\n' % (origin + W + x_mmpd))
else:
stream.write('0 1 %0.3f\n' % (origin))
stream.close()
streamer.wait()
print 'DONE!'