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 / feed.py
1 """
2 This page is in the table of contents.
3 The feed script sets the maximum feed rate, operating feed rate & travel feed rate.
4
5 ==Operation==
6 The default 'Activate Feed' 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 ===Feed Rate===
10 Default is 16 millimeters/second.
11
12 Defines the feed rate for the shape.
13
14 ===Maximum Z Drill Feed Rate===
15 Default is 0.1 millimeters/second.
16
17 If your firmware limits the z feed rate, you do not need to set this setting.
18
19 Defines the maximum feed that the tool head will move in the z direction while the tool is on.
20
21 ===Maximum Z Feed Rate===
22 Default is one millimeter per second.
23
24 Defines the maximum speed that the tool head will move in the z direction.
25
26 ===Travel Feed Rate===
27 Default is 16 millimeters/second.
28
29 Defines the feed rate when the cutter is off.  The travel feed rate could be set as high as the cutter can be moved, it does not have to be limited by the maximum cutter rate.
30
31 ==Examples==
32 The following examples feed the file Screw Holder Bottom.stl.  The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and feed.py.
33
34 > python feed.py
35 This brings up the feed dialog.
36
37 > python feed.py Screw Holder Bottom.stl
38 The feed tool is parsing the file:
39 Screw Holder Bottom.stl
40 ..
41 The feed tool has created the file:
42 .. Screw Holder Bottom_feed.gcode
43
44 """
45
46 from __future__ import absolute_import
47
48 from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
49 from fabmetheus_utilities import archive
50 from fabmetheus_utilities import gcodec
51 from fabmetheus_utilities import settings
52 from skeinforge_application.skeinforge_utilities import skeinforge_craft
53 from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
54 from skeinforge_application.skeinforge_utilities import skeinforge_profile
55 import sys
56
57 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
58 __date__ = '$Date: 2008/21/04 $'
59 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
60
61
62 def getCraftedText(fileName, gcodeText='', repository=None):
63         "Feed the file or text."
64         return getCraftedTextFromText( archive.getTextIfEmpty( fileName, gcodeText ), repository )
65
66 def getCraftedTextFromText(gcodeText, repository=None):
67         "Feed a gcode linear move text."
68         if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'feed'):
69                 return gcodeText
70         if repository == None:
71                 repository = settings.getReadRepository(FeedRepository())
72         if not repository.activateFeed.value:
73                 return gcodeText
74         return FeedSkein().getCraftedGcode(gcodeText, repository)
75
76 def getNewRepository():
77         'Get new repository.'
78         return FeedRepository()
79
80 def writeOutput(fileName, shouldAnalyze=True):
81         "Feed a gcode linear move file."
82         skeinforge_craft.writeChainTextWithNounMessage(fileName, 'feed', shouldAnalyze)
83
84 class FeedRepository(object):
85         "A class to handle the feed settings."
86         def __init__(self):
87                 "Set the default settings, execute title & settings fileName."
88                 skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.feed.html', self)
89                 self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Feed', self, '')
90                 self.activateFeed = settings.BooleanSetting().getFromValue('Activate Feed', self, True)
91                 self.feedRatePerSecond = settings.FloatSpin().getFromValue(2.0, 'Feed Rate (mm/s):', self, 50.0, 16.0)
92                 self.maximumZDrillFeedRatePerSecond = settings.FloatSpin().getFromValue(0.02, 'Maximum Z Drill Feed Rate (mm/s):', self, 0.5, 0.1)
93                 self.maximumZFeedRatePerSecond = settings.FloatSpin().getFromValue(0.5, 'Maximum Z Feed Rate (mm/s):', self, 10.0, 1.0)
94                 self.travelFeedRatePerSecond = settings.FloatSpin().getFromValue(2.0, 'Travel Feed Rate (mm/s):', self, 50.0, 16.0)
95                 self.executeTitle = 'Feed'
96
97         def execute(self):
98                 "Feed button has been clicked."
99                 fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
100                 for fileName in fileNames:
101                         writeOutput(fileName)
102
103
104 class FeedSkein(object):
105         "A class to feed a skein of cuttings."
106         def __init__(self):
107                 self.distanceFeedRate = gcodec.DistanceFeedRate()
108                 self.feedRatePerSecond = 16.0
109                 self.isExtruderActive = False
110                 self.lineIndex = 0
111                 self.lines = None
112                 self.oldFlowrateString = None
113                 self.oldLocation = None
114
115         def getCraftedGcode(self, gcodeText, repository):
116                 "Parse gcode text and store the feed gcode."
117                 self.repository = repository
118                 self.feedRatePerSecond = repository.feedRatePerSecond.value
119                 self.travelFeedRateMinute = 60.0 * self.repository.travelFeedRatePerSecond.value
120                 self.lines = archive.getTextLines(gcodeText)
121                 self.parseInitialization()
122                 for line in self.lines[self.lineIndex :]:
123                         self.parseLine(line)
124                 return self.distanceFeedRate.output.getvalue()
125
126         def getFeededLine(self, line, splitLine):
127                 "Get gcode line with feed rate."
128                 location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
129                 self.oldLocation = location
130                 feedRateMinute = 60.0 * self.feedRatePerSecond
131                 if not self.isExtruderActive:
132                         feedRateMinute = self.travelFeedRateMinute
133                 return self.distanceFeedRate.getLineWithFeedRate(feedRateMinute, line, splitLine)
134
135         def parseInitialization(self):
136                 'Parse gcode initialization and store the parameters.'
137                 for self.lineIndex in xrange(len(self.lines)):
138                         line = self.lines[self.lineIndex]
139                         splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
140                         firstWord = gcodec.getFirstWord(splitLine)
141                         self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
142                         if firstWord == '(</extruderInitialization>)':
143                                 self.distanceFeedRate.addTagBracketedProcedure('feed')
144                                 return
145                         elif firstWord == '(<edgeWidth>':
146                                 self.absoluteEdgeWidth = abs(float(splitLine[1]))
147                                 self.distanceFeedRate.addTagBracketedLine('maximumZDrillFeedRatePerSecond', self.repository.maximumZDrillFeedRatePerSecond.value)
148                                 self.distanceFeedRate.addTagBracketedLine('maximumZFeedRatePerSecond', self.repository.maximumZFeedRatePerSecond.value )
149                                 self.distanceFeedRate.addTagBracketedLine('operatingFeedRatePerSecond', self.feedRatePerSecond)
150                                 self.distanceFeedRate.addTagBracketedLine('travelFeedRatePerSecond', self.repository.travelFeedRatePerSecond.value)
151                         self.distanceFeedRate.addLine(line)
152
153         def parseLine(self, line):
154                 "Parse a gcode line and add it to the feed skein."
155                 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
156                 if len(splitLine) < 1:
157                         return
158                 firstWord = splitLine[0]
159                 if firstWord == 'G1':
160                         line = self.getFeededLine(line, splitLine)
161                 elif firstWord == 'M101':
162                         self.isExtruderActive = True
163                 elif firstWord == 'M103':
164                         self.isExtruderActive = False
165                 self.distanceFeedRate.addLine(line)
166
167
168 def main():
169         'Display the feed dialog.'
170         if len(sys.argv) > 1:
171                 writeOutput(' '.join(sys.argv[1 :]))
172         else:
173                 settings.startMainLoopFromConstructor(getNewRepository())
174
175 if __name__ == "__main__":
176         main()