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
31 from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
32 from fabmetheus_utilities import archive
33 from fabmetheus_utilities import euclidean
34 from fabmetheus_utilities import gcodec
35 from fabmetheus_utilities import settings
36 from skeinforge_application.skeinforge_utilities import skeinforge_craft
37 from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
38 from skeinforge_application.skeinforge_utilities import skeinforge_profile
42 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
43 __date__ = '$Date: 2008/21/04 $'
44 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
47 def getCraftedText( fileName, text='', flowRepository = None ):
48 "Flow the file or text."
49 return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), flowRepository )
51 def getCraftedTextFromText( gcodeText, flowRepository = None ):
52 "Flow a gcode linear move text."
53 if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'flow'):
55 if flowRepository == None:
56 flowRepository = settings.getReadRepository( FlowRepository() )
57 if not flowRepository.activateFlow.value:
59 return FlowSkein().getCraftedGcode( gcodeText, flowRepository )
61 def getNewRepository():
63 return FlowRepository()
65 def writeOutput(fileName, shouldAnalyze=True):
66 "Flow a gcode linear move file."
67 skeinforge_craft.writeChainTextWithNounMessage(fileName, 'flow', shouldAnalyze)
70 class FlowRepository(object):
71 "A class to handle the flow settings."
73 "Set the default settings, execute title & settings fileName."
74 skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.flow.html', self )
75 self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Flow', self, '')
76 self.activateFlow = settings.BooleanSetting().getFromValue('Activate Flow', self, True )
77 self.flowRate = settings.FloatSpin().getFromValue( 50.0, 'Flow Rate (arbitrary units):', self, 250.0, 210.0 )
78 self.executeTitle = 'Flow'
81 "Flow button has been clicked."
82 fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
83 for fileName in fileNames:
87 class FlowSkein(object):
88 "A class to flow a skein of extrusions."
90 self.distanceFeedRate = gcodec.DistanceFeedRate()
93 self.oldFlowRate = None
94 self.oldLocation = None
96 def addFlowRateLine(self):
98 flowRate = self.flowRepository.flowRate.value
99 if flowRate != self.oldFlowRate:
100 self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate))
101 self.oldFlowRate = flowRate
103 def getCraftedGcode( self, gcodeText, flowRepository ):
104 "Parse gcode text and store the flow gcode."
105 self.flowRepository = flowRepository
106 self.lines = archive.getTextLines(gcodeText)
107 self.parseInitialization()
108 for line in self.lines[self.lineIndex :]:
110 return self.distanceFeedRate.output.getvalue()
112 def parseInitialization(self):
113 'Parse gcode initialization and store the parameters.'
114 for self.lineIndex in xrange(len(self.lines)):
115 line = self.lines[self.lineIndex]
116 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
117 firstWord = gcodec.getFirstWord(splitLine)
118 self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
119 if firstWord == '(</extruderInitialization>)':
120 self.distanceFeedRate.addTagBracketedProcedure('flow')
122 self.distanceFeedRate.addLine(line)
124 def parseLine(self, line):
125 "Parse a gcode line and add it to the flow skein."
126 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
127 if len(splitLine) < 1:
129 firstWord = splitLine[0]
130 if firstWord == 'G1' or firstWord == '(<layer>':
131 self.addFlowRateLine()
132 self.distanceFeedRate.addLine(line)
136 "Display the flow dialog."
137 if len(sys.argv) > 1:
138 writeOutput(' '.join(sys.argv[1 :]))
140 settings.startMainLoopFromConstructor(getNewRepository())
142 if __name__ == "__main__":