2 This page is in the table of contents.
3 The flow script sets the flow rate by writing the M108 gcode.
6 The default 'Activate Flow' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.
12 Defines the flow rate which will be written following the M108 command. The flow rate is usually a PWM setting, but could be anything, like the rpm of the tool or the duty cycle of the tool.
15 The following examples flow the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and flow.py.
18 This brings up the flow dialog.
20 > python flow.py Screw Holder Bottom.stl
21 The flow tool is parsing the file:
22 Screw Holder Bottom.stl
24 The flow tool has created the file:
25 .. Screw Holder Bottom_flow.gcode
29 from __future__ import absolute_import
30 #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
33 from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
34 from fabmetheus_utilities import archive
35 from fabmetheus_utilities import euclidean
36 from fabmetheus_utilities import gcodec
37 from fabmetheus_utilities import settings
38 from skeinforge_application.skeinforge_utilities import skeinforge_craft
39 from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
40 from skeinforge_application.skeinforge_utilities import skeinforge_profile
44 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
45 __date__ = '$Date: 2008/21/04 $'
46 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
49 def getCraftedText( fileName, text='', flowRepository = None ):
50 "Flow the file or text."
51 return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), flowRepository )
53 def getCraftedTextFromText( gcodeText, flowRepository = None ):
54 "Flow a gcode linear move text."
55 if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'flow'):
57 if flowRepository == None:
58 flowRepository = settings.getReadRepository( FlowRepository() )
59 if not flowRepository.activateFlow.value:
61 return FlowSkein().getCraftedGcode( gcodeText, flowRepository )
63 def getNewRepository():
65 return FlowRepository()
67 def writeOutput(fileName, shouldAnalyze=True):
68 "Flow a gcode linear move file."
69 skeinforge_craft.writeChainTextWithNounMessage(fileName, 'flow', shouldAnalyze)
73 "A class to handle the flow settings."
75 "Set the default settings, execute title & settings fileName."
76 skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.flow.html', self )
77 self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Flow', self, '')
78 self.activateFlow = settings.BooleanSetting().getFromValue('Activate Flow', self, True )
79 self.flowRate = settings.FloatSpin().getFromValue( 50.0, 'Flow Rate (arbitrary units):', self, 250.0, 210.0 )
80 self.executeTitle = 'Flow'
83 "Flow button has been clicked."
84 fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
85 for fileName in fileNames:
90 "A class to flow a skein of extrusions."
92 self.distanceFeedRate = gcodec.DistanceFeedRate()
95 self.oldFlowRate = None
96 self.oldLocation = None
98 def addFlowRateLine(self):
100 flowRate = self.flowRepository.flowRate.value
101 if flowRate != self.oldFlowRate:
102 self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate))
103 self.oldFlowRate = flowRate
105 def getCraftedGcode( self, gcodeText, flowRepository ):
106 "Parse gcode text and store the flow gcode."
107 self.flowRepository = flowRepository
108 self.lines = archive.getTextLines(gcodeText)
109 self.parseInitialization()
110 for line in self.lines[self.lineIndex :]:
112 return self.distanceFeedRate.output.getvalue()
114 def parseInitialization(self):
115 'Parse gcode initialization and store the parameters.'
116 for self.lineIndex in xrange(len(self.lines)):
117 line = self.lines[self.lineIndex]
118 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
119 firstWord = gcodec.getFirstWord(splitLine)
120 self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
121 if firstWord == '(</extruderInitialization>)':
122 self.distanceFeedRate.addTagBracketedProcedure('flow')
124 self.distanceFeedRate.addLine(line)
126 def parseLine(self, line):
127 "Parse a gcode line and add it to the flow skein."
128 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
129 if len(splitLine) < 1:
131 firstWord = splitLine[0]
132 if firstWord == 'G1' or firstWord == '(<layer>':
133 self.addFlowRateLine()
134 self.distanceFeedRate.addLine(line)
138 "Display the flow dialog."
139 if len(sys.argv) > 1:
140 writeOutput(' '.join(sys.argv[1 :]))
142 settings.startMainLoopFromConstructor(getNewRepository())
144 if __name__ == "__main__":