chiark / gitweb /
Add back the ultimaker platform, and made the platform mesh simpler.
[cura.git] / Cura / slice / cura_sf / skeinforge_application / skeinforge_plugins / craft_plugins / home.py
1 """
2 This page is in the table of contents.
3 Plugin to home the tool at beginning of each layer.
4
5 The home manual page is at:
6 http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Home
7
8 ==Operation==
9 The default 'Activate Home' checkbox is on.  When it is on, the functions described below will work, when it is off, nothing will be done.
10
11 ==Settings==
12 ===Name of Home File===
13 Default: home.gcode
14
15 At the beginning of a each layer, home will add the commands of a gcode script with the name of the "Name of Home File" setting, if one exists.  Home does not care if the text file names are capitalized, but some file systems do not handle file name cases properly, so to be on the safe side you should give them lower case names.  Home looks for those files in the alterations folder in the .skeinforge folder in the home directory. If it doesn't find the file it then looks in the alterations folder in the skeinforge_plugins folder.
16
17 ==Examples==
18 The following examples home the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and home.py.
19
20 > python home.py
21 This brings up the home dialog.
22
23 > python home.py Screw Holder Bottom.stl
24 The home tool is parsing the file:
25 Screw Holder Bottom.stl
26 ..
27 The home tool has created the file:
28 .. Screw Holder Bottom_home.gcode
29
30 """
31
32 from __future__ import absolute_import
33
34 from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
35 from fabmetheus_utilities.vector3 import Vector3
36 from fabmetheus_utilities import archive
37 from fabmetheus_utilities import euclidean
38 from fabmetheus_utilities import gcodec
39 from fabmetheus_utilities import settings
40 from skeinforge_application.skeinforge_utilities import skeinforge_craft
41 from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
42 from skeinforge_application.skeinforge_utilities import skeinforge_profile
43 import sys
44
45
46 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
47 __date__ = '$Date: 2008/21/04 $'
48 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
49
50
51 def getCraftedText( fileName, text, repository = None ):
52         "Home a gcode linear move file or text."
53         return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
54
55 def getCraftedTextFromText( gcodeText, repository = None ):
56         "Home a gcode linear move text."
57         if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'home'):
58                 return gcodeText
59         if repository == None:
60                 repository = settings.getReadRepository( HomeRepository() )
61         if not repository.activateHome.value:
62                 return gcodeText
63         return HomeSkein().getCraftedGcode(gcodeText, repository)
64
65 def getNewRepository():
66         'Get new repository.'
67         return HomeRepository()
68
69 def writeOutput(fileName, shouldAnalyze=True):
70         "Home a gcode linear move file.  Chain home the gcode if it is not already homed."
71         skeinforge_craft.writeChainTextWithNounMessage(fileName, 'home', shouldAnalyze)
72
73
74 class HomeRepository(object):
75         "A class to handle the home settings."
76         def __init__(self):
77                 "Set the default settings, execute title & settings fileName."
78                 skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.home.html', self)
79                 self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Home', self, '')
80                 self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Home')
81                 self.activateHome = settings.BooleanSetting().getFromValue('Activate Home', self, False )
82                 self.nameOfHomeFile = settings.StringSetting().getFromValue('Name of Home File:', self, 'home.gcode')
83                 self.executeTitle = 'Home'
84  
85         def execute(self):
86                 "Home button has been clicked."
87                 fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
88                 for fileName in fileNames:
89                         writeOutput(fileName)
90
91
92 class HomeSkein(object):
93         "A class to home a skein of extrusions."
94         def __init__(self):
95                 self.distanceFeedRate = gcodec.DistanceFeedRate()
96                 self.extruderActive = False
97                 self.highestZ = None
98                 self.homeLines = []
99                 self.layerCount = settings.LayerCount()
100                 self.lineIndex = 0
101                 self.lines = None
102                 self.oldLocation = None
103                 self.shouldHome = False
104                 self.travelFeedRateMinute = 957.0
105
106         def addFloat( self, begin, end ):
107                 "Add dive to the original height."
108                 beginEndDistance = begin.distance(end)
109                 alongWay = self.absoluteEdgeWidth / beginEndDistance
110                 closeToEnd = euclidean.getIntermediateLocation( alongWay, end, begin )
111                 closeToEnd.z = self.highestZ
112                 self.distanceFeedRate.addLine( self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( self.travelFeedRateMinute, closeToEnd.dropAxis(), closeToEnd.z ) )
113
114         def addHomeTravel( self, splitLine ):
115                 "Add the home travel gcode."
116                 location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
117                 self.highestZ = max( self.highestZ, location.z )
118                 if not self.shouldHome:
119                         return
120                 self.shouldHome = False
121                 if self.oldLocation == None:
122                         return
123                 if self.extruderActive:
124                         self.distanceFeedRate.addLine('M103')
125                 self.addHopUp( self.oldLocation )
126                 self.distanceFeedRate.addLinesSetAbsoluteDistanceMode(self.homeLines)
127                 self.addHopUp( self.oldLocation )
128                 self.addFloat( self.oldLocation, location )
129                 if self.extruderActive:
130                         self.distanceFeedRate.addLine('M101')
131
132         def addHopUp(self, location):
133                 "Add hop to highest point."
134                 locationUp = Vector3( location.x, location.y, self.highestZ )
135                 self.distanceFeedRate.addLine( self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( self.travelFeedRateMinute, locationUp.dropAxis(), locationUp.z ) )
136
137         def getCraftedGcode( self, gcodeText, repository ):
138                 "Parse gcode text and store the home gcode."
139                 self.repository = repository
140                 self.homeLines = settings.getAlterationFileLines(repository.nameOfHomeFile.value)
141                 if len(self.homeLines) < 1:
142                         return gcodeText
143                 self.lines = archive.getTextLines(gcodeText)
144                 self.parseInitialization( repository )
145                 for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
146                         line = self.lines[self.lineIndex]
147                         self.parseLine(line)
148                 return self.distanceFeedRate.output.getvalue()
149
150         def parseInitialization( self, repository ):
151                 'Parse gcode initialization and store the parameters.'
152                 for self.lineIndex in xrange(len(self.lines)):
153                         line = self.lines[self.lineIndex]
154                         splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
155                         firstWord = gcodec.getFirstWord(splitLine)
156                         self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
157                         if firstWord == '(</extruderInitialization>)':
158                                 self.distanceFeedRate.addTagBracketedProcedure('home')
159                                 return
160                         elif firstWord == '(<edgeWidth>':
161                                 self.absoluteEdgeWidth = abs(float(splitLine[1]))
162                         elif firstWord == '(<travelFeedRatePerSecond>':
163                                 self.travelFeedRateMinute = 60.0 * float(splitLine[1])
164                         self.distanceFeedRate.addLine(line)
165
166         def parseLine(self, line):
167                 "Parse a gcode line and add it to the bevel gcode."
168                 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
169                 if len(splitLine) < 1:
170                         return
171                 firstWord = splitLine[0]
172                 if firstWord == 'G1':
173                         self.addHomeTravel(splitLine)
174                         self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
175                 elif firstWord == '(<layer>':
176                         self.layerCount.printProgressIncrement('home')
177                         if len(self.homeLines) > 0:
178                                 self.shouldHome = True
179                 elif firstWord == 'M101':
180                         self.extruderActive = True
181                 elif firstWord == 'M103':
182                         self.extruderActive = False
183                 self.distanceFeedRate.addLine(line)
184
185
186 def main():
187         "Display the home dialog."
188         if len(sys.argv) > 1:
189                 writeOutput(' '.join(sys.argv[1 :]))
190         else:
191                 settings.startMainLoopFromConstructor(getNewRepository())
192
193 if __name__ == "__main__":
194         main()