chiark / gitweb /
Add uppercase STL and HEX to file dialog filters for linux/MacOS
[cura.git] / Cura / skeinforge_application / skeinforge_utilities / skeinforge_craft.py
1 """
2 Craft is a script to access the plugins which craft a gcode file.
3
4 The plugin buttons which are commonly used are bolded and the ones which are rarely used have normal font weight.
5
6 """
7
8 from __future__ import absolute_import
9 #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.
10 import __init__
11
12 from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
13 from fabmetheus_utilities import archive
14 from fabmetheus_utilities import euclidean
15 from fabmetheus_utilities import gcodec
16 from fabmetheus_utilities import settings
17 from skeinforge_application.skeinforge_utilities import skeinforge_analyze
18 from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
19 from skeinforge_application.skeinforge_utilities import skeinforge_profile
20 import os
21 import sys
22 import time
23
24
25 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
26 __date__ = '$Date: 2008/21/04 $'
27 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
28
29
30 def getChainText( fileName, procedure ):
31         "Get a crafted shape file."
32         text=''
33         if fileName.endswith('.gcode') or fileName.endswith('.svg'):
34                 text = archive.getFileText(fileName)
35         procedures = getProcedures( procedure, text )
36         return getChainTextFromProcedures( fileName, procedures, text )
37
38 def getChainTextFromProcedures(fileName, procedures, text):
39         'Get a crafted shape file from a list of procedures.'
40         lastProcedureTime = time.time()
41         for procedure in procedures:
42                 craftModule = getCraftModule(procedure)
43                 if craftModule != None:
44                         text = craftModule.getCraftedText(fileName, text)
45                         if text == '':
46                                 print('Warning, the text was not recognized in getChainTextFromProcedures in skeinforge_craft for')
47                                 print(fileName)
48                                 return ''
49                         if gcodec.isProcedureDone( text, procedure ):
50                                 print('%s procedure took %s.' % (procedure.capitalize(), euclidean.getDurationString(time.time() - lastProcedureTime)))
51                                 lastProcedureTime = time.time()
52         return text
53
54 def getCraftModule(pluginName):
55         'Get craft module.'
56         return archive.getModuleWithDirectoryPath(getPluginsDirectoryPath(), pluginName)
57
58 def getCraftPreferences(pluginName):
59         'Get craft preferences.'
60         return settings.getReadRepository(getCraftModule(pluginName).getNewRepository()).preferences
61
62 def getCraftValue(preferenceName, preferences):
63         "Get craft preferences value."
64         for preference in preferences:
65                 if preference.name.startswith(preferenceName):
66                         return preference.value
67         return None
68
69 def getLastModule():
70         "Get the last tool."
71         craftSequence = getReadCraftSequence()
72         if len( craftSequence ) < 1:
73                 return None
74         return getCraftModule( craftSequence[-1] )
75
76 def getNewRepository():
77         'Get new repository.'
78         return CraftRepository()
79
80 def getPluginFileNames():
81         "Get craft plugin fileNames."
82         craftSequence = getReadCraftSequence()
83         craftSequence.sort()
84         return craftSequence
85
86 def getPluginsDirectoryPath():
87         "Get the plugins directory path."
88         return archive.getCraftPluginsDirectoryPath()
89
90 def getProcedures(procedure, text):
91         'Get the procedures up to and including the given procedure.'
92         craftSequence = getReadCraftSequence()
93         sequenceIndexFromProcedure = 0
94         if procedure in craftSequence:
95                 sequenceIndexFromProcedure = craftSequence.index(procedure)
96         craftSequence = craftSequence[: sequenceIndexFromProcedure + 1]
97         for craftSequenceIndex in xrange(len(craftSequence) - 1, -1, -1):
98                 procedure = craftSequence[craftSequenceIndex]
99                 if gcodec.isProcedureDone(text, procedure):
100                         return craftSequence[craftSequenceIndex + 1 :]
101         return craftSequence
102
103 def getReadCraftSequence():
104         "Get profile sequence."
105         return skeinforge_profile.getCraftTypePluginModule().getCraftSequence()
106
107 def writeChainTextWithNounMessage(fileName, procedure, shouldAnalyze=True):
108         'Get and write a crafted shape file.'
109         print('')
110         print('The %s tool is parsing the file:' % procedure)
111         print(os.path.basename(fileName))
112         print('')
113         startTime = time.time()
114         fileNameSuffix = fileName[: fileName.rfind('.')] + '_' + procedure + '.gcode'
115         craftText = getChainText(fileName, procedure)
116         if craftText == '':
117                 print('Warning, there was no text output in writeChainTextWithNounMessage in skeinforge_craft for:')
118                 print(fileName)
119                 return
120         archive.writeFileText(fileNameSuffix, craftText)
121         window = None
122         if shouldAnalyze:
123                 window = skeinforge_analyze.writeOutput(fileName, fileNameSuffix, fileNameSuffix, True, craftText)
124         print('')
125         print('The %s tool has created the file:' % procedure)
126         print(fileNameSuffix)
127         print('')
128         print('It took %s to craft the file.' % euclidean.getDurationString(time.time() - startTime))
129         return window
130
131 def writeOutput(fileName, shouldAnalyze=True):
132         "Craft a gcode file with the last module."
133         pluginModule = getLastModule()
134         if pluginModule != None:
135                 return pluginModule.writeOutput(fileName, shouldAnalyze)
136
137 def writeSVGTextWithNounMessage(fileName, repository, shouldAnalyze=True):
138         'Get and write an svg text and print messages.'
139         print('')
140         print('The %s tool is parsing the file:' % repository.lowerName)
141         print(os.path.basename(fileName))
142         print('')
143         startTime = time.time()
144         fileNameSuffix = fileName[: fileName.rfind('.')] + '_' + repository.lowerName + '.svg'
145         craftText = getChainText(fileName, repository.lowerName)
146         if craftText == '':
147                 return
148         archive.writeFileText(fileNameSuffix, craftText)
149         print('')
150         print('The %s tool has created the file:' % repository.lowerName)
151         print(fileNameSuffix)
152         print('')
153         print('It took %s to craft the file.' % euclidean.getDurationString(time.time() - startTime))
154         if shouldAnalyze:
155                 settings.getReadRepository(repository)
156                 settings.openSVGPage(fileNameSuffix, repository.svgViewer.value)
157
158
159 class CraftRadioButtonsSaveListener:
160         "A class to update the craft radio buttons."
161         def addToDialog( self, gridPosition ):
162                 "Add this to the dialog."
163                 euclidean.addElementToListDictionaryIfNotThere( self, self.repository.repositoryDialog, settings.globalProfileSaveListenerListTable )
164                 self.gridPosition = gridPosition.getCopy()
165                 self.gridPosition.row = gridPosition.rowStart
166                 self.gridPosition.increment()
167                 self.setRadioButtons()
168
169         def getFromRadioPlugins( self, radioPlugins, repository ):
170                 "Initialize."
171                 self.name = 'CraftRadioButtonsSaveListener'
172                 self.radioPlugins = radioPlugins
173                 self.repository = repository
174                 repository.displayEntities.append(self)
175                 return self
176
177         def save(self):
178                 "Profile has been saved and craft radio plugins should be updated."
179                 self.setRadioButtons()
180
181         def setRadioButtons(self):
182                 "Profile has been saved and craft radio plugins should be updated."
183                 activeRadioPlugins = []
184                 craftSequence = skeinforge_profile.getCraftTypePluginModule().getCraftSequence()
185                 gridPosition = self.gridPosition.getCopy()
186                 isRadioPluginSelected = False
187                 settings.getReadRepository(self.repository)
188                 for radioPlugin in self.radioPlugins:
189                         if radioPlugin.name in craftSequence:
190                                 activeRadioPlugins.append(radioPlugin)
191                                 radioPlugin.incrementGridPosition(gridPosition)
192                                 if radioPlugin.value:
193                                         radioPlugin.setSelect()
194                                         isRadioPluginSelected = True
195                         else:
196                                 radioPlugin.radiobutton.grid_remove()
197                 if not isRadioPluginSelected:
198                         radioPluginNames = self.repository.importantFileNames + [activeRadioPlugins[0].name]
199                         settings.getSelectedRadioPlugin(radioPluginNames , activeRadioPlugins).setSelect()
200                 self.repository.pluginFrame.update()
201
202
203 class CraftRepository:
204         "A class to handle the craft settings."
205         def __init__(self):
206                 "Set the default settings, execute title & settings fileName."
207                 skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_utilities.skeinforge_craft.html', self)
208                 self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Craft', self, '')
209                 self.importantFileNames = ['carve', 'chop', 'feed', 'flow', 'lift', 'raft', 'speed']
210                 allCraftNames = archive.getPluginFileNamesFromDirectoryPath(getPluginsDirectoryPath())
211                 self.radioPlugins = settings.getRadioPluginsAddPluginFrame(getPluginsDirectoryPath(), self.importantFileNames, allCraftNames, self)
212                 CraftRadioButtonsSaveListener().getFromRadioPlugins(self.radioPlugins, self)
213                 self.executeTitle = 'Craft'
214
215         def execute(self):
216                 "Craft button has been clicked."
217                 fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode( self.fileNameInput.value, [], self.fileNameInput.wasCancelled )
218                 for fileName in fileNames:
219                         writeOutput(fileName)
220
221
222 def main():
223         "Write craft output."
224         writeOutput(' '.join(sys.argv[1 :]), False)
225
226 if __name__ == "__main__":
227         main()