2 This page is in the table of contents.
3 Plugin to home the tool at beginning of each layer.
5 The home manual page is at:
6 http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Home
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.
12 ===Name of Home File===
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.
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.
21 This brings up the home dialog.
23 > python home.py Screw Holder Bottom.stl
24 The home tool is parsing the file:
25 Screw Holder Bottom.stl
27 The home tool has created the file:
28 .. Screw Holder Bottom_home.gcode
32 from __future__ import absolute_import
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
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'
51 def getCraftedText( fileName, text, repository = None ):
52 "Home a gcode linear move file or text."
53 return getCraftedTextFromText(archive.getTextIfEmpty(fileName, text), repository)
55 def getCraftedTextFromText( gcodeText, repository = None ):
56 "Home a gcode linear move text."
57 if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'home'):
59 if repository == None:
60 repository = settings.getReadRepository( HomeRepository() )
61 if not repository.activateHome.value:
63 return HomeSkein().getCraftedGcode(gcodeText, repository)
65 def getNewRepository():
67 return HomeRepository()
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)
74 class HomeRepository(object):
75 "A class to handle the home settings."
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'
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:
92 class HomeSkein(object):
93 "A class to home a skein of extrusions."
95 self.distanceFeedRate = gcodec.DistanceFeedRate()
96 self.extruderActive = False
99 self.layerCount = settings.LayerCount()
102 self.oldLocation = None
103 self.shouldHome = False
104 self.travelFeedRateMinute = 957.0
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 ) )
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:
120 self.shouldHome = False
121 if self.oldLocation == None:
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')
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 ) )
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:
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]
148 return self.distanceFeedRate.output.getvalue()
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')
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)
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:
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)
187 "Display the home dialog."
188 if len(sys.argv) > 1:
189 writeOutput(' '.join(sys.argv[1 :]))
191 settings.startMainLoopFromConstructor(getNewRepository())
193 if __name__ == "__main__":