2 This page is in the table of contents.
3 Oozebane is a script to turn off the extruder before the end of a thread and turn it on before the beginning.
5 The oozebane manual page is at:
6 http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Oozebane
8 After oozebane turns the extruder on, it slows the feed rate down where the thread starts. Then it speeds it up in steps so in theory the thread will remain at roughly the same thickness from the beginning.
11 The default 'Activate Oozebane' checkbox is on. When it is on, the functions described below will work, when it is off, the functions will not be called.
14 ===After Startup Distance===
17 When oozebane reaches the point where the extruder would of turned on, it slows down so that the thread will be thick at that point. Afterwards it speeds the extruder back up to operating speed. The speed up distance is the "After Startup Distance".
19 ===Early Shutdown Distance===
22 Defines the distance before the end of the thread that the extruder will be turned off. It is the most important oozebane setting. A higher distance means the extruder will turn off sooner and the end of the line will be thinner.
24 ===Early Startup Maximum Distance===
27 Defines the maximum distance before the thread starts that the extruder will be turned on
29 ===Early Startup Distance Constant===
32 The longer the extruder has been off, the earlier the extruder will turn back on, the ratio is one minus one over e to the power of the distance the extruder has been off over the "Early Startup Distance Constant".
34 ===First Early Startup Distance===
35 Default is twenty five.
37 Defines the distance before the first thread starts that the extruder will be turned off. This value should be high because, according to Marius, the extruder takes a second or two to extrude when starting for the first time.
39 ===Minimum Distance for Early Shutdown===
42 Defines the minimum distance that the extruder has to be off after the thread end for the early shutdown feature to activate.
44 ===Minimum Distance for Early Startup===
47 Defines the minimum distance that the extruder has to be off before the thread begins for the early start up feature to activate.
49 ===Slowdown Startup Steps===
52 When oozebane turns the extruder off, it slows the feed rate down in steps so in theory the thread will remain at roughly the same thickness until the end. The "Slowdown Startup Steps" setting is the number of steps, the more steps the smaller the size of the step that the feed rate will be decreased and the larger the size of the resulting gcode file.
55 The following examples oozebane the file Screw Holder Bottom.stl. The examples are run in a terminal in the folder which contains Screw Holder Bottom.stl and oozebane.py.
58 This brings up the oozebane dialog.
60 > python oozebane.py Screw Holder Bottom.stl
61 The oozebane tool is parsing the file:
62 Screw Holder Bottom.stl
64 The oozebane tool has created the file:
65 .. Screw Holder Bottom_oozebane.gcode
69 from __future__ import absolute_import
70 #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.
73 from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
74 from fabmetheus_utilities import archive
75 from fabmetheus_utilities import euclidean
76 from fabmetheus_utilities import gcodec
77 from fabmetheus_utilities import settings
78 from skeinforge_application.skeinforge_utilities import skeinforge_craft
79 from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
80 from skeinforge_application.skeinforge_utilities import skeinforge_profile
85 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
86 __date__ = '$Date: 2008/21/04 $'
87 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
90 def getCraftedText( fileName, text, oozebaneRepository = None ):
91 "Oozebane a gcode linear move file or text."
92 return getCraftedTextFromText( archive.getTextIfEmpty(fileName, text), oozebaneRepository )
94 def getCraftedTextFromText( gcodeText, oozebaneRepository = None ):
95 "Oozebane a gcode linear move text."
96 if gcodec.isProcedureDoneOrFileIsEmpty( gcodeText, 'oozebane'):
98 if oozebaneRepository == None:
99 oozebaneRepository = settings.getReadRepository( OozebaneRepository() )
100 if not oozebaneRepository.activateOozebane.value:
102 return OozebaneSkein().getCraftedGcode( gcodeText, oozebaneRepository )
104 def getNewRepository():
105 'Get new repository.'
106 return OozebaneRepository()
108 def writeOutput(fileName, shouldAnalyze=True):
109 "Oozebane a gcode linear move file."
110 skeinforge_craft.writeChainTextWithNounMessage(fileName, 'oozebane', shouldAnalyze)
113 class OozebaneRepository:
114 "A class to handle the oozebane settings."
116 "Set the default settings, execute title & settings fileName."
117 skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.oozebane.html', self )
118 self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Oozebane', self, '')
119 self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Oozebane')
120 self.activateOozebane = settings.BooleanSetting().getFromValue('Activate Oozebane', self, False )
121 self.afterStartupDistance = settings.FloatSpin().getFromValue( 0.7, 'After Startup Distance (millimeters):', self, 1.7, 1.2 )
122 self.earlyShutdownDistance = settings.FloatSpin().getFromValue( 0.7, 'Early Shutdown Distance (millimeters):', self, 1.7, 1.2 )
123 self.earlyStartupDistanceConstant = settings.FloatSpin().getFromValue( 10.0, 'Early Startup Distance Constant (millimeters):', self, 30.0, 20.0 )
124 self.earlyStartupMaximumDistance = settings.FloatSpin().getFromValue( 0.7, 'Early Startup Maximum Distance (millimeters):', self, 1.7, 1.2 )
125 self.firstEarlyStartupDistance = settings.FloatSpin().getFromValue( 5.0, 'First Early Startup Distance (millimeters):', self, 45.0, 25.0 )
126 self.minimumDistanceForEarlyStartup = settings.FloatSpin().getFromValue( 0.0, 'Minimum Distance for Early Startup (millimeters):', self, 10.0, 0.0 )
127 self.minimumDistanceForEarlyShutdown = settings.FloatSpin().getFromValue( 0.0, 'Minimum Distance for Early Shutdown (millimeters):', self, 10.0, 0.0 )
128 self.slowdownStartupSteps = settings.IntSpin().getFromValue( 2, 'Slowdown Startup Steps (positive integer):', self, 5, 3 )
129 self.executeTitle = 'Oozebane'
132 "Oozebane button has been clicked."
133 fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
134 for fileName in fileNames:
135 writeOutput(fileName)
139 "A class to oozebane a skein of extrusions."
141 self.distanceFeedRate = gcodec.DistanceFeedRate()
142 self.distanceFromThreadEndToThreadBeginning = None
143 self.earlyStartupDistance = None
144 self.extruderInactiveLongEnough = True
145 self.feedRateMinute = 961.0
146 self.isExtruderActive = False
147 self.isFirstExtrusion = True
148 self.isShutdownEarly = False
149 self.isStartupEarly = False
152 self.oldLocation = None
153 self.operatingFeedRateMinute = 959.0
154 self.shutdownStepIndex = 999999999
155 self.startupStepIndex = 999999999
157 def addAfterStartupLine( self, splitLine ):
158 "Add the after startup lines."
159 distanceAfterThreadBeginning = self.getDistanceAfterThreadBeginning()
160 location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
161 segment = self.oldLocation - location
162 segmentLength = segment.magnitude()
163 distanceBack = distanceAfterThreadBeginning - self.afterStartupDistances[ self.startupStepIndex ]
164 if segmentLength > 0.0:
165 locationBack = location + segment * distanceBack / segmentLength
166 feedRate = self.operatingFeedRateMinute * self.afterStartupFlowRates[ self.startupStepIndex ]
167 if not self.isCloseToEither( locationBack, location, self.oldLocation ):
168 self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( feedRate, locationBack ) )
169 self.startupStepIndex += 1
171 def addLineSetShutdowns(self, line):
172 "Add a line and set the shutdown variables."
173 self.distanceFeedRate.addLine(line)
174 self.isShutdownEarly = True
176 def getActiveFeedRateRatio(self):
177 "Get the feed rate of the first active move over the operating feed rate."
178 isSearchExtruderActive = self.isExtruderActive
179 for afterIndex in xrange(self.lineIndex, len(self.lines)):
180 line = self.lines[ afterIndex ]
181 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
182 firstWord = gcodec.getFirstWord(splitLine)
183 if firstWord == 'G1':
184 if isSearchExtruderActive:
185 return gcodec.getFeedRateMinute( self.feedRateMinute, splitLine ) / self.operatingFeedRateMinute
186 elif firstWord == 'M101':
187 isSearchExtruderActive = True
188 print('active feed rate ratio was not found in oozebane.')
191 def getAddAfterStartupLines(self, line):
192 "Get and / or add after the startup lines."
193 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
194 while self.isDistanceAfterThreadBeginningGreater():
195 self.addAfterStartupLine(splitLine)
196 if self.startupStepIndex >= len( self.afterStartupDistances ):
197 self.startupStepIndex = len( self.afterStartupDistances ) + 999999999999
198 return self.getLinearMoveWithFeedRateSplitLine( self.operatingFeedRateMinute, splitLine )
199 feedRate = self.operatingFeedRateMinute * self.getStartupFlowRateMultiplier( self.getDistanceAfterThreadBeginning() / self.afterStartupDistance, len( self.afterStartupDistances ) )
200 return self.getLinearMoveWithFeedRateSplitLine( feedRate, splitLine )
202 def getAddBeforeStartupLines(self, line):
203 "Get and / or add before the startup lines."
204 distanceThreadBeginning = self.getDistanceToThreadBeginning()
205 if distanceThreadBeginning == None:
207 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
208 self.extruderInactiveLongEnough = False
209 self.isStartupEarly = True
210 location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
211 segment = self.oldLocation - location
212 segmentLength = segment.magnitude()
213 distanceBack = self.earlyStartupDistance - distanceThreadBeginning
214 if segmentLength <= 0.0:
215 print('This should never happen, segmentLength is zero in getAddBeforeStartupLines in oozebane.')
217 self.extruderInactiveLongEnough = True
218 self.isStartupEarly = False
220 locationBack = location + segment * distanceBack / segmentLength
221 self.distanceFeedRate.addLine( self.getLinearMoveWithFeedRate( gcodec.getFeedRateMinute( self.feedRateMinute, splitLine ) , locationBack ) )
222 self.distanceFeedRate.addLine('M101')
223 if self.isCloseToEither( locationBack, location, self.oldLocation ):
225 return self.getLinearMoveWithFeedRate( self.operatingFeedRateMinute, location )
227 def getAddShutSlowDownLine(self, line):
228 "Add the shutdown and slowdown lines."
229 if self.shutdownStepIndex >= len( self.earlyShutdownDistances ):
230 self.shutdownStepIndex = len( self.earlyShutdownDistances ) + 99999999
232 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
233 distanceThreadEnd = self.getDistanceToExtruderOffCommand( self.earlyShutdownDistances[ self.shutdownStepIndex ] )
234 location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
235 if distanceThreadEnd == None:
236 distanceThreadEnd = self.getDistanceToExtruderOffCommand( self.earlyShutdownDistances[0] )
237 if distanceThreadEnd != None:
238 shutdownFlowRateMultiplier = self.getShutdownFlowRateMultiplier( 1.0 - distanceThreadEnd / self.earlyShutdownDistance, len( self.earlyShutdownDistances ) )
239 line = self.getLinearMoveWithFeedRate( self.feedRateMinute * shutdownFlowRateMultiplier, location )
240 self.distanceFeedRate.addLine(line)
242 segment = self.oldLocation - location
243 segmentLength = segment.magnitude()
244 distanceBack = self.earlyShutdownDistances[ self.shutdownStepIndex ] - distanceThreadEnd
245 locationBack = location
246 if segmentLength > 0.0:
247 locationBack = location + segment * distanceBack / segmentLength
248 if self.shutdownStepIndex == 0:
249 if not self.isCloseToEither( locationBack, location, self.oldLocation ):
250 line = self.getLinearMoveWithFeedRate( self.feedRateMinute, locationBack )
251 self.distanceFeedRate.addLine(line)
252 self.addLineSetShutdowns('M103')
254 if self.isClose( locationBack, self.oldLocation ):
256 feedRate = self.feedRateMinute * self.earlyShutdownFlowRates[ self.shutdownStepIndex ]
257 line = self.getLinearMoveWithFeedRate( feedRate, locationBack )
258 if self.isClose( locationBack, location ):
259 line = self.getLinearMoveWithFeedRate( feedRate, location )
260 self.distanceFeedRate.addLine(line)
263 def getAddShutSlowDownLines(self, line):
264 "Get and / or add the shutdown and slowdown lines."
265 while self.getAddShutSlowDownLine(line):
266 self.shutdownStepIndex += 1
269 def getCraftedGcode( self, gcodeText, oozebaneRepository ):
270 "Parse gcode text and store the oozebane gcode."
271 self.lines = archive.getTextLines(gcodeText)
272 self.oozebaneRepository = oozebaneRepository
273 self.parseInitialization( oozebaneRepository )
274 for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
275 line = self.lines[self.lineIndex]
277 return self.distanceFeedRate.output.getvalue()
279 def getDistanceAfterThreadBeginning(self):
280 "Get the distance after the beginning of the thread."
281 line = self.lines[self.lineIndex]
282 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
283 lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
285 extruderOnReached = False
286 for beforeIndex in xrange( self.lineIndex - 1, 3, - 1 ):
287 line = self.lines[ beforeIndex ]
288 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
289 firstWord = gcodec.getFirstWord(splitLine)
290 if firstWord == 'G1':
291 location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine )
292 totalDistance += location.distance( lastThreadLocation )
293 lastThreadLocation = location
294 if extruderOnReached:
296 elif firstWord == 'M101':
297 extruderOnReached = True
300 def getDistanceToExtruderOffCommand( self, remainingDistance ):
301 "Get the distance to the word."
302 line = self.lines[self.lineIndex]
303 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
304 lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
306 for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ):
307 line = self.lines[ afterIndex ]
308 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
309 firstWord = gcodec.getFirstWord(splitLine)
310 if firstWord == 'G1':
311 location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine )
312 totalDistance += location.distance( lastThreadLocation )
313 lastThreadLocation = location
314 if totalDistance >= remainingDistance:
316 elif firstWord == 'M103':
320 def getDistanceToThreadBeginning(self):
321 "Get the distance to the beginning of the thread."
322 if self.earlyStartupDistance == None:
324 line = self.lines[self.lineIndex]
325 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
326 lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
328 for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ):
329 line = self.lines[ afterIndex ]
330 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
331 firstWord = gcodec.getFirstWord(splitLine)
332 if firstWord == 'G1':
333 location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine )
334 totalDistance += location.distance( lastThreadLocation )
335 lastThreadLocation = location
336 if totalDistance >= self.earlyStartupDistance:
338 elif firstWord == 'M101':
342 def getDistanceToThreadBeginningAfterThreadEnd( self, remainingDistance ):
343 "Get the distance to the thread beginning after the end of this thread."
344 extruderOnReached = False
345 line = self.lines[self.lineIndex]
346 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
347 lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
348 threadEndReached = False
350 for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ):
351 line = self.lines[ afterIndex ]
352 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
353 firstWord = gcodec.getFirstWord(splitLine)
354 if firstWord == 'G1':
355 location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine )
357 totalDistance += location.distance( lastThreadLocation )
358 if totalDistance >= remainingDistance:
360 if extruderOnReached:
362 lastThreadLocation = location
363 elif firstWord == 'M101':
364 extruderOnReached = True
365 elif firstWord == 'M103':
366 threadEndReached = True
369 def getDistanceToThreadEnd(self):
370 "Get the distance to the end of the thread."
371 if self.shutdownStepIndex >= len( self.earlyShutdownDistances ):
373 return self.getDistanceToExtruderOffCommand( self.earlyShutdownDistances[ self.shutdownStepIndex ] )
375 def getLinearMoveWithFeedRate( self, feedRate, location ):
376 "Get a linear move line with the feed rate."
377 return self.distanceFeedRate.getLinearGcodeMovementWithFeedRate( feedRate, location.dropAxis(), location.z )
379 def getLinearMoveWithFeedRateSplitLine( self, feedRate, splitLine ):
380 "Get a linear move line with the feed rate and split line."
381 location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
382 return self.getLinearMoveWithFeedRate( feedRate, location )
384 def getOozebaneLine(self, line):
385 "Get oozebaned gcode line."
386 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
387 self.feedRateMinute = gcodec.getFeedRateMinute( self.feedRateMinute, splitLine )
388 if self.oldLocation == None:
390 if self.startupStepIndex < len( self.afterStartupDistances ):
391 return self.getAddAfterStartupLines(line)
392 if self.extruderInactiveLongEnough:
393 return self.getAddBeforeStartupLines(line)
394 if self.shutdownStepIndex < len( self.earlyShutdownDistances ):
395 return self.getAddShutSlowDownLines(line)
396 if self.isStartupEarly:
397 return self.getLinearMoveWithFeedRateSplitLine( self.operatingFeedRateMinute, splitLine )
400 def getShutdownFlowRateMultiplier( self, along, numberOfDistances ):
401 "Get the shut down flow rate multipler."
402 if numberOfDistances <= 0:
404 return 1.0 - 0.5 / float( numberOfDistances ) - along * float( numberOfDistances - 1 ) / float( numberOfDistances )
406 def getStartupFlowRateMultiplier( self, along, numberOfDistances ):
407 "Get the startup flow rate multipler."
408 if numberOfDistances <= 0:
410 return min( 1.0, 0.5 / float( numberOfDistances ) + along )
412 def isClose( self, location, otherLocation ):
413 "Determine if the location is close to the other location."
414 return location.distanceSquared( otherLocation ) < self.closeSquared
416 def isCloseToEither( self, location, otherLocationFirst, otherLocationSecond ):
417 "Determine if the location is close to the other locations."
418 if self.isClose( location, otherLocationFirst ):
420 return self.isClose( location, otherLocationSecond )
422 def isDistanceAfterThreadBeginningGreater(self):
423 "Determine if the distance after the thread beginning is greater than the step index after startup distance."
424 if self.startupStepIndex >= len( self.afterStartupDistances ):
426 return self.getDistanceAfterThreadBeginning() > self.afterStartupDistances[ self.startupStepIndex ]
428 def parseInitialization( self, oozebaneRepository ):
429 'Parse gcode initialization and store the parameters.'
430 for self.lineIndex in xrange(len(self.lines)):
431 line = self.lines[self.lineIndex]
432 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
433 firstWord = gcodec.getFirstWord(splitLine)
434 self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
435 if firstWord == '(</extruderInitialization>)':
436 self.distanceFeedRate.addTagBracketedProcedure('oozebane')
438 elif firstWord == '(<operatingFeedRatePerSecond>':
439 self.operatingFeedRateMinute = 60.0 * float(splitLine[1])
440 self.feedRateMinute = self.operatingFeedRateMinute
441 elif firstWord == '(<edgeWidth>':
442 self.edgeWidth = float(splitLine[1])
443 self.setExtrusionWidth( oozebaneRepository )
444 self.distanceFeedRate.addLine(line)
446 def parseLine(self, line):
447 "Parse a gcode line and add it to the bevel gcode."
448 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
449 if len(splitLine) < 1:
451 firstWord = splitLine[0]
452 if firstWord == 'G1':
453 self.setEarlyStartupDistance(splitLine)
454 line = self.getOozebaneLine(line)
455 self.oldLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
456 elif firstWord == 'M101':
457 self.isExtruderActive = True
458 self.extruderInactiveLongEnough = False
459 if self.getDistanceToExtruderOffCommand( self.earlyShutdownDistance ) == None:
460 self.setEarlyShutdown()
461 if self.getDistanceToExtruderOffCommand( 1.03 * ( self.earlyShutdownDistance + self.afterStartupDistance ) ) == None:
462 afterStartupRatio = 1.0
463 if self.minimumDistanceForEarlyStartup > 0.0:
464 if self.distanceFromThreadEndToThreadBeginning != None:
465 afterStartupRatio = self.distanceFromThreadEndToThreadBeginning / self.minimumDistanceForEarlyStartup
466 self.setAfterStartupFlowRates( afterStartupRatio )
467 self.startupStepIndex = 9999999999
468 if len( self.afterStartupDistances ) > 0:
469 self.startupStepIndex = 0
470 if self.isStartupEarly:
471 self.isStartupEarly = False
473 elif firstWord == 'M103':
474 self.isExtruderActive = False
475 self.shutdownStepIndex = 999999999
476 if self.getDistanceToThreadBeginning() == None:
477 self.extruderInactiveLongEnough = True
478 self.distanceFromThreadEndToThreadBeginning = None
479 self.earlyStartupDistance = None
480 if self.isShutdownEarly:
481 self.isShutdownEarly = False
483 self.distanceFeedRate.addLine(line)
485 def setAfterStartupFlowRates( self, afterStartupRatio ):
486 "Set the after startup flow rates."
487 afterStartupRatio = min( 1.0, afterStartupRatio )
488 afterStartupRatio = max( 0.0, afterStartupRatio )
489 self.afterStartupDistance = afterStartupRatio * self.getActiveFeedRateRatio() * self.oozebaneRepository.afterStartupDistance.value
490 self.afterStartupDistances = []
491 self.afterStartupFlowRate = 1.0
492 self.afterStartupFlowRates = []
493 afterStartupSteps = int( math.floor( afterStartupRatio * float( self.oozebaneRepository.slowdownStartupSteps.value ) ) )
494 if afterStartupSteps < 1:
496 if afterStartupSteps < 2:
497 afterStartupSteps = 2
498 for stepIndex in xrange( afterStartupSteps ):
499 afterWay = ( stepIndex + 1 ) / float( afterStartupSteps )
500 afterMiddleWay = self.getStartupFlowRateMultiplier( stepIndex / float( afterStartupSteps ), afterStartupSteps )
501 self.afterStartupDistances.append( afterWay * self.afterStartupDistance )
503 self.afterStartupFlowRate = afterMiddleWay
505 self.afterStartupFlowRates.append( afterMiddleWay )
506 if afterStartupSteps > 0:
507 self.afterStartupFlowRates.append(1.0)
509 def setEarlyShutdown(self):
510 "Set the early shutdown variables."
511 distanceToThreadBeginning = self.getDistanceToThreadBeginningAfterThreadEnd( self.minimumDistanceForEarlyShutdown )
512 earlyShutdownRatio = 1.0
513 if distanceToThreadBeginning != None:
514 if self.minimumDistanceForEarlyShutdown > 0.0:
515 earlyShutdownRatio = distanceToThreadBeginning / self.minimumDistanceForEarlyShutdown
516 self.setEarlyShutdownFlowRates( earlyShutdownRatio )
517 if len( self.earlyShutdownDistances ) > 0:
518 self.shutdownStepIndex = 0
520 def setEarlyShutdownFlowRates( self, earlyShutdownRatio ):
521 "Set the extrusion width."
522 earlyShutdownRatio = min( 1.0, earlyShutdownRatio )
523 earlyShutdownRatio = max( 0.0, earlyShutdownRatio )
524 self.earlyShutdownDistance = earlyShutdownRatio * self.getActiveFeedRateRatio() * self.oozebaneRepository.earlyShutdownDistance.value
525 self.earlyShutdownDistances = []
526 self.earlyShutdownFlowRates = []
527 earlyShutdownSteps = int( math.floor( earlyShutdownRatio * float( self.oozebaneRepository.slowdownStartupSteps.value ) ) )
528 if earlyShutdownSteps < 2:
529 earlyShutdownSteps = 0
530 earlyShutdownStepsMinusOne = float( earlyShutdownSteps ) - 1.0
531 for stepIndex in xrange( earlyShutdownSteps ):
532 downMiddleWay = self.getShutdownFlowRateMultiplier( stepIndex / earlyShutdownStepsMinusOne, earlyShutdownSteps )
533 downWay = 1.0 - stepIndex / earlyShutdownStepsMinusOne
534 self.earlyShutdownFlowRates.append( downMiddleWay )
535 self.earlyShutdownDistances.append( downWay * self.earlyShutdownDistance )
537 def setEarlyStartupDistance( self, splitLine ):
538 "Set the early startup distance."
539 if self.earlyStartupDistance != None:
541 self.distanceFromThreadEndToThreadBeginning = 0.0
542 lastThreadLocation = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
543 if self.oldLocation != None:
544 self.distanceFromThreadEndToThreadBeginning = lastThreadLocation.distance( self.oldLocation )
545 for afterIndex in xrange( self.lineIndex + 1, len(self.lines) ):
546 line = self.lines[ afterIndex ]
547 splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
548 firstWord = gcodec.getFirstWord(splitLine)
549 if firstWord == 'G1':
550 location = gcodec.getLocationFromSplitLine( lastThreadLocation, splitLine )
551 self.distanceFromThreadEndToThreadBeginning += location.distance( lastThreadLocation )
552 lastThreadLocation = location
553 elif firstWord == 'M101':
554 distanceConstantRatio = self.distanceFromThreadEndToThreadBeginning / self.earlyStartupDistanceConstant
555 earlyStartupOperatingDistance = self.earlyStartupMaximumDistance * ( 1.0 - math.exp( - distanceConstantRatio ) )
556 if self.isFirstExtrusion:
557 earlyStartupOperatingDistance = self.oozebaneRepository.firstEarlyStartupDistance.value
558 self.isFirstExtrusion = False
559 self.earlyStartupDistance = earlyStartupOperatingDistance * self.getActiveFeedRateRatio()
562 def setExtrusionWidth( self, oozebaneRepository ):
563 "Set the extrusion width."
564 self.closeSquared = 0.01 * self.edgeWidth * self.edgeWidth
565 self.earlyStartupMaximumDistance = oozebaneRepository.earlyStartupMaximumDistance.value
566 self.earlyStartupDistanceConstant = oozebaneRepository.earlyStartupDistanceConstant.value
567 self.minimumDistanceForEarlyStartup = oozebaneRepository.minimumDistanceForEarlyStartup.value
568 self.minimumDistanceForEarlyShutdown = oozebaneRepository.minimumDistanceForEarlyShutdown.value
569 self.setEarlyShutdownFlowRates(1.0)
570 self.setAfterStartupFlowRates(1.0)
574 "Display the oozebane dialog."
575 if len(sys.argv) > 1:
576 writeOutput(' '.join(sys.argv[1 :]))
578 settings.startMainLoopFromConstructor(getNewRepository())
580 if __name__ == "__main__":