Added experimental Slic3r option as backend. This does not support all options.

master
daid 2012-03-26 15:03:26 +02:00
parent 3f0c86d1d9
commit 22291be50e
5 changed files with 135 additions and 34 deletions

View File

@ -36,43 +36,19 @@ def storedPercentSetting(name):
return lambda setting: float(profile.getProfileSetting(name)) / 100
def calculateEdgeWidth(setting):
wallThickness = float(profile.getProfileSetting('wall_thickness'))
nozzleSize = float(profile.getProfileSetting('nozzle_size'))
if wallThickness < nozzleSize:
return wallThickness
lineCount = int(wallThickness / nozzleSize)
lineWidth = wallThickness / lineCount
lineWidthAlt = wallThickness / (lineCount + 1)
if lineWidth > nozzleSize * 1.5:
return lineWidthAlt
return lineWidth
return profile.calculateEdgeWidth()
def calculateShells(setting):
return calculateShellsImp(float(profile.getProfileSetting('wall_thickness')))
return profile.calculateLineCount() - 1
def calculateShellsBase(setting):
return calculateShellsImp(float(profile.getProfileSetting('wall_thickness')) + float(profile.getProfileSetting('extra_base_wall_thickness')))
def calculateShellsImp(wallThickness):
nozzleSize = float(profile.getProfileSetting('nozzle_size'))
edgeWidth = profile.calculateEdgeWidth()
extraWall = float(profile.getProfileSetting('extra_base_wall_thickness'))
if wallThickness < nozzleSize:
return 0
lineCount = int(wallThickness / nozzleSize + 0.0001)
lineWidth = wallThickness / lineCount
lineWidthAlt = wallThickness / (lineCount + 1)
if lineWidth > nozzleSize * 1.5:
return lineCount
return lineCount - 1
return profile.calculateLineCount() - 1 + int(extraWall / edgeWidth + 0.0001)
def calculateSolidLayerCount(setting):
layerHeight = float(profile.getProfileSetting('layer_height'))
solidThickness = float(profile.getProfileSetting('solid_layer_thickness'))
ret = int(math.ceil(solidThickness / layerHeight - 0.0001))
return ret
return profile.calculateSolidLayerCount()
def firstLayerSpeedRatio(setting):
bottomSpeed = float(profile.getProfileSetting('bottom_layer_speed'))

View File

@ -46,6 +46,17 @@ class gcode():
pathType = line[6:].strip()
if pathType != "CUSTOM":
startCodeDone = True
if ';' in line:
comment = line[line.find(';')+1:].strip()
if comment == 'fill':
pathType = 'FILL'
elif comment == 'perimeter':
pathType = 'WALL-INNER'
elif comment == 'skirt':
pathType = 'SKIRT'
if pathType != "CUSTOM":
startCodeDone = True
line = line[0:line.find(';')]
G = self.getCodeInt(line, 'G')
if G is not None:
if G == 0 or G == 1: #Move

View File

@ -28,6 +28,9 @@ class preferencesDialog(configBase.configWindowBase):
configBase.TitleRow(left, 'Communication settings')
c = configBase.SettingRow(left, 'Serial port', 'serial_port', ['AUTO'] + machineCom.serialList(), 'Serial port to use for communication with the printer', type = 'preference')
c = configBase.SettingRow(left, 'Baudrate', 'serial_baud', '250000', 'Speed of the serial port communication\nNeeds to match your firmware settings\nCommon values are 250000, 115200, 57600', type = 'preference')
configBase.TitleRow(left, 'Slicer settings')
c = configBase.SettingRow(left, 'Slicer selection', 'slicer', ['Cura (Skeinforge based)', 'Slic3r'], 'Which slicer to use to slice objects. Usually the Cura engine produces the best results. But Slic3r is developing fast and is faster with slicing.', type = 'preference')
self.MakeModal(True)
main.Fit()

View File

@ -5,6 +5,7 @@ import __init__
import ConfigParser
import os
import traceback
import math
#Single place to store the defaults, so we have a consistent set of default settings.
profileDefaultSettings = {
@ -63,6 +64,7 @@ preferencesDefaultSettings = {
'steps_per_e': '0',
'serial_port': 'AUTO',
'serial_baud': '250000',
'slicer': 'Cura (Skeinforge based)',
}
def getDefaultProfilePath():
@ -146,3 +148,39 @@ def putPreference(name, value):
globalPreferenceParser.add_section('preference')
globalPreferenceParser.set('preference', name, str(value))
globalPreferenceParser.write(open(getPreferencePath(), 'w'))
## Utility functions to calculate common profile values
def calculateEdgeWidth():
wallThickness = float(getProfileSetting('wall_thickness'))
nozzleSize = float(getProfileSetting('nozzle_size'))
if wallThickness < nozzleSize:
return wallThickness
lineCount = int(wallThickness / nozzleSize)
lineWidth = wallThickness / lineCount
lineWidthAlt = wallThickness / (lineCount + 1)
if lineWidth > nozzleSize * 1.5:
return lineWidthAlt
return lineWidth
def calculateLineCount():
wallThickness = float(getProfileSetting('wall_thickness'))
nozzleSize = float(getProfileSetting('nozzle_size'))
if wallThickness < nozzleSize:
return 1
lineCount = int(wallThickness / nozzleSize + 0.0001)
lineWidth = wallThickness / lineCount
lineWidthAlt = wallThickness / (lineCount + 1)
if lineWidth > nozzleSize * 1.5:
return lineCount + 1
return lineCount
def calculateSolidLayerCount():
layerHeight = float(getProfileSetting('layer_height'))
solidThickness = float(getProfileSetting('solid_layer_thickness'))
return int(math.ceil(solidThickness / layerHeight - 0.0001))

View File

@ -3,6 +3,7 @@ from __future__ import absolute_import
import platform, os, subprocess, sys
from skeinforge_application.skeinforge_utilities import skeinforge_craft
from newui import profile
def getPyPyExe():
"Return the path to the pypy executable if we can find it. Else return False"
@ -23,6 +24,25 @@ def getPyPyExe():
return pypyExe
return False
def getSlic3rExe():
"Return the path to the pypy executable if we can find it. Else return False"
if platform.system() == "Windows":
exeName = "slic3r.exe"
slic3rExe = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../Slic3r/bin/slic3r.exe"));
else:
exeName = "slic3r"
slic3rExe = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../Slic3r/bin/slic3r"));
if os.path.exists(slic3rExe):
return slic3rExe
path = os.environ['PATH']
paths = path.split(os.pathsep)
for p in paths:
slic3rExe = os.path.join(p, exeName)
if os.path.exists(slic3rExe):
return slic3rExe
return False
def runSlice(fileNames):
"Run the slicer on the files. If we are running with PyPy then just do the slicing action. If we are running as Python, try to find pypy."
pypyExe = getPyPyExe()
@ -41,7 +61,60 @@ def runSlice(fileNames):
subprocess.call([pypyExe, os.path.join(sys.path[0], sys.argv[0]), fileName])
def getSliceCommand(filename):
pypyExe = getPyPyExe()
if pypyExe == False:
pypyExe = sys.executable
return [pypyExe, os.path.join(sys.path[0], os.path.split(sys.argv[0])[1]), filename]
if profile.getPreference('slicer').startswith('Slic3r'):
slic3rExe = getSlic3rExe()
if slic3rExe == False:
return False
cmd = [slic3rExe,
'--output-filename-format', '[input_filename_base]_export.gcode',
'--nozzle-diameter', str(profile.calculateEdgeWidth()),
'--print-center', '%s,%s' % (profile.getProfileSetting('machine_center_x'), profile.getProfileSetting('machine_center_y')),
'--z-offset', '0',
'--gcode-flavor', 'reprap',
'--gcode-comments',
'--filament-diameter', profile.getProfileSetting('filament_diameter'),
'--extrusion-multiplier', profile.getProfileSetting('filament_density'),
'--temperature', profile.getProfileSetting('print_temperature'),
'--travel-speed', profile.getProfileSetting('travel_speed'),
'--perimeter-speed', profile.getProfileSetting('print_speed'),
'--small-perimeter-speed', profile.getProfileSetting('print_speed'),
'--infill-speed', profile.getProfileSetting('print_speed'),
'--solid-infill-speed', profile.getProfileSetting('print_speed'),
'--bridge-speed', profile.getProfileSetting('print_speed'),
'--bottom-layer-speed-ratio', str(float(profile.getProfileSetting('bottom_layer_speed')) / float(profile.getProfileSetting('print_speed'))),
'--layer-height', profile.getProfileSetting('layer_height'),
'--first-layer-height-ratio', '1.0',
'--infill-every-layers', '1',
'--perimeters', str(profile.calculateLineCount()),
'--solid-layers', str(profile.calculateSolidLayerCount()),
'--fill-density', str(float(profile.getProfileSetting('fill_density'))/100),
'--fill-angle', '45',
'--fill-pattern', 'rectilinear',
'--solid-fill-pattern', 'rectilinear',
'--start-gcode', '',
'--end-gcode', '',
'--retract-length', profile.getProfileSetting('retraction_amount'),
'--retract-speed', str(int(float(profile.getProfileSetting('retraction_speed')))),
'--retract-restart-extra', profile.getProfileSetting('retraction_extra'),
'--retract-before-travel', profile.getProfileSetting('retraction_min_travel'),
'--retract-lift', '0',
'--slowdown-below-layer-time', profile.getProfileSetting('cool_min_layer_time'),
'--min-print-speed', profile.getProfileSetting('cool_min_feedrate'),
'--skirts', profile.getProfileSetting('skirt_line_count'),
'--skirt-distance', str(int(float(profile.getProfileSetting('skirt_gap')))),
'--skirt-height', '1',
'--scale', profile.getProfileSetting('model_scale'),
'--rotate', profile.getProfileSetting('model_rotate_base'),
'--duplicate-x', profile.getProfileSetting('model_multiply_x'),
'--duplicate-y', profile.getProfileSetting('model_multiply_y'),
'--duplicate-distance', '10']
if profile.getProfileSetting('support') != 'None':
cmd.extend(['--support-material'])
cmd.extend([filename])
return cmd
else:
pypyExe = getPyPyExe()
if pypyExe == False:
pypyExe = sys.executable
return [pypyExe, os.path.join(sys.path[0], os.path.split(sys.argv[0])[1]), filename]