2 This page is in the table of contents.
3 Gcode step is an export plugin to convert gcode from float position to number of steps.
5 An export plugin is a script in the export_plugins folder which has the getOutput function, the globalIsReplaceable variable and if it's output is not replaceable, the writeOutput function. It is meant to be run from the export tool. To ensure that the plugin works on platforms which do not handle file capitalization properly, give the plugin a lower case name.
7 The getOutput function of this script takes a gcode text and returns it with the positions converted into number of steps. The writeOutput function of this script takes a gcode text and writes that with the positions converted into number of steps.
10 ===Add Feed Rate Even When Unchanging===
13 When selected, the feed rate will be added even when it did not change from the previous line.
15 ===Add Space Between Words===
18 When selected, a space will be added between each gcode word.
20 ===Add Z Even When Unchanging===
23 When selected, the z word will be added even when it did not change.
25 ===Feed Rate Step Length===
26 Default is 0.1 millimeters/second.
28 Defines the feed rate step length.
48 Default is 0.1 millimeters.
50 Defines the E extrusion distance step length.
52 ===Radius Rate Step Length===
53 Default is 0.1 millimeters/second.
55 Defines the radius step length.
58 Default is 0.1 millimeters.
60 Defines the X axis step length.
63 Default is 0.1 millimeters.
65 Defines the Y axis step length.
68 Default is 0.01 millimeters.
70 Defines the Z axis step length.
75 from __future__ import absolute_import
77 from fabmetheus_utilities import archive
78 from fabmetheus_utilities import gcodec
79 from fabmetheus_utilities import settings
80 from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
81 from skeinforge_application.skeinforge_utilities import skeinforge_profile
86 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
87 __date__ = '$Date: 2008/21/04 $'
88 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
91 # This is true if the output is text and false if it is binary.
92 globalIsReplaceable = True
95 def getCharacterIntegerString(character, offset, splitLine, stepLength):
96 'Get a character and integer string.'
97 floatValue = getFloatFromCharacterSplitLine(character, splitLine)
98 if floatValue == None:
101 integerValue = int(round(float(floatValue / stepLength)))
102 return character + str(integerValue)
104 def getFloatFromCharacterSplitLine(character, splitLine):
105 'Get the float after the first occurence of the character in the split line.'
106 lineFromCharacter = gcodec.getStringFromCharacterSplitLine(character, splitLine)
107 if lineFromCharacter == None:
109 return float(lineFromCharacter)
111 def getNewRepository():
112 'Get new repository.'
113 return GcodeStepRepository()
115 def getOutput(gcodeText, repository=None):
116 'Get the exported version of a gcode file.'
119 if repository == None:
120 repository = GcodeStepRepository()
121 settings.getReadRepository(repository)
122 return GcodeStepSkein().getCraftedGcode(repository, gcodeText)
124 def writeOutput( fileName, gcodeText = ''):
125 'Write the exported version of a gcode file.'
126 gcodeText = gcodec.getGcodeFileText(fileName, gcodeText)
127 repository = GcodeStepRepository()
128 settings.getReadRepository(repository)
129 output = getOutput(gcodeText, repository)
130 suffixFileName = fileName[: fileName.rfind('.')] + '_gcode_step.gcode'
131 archive.writeFileText(suffixFileName, output)
132 print('The converted file is saved as ' + archive.getSummarizedFileName(suffixFileName))
135 class GcodeStepRepository(object):
136 'A class to handle the export settings.'
138 'Set the default settings, execute title & settings fileName.'
139 skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.export_plugins.gcode_step.html', self)
140 self.addFeedRateEvenWhenUnchanging = settings.BooleanSetting().getFromValue('Add Feed Rate Even When Unchanging', self, True)
141 self.addSpaceBetweenWords = settings.BooleanSetting().getFromValue('Add Space Between Words', self, True)
142 self.addZEvenWhenUnchanging = settings.BooleanSetting().getFromValue('Add Z Even When Unchanging', self, True)
143 self.fileNameInput = settings.FileNameInput().getFromFileName([('Gcode text files', '*.gcode')], 'Open File to be Converted to Gcode Step', self, '')
144 self.feedRateStepLength = settings.FloatSpin().getFromValue(0.0, 'Feed Rate Step Length (millimeters/second)', self, 1.0, 0.1)
145 settings.LabelSeparator().getFromRepository(self)
146 settings.LabelDisplay().getFromName('- Offset -', self )
147 self.xOffset = settings.FloatSpin().getFromValue(-100.0, 'X Offset (millimeters)', self, 100.0, 0.0)
148 self.yOffset = settings.FloatSpin().getFromValue(-100.0, 'Y Offset (millimeters)', self, 100.0, 0.0)
149 self.zOffset = settings.FloatSpin().getFromValue(-10.0, 'Z Offset (millimeters)', self, 10.0, 0.0)
150 settings.LabelSeparator().getFromRepository(self)
151 settings.LabelDisplay().getFromName('- Step Length -', self )
152 self.eStepLength = settings.FloatSpin().getFromValue(0.0, 'E Step Length (float)', self, 1.0, 0.1)
153 self.radiusStepLength = settings.FloatSpin().getFromValue(0.0, 'Radius Step Length (millimeters)', self, 1.0, 0.1)
154 self.xStepLength = settings.FloatSpin().getFromValue(0.0, 'X Step Length (millimeters)', self, 1.0, 0.1)
155 self.yStepLength = settings.FloatSpin().getFromValue(0.0, 'Y Step Length (millimeters)', self, 1.0, 0.1)
156 self.zStepLength = settings.FloatSpin().getFromValue(0.0, 'Z Step Length (millimeters)', self, 0.2, 0.01)
157 self.executeTitle = 'Convert to Gcode Step'
160 'Convert to gcode step button has been clicked.'
161 fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, ['.gcode'], self.fileNameInput.wasCancelled)
162 for fileName in fileNames:
163 writeOutput(fileName)
166 class GcodeStepSkein(object):
167 'A class to convert gcode into 16 byte binary segments.'
169 self.oldFeedRateString = None
170 self.oldZString = None
171 self.output = cStringIO.StringIO()
173 def addCharacterInteger(self, character, lineStringIO, offset, splitLine, stepLength):
174 'Add a character and integer to line string.'
175 characterIntegerString = getCharacterIntegerString(character, offset, splitLine, stepLength)
176 self.addStringToLine(lineStringIO, characterIntegerString)
178 def addLine(self, line):
179 'Add a line of text and a newline to the output.'
180 self.output.write(line + '\n')
182 def addStringToLine(self, lineStringIO, wordString):
183 'Add a character and integer to line string.'
186 if self.repository.addSpaceBetweenWords.value:
187 lineStringIO.write(' ')
188 lineStringIO.write(wordString)
190 def getCraftedGcode(self, repository, gcodeText):
191 'Parse gcode text and store the gcode.'
192 self.repository = repository
193 lines = archive.getTextLines(gcodeText)
196 return self.output.getvalue()
198 def parseLine(self, line):
199 'Parse a gcode line.'
200 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
201 firstWord = gcodec.getFirstWord(splitLine)
202 if len(firstWord) < 1:
204 firstLetter = firstWord[0]
205 if firstLetter == '(':
207 if firstWord != 'G1' and firstWord != 'G2' and firstWord != 'G3':
210 lineStringIO = cStringIO.StringIO()
211 lineStringIO.write(firstWord)
212 self.addCharacterInteger('I', lineStringIO, 0.0, splitLine, self.repository.xStepLength.value)
213 self.addCharacterInteger('J', lineStringIO, 0.0, splitLine, self.repository.yStepLength.value)
214 self.addCharacterInteger('R', lineStringIO, 0.0, splitLine, self.repository.radiusStepLength.value)
215 self.addCharacterInteger('X', lineStringIO, self.repository.xOffset.value, splitLine, self.repository.xStepLength.value)
216 self.addCharacterInteger('Y', lineStringIO, self.repository.yOffset.value, splitLine, self.repository.yStepLength.value)
217 zString = getCharacterIntegerString('Z', self.repository.zOffset.value, splitLine, self.repository.zStepLength.value)
218 feedRateString = getCharacterIntegerString('F', 0.0, splitLine, self.repository.feedRateStepLength.value)
220 if zString != self.oldZString or self.repository.addZEvenWhenUnchanging.value:
221 self.addStringToLine(lineStringIO, zString)
222 if feedRateString != '':
223 if feedRateString != self.oldFeedRateString or self.repository.addFeedRateEvenWhenUnchanging.value:
224 self.addStringToLine(lineStringIO, feedRateString)
225 self.addCharacterInteger('E', lineStringIO, 0.0, splitLine, self.repository.eStepLength.value)
226 self.addLine(lineStringIO.getvalue())
227 self.oldFeedRateString = feedRateString
228 self.oldZString = zString
232 'Display the export dialog.'
233 if len(sys.argv) > 1:
234 writeOutput(' '.join(sys.argv[1 :]))
236 settings.startMainLoopFromConstructor(getNewRepository())
238 if __name__ == '__main__':