Added joris plugin

Added bunch of advanced settings for cups/vases
Added missing help tooltips
This commit is contained in:
daid 2012-02-27 17:14:51 +01:00
parent bca89f9ce5
commit e7a8601246

View File

@ -0,0 +1,188 @@
"""
This page is in the table of contents.
The Joris plugin makes the perimiter slowly increase in Z over the layer. This will make vases/cups without a z blob.
==Operation==
The default 'Activate Joris' checkbox is off. When it is on, the Joris plugin will do it's work.
==Settings==
===Layers From===
Default: 1
Defines which layer of the print the joris process starts from.
==Tips==
==Examples==
"""
from __future__ import absolute_import
#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.
import __init__
from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
from fabmetheus_utilities.geometry.solids import triangle_mesh
from fabmetheus_utilities.vector3 import Vector3
from fabmetheus_utilities import archive
from fabmetheus_utilities import euclidean
from fabmetheus_utilities import gcodec
from fabmetheus_utilities import intercircle
from fabmetheus_utilities import settings
from skeinforge_application.skeinforge_utilities import skeinforge_craft
from skeinforge_application.skeinforge_utilities import skeinforge_polyfile
from skeinforge_application.skeinforge_utilities import skeinforge_profile
import sys
__author__ = 'Daid (daid303@gmail.com'
__date__ = '$Date: 2012/24/01 $'
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
def getCraftedText(fileName, gcodeText, repository=None):
'Joris a gcode linear move text.'
return getCraftedTextFromText(archive.getTextIfEmpty(fileName, gcodeText), repository)
def getCraftedTextFromText(gcodeText, repository=None):
'Joris a gcode linear move text.'
if gcodec.isProcedureDoneOrFileIsEmpty(gcodeText, 'Joris'):
return gcodeText
if repository == None:
repository = settings.getReadRepository(JorisRepository())
if not repository.activateJoris.value:
return gcodeText
return JorisSkein().getCraftedGcode(gcodeText, repository)
def getIsMinimumSides(loops, sides=3):
'Determine if all the loops have at least the given number of sides.'
for loop in loops:
if len(loop) < sides:
return False
return True
def getNewRepository():
'Get new repository.'
return JorisRepository()
def writeOutput(fileName, shouldAnalyze=True):
'Joris a gcode linear move file. Chain Joris the gcode if it is not already Jorised.'
skeinforge_craft.writeChainTextWithNounMessage(fileName, 'joris', shouldAnalyze)
class JorisRepository:
'A class to handle the Joris settings.'
def __init__(self):
'Set the default settings, execute title & settings fileName.'
skeinforge_profile.addListsToCraftTypeRepository('skeinforge_application.skeinforge_plugins.craft_plugins.joris.html', self )
self.fileNameInput = settings.FileNameInput().getFromFileName( fabmetheus_interpret.getGNUTranslatorGcodeFileTypeTuples(), 'Open File for Joris', self, '')
self.openWikiManualHelpPage = settings.HelpPage().getOpenFromAbsolute('http://fabmetheus.crsndoo.com/wiki/index.php/Skeinforge_Joris')
self.activateJoris = settings.BooleanSetting().getFromValue('Activate Joris', self, False)
settings.LabelSeparator().getFromRepository(self)
self.layersFrom = settings.IntSpin().getSingleIncrementFromValue(0, 'Layers From (index):', self, 912345678, 1)
self.executeTitle = 'Joris'
def execute(self):
'Joris button has been clicked.'
fileNames = skeinforge_polyfile.getFileOrDirectoryTypesUnmodifiedGcode(self.fileNameInput.value, fabmetheus_interpret.getImportPluginFileNames(), self.fileNameInput.wasCancelled)
for fileName in fileNames:
writeOutput(fileName)
class JorisSkein:
'A class to Joris a skein of extrusions.'
def __init__(self):
'Initialize.'
self.distanceFeedRate = gcodec.DistanceFeedRate()
self.lines = None
self.layerIndex = -1
self.feedRateMinute = 959.0
self.travelFeedRateMinute = 957.0
self.perimeter = None
self.oldLocation = None
def getCraftedGcode( self, gcodeText, repository ):
'Parse gcode text and store the skin gcode.'
self.lines = archive.getTextLines(gcodeText)
self.repository = repository
self.layersFromBottom = repository.layersFrom.value
self.parseInitialization()
for self.lineIndex in xrange(self.lineIndex, len(self.lines)):
line = self.lines[self.lineIndex]
self.parseLine(line)
return gcodec.getGcodeWithoutDuplication('M108', self.distanceFeedRate.output.getvalue())
def parseInitialization(self):
'Parse gcode initialization and store the parameters.'
for self.lineIndex in xrange(len(self.lines)):
line = self.lines[self.lineIndex]
splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
firstWord = gcodec.getFirstWord(splitLine)
self.distanceFeedRate.parseSplitLine(firstWord, splitLine)
if firstWord == '(<layerThickness>':
self.layerThickness = float(splitLine[1])
elif firstWord == '(</extruderInitialization>)':
self.distanceFeedRate.addTagBracketedProcedure('skin')
return
elif firstWord == '(<travelFeedRatePerSecond>':
self.travelFeedRateMinute = 60.0 * float(splitLine[1])
self.distanceFeedRate.addLine(line)
def parseLine(self, line):
'Parse a gcode line and add it to the skin skein.'
splitLine = gcodec.getSplitLineBeforeBracketSemicolon(line)
if len(splitLine) < 1:
return
firstWord = splitLine[0]
if firstWord == 'G1':
self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine)
location = gcodec.getLocationFromSplitLine(self.oldLocation, splitLine)
self.oldLocation = location
if self.perimeter != None:
self.perimeter.append(location.dropAxis())
return
elif firstWord == '(<layer>':
self.layerIndex += 1
settings.printProgress(self.layerIndex, 'joris')
elif firstWord == 'M108':
self.oldFlowRate = gcodec.getDoubleAfterFirstLetter(splitLine[1])
elif firstWord == '(<perimeter>':
if self.layerIndex >= self.layersFromBottom:
self.perimeter = []
elif firstWord == '(</perimeter>)':
self.addJorisedPerimeter()
self.distanceFeedRate.addLine(line)
def addJorisedPerimeter(self):
'Add skinned perimeter.'
if self.perimeter == None:
return
#Calculate the total length of the perimeter.
p = self.oldLocation.dropAxis()
perimeterLength = 0;
for point in self.perimeter[1 :]:
perimeterLength += abs( point - p );
p = point
#Build the perimeter with an increasing Z over the length.
p = self.oldLocation.dropAxis()
len = 0;
self.distanceFeedRate.addLine('M101') # Turn extruder on.
for point in self.perimeter[1 :]:
len += abs( point - p );
p = point
self.distanceFeedRate.addGcodeMovementZWithFeedRate(self.feedRateMinute, point, self.oldLocation.z + self.layerThickness * len / perimeterLength)
self.distanceFeedRate.addLine('M103') # Turn extruder off.
self.perimeter = None
def main():
'Display the skin dialog.'
if len(sys.argv) > 1:
writeOutput(' '.join(sys.argv[1 :]))
else:
settings.startMainLoopFromConstructor(getNewRepository())
if __name__ == '__main__':
main()