-
Notifications
You must be signed in to change notification settings - Fork 175
/
Copy pathlayers.cfg
411 lines (381 loc) · 17.9 KB
/
layers.cfg
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
# Copyright (C) 2022 Justin Schuh <code@justinschuh.com>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
[gcode_macro before_layer_change]
description: Add this to the "before layer change" input box in the slicer.
Usage: BEFORE_LAYER_CHANGE HEIGHT=<current_height> LAYER=<current_layer>
gcode:
{% set height = params.HEIGHT|default(printer.toolhead.position.z)|float %}
{% set layer = params.LAYER|default(-1)|int + 1 %}
{% if height >= 0.0 and layer >= 0 %}
SET_PRINT_STATS_INFO CURRENT_LAYER="{layer}"
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=cur_height VALUE="{height}"
{% if printer["gcode_macro _km_layer_run"].clearance_z < height %}
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=clearance_z VALUE="{
height}"
{% endif %}
{% endif %}
[gcode_macro after_layer_change]
description: Add this to the "after layer change" input box in the slicer.
Usage: AFTER_LAYER_CHANGE
gcode:
_KM_LAYER_RUN
[gcode_macro gcode_at_layer]
description: Schedules the specified g-code command to be run at the specified
layer. LAYER=next will cause the command to run at the next layer change.
Usage: GCODE_AT_LAYER { HEIGHT=<pos> | LAYER=<layer> } COMMAND=<gcode>
[CANCEL=<0|1>]
gcode:
{% set tot_layers = printer.print_stats.info.total_layer %}
{% if params|length > 0 %}
_KM_CHECK_IS_PRINTING
{% set CANCEL = params.CANCEL|default(0)|int != 0 %}
{% set COMMAND = params.COMMAND|default(None) %}
{% if COMMAND %} # This makes it easier to match commands for cancellation.
{% set COMMAND = COMMAND.lstrip().split(None, 1) %}
{% set COMMAND = " ".join([COMMAND[0]|upper] + COMMAND[1:]) %}
{% endif %}
{% if "LAYER" in params %}
{% set cmd_container = "commands_layer" %}
{% set cur_layer = printer.print_stats.info.current_layer|int %}
{% if "HEIGHT" in params %}
{action_raise_error("Conflicting HEIGHT and LAYER arguments provided.")}
{% elif params.LAYER|string|lower == "next" %}
{% set LAYER = cur_layer + 1 %}
{% else %}
{% set LAYER = params.LAYER|int %}
{% endif %}
{% if LAYER <= cur_layer %}
{action_raise_error("LAYER[%i] must be above current print layer[%i]."
| format(LAYER, cur_layer))}
{% elif tot_layers and LAYER > tot_layers %}
{action_raise_error("LAYER[%i] must not be above top layer[%i]."
| format(LAYER, tot_layers))}
{% endif %}
{% set key = LAYER %}
{% elif "HEIGHT" in params %}
{% set cmd_container = "commands_height" %}
{% set HEIGHT = params.HEIGHT|float %}
{% set cur_height = printer["gcode_macro _km_layer_run"].cur_height %}
{% if HEIGHT <= cur_height %}
{action_raise_error(
"HEIGHT[%.3f] must be above current print height[%.3f].")
| format(HEIGHT, cur_height)}
{% elif HEIGHT >= printer.toolhead.axis_maximum.z %}
{action_raise_error(
"HEIGHT[%.3f] must be below maximum Z height[%.3f].")
| format(HEIGHT, printer.toolhead.axis_maximum.z)}
{% endif %}
{% set key = HEIGHT %}
{% else %}
{action_raise_error("No HEIGHT or LAYER argument provided.")}
{% endif %}
{% set commands = printer["gcode_macro _km_layer_run"][cmd_container] %}
{% if key not in commands and not CANCEL %}
{% set dummy = commands.__setitem__(key, []) %}
{% endif %}
{% if CANCEL %}
{% if key in commands %}
{% set pos = ("%i"|format(key)) if key is integer else
("%.3fmm"|format(key)) %}
{% if COMMAND %}
{% set dummy = commands[key].remove(COMMAND) %}
{% if commands[key]|length == 0 %}
{% set dummy = commands.__delitem__(key) %}
{% endif %}
{action_respond_info("Cancelled %s %s:\n* %s" |
format("layer" if k is integer else "height",
pos, COMMAND))}
{% else %}
{% set dummy = commands.__delitem__(key) %}
{action_respond_info("Cancelled all commands at %s %s." |
format("layer" if k is integer else "height",
pos))}
{% endif %}
{% endif %}
{% elif not COMMAND %}
{action_raise_error("No COMMAND argument provided.")}
{% elif COMMAND in commands[key] %}
{action_raise_error("Duplicate command previously scheduled.")}
{% else %}
{% set dummy = commands[key].append(COMMAND) %}
{% set pos = ("%i"|format(key)) if key is integer else
("%.3fmm"|format(key)) %}
{action_respond_info("%s %s:\n* %s" |
format("layer" if key is integer else "height",
pos, COMMAND))}
{% endif %}
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE={cmd_container} VALUE="{
commands|replace('\"','\\\"')}"
_UPDATE_LAYER_COMPAT
# No arguments means just list all the triggers.
{% else %}
{% set output = [] %}
{% set commands = printer["gcode_macro _km_layer_run"].commands_layer %}
{% for key in commands|list|sort %}
{% set dummy = output.append("layer %i:" | format(key)) %}
{% for c in commands[key] %}
{% set dummy = output.append("* %s" | format(c)) %}
{% endfor %}
{% endfor %}
{% set commands = printer["gcode_macro _km_layer_run"].commands_height %}
{% for key in commands|list|sort %}
{% set dummy = output.append("height %.3fmm:" | format(key)) %}
{% for c in commands[key] %}
{% set dummy = output.append("* %s" | format(c)) %}
{% endfor %}
{% endfor %}
{action_respond_info(output|join('\n'))}
{% endif %}
[gcode_macro _km_layer_run]
description: Runs pending commands for the current layer change.
Usage: _KM_LAYER_RUN
variable_cur_height: 0.0
variable_clearance_z: 0.0
variable_commands_layer: {}
variable_commands_height: {}
gcode:
{% set cur_layer = printer.print_stats.info.current_layer %}
{% for key in commands_layer | select("<=", cur_layer) | sort %}
{action_respond_info("Executing scheduled commands at layer %d:\n%s" |
format(key, commands_layer[key]|join('\n')))}
{% for c in commands_layer[key] %}
{c}
{% endfor %}
{% set dummy = commands_layer.__delitem__(key) %}
{% endfor %}
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=commands_layer VALUE="{
commands_layer|replace('\"','\\\"')}"
{% for key in commands_height | select("<=", cur_height) | sort %}
{action_respond_info("Executing scheduled commands at height %.3f:\n%s" |
format(key, commands_height[key]|join('\n')))}
{% for c in commands_height[key] %}
{c}
{% endfor %}
{% set dummy = commands_height.__delitem__(key) %}
{% endfor %}
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=commands_height VALUE="{
commands_height|replace('\"','\\\"')}"
_UPDATE_LAYER_COMPAT
[gcode_macro init_layer_gcode]
description: Clears scheduled gcode commands and state for all layers.
Usage: INIT_LAYER_GCODE LAYERS=<num>
gcode:
SET_PRINT_STATS_INFO TOTAL_LAYER="{params.LAYERS|int + 1}" CURRENT_LAYER="{0}"
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=cur_height VALUE="{0.0}"
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=clearance_z VALUE="{0.0}"
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=commands_layer VALUE="{{}}"
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=commands_height VALUE="{{}}"
_UPDATE_LAYER_COMPAT
[gcode_macro _reset_layer_gcode]
description: Clears scheduled gcode commands and state for all layers.
Usage: _RESET_LAYER_GCODE
gcode:
SET_PRINT_STATS_INFO TOTAL_LAYER="{0}" CURRENT_LAYER="{0}"
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=cur_height VALUE="{0.0}"
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=clearance_z VALUE="{0.0}"
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=commands_layer VALUE="{{}}"
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=commands_height VALUE="{{}}"
_UPDATE_LAYER_COMPAT
[gcode_macro cancel_all_layer_gcode]
description: Clears all scheduled gcode commands.
Usage: CANCEL_ALL_LAYER_GCODE
gcode:
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=commands_layer VALUE="{{}}"
SET_GCODE_VARIABLE MACRO=_km_layer_run VARIABLE=commands_height VALUE="{{}}"
_UPDATE_LAYER_COMPAT
#
# Begin Mainsail/Fluidd compat
#
[gcode_macro SET_PAUSE_NEXT_LAYER]
description: Enable a pause if the next layer is reached
gcode:
_KM_CHECK_IS_PRINTING
{% set pause_next_layer =
printer['gcode_macro SET_PRINT_STATS_INFO'].pause_next_layer %}
{% set ENABLE = params.ENABLE | default(1) | int != 0 %}
{% set MACRO = params.MACRO | default(pause_next_layer.call, True) %}
SET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VALUE="{
{ 'enable': False, 'call': MACRO }}" VARIABLE=pause_next_layer
GCODE_AT_LAYER COMMAND="{MACRO|replace('\"','\\\"')
}" CANCEL="{0 if ENABLE else 1}" LAYER="next"
[gcode_macro SET_PAUSE_AT_LAYER]
description: Enable/disable a pause if a given layer number is reached
gcode:
_KM_CHECK_IS_PRINTING
{% set pause_at_layer =
printer['gcode_macro SET_PRINT_STATS_INFO'].pause_at_layer %}
# This enable logic is copied directly from Fluidd/Mainsail.
{% set ENABLE = params.ENABLE | int != 0 if params.ENABLE is defined else
params.LAYER is defined %}
{% set LAYER = params.LAYER |
default((pause_at_layer.layer|int,
printer.print_stats.info.current_layer|int + 1)|max)%}
{% set MACRO = params.MACRO | default(pause_at_layer.call, True) %}
SET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_at_layer VALUE="{
{ 'enable': False, 'layer': 0, 'call': MACRO }}"
{% if ENABLE and pause_at_layer.enable %}
# Remove the previously scheduled command if we're replacing it.
GCODE_AT_LAYER COMMAND="{pause_at_layer.call|replace('\"','\\\"')
}" CANCEL="{1}" LAYER="{pause_at_layer.layer}"
{% endif %}
# Add the new command.
GCODE_AT_LAYER COMMAND="{MACRO|replace('\"','\\\"')
}" CANCEL="{0 if ENABLE else 1}" LAYER="{LAYER}"
[gcode_macro SET_PRINT_STATS_INFO]
rename_existing: _KM_SET_PRINT_STATS_INFO
description: Overwrite, to get pause_next_layer and pause_at_layer feature
variable_pause_next_layer: { 'enable': False, 'call': "PAUSE" }
variable_pause_at_layer : { 'enable': False, 'layer': 0, 'call': "PAUSE" }
gcode:
_KM_SET_PRINT_STATS_INFO {rawparams}
[gcode_macro _update_layer_compat]
gcode:
{% set next_layer = printer.print_stats.info.current_layer|int + 1 %}
{% set commands_layer = printer["gcode_macro _km_layer_run"].commands_layer %}
{% set keys = commands_layer | sort(reverse=True) %}
{% set pause_next_layer = {'enable': False, 'call':
printer['gcode_macro SET_PRINT_STATS_INFO'].pause_next_layer.call} %}
{% if pause_next_layer.call in commands_layer[next_layer] | default([]) %}
{% set dummy = pause_next_layer.__setitem__('enable', True) %}
{% endif %}
SET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_next_layer VALUE="{
pause_next_layer|replace('\"','\\\"') }"
# Don't just make pause_at_layer a copy of pause_next_layer.
{% set pause_at_layer = {'enable': False, 'layer': 0, 'call':
printer['gcode_macro SET_PRINT_STATS_INFO'].pause_at_layer.call} %}
{% if pause_next_layer.enable and
pause_next_layer.call == pause_at_layer.call %}
{% set keys = keys | reject("==", next_layer) %}
{% endif %}
# We iterate through the entire reverse sorted key list because Jinja2 doesn't
# have a filter for dict values. It's ugly, but there should be only a few
# items in the dict.
{% for key in keys %}
{% if pause_at_layer.call in commands_layer[key] %}
{% set dummy = pause_at_layer.__setitem__('enable', True) %}
{% set dummy = pause_at_layer.__setitem__('layer', key) %}
{% endif %}
{% endfor %}
SET_GCODE_VARIABLE MACRO=SET_PRINT_STATS_INFO VARIABLE=pause_at_layer VALUE="{
pause_at_layer|replace('\"','\\\"') }"
#
# End Mainsail/Fluidd compat
#
[gcode_macro pause_next_layer]
description: Convenience macro to schedule the current print to pause at the
next layer change. See PAUSE for additional arguments.
Usage: PAUSE_NEXT_LAYER ...
gcode:
_CHECK_KINEMATIC_LIMITS{% for k in params%}{' ' ~k~ '=' ~ params[k]
}{% endfor %}
GCODE_AT_LAYER LAYER=NEXT COMMAND="PAUSE{% for k in params %}{
' ' ~ k ~ '=' ~ params[k]}{% endfor %}"
[gcode_macro pause_at_layer]
description: Convenience macro to schedule the current print to pause at the
specified layer change. LAYER=next will cause the command to run at the next
layer change. See PAUSE for additional arguments.
Usage: PAUSE_AT_LAYER { HEIGHT=<pos> | LAYER=<layer> } ...
gcode:
# Dummy argument block for Mainsail
{% set dummy = None if True else "
{% set dummy = params.LAYER|default(layer number)|float %}
{% set dummy = params.HEIGHT|default(Z height)|int %}
" %} # End argument block for Mainsail
{% set filtered_params = params|reject('in',['HEIGHT','LAYER'])|list|sort %}
_CHECK_KINEMATIC_LIMITS{% for k in filtered_params%}{' ' ~k~ '=' ~ params[k]
}{% endfor %}
GCODE_AT_LAYER {% for k in params|select('in',['HEIGHT','LAYER'])|list %}{
' ' ~ k ~ '=' ~ params[k] }{% endfor
%} COMMAND="PAUSE{% for k in filtered_params %}{
' ' ~ k ~ '=' ~ params[k]}{% endfor %}"
[gcode_macro speed_at_layer]
description: Convenience macro to schedule a feedrate adjustment at the
specified layer change. LAYER=next will cause the command to run at the next
layer change. (SPEED parameter behaves the same as the M220 S parameter.)
Usage: SPEED_AT_LAYER { HEIGHT=<pos> | LAYER=<layer> } SPEED=<percentage>
gcode:
{% set SPEED = params.SPEED|default(0)|int %}
{% if SPEED < 1 or SPEED > 500 %}
{action_raise_error("SPEED[%i] parameter between 1 and 500 is required."
% SPEED)}
{% endif %}
GCODE_AT_LAYER {% for k in params|select('in',['HEIGHT','LAYER'])|list %}{
' ' ~ k ~ '=' ~ params[k] }{% endfor %} COMMAND="M220 S{SPEED|int}"
# Dummy argument block for Mainsail
{% set dummy = None if True else "
{% set dummy = params.LAYER|default(layer number)|float %}
{% set dummy = params.HEIGHT|default(Z height)|int %}
{% set dummy = params.SPEED|default(percentage)|int %}
" %} # End argument block for Mainsail
[gcode_macro flow_at_layer]
description: Convenience macro to schedule a flow percentage adjustment at the
specified layer change. LAYER=next will cause the command to run at the next
layer change. (FLOW parameter behaves the same as the M221 S parameter.)
Usage: FLOW_AT_LAYER { HEIGHT=<pos> | LAYER=<layer> } FLOW=<percentage>
gcode:
{% set FLOW = params.FLOW|default(0)|int %}
{% if FLOW < 1 or FLOW > 500 %}
{action_raise_error("FLOW[%i] parameter between 1 and 500 is required."
% FLOW)}
{% endif %}
GCODE_AT_LAYER {% for k in params|select('in',['HEIGHT','LAYER'])|list %}{
' ' ~ k ~ '=' ~ params[k] }{% endfor %} COMMAND="M221 S{FLOW|int}"
# Dummy argument block for Mainsail
{% set dummy = None if True else "
{% set dummy = params.LAYER|default(layer number)|float %}
{% set dummy = params.HEIGHT|default(Z height)|int %}
{% set dummy = params.FLOW|default(percentage)|int %}
" %} # End argument block for Mainsail
[gcode_macro fan_at_layer]
description: Convenience macro to schedule a fan adjustment at the specified
layer change. LAYER=next will cause the command to run at the next layer
change. See SET_FAN_SCALING for additional arguments.
Usage: FAN_AT_LAYER { HEIGHT=<pos> | LAYER=<layer> } ...
gcode:
# Dummy argument block for Mainsail
{% set dummy = None if True else "
{% set dummy = params.LAYER|default(layer number)|float %}
{% set dummy = params.HEIGHT|default(Z height)|int %}
{% set dummy = params.SCALE|default(1.0)|float %}
{% set dummy = params.BUMP|default(0)|int %}
{% set dummy = params.MAXIMUM|default(0)|int %}
{% set dummy = params.MINIMUM|default(255)|int %}
{% set dummy = params.SPEED|default(current speed)|int %}
" %} # End argument block for Mainsail
{% set filtered_params = params|reject('in',['HEIGHT','LAYER'])|list|sort %}
{% if filtered_params|length == 0 %}
{action_raise_error("No fan parameters provided.")}
{% endif %}
_CHECK_FAN_PARAMS{% for k in filtered_params %}{' '~k~'='~params[k]
}{% endfor %}
GCODE_AT_LAYER {% for k in params|select('in',['HEIGHT','LAYER'])|list %}{
' ' ~ k ~ '=' ~ params[k] }{% endfor
%} COMMAND="SET_FAN_SCALING{% for k in filtered_params %}{
' ' ~ k ~ '=' ~ params[k]}{% endfor %}"
[gcode_macro heater_at_layer]
description: Convenience macro to schedule a heater adjustment at the specified
layer change. LAYER=next will cause the command to run at the next layer
change. See SET_HEATER_SCALING for additional arguments.
Usage: HEATER_AT_LAYER { HEIGHT=<pos> | LAYER=<layer> } ...
gcode:
# Dummy argument block for Mainsail
{% set dummy = None if True else "
{% set dummy = params.LAYER|default(layer number)|float %}
{% set dummy = params.HEIGHT|default(Z height)|int %}
{% set dummy = params.HEATER|default(e.g. extruder) %}
{% set dummy = params.SCALE|default(1.0)|float %}
{% set dummy = params.BUMP|default(0.0)|float %}
{% set dummy = params.MAXIMUM|default(max_temp)|float %}
{% set dummy = params.MINIMUM|default(min_temp)|float %}
{% set dummy = params.TARGET|default(current target)|float %}
" %} # End argument block for Mainsail
{% set filtered_params = params|reject('in',['HEIGHT','LAYER'])|list|sort %}
_CHECK_HEATER_PARAMS{% for k in filtered_params%}{' ' ~ k ~ '=' ~ params[k]
}{% endfor %}
GCODE_AT_LAYER{% for k in params|select('in',['HEIGHT','LAYER'])|list %}{
' ' ~ k ~ '=' ~ params[k] }{% endfor
%} COMMAND="SET_HEATER_SCALING{% for k in filtered_params %}{
' ' ~ k ~ '=\\\"' ~ params[k]|replace('\\','\\\\')|replace('\'','\\\'')
|replace('\"','\\\"') ~ '\\\"'
}{% endfor %}"