@@ -32,20 +32,27 @@ def __init__(self, fileBufferedReader, python_version, logger, coeffs, zMin, zMa
3232 self .xPrev = 0.0
3333 self .yPrev = 0.0
3434 self .zPrev = 0.0
35+ self .ePrev = 0.0
3536
3637 self .xCurr = 0.0
3738 self .yCurr = 0.0
3839 self .zCurr = 0.0
39- self .fCurr = 0.0
40- self .fChanged = False
41- # self.eCurr = 0.0
42- # self.eUsed = False
40+
41+ self .eCurr = 0.0
42+
43+ self .eMode = "None"
44+ self .moveMode = "Absolute"
45+
46+ self .spareParts = ""
47+
4348
4449 self .afterStart = False
4550
4651 self .move_pattern = re .compile ("^G[0-1]\s" )
4752 self .feed_pattern = re .compile ("^F" )
48- self .comment_pattern = re .compile (";.*$[\n ]*" )
53+ self .move_mode_pattern = re .compile ("^G9[0-1]" )
54+ self .extruder_mode_pattern = re .compile ("^M8[2-3]" )
55+ self .comment_pattern = re .compile (";" )
4956
5057 def move_dist (self ):
5158 return ((self .xCurr - self .xPrev )** 2 + (self .yCurr - self .yPrev )** 2 + (self .zCurr - self .zPrev )** 2 )** 0.5
@@ -55,24 +62,32 @@ def get_z(self, x, y, zOffset):
5562
5663 if (zNew < self .zMin or zNew > self .zMax ):
5764 raise GcodeLevelingError ("Computed Z was outside of bounds" , "Gcode Leveling config likely needs to be changed" )
58- return zNew
65+ return round ( zNew , 3 )
5966
60- def construct_line (self , basePos , dirVector , dist ):
67+ def construct_line (self , basePos , dirVector , seg ):
6168 outLine = self .moveCurr
6269
63- xNew = basePos [0 ] + dirVector [0 ]* dist
64- yNew = basePos [1 ] + dirVector [1 ]* dist
65- zOffset = basePos [2 ] + dirVector [2 ]* dist
70+ xNew = basePos [0 ] + dirVector [0 ]* seg
71+ yNew = basePos [1 ] + dirVector [1 ]* seg
72+ zOffset = basePos [2 ] + dirVector [2 ]* seg
6673
6774
6875
69- outLine += " X" + str (xNew )
70- outLine += " Y" + str (yNew )
76+ outLine += " X" + str (round ( xNew , 3 ) )
77+ outLine += " Y" + str (round ( yNew , 3 ) )
7178 outLine += " Z" + str (self .get_z (xNew , yNew , zOffset ))
7279
73- if self .fChanged == True :
74- outLine += " F" + str (self .fCurr )
75- self .fChanged = False
80+ if (self .eMode == "Absolute" ):
81+ eNew = basePos [3 ] + dirVector [3 ]* seg
82+ outLine += " E" + str (round (eNew , 5 ))
83+ elif (self .eMode == "Relative" ):
84+ eNew = dirVector [3 ]
85+ outLine += " E" + str (round (eNew , 5 ))
86+
87+
88+
89+ outLine += " " + self .spareParts
90+ self .spareParts = ""
7691
7792 outLine += "\n "
7893
@@ -81,36 +96,38 @@ def construct_line(self, basePos, dirVector, dist):
8196 def reconstruct_line (self ):
8297 outLine = self .moveCurr
8398
84- outLine += " X" + str (self .xCurr )
85- outLine += " Y" + str (self .yCurr )
99+ outLine += " X" + str (round ( self .xCurr , 3 ) )
100+ outLine += " Y" + str (round ( self .yCurr , 3 ) )
86101 outLine += " Z" + str (self .get_z (self .xCurr , self .yCurr , self .zCurr ))
87102
88- if self .fChanged == True :
89- outLine += " F " + str (self .fCurr )
90- self . fChanged = False
91- # if self.eUsed == True:
92- # outLine + = " E" + str(self.eCurr)
103+ if self .eMode != "None" :
104+ outLine += " E " + str (round ( self .eCurr , 5 ) )
105+
106+ outLine += " " + self . spareParts
107+ self . spareParts = ""
93108
94109 outLine += "\n "
95110
96111 return outLine
97112
98113 def break_up_line (self ):
99114 numSegments = int (self .moveDist // self .lineBreakDist )
100- lenSegments = self .moveDist / numSegments
101115
102- xUnit = (self .xCurr - self .xPrev )/ self .moveDist
103- yUnit = (self .yCurr - self .yPrev )/ self .moveDist
104- zUnit = (self .zCurr - self .zPrev )/ self .moveDist
116+ eSeg = (self .eCurr - self .ePrev )/ numSegments
117+
118+ xSeg = (self .xCurr - self .xPrev )/ numSegments
119+ ySeg = (self .yCurr - self .yPrev )/ numSegments
120+ zSeg = (self .zCurr - self .zPrev )/ numSegments
105121
106122 outLines = ""
107123
108124 for seg in range (1 , numSegments + 1 ):
109- outLines += self .construct_line ((self .xPrev , self .yPrev , self .zPrev ), (xUnit , yUnit , zUnit ), lenSegments * seg )
125+ outLines += self .construct_line ((self .xPrev , self .yPrev , self .zPrev , self . ePrev ), (xSeg , ySeg , zSeg , eSeg ), seg )
110126
111127 return outLines
112128
113129 def process_line (self , origLine ):
130+
114131 if not len (origLine ):
115132 return None
116133
@@ -119,19 +136,26 @@ def process_line(self, origLine):
119136 else :
120137 line = origLine
121138
122- # Check for lone Feed rate commands
123- if re .match (self .feed_pattern , line ) is not None :
124- line = re .sub (self .comment_pattern , "" , line )
139+ # Check for standard Movement commands
140+ if (re .match (self .move_pattern , line ) is not None ) and (self .moveMode != "Relative" ):
141+ # Logic to seperate comments so they can be reattached after processing
142+ if line .find (";" ) != - 1 :
143+ comSplit = line .split (";" )
144+ if len (comSplit ) > 1 :
145+ activeCode = comSplit [0 ]
146+
147+ self .spareParts += ";"
148+
149+ for part in comSplit [1 :]:
150+ self .spareParts += part + " "
151+ else :
152+ return origLine
153+ else :
154+ activeCode = line
125155
126- fCommand = re .split ("\s" , line )[0 ]
127- self .fCurr = float (fCommand [1 :])
128156
129- return origLine
157+ gcodeParts = re . split ( "\s" , activeCode )
130158
131- # Check for standard Movement commands
132- if re .match (self .move_pattern , line ) is not None :
133- line = re .sub (self .comment_pattern , "" , line )
134- gcodeParts = re .split ("\s" , line )[:]
135159
136160 self .xPrev = self .xCurr
137161 self .yPrev = self .yCurr
@@ -140,40 +164,77 @@ def process_line(self, origLine):
140164 self .moveCurr = gcodeParts [0 ]
141165
142166 for part in gcodeParts [1 :]:
143- if part != "" :
167+ if len ( part ) > 1 :
144168 leadChar = part [0 ]
145169 if leadChar == "X" :
146170 self .xCurr = float (part [1 :])
147171 elif leadChar == 'Y' :
148172 self .yCurr = float (part [1 :])
149173 elif leadChar == 'Z' :
150174 self .zCurr = float (part [1 :])
151- elif leadChar == 'F' :
152- fNew = float (part [1 :])
153- if (fNew != self .fCurr ):
154- self .fChanged = True
155- self .fCurr = fNew
156-
157- # elif leadChar == 'E':
158- # self.ePrev = self.eCurr
159- # self.eUsed = True
160- # self.eCurr = float(part[1:])
161-
175+ elif leadChar == 'E' :
176+ # Extrusion Mode Stuff
177+ if (self .eMode == "Relative" ):
178+ self .ePrev = 0
179+ elif (self .eMode == "Absolute" ):
180+ self .ePrev = self .eCurr
181+ else :
182+ self .eMode = "Absolute"
183+ self .ePrev = self .eCurr
184+
185+
186+ self .eCurr = float (part [1 :])
187+ else :
188+ self .spareParts = part + " " + self .spareParts
162189 self .moveDist = self .move_dist ()
163190
164191
192+
165193 # self.afterStart ensures that the first move isn't broken up and doesnt start at 0, 0, 0
166194 if (self .afterStart and self .moveDist > self .lineBreakDist and self .lineBreakDist != 0.0 ):
167195 line = self .break_up_line ()
168196 else :
169197 self .afterStart = True
170198 line = self .reconstruct_line ()
171199
200+ # Check for movement mode
201+ if re .match (self .move_mode_pattern , line ) is not None :
202+ line = re .sub (self .comment_pattern , "" , line )
203+
204+ mode = re .split ("\s" , line )[0 ]
205+
206+ if mode == "G90" :
207+ self .moveMode = "Absolute"
208+ elif mode == "G91" :
209+ self .moveMode = "Relative"
210+
211+ # self._logger.info("Line sets move mode " + self.moveMode)
212+
213+
214+ return origLine
215+
216+ # Check for extruder movement mode
217+ if re .match (self .extruder_mode_pattern , line ) is not None :
218+ line = re .sub (self .comment_pattern , "" , line )
219+
220+ mode = re .split ("\s" , line )[0 ]
221+
222+ if mode == "M82" :
223+ self .eMode = "Absolute"
224+ elif mode == "M83" :
225+ self .eMode = "Relative"
226+
227+ # self._logger.info("Line sets extruder mode " + self.eMode)
228+
229+
230+ return origLine
172231
173232
174233 if (self .python_version == 3 ):
175234 line = line .encode ('utf-8' )
176235
236+ # self._logger.info(line)
237+
177238 return line
178239
179240class GcodeLevelingPlugin (octoprint .plugin .StartupPlugin ,
@@ -190,7 +251,6 @@ def createFilePreProcessor(self, path, file_object, blinks=None, printer_profile
190251 fileStream = file_object .stream ()
191252 self ._logger .info ("Gcode PreProcessing started." )
192253 self .gcode_preprocessor = GcodePreProcessor (fileStream , self .python_version , self ._logger , self .coeffs , self .zMin , self .zMax , self .lineBreakDist , self .invertPosition )
193- self ._logger .info ("Gcode PreProcessing finished." )
194254 return octoprint .filemanager .util .StreamWrapper (fileName , self .gcode_preprocessor )
195255
196256
0 commit comments