mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-06 08:26:07 +08:00
Added joris plugin
Added bunch of advanced settings for cups/vases Added missing help tooltips
This commit is contained in:
parent
bca89f9ce5
commit
e7a8601246
@ -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()
|
Loading…
x
Reference in New Issue
Block a user