chiark / gitweb /
TweakAtZ
[cura.git] / plugins / TweakAtZ.py
1 #Name: Tweak At Z 3.2
2 #Info: Change printing parameters at a given height
3 #Help: TweakAtZ
4 #Depend: GCode
5 #Type: postprocess
6 #Param: targetZ(float:5.0) Z height to tweak at (mm)
7 #Param: targetL(int:) (ALT) Layer no. to tweak at
8 #Param: speed(int:) New Speed (%)
9 #Param: flowrate(int:) New General Flow Rate (%)
10 #Param: flowrateOne(int:) New Flow Rate Extruder 1 (%)
11 #Param: flowrateTwo(int:) New Flow Rate Extruder 2 (%)
12 #Param: platformTemp(int:) New Bed Temp (deg C)
13 #Param: extruderOne(int:) New Extruder 1 Temp (deg C)
14 #Param: extruderTwo(int:) New Extruder 2 Temp (deg C)
15 #Ex3 #Param: extruderThree(int:) New Extruder 3 Temp (deg C)
16 #Param: fanSpeed(int:) New Fan Speed (0-255 PWM)
17
18 ## Written by Steven Morlock, smorloc@gmail.com
19 ## Modified by Ricardo Gomez, ricardoga@otulook.com, to add Bed Temperature and make it work with Cura_13.06.04+
20 ## Modified by Stefan Heule, Dim3nsioneer@gmx.ch, to add Flow Rate, restoration of initial values when returning to low Z, extended stage numbers, direct stage manipulation by GCODE-comments, UltiGCode regocnition, addition of fan speed, alternative selection by layer no., disabling extruder three, addition of flow rate for specific extruder
21 ## This script is licensed under the Creative Commons - Attribution - Share Alike (CC BY-SA) terms
22
23 # Uses -
24 # M220 S<factor in percent> - set speed factor override percentage
25 # M221 S<factor in percent> - set flow factor override percentage
26 # M221 S<factor in percent> T<0-#toolheads> - set flow factor override percentage for single extruder
27 # M104 S<temp> T<0-#toolheads> - set extruder <T> to target temperature <S>
28 # M140 S<temp> - set bed target temperature
29 # M106 S<PWM> - set fan speed to target speed <S>
30
31 #history / changelog:
32 #V3.0.1: TweakAtZ-state default 1 (i.e. the plugin works without any TweakAtZ comment)
33 #V3.1:   Recognizes UltiGCode and deactivates value reset, fan speed added, alternatively layer no. to tweak at, extruder three temperature disabled by '#Ex3'
34 #V3.1.1: Bugfix reset flow rate
35 #V3.1.2: Bugfix disable TweakAtZ on Cool Head Lift
36 #V3.2:   Flow rate for specific extruder added (only for 2 extruders), bugfix parser, added speed reset at the end of the print
37
38 version = '3.2'
39
40 import re
41
42 def getValue(line, key, default = None):
43         if not key in line or (';' in line and line.find(key) > line.find(';') and not ";TweakAtZ" in key and not ";LAYER:" in key):
44                 return default
45         subPart = line[line.find(key) + len(key):] #allows for string lengths larger than 1
46         if ";TweakAtZ" in key:
47                 m = re.search('^[0-3]', subPart)
48         elif ";LAYER:" in key:
49                 m = re.search('^[+-]?[0-9]*', subPart)
50         else:
51                 m = re.search('^[-]?[0-9]+\.?[0-9]*', subPart) #the minus at the beginning allows for negative values, e.g. for delta printers
52         if m == None:
53                 return default
54         try:
55                 return float(m.group(0))
56         except:
57                 return default
58
59 with open(filename, "r") as f:
60         lines = f.readlines()
61
62 old_speed = 100
63 old_flowrate = 100
64 old_flowrateOne = 100
65 old_flowrateTwo = 100
66 old_platformTemp = -1
67 old_extruderOne = -1
68 old_extruderTwo = -1
69 #Ex3 old_extruderThree = -1
70 old_fanSpeed = 0
71 pres_ext = 0
72 z = 0
73 x = None
74 y = None
75 layer = -100000 #layer no. may be negative (raft) but never that low
76 state = 1 #state 0: deactivated, state 1: activated, state 2: active, but below z, state 3: active, passed z
77 old_state = -1
78 no_reset = 0 #Default setting is reset (ok for Marlin/Sprinter), has to be set to 1 for UltiGCode (work-around for missing default values)
79
80 try:
81         targetL_i = int(targetL)
82         targetZ = 100000
83 except:
84         targetL_i = -100000
85
86 with open(filename, "w") as f:
87         for line in lines:
88                 if not ('M84' in line or 'M25' in line):
89                         f.write(line)
90                 if 'FLAVOR:UltiGCode' in line: #Flavor is UltiGCode! No reset of values
91                         no_reset = 1
92                 if ';TweakAtZ-state' in line: #checks for state change comment
93                         state = getValue(line, ';TweakAtZ-state', state)
94                 if ';Small layer' in line: #checks for begin of Cool Head Lift
95                         old_state = state
96                         state = 0
97                 if ('G4' in line) and old_state > -1:
98                         state = old_state
99                         old_state = -1
100                 if ';LAYER:' in line: #new layer no. found
101                         layer = getValue(line, ';LAYER:', layer)
102                         if targetL_i > -100000: #target selected by layer no.
103                                 if state == 2 and layer >= targetL_i: #determine targetZ from layer no.
104                                         targetZ = z + 0.001
105                 if (getValue(line, 'T', None) is not None) and (getValue(line, 'M', None) is None): #looking for single T-command
106                         pres_ext = getValue(line, 'T', pres_ext)
107                 if 'M190' in line or 'M140' in line and state < 3: #looking for bed temp, stops after target z is passed
108                         old_platformTemp = getValue(line, 'S', old_platformTemp)
109                 if 'M109' in line or 'M104' in line and state < 3: #looking for extruder temp, stops after target z is passed
110                         if getValue(line, 'T', pres_ext) == 0:
111                                 old_extruderOne = getValue(line, 'S', old_extruderOne)
112                         elif getValue(line, 'T', pres_ext) == 1:
113                                 old_extruderTwo = getValue(line, 'S', old_extruderTwo)
114 #Ex3                        elif getValue(line, 'T', pres_ext) == 2:
115 #Ex3                                old_extruderThree = getValue(line, 'S', old_extruderThree)
116                 if 'M107' in line: #fan is stopped; is always updated in order not to miss switch off for next object
117                         old_fanSpeed = 0
118                 if 'M106' in line and state < 3: #looking for fan speed
119                         old_fanSpeed = getValue(line, 'S', old_fanSpeed)
120                 if 'M221' in line and state < 3: #looking for flow rate
121                         tmp_extruder = getValue(line,'T',None)
122                         if tmp_extruder == None: #check if extruder is specified
123                                 old_flowrate = getValue(line, 'S', old_flowrate)
124                         else:
125                                 if tmp_extruder == 0: #first extruder
126                                         old_flowrateOne = getValue(line, 'S', old_flowrateOne)
127                                 if tmp_extruder == 1: #second extruder
128                                         old_flowrateOne = getValue(line, 'S', old_flowrateOne)
129                 if ('M84' in line or 'M25' in line):
130                         if state>0 and speed is not None and speed != '': #'finish' commands for UM Original and UM2
131                                 f.write("M220 S100 ; speed reset to 100% at the end of print\n");
132                                 f.write("M117                     \n")
133                         f.write(line)
134                 if 'G1' in line or 'G0' in line:
135                         newZ = getValue(line, 'Z', z)
136                         x = getValue(line, 'X', None)
137                         y = getValue(line, 'Y', None)
138                         if (newZ != z) and (x is not None) and (y is not None): #no tweaking on retraction hops which have no x and y coordinate
139                                 z = newZ
140                                 if z < targetZ and state == 1:
141                                         state = 2
142                                 if z >= targetZ and state == 2:
143                                         state = 3
144                                         if targetL_i > -100000:
145                                                 f.write(";TweakAtZ V%s: executed at Layer %d\n" % (version,targetL_i))
146                                                 f.write("M117 Printing... tw@L%4d\n" % targetL_i)
147                                         else:
148                                                 f.write(";TweakAtZ V%s: executed at %1.2f mm\n" % (version,targetZ))
149                                                 f.write("M117 Printing... tw@%5.1f\n" % targetZ)
150                                         if speed is not None and speed != '':
151                                                 f.write("M220 S%f\n" % float(speed))
152                                         if flowrate is not None and flowrate != '':
153                                                 f.write("M221 S%f\n" % float(flowrate))
154                                         if flowrateOne is not None and flowrateOne != '':
155                                                 f.write("M221 T0 S%f\n" % float(flowrateOne))
156                                         if flowrateTwo is not None and flowrateTwo != '':
157                                                 f.write("M221 T1 S%f\n" % float(flowrateTwo))
158                                         if platformTemp is not None and platformTemp != '':
159                                                 f.write("M140 S%f\n" % float(platformTemp))
160                                         if extruderOne is not None and extruderOne != '':
161                                                 f.write("M104 S%f T0\n" % float(extruderOne))
162                                         if extruderTwo is not None and extruderTwo != '':
163                                                 f.write("M104 S%f T1\n" % float(extruderTwo))
164 #Ex3                                    if extruderThree is not None and extruderThree != '':
165 #Ex3                                            f.write("M104 S%f T2\n" % float(extruderThree))                                 
166                                         if fanSpeed is not None and fanSpeed != '':
167                                                 f.write("M106 S%d\n" % int(fanSpeed))                                   
168                                 if z < targetZ and state == 3: #re-activates the plugin if executed by pre-print G-command, resets settings
169                                         state = 2
170                                         if no_reset == 0: #executes only for UM Original and UM2 with RepRap flavor
171                                                 if targetL_i > -100000:
172                                                         f.write(";TweakAtZ V%s: reset below Layer %d\n" % (version,targetL_i))
173                                                 else:
174                                                         f.write(";TweakAtZ V%s: reset below %1.2f mm\n" % (version,targetZ))
175                                                 if speed is not None and speed != '':
176                                                         f.write("M220 S%f\n" % float(old_speed))
177                                                 if flowrate is not None and flowrate != '':
178                                                         f.write("M221 S%f\n" % float(old_flowrate))
179                                                 if flowrateOne is not None and flowrateOne != '':
180                                                         f.write("M221 T0 S%f\n" % float(old_flowrateOne))
181                                                 if flowrateTwo is not None and flowrateTwo != '':
182                                                         f.write("M221 T1 S%f\n" % float(old_flowrateTwo))
183                                                 if platformTemp is not None and platformTemp != '':
184                                                         f.write("M140 S%f\n" % float(old_platformTemp))
185                                                 if extruderOne is not None and extruderOne != '':
186                                                         f.write("M104 S%f T0\n" % float(old_extruderOne))
187                                                 if extruderTwo is not None and extruderTwo != '':
188                                                         f.write("M104 S%f T1\n" % float(old_extruderTwo))
189 #Ex3                                                if extruderThree is not None and extruderThree != '':
190 #Ex3                                                        f.write("M104 S%f T2\n" % float(old_extruderThree))                                 
191                                                 if fanSpeed is not None and fanSpeed != '':
192                                                         f.write("M106 S%d;\n" % int(old_fanSpeed))                                      
193