Thu, 30 May 2019 19:02:52 +0200
bugfixes on rastered image column endings, force laser off with G0 + little offset
15 | 1 | # This file is copied from GCoder. |
2 | # | |
3 | # GCoder is free software: you can redistribute it and/or modify | |
4 | # it under the terms of the GNU General Public License as published by | |
5 | # the Free Software Foundation, either version 3 of the License, or | |
6 | # (at your option) any later version. | |
7 | # | |
8 | # GCoder is distributed in the hope that it will be useful, | |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
12 | # | |
13 | # You should have received a copy of the GNU General Public License | |
14 | # along with Printrun. If not, see <http://www.gnu.org/licenses/>. | |
15 | ||
16 | from libc.stdlib cimport malloc, free | |
17 | from libc.stdint cimport uint8_t, uint32_t | |
18 | from libc.string cimport strlen, strncpy | |
19 | ||
20 | cdef char* copy_string(object value): | |
21 | cdef char* orig = value | |
22 | str_len = len(orig) | |
23 | cdef char* array = <char *>malloc(str_len + 1) | |
24 | strncpy(array, orig, str_len) | |
25 | array[str_len] = 0; | |
26 | return array | |
27 | ||
28 | cdef enum BitPos: | |
29 | pos_raw = 1 << 0 | |
30 | pos_command = 1 << 1 | |
31 | pos_is_move = 1 << 2 | |
32 | pos_x = 1 << 3 | |
33 | pos_y = 1 << 4 | |
34 | pos_z = 1 << 5 | |
35 | pos_e = 1 << 6 | |
36 | pos_f = 1 << 7 | |
37 | pos_i = 1 << 8 | |
38 | pos_j = 1 << 9 | |
39 | pos_relative = 1 << 10 | |
40 | pos_relative_e = 1 << 11 | |
41 | pos_extruding = 1 << 12 | |
42 | pos_current_x = 1 << 13 | |
43 | pos_current_y = 1 << 14 | |
44 | pos_current_z = 1 << 15 | |
45 | pos_current_tool = 1 << 16 | |
46 | pos_gcview_end_vertex = 1 << 17 | |
47 | # WARNING: don't use bits 24 to 31 as we store current_tool there | |
48 | ||
49 | cdef inline uint32_t has_var(uint32_t status, uint32_t pos): | |
50 | return status & pos | |
51 | ||
52 | cdef inline uint32_t set_has_var(uint32_t status, uint32_t pos): | |
53 | return status | pos | |
54 | ||
55 | cdef inline uint32_t unset_has_var(uint32_t status, uint32_t pos): | |
56 | return status & ~pos | |
57 | ||
58 | cdef class GLine: | |
59 | ||
60 | cdef char* _raw | |
61 | cdef char* _command | |
62 | cdef float _x, _y, _z, _e, _f, _i, _j | |
63 | cdef float _current_x, _current_y, _current_z | |
64 | cdef uint32_t _gcview_end_vertex | |
65 | cdef uint32_t _status | |
66 | ||
67 | __slots__ = () | |
68 | ||
69 | def __cinit__(self): | |
70 | self._status = 0 | |
71 | self._raw = NULL | |
72 | self._command = NULL | |
73 | ||
74 | def __init__(self, line): | |
75 | self.raw = line | |
76 | ||
77 | def __dealloc__(self): | |
78 | if self._raw != NULL: free(self._raw) | |
79 | if self._command != NULL: free(self._command) | |
80 | ||
81 | property x: | |
82 | def __get__(self): | |
83 | if has_var(self._status, pos_x): return self._x | |
84 | else: return None | |
85 | def __set__(self, value): | |
86 | self._x = value | |
87 | self._status = set_has_var(self._status, pos_x) | |
88 | property y: | |
89 | def __get__(self): | |
90 | if has_var(self._status, pos_y): return self._y | |
91 | else: return None | |
92 | def __set__(self, value): | |
93 | self._y = value | |
94 | self._status = set_has_var(self._status, pos_y) | |
95 | property z: | |
96 | def __get__(self): | |
97 | if has_var(self._status, pos_z): return self._z | |
98 | else: return None | |
99 | def __set__(self, value): | |
100 | self._z = value | |
101 | self._status = set_has_var(self._status, pos_z) | |
102 | property e: | |
103 | def __get__(self): | |
104 | if has_var(self._status, pos_e): return self._e | |
105 | else: return None | |
106 | def __set__(self, value): | |
107 | self._e = value | |
108 | self._status = set_has_var(self._status, pos_e) | |
109 | property f: | |
110 | def __get__(self): | |
111 | if has_var(self._status, pos_f): return self._f | |
112 | else: return None | |
113 | def __set__(self, value): | |
114 | self._f = value | |
115 | self._status = set_has_var(self._status, pos_f) | |
116 | property i: | |
117 | def __get__(self): | |
118 | if has_var(self._status, pos_i): return self._i | |
119 | else: return None | |
120 | def __set__(self, value): | |
121 | self._i = value | |
122 | self._status = set_has_var(self._status, pos_i) | |
123 | property j: | |
124 | def __get__(self): | |
125 | if has_var(self._status, pos_j): return self._j | |
126 | else: return None | |
127 | def __set__(self, value): | |
128 | self._j = value | |
129 | self._status = set_has_var(self._status, pos_j) | |
130 | property is_move: | |
131 | def __get__(self): | |
132 | if has_var(self._status, pos_is_move): return True | |
133 | else: return False | |
134 | def __set__(self, value): | |
135 | if value: self._status = set_has_var(self._status, pos_is_move) | |
136 | else: self._status = unset_has_var(self._status, pos_is_move) | |
137 | property relative: | |
138 | def __get__(self): | |
139 | if has_var(self._status, pos_relative): return True | |
140 | else: return False | |
141 | def __set__(self, value): | |
142 | if value: self._status = set_has_var(self._status, pos_relative) | |
143 | else: self._status = unset_has_var(self._status, pos_relative) | |
144 | property relative_e: | |
145 | def __get__(self): | |
146 | if has_var(self._status, pos_relative_e): return True | |
147 | else: return False | |
148 | def __set__(self, value): | |
149 | if value: self._status = set_has_var(self._status, pos_relative_e) | |
150 | else: self._status = unset_has_var(self._status, pos_relative_e) | |
151 | property extruding: | |
152 | def __get__(self): | |
153 | if has_var(self._status, pos_extruding): return True | |
154 | else: return False | |
155 | def __set__(self, value): | |
156 | if value: self._status = set_has_var(self._status, pos_extruding) | |
157 | else: self._status = unset_has_var(self._status, pos_extruding) | |
158 | property current_x: | |
159 | def __get__(self): | |
160 | if has_var(self._status, pos_current_x): return self._current_x | |
161 | else: return None | |
162 | def __set__(self, value): | |
163 | self._current_x = value | |
164 | self._status = set_has_var(self._status, pos_current_x) | |
165 | property current_y: | |
166 | def __get__(self): | |
167 | if has_var(self._status, pos_current_y): return self._current_y | |
168 | else: return None | |
169 | def __set__(self, value): | |
170 | self._current_y = value | |
171 | self._status = set_has_var(self._status, pos_current_y) | |
172 | property current_z: | |
173 | def __get__(self): | |
174 | if has_var(self._status, pos_current_z): return self._current_z | |
175 | else: return None | |
176 | def __set__(self, value): | |
177 | self._current_z = value | |
178 | self._status = set_has_var(self._status, pos_current_z) | |
179 | property current_tool: | |
180 | def __get__(self): | |
181 | if has_var(self._status, pos_current_tool): return self._status >> 24 | |
182 | else: return None | |
183 | def __set__(self, value): | |
184 | self._status = (self._status & ((1 << 24) - 1)) | (value << 24) | |
185 | self._status = set_has_var(self._status, pos_current_tool) | |
186 | property gcview_end_vertex: | |
187 | def __get__(self): | |
188 | if has_var(self._status, pos_gcview_end_vertex): return self._gcview_end_vertex | |
189 | else: return None | |
190 | def __set__(self, value): | |
191 | self._gcview_end_vertex = value | |
192 | self._status = set_has_var(self._status, pos_gcview_end_vertex) | |
193 | property raw: | |
194 | def __get__(self): | |
195 | if has_var(self._status, pos_raw): return self._raw | |
196 | else: return None | |
197 | def __set__(self, value): | |
198 | # WARNING: memory leak could happen here, as we don't do the following : | |
199 | # if self._raw != NULL: free(self._raw) | |
200 | self._raw = copy_string(value) | |
201 | self._status = set_has_var(self._status, pos_raw) | |
202 | property command: | |
203 | def __get__(self): | |
204 | if has_var(self._status, pos_command): return self._command | |
205 | else: return None | |
206 | def __set__(self, value): | |
207 | # WARNING: memory leak could happen here, as we don't do the following : | |
208 | # if self._command != NULL: free(self._command) | |
209 | self._command = copy_string(value) | |
210 | self._status = set_has_var(self._status, pos_command) | |
211 | ||
212 | cdef class GLightLine: | |
213 | ||
214 | cdef char* _raw | |
215 | cdef char* _command | |
216 | cdef uint8_t _status | |
217 | ||
218 | __slots__ = () | |
219 | ||
220 | def __cinit__(self): | |
221 | self._status = 0 | |
222 | self._raw = NULL | |
223 | self._command = NULL | |
224 | ||
225 | def __init__(self, line): | |
226 | self.raw = line | |
227 | ||
228 | def __dealloc__(self): | |
229 | if self._raw != NULL: free(self._raw) | |
230 | if self._command != NULL: free(self._command) | |
231 | ||
232 | property raw: | |
233 | def __get__(self): | |
234 | if has_var(self._status, pos_raw): return self._raw | |
235 | else: return None | |
236 | def __set__(self, value): | |
237 | # WARNING: memory leak could happen here, as we don't do the following : | |
238 | # if self._raw != NULL: free(self._raw) | |
239 | self._raw = copy_string(value) | |
240 | self._status = set_has_var(self._status, pos_raw) | |
241 | property command: | |
242 | def __get__(self): | |
243 | if has_var(self._status, pos_command): return self._command | |
244 | else: return None | |
245 | def __set__(self, value): | |
246 | # WARNING: memory leak could happen here, as we don't do the following : | |
247 | # if self._command != NULL: free(self._command) | |
248 | self._command = copy_string(value) | |
249 | self._status = set_has_var(self._status, pos_command) | |
250 | property is_move: | |
251 | def __get__(self): | |
252 | if has_var(self._status, pos_is_move): return True | |
253 | else: return False | |
254 | def __set__(self, value): | |
255 | if value: self._status = set_has_var(self._status, pos_is_move) | |
256 | else: self._status = unset_has_var(self._status, pos_is_move) |