chiark / gitweb /
Add uppercase STL and HEX to file dialog filters for linux/MacOS
[cura.git] / Cura / cura_sf / skeinforge_application / skeinforge_plugins / craft_plugins / flow.py
1 """
2 This page is in the table of contents.
3 The flow script sets the flow rate by writing the M108 gcode.
4
5 ==Operation==
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.
7
8 ==Settings==
9 ===Flow Rate===
10 Default is 210.
11
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.
13
14 ==Examples==
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.
16
17 > python flow.py
18 This brings up the flow dialog.
19
20 > python flow.py Screw Holder Bottom.stl
21 The flow tool is parsing the file:
22 Screw Holder Bottom.stl
23 ..
24 The flow tool has created the file:
25 .. Screw Holder Bottom_flow.gcode
26
27 """
28
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.
31 import __init__
32
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
41 import sys
42
43
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'
47
48
49 def getCraftedText( fileName, text='', flowRepository = None ):
50         "Flow the file or text."
51         return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), flowRepository )
52
53 def getCraftedTextFromText( gcodeText, flowRepository = None ):
54         "Flow a gcode linear move text."
55         if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'flow'):
56                 return gcodeText
57         if flowRepository == None:
58                 flowRepository = settings.getReadRepository( FlowRepository() )
59         if not flowRepository.activateFlow.value:
60                 return gcodeText
61         return FlowSkein().getCraftedGcode( gcodeText, flowRepository )
62
63 def getNewRepository():
64         'Get new repository.'
65         return FlowRepository()
66
67 def writeOutput(fileName, shouldAnalyze=True):
68         "Flow a gcode linear move file."
69         skeinforge_craft.writeChainTextWithNounMessage(fileName, 'flow', shouldAnalyze)
70
71
72 class FlowRepository:
73         "A class to handle the flow settings."
74         def __init__(self):
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'
81
82         def execute(self):
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:
86                         writeOutput(fileName)
87
88
89 class FlowSkein:
90         "A class to flow a skein of extrusions."
91         def __init__(self):
92                 self.distanceFeedRate = gcodec.DistanceFeedRate()
93                 self.lineIndex = 0
94                 self.lines = None
95                 self.oldFlowRate = None
96                 self.oldLocation = None
97
98         def addFlowRateLine(self):
99                 "Add flow rate line."
100                 flowRate = self.flowRepository.flowRate.value
101                 if flowRate != self.oldFlowRate:
102                         self.distanceFeedRate.addLine('M108 S' + euclidean.getFourSignificantFigures(flowRate))
103                 self.oldFlowRate = flowRate
104
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 :]:
111                         self.parseLine(line)
112                 return self.distanceFeedRate.output.getvalue()
113
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')
123                                 return
124                         self.distanceFeedRate.addLine(line)
125
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:
130                         return
131                 firstWord = splitLine[0]
132                 if firstWord == 'G1' or firstWord == '(<layer>':
133                         self.addFlowRateLine()
134                 self.distanceFeedRate.addLine(line)
135
136
137 def main():
138         "Display the flow dialog."
139         if len(sys.argv) > 1:
140                 writeOutput(' '.join(sys.argv[1 :]))
141         else:
142                 settings.startMainLoopFromConstructor(getNewRepository())
143
144 if __name__ == "__main__":
145         main()