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 / 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 #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.
48 import __init__
49
50 from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
51 from fabmetheus_utilities import archive
52 from fabmetheus_utilities import euclidean
53 from fabmetheus_utilities import gcodec
54 from fabmetheus_utilities import intercircle
55 from fabmetheus_utilities import settings
56 from skeinforge_application.skeinforge_utilities import skeinforge_craft
57 from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
58 from skeinforge_application.skeinforge_utilities import skeinforge_profile
59 import math
60 import sys
61
62
63 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
64 __date__ = '$Date: 2008/21/04 $'
65 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
66
67
68 def getCraftedText(fileName, gcodeText='', repository=None):
69         "Feed the file or text."
70         return getCraftedTextFromText( archive.getTextIfEmpty( fileName, gcodeText ), repository )
71
72 def getCraftedTextFromText(gcodeText, repository=None):
73         "Feed a gcode linear move text."
74         if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'feed'):
75                 return gcodeText
76         if repository == None:
77                 repository = settings.getReadRepository(FeedRepository())
78         if not repository.activateFeed.value:
79                 return gcodeText
80         return FeedSkein().getCraftedGcode(gcodeText, repository)
81
82 def getNewRepository():
83         'Get new repository.'
84         return FeedRepository()
85
86 def writeOutput(fileName, shouldAnalyze=True):
87         "Feed a gcode linear move file."
88         skeinforge_craft.writeChainTextWithNounMessage(fileName, 'feed', shouldAnalyze)
89
90
91 class FeedRepository:
92         "A class to handle the feed settings."
93         def __init__(self):
94                 "Set the default settings, execute title & settings fileName."
95                 skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.feed.html', self)
96                 self.fileNameInput = settings.FileNameInput().getFromFileName(fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Feed', self, '')
97                 self.activateFeed = settings.BooleanSetting().getFromValue('Activate Feed', self, True)
98                 self.feedRatePerSecond = settings.FloatSpin().getFromValue(2.0, 'Feed Rate (mm/s):', self, 50.0, 16.0)
99                 self.maximumZDrillFeedRatePerSecond = settings.FloatSpin().getFromValue(0.02, 'Maximum Z Drill Feed Rate (mm/s):', self, 0.5, 0.1)
100                 self.maximumZFeedRatePerSecond = settings.FloatSpin().getFromValue(0.5, 'Maximum Z Feed Rate (mm/s):', self, 10.0, 1.0)
101                 self.travelFeedRatePerSecond = settings.FloatSpin().getFromValue(2.0, 'Travel Feed Rate (mm/s):', self, 50.0, 16.0)
102                 self.executeTitle = 'Feed'
103
104         def execute(self):
105                 "Feed button has been clicked."
106                 fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
107                 for fileName in fileNames:
108                         writeOutput(fileName)
109
110
111 class FeedSkein:
112         "A class to feed a skein of cuttings."
113         def __init__(self):
114                 self.distanceFeedRate = gcodec.DistanceFeedRate()
115                 self.feedRatePerSecond = 16.0
116                 self.isExtruderActive = False
117                 self.lineIndex = 0
118                 self.lines = None
119                 self.oldFlowrateString = None
120                 self.oldLocation = None
121
122         def getCraftedGcode(self, gcodeText, repository):
123                 "Parse gcode text and store the feed gcode."
124                 self.repository = repository
125                 self.feedRatePerSecond = repository.feedRatePerSecond.value
126                 self.travelFeedRateMinute = 60.0 * self.repository.travelFeedRatePerSecond.value
127                 self.lines = archive.getTextLines(gcodeText)
128                 self.parseInitialization()
129                 for line in self.lines[self.lineIndex :]:
130                         self.parseLine(line)
131                 return self.distanceFeedRate.output.getvalue()
132
133         def getFeededLine(self, line, splitLine):
134                 "Get gcode line with feed rate."
135                 location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
136                 self.oldLocation = location
137                 feedRateMinute = 60.0 * self.feedRatePerSecond
138                 if not self.isExtruderActive:
139                         feedRateMinute = self.travelFeedRateMinute
140                 return self.distanceFeedRate.getLineWithFeedRate(feedRateMinute, line, splitLine)
141
142         def parseInitialization(self):
143                 'Parse gcode initialization and store the parameters.'
144                 for self.lineIndex in xrange(len(self.lines)):
145                         line = self.lines[self.lineIndex]
146                         splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
147                         firstWord = gcodec.getFirstWord(splitLine)
148                         self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
149                         if firstWord == '(</extruderInitialization>)':
150                                 self.distanceFeedRate.addTagBracketedProcedure('feed')
151                                 return
152                         elif firstWord == '(<edgeWidth>':
153                                 self.absoluteEdgeWidth = abs(float(splitLine[1]))
154                                 self.distanceFeedRate.addTagBracketedLine('maximumZDrillFeedRatePerSecond', self.repository.maximumZDrillFeedRatePerSecond.value)
155                                 self.distanceFeedRate.addTagBracketedLine('maximumZFeedRatePerSecond', self.repository.maximumZFeedRatePerSecond.value )
156                                 self.distanceFeedRate.addTagBracketedLine('operatingFeedRatePerSecond', self.feedRatePerSecond)
157                                 self.distanceFeedRate.addTagBracketedLine('travelFeedRatePerSecond', self.repository.travelFeedRatePerSecond.value)
158                         self.distanceFeedRate.addLine(line)
159
160         def parseLine(self, line):
161                 "Parse a gcode line and add it to the feed skein."
162                 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
163                 if len(splitLine) < 1:
164                         return
165                 firstWord = splitLine[0]
166                 if firstWord == 'G1':
167                         line = self.getFeededLine(line, splitLine)
168                 elif firstWord == 'M101':
169                         self.isExtruderActive = True
170                 elif firstWord == 'M103':
171                         self.isExtruderActive = False
172                 self.distanceFeedRate.addLine(line)
173
174
175 def main():
176         'Display the feed dialog.'
177         if len(sys.argv) > 1:
178                 writeOutput(' '.join(sys.argv[1 :]))
179         else:
180                 settings.startMainLoopFromConstructor(getNewRepository())
181
182 if __name__ == "__main__":
183         main()