chiark / gitweb /
Move SF into its own directory, to seperate SF and Cura. Rename newui to gui.
[cura.git] / Cura / cura_sf / skeinforge_application / skeinforge_plugins / craft_plugins / preface.py
1 #! /usr/bin/env python
2 """
3 This page is in the table of contents.
4 Preface converts the svg slices into gcode extrusion layers, optionally with home, positioning, turn off, and unit commands.
5
6 The preface manual page is at:
7 http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Preface
8
9 ==Settings==
10 ===Meta===
11 Default is empty.
12
13 The 'Meta' field is to add meta tags or a note to all your files.  Whatever is in that field will be added in a meta tagged line to the output.
14
15 ===Set Positioning to Absolute===
16 Default is on.
17
18 When selected, preface will add the G90 command to set positioning to absolute.
19
20 ===Set Units to Millimeters===
21 Default is on.
22
23 When selected, preface will add the G21 command to set the units to millimeters.
24
25 ===Start at Home===
26 Default is off.
27
28 When selected, the G28 go to home gcode will be added at the beginning of the file.
29
30 ===Turn Extruder Off===
31 ====Turn Extruder Off at Shut Down====
32 Default is on.
33
34 When selected, the M103 turn extruder off gcode will be added at the end of the file.
35
36 ====Turn Extruder Off at Start Up====
37 Default is on.
38
39 When selected, the M103 turn extruder off gcode will be added at the beginning of the file.
40
41 ==Examples==
42 The following examples preface the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and preface.py.
43
44 > python preface.py
45 This brings up the preface dialog.
46
47 > python preface.py Screw Holder Bottom.stl
48 The preface tool is parsing the file:
49 Screw Holder Bottom.stl
50 ..
51 The preface tool has created the file:
52 .. Screw Holder Bottom_preface.gcode
53
54 """
55
56 from __future__ import absolute_import
57 #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.
58 import __init__
59
60 from datetime import date, datetime
61 from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
62 from fabmetheus_utilities.svg_reader import SVGReader
63 from fabmetheus_utilities import archive
64 from fabmetheus_utilities import euclidean
65 from fabmetheus_utilities import gcodec
66 from fabmetheus_utilities import intercircle
67 from fabmetheus_utilities import settings
68 from fabmetheus_utilities import svg_writer
69 from skeinforge_application.skeinforge_utilities import skeinforge_craft
70 from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
71 from skeinforge_application.skeinforge_utilities import skeinforge_profile
72 from time import strftime
73 import os
74 import sys
75
76
77 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
78 __date__ = '$Date: 2008/02/05 $'
79 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
80
81
82 def getCraftedText( fileName, text='', repository = None ):
83         "Preface and convert an svg file or text."
84         return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
85
86 def getCraftedTextFromText( text, repository = None ):
87         "Preface and convert an svg text."
88         if gcodec.isProcedureDoneOrFileIsEmpty( text, 'preface'):
89                 return text
90         if repository == None:
91                 repository = settings.getReadRepository(PrefaceRepository())
92         return PrefaceSkein().getCraftedGcode(repository, text)
93
94 def getNewRepository():
95         'Get new repository.'
96         return PrefaceRepository()
97
98 def writeOutput(fileName, shouldAnalyze=True):
99         "Preface the carving of a gcode file."
100         skeinforge_craft.writeChainTextWithNounMessage(fileName, 'preface', shouldAnalyze)
101
102
103 class PrefaceRepository:
104         "A class to handle the preface settings."
105         def __init__(self):
106                 "Set the default settings, execute title & settings fileName."
107                 skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.preface.html', self )
108                 self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Preface', self, '')
109                 self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Preface')
110                 self.meta = settings.StringSetting().getFromValue('Meta:', self, '')
111                 self.setPositioningToAbsolute = settings.BooleanSetting().getFromValue('Set Positioning to Absolute', self, True )
112                 self.setUnitsToMillimeters = settings.BooleanSetting().getFromValue('Set Units to Millimeters', self, True )
113                 self.startAtHome = settings.BooleanSetting().getFromValue('Start at Home', self, False )
114                 settings.LabelSeparator().getFromRepository(self)
115                 settings.LabelDisplay().getFromName('- Turn Extruder Off -', self )
116                 self.turnExtruderOffAtShutDown = settings.BooleanSetting().getFromValue('Turn Extruder Off at Shut Down', self, True )
117                 self.turnExtruderOffAtStartUp = settings.BooleanSetting().getFromValue('Turn Extruder Off at Start Up', self, True )
118                 self.executeTitle = 'Preface'
119
120         def execute(self):
121                 "Preface button has been clicked."
122                 fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
123                 for fileName in fileNames:
124                         writeOutput(fileName)
125
126
127 class PrefaceSkein:
128         "A class to preface a skein of extrusions."
129         def __init__(self):
130                 self.distanceFeedRate = gcodec.DistanceFeedRate()
131                 self.extruderActive = False
132                 self.lineIndex = 0
133                 self.oldLocation = None
134                 self.svgReader = SVGReader()
135
136         def addInitializationToOutput(self):
137                 "Add initialization gcode to the output."
138                 self.distanceFeedRate.addTagBracketedLine('format', 'skeinforge gcode')
139                 absoluteFilePathUntilDot = archive.getUntilDot(archive.getCraftPluginsDirectoryPath('preface.py'))
140                 dateTodayString = date.today().isoformat().replace('-', '.')[2 :]
141                 if absoluteFilePathUntilDot == '/home/enrique/Desktop/backup/babbleold/script/reprap/fabmetheus/skeinforge_application/skeinforge_plugins/craft_plugins/preface': #is this script on Enrique's computer?
142                         archive.writeFileText(archive.getVersionFileName(), dateTodayString)
143                 versionText = archive.getFileText(archive.getVersionFileName())
144                 self.distanceFeedRate.addTagBracketedLine('version', versionText)
145                 dateTimeTuple = datetime.now().timetuple()
146                 created = dateTodayString + '|%s:%s' % (dateTimeTuple[3], dateTimeTuple[4])
147                 self.distanceFeedRate.addTagBracketedLine('created', created)
148                 self.distanceFeedRate.addLine('(<extruderInitialization>)')
149                 if self.repository.setPositioningToAbsolute.value:
150                         self.distanceFeedRate.addLine('G90 ;set positioning to absolute') # Set positioning to absolute.
151                 if self.repository.setUnitsToMillimeters.value:
152                         self.distanceFeedRate.addLine('G21 ;set units to millimeters') # Set units to millimeters.
153                 if self.repository.startAtHome.value:
154                         self.distanceFeedRate.addLine('G28 ;start at home') # Start at home.
155                 if self.repository.turnExtruderOffAtStartUp.value:
156                         self.distanceFeedRate.addLine('M103') # Turn extruder off.
157                 craftTypeName = skeinforge_profile.getCraftTypeName()
158                 self.distanceFeedRate.addTagBracketedLine('craftTypeName', craftTypeName)
159                 self.distanceFeedRate.addTagBracketedLine('decimalPlacesCarried', self.distanceFeedRate.decimalPlacesCarried)
160                 layerHeight = float(self.svgReader.sliceDictionary['layerHeight'])
161                 self.distanceFeedRate.addTagRoundedLine('layerThickness', layerHeight)
162                 self.distanceFeedRate.addTagRoundedLine('layerHeight', layerHeight)
163                 if self.repository.meta.value:
164                         self.distanceFeedRate.addTagBracketedLine('meta', self.repository.meta.value)
165                 edgeWidth = float(self.svgReader.sliceDictionary['edgeWidth'])
166                 self.distanceFeedRate.addTagRoundedLine('edgeWidth', edgeWidth)
167                 self.distanceFeedRate.addTagRoundedLine('perimeterWidth', edgeWidth)
168                 self.distanceFeedRate.addTagBracketedLine('profileName', skeinforge_profile.getProfileName(craftTypeName))
169                 self.distanceFeedRate.addLine('(<settings>)')
170                 pluginFileNames = skeinforge_craft.getPluginFileNames()
171                 for pluginFileName in pluginFileNames:
172                         self.addToolSettingLines(pluginFileName)
173                 self.distanceFeedRate.addLine('(</settings>)')
174                 self.distanceFeedRate.addTagBracketedLine('timeStampPreface', strftime('%Y%m%d_%H%M%S'))
175                 procedureNames = self.svgReader.sliceDictionary['procedureName'].replace(',', ' ').split()
176                 for procedureName in procedureNames:
177                         self.distanceFeedRate.addTagBracketedProcedure(procedureName)
178                 self.distanceFeedRate.addTagBracketedProcedure('preface')
179                 self.distanceFeedRate.addLine('(</extruderInitialization>)') # Initialization is finished, extrusion is starting.
180                 self.distanceFeedRate.addLine('(<crafting>)') # Initialization is finished, crafting is starting.
181
182         def addPreface( self, loopLayer ):
183                 "Add preface to the carve layer."
184                 self.distanceFeedRate.addLine('(<layer> %s )' % loopLayer.z ) # Indicate that a new layer is starting.
185                 for loop in loopLayer.loops:
186                         self.distanceFeedRate.addGcodeFromLoop(loop, loopLayer.z)
187                 self.distanceFeedRate.addLine('(</layer>)')
188
189         def addShutdownToOutput(self):
190                 "Add shutdown gcode to the output."
191                 self.distanceFeedRate.addLine('(</crafting>)') # GCode formatted comment
192                 if self.repository.turnExtruderOffAtShutDown.value:
193                         self.distanceFeedRate.addLine('M103') # Turn extruder motor off.
194
195         def addToolSettingLines(self, pluginName):
196                 "Add tool setting lines."
197                 preferences = skeinforge_craft.getCraftPreferences(pluginName)
198                 if skeinforge_craft.getCraftValue('Activate %s' % pluginName.capitalize(), preferences) != True:
199                         return
200                 for preference in preferences:
201                         valueWithoutReturn = str(preference.value).replace('\n', ' ').replace('\r', ' ')
202                         if preference.name != 'WindowPosition' and not preference.name.startswith('Open File'):
203                                 line = '%s %s %s' % (pluginName, preference.name.replace(' ', '_'), valueWithoutReturn)
204                                 self.distanceFeedRate.addTagBracketedLine('setting', line)
205
206         def getCraftedGcode( self, repository, gcodeText ):
207                 "Parse gcode text and store the bevel gcode."
208                 self.repository = repository
209                 self.svgReader.parseSVG('', gcodeText)
210                 if self.svgReader.sliceDictionary == None:
211                         print('Warning, nothing will be done because the sliceDictionary could not be found getCraftedGcode in preface.')
212                         return ''
213                 self.distanceFeedRate.decimalPlacesCarried = int(self.svgReader.sliceDictionary['decimalPlacesCarried'])
214                 self.addInitializationToOutput()
215                 for loopLayerIndex, loopLayer in enumerate(self.svgReader.loopLayers):
216                         settings.printProgressByNumber(loopLayerIndex, len(self.svgReader.loopLayers), 'preface')
217                         self.addPreface( loopLayer )
218                 self.addShutdownToOutput()
219                 return self.distanceFeedRate.output.getvalue()
220
221
222 def main():
223         "Display the preface dialog."
224         if len(sys.argv) > 1:
225                 writeOutput(' '.join(sys.argv[1 :]))
226         else:
227                 settings.startMainLoopFromConstructor(getNewRepository())
228
229 if __name__ == "__main__":
230         main()