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 return lambda setting: float(profile.getProfileSetting(name)) / 100
def calculateEdgeWidth(setting): def calculateEdgeWidth(setting):
wallThickness = float(profile.getProfileSetting('wall_thickness')) return profile.calculateEdgeWidth()
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
def calculateShells(setting): def calculateShells(setting):
return calculateShellsImp(float(profile.getProfileSetting('wall_thickness'))) return profile.calculateLineCount() - 1
def calculateShellsBase(setting): def calculateShellsBase(setting):
return calculateShellsImp(float(profile.getProfileSetting('wall_thickness')) + float(profile.getProfileSetting('extra_base_wall_thickness'))) edgeWidth = profile.calculateEdgeWidth()
extraWall = float(profile.getProfileSetting('extra_base_wall_thickness'))
def calculateShellsImp(wallThickness):
nozzleSize = float(profile.getProfileSetting('nozzle_size'))
if wallThickness < nozzleSize: return profile.calculateLineCount() - 1 + int(extraWall / edgeWidth + 0.0001)
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
def calculateSolidLayerCount(setting): def calculateSolidLayerCount(setting):
layerHeight = float(profile.getProfileSetting('layer_height')) return profile.calculateSolidLayerCount()
solidThickness = float(profile.getProfileSetting('solid_layer_thickness'))
ret = int(math.ceil(solidThickness / layerHeight - 0.0001))
return ret
def firstLayerSpeedRatio(setting): def firstLayerSpeedRatio(setting):
bottomSpeed = float(profile.getProfileSetting('bottom_layer_speed')) bottomSpeed = float(profile.getProfileSetting('bottom_layer_speed'))

View File

@ -46,6 +46,17 @@ class gcode():
pathType = line[6:].strip() pathType = line[6:].strip()
if pathType != "CUSTOM": if pathType != "CUSTOM":
startCodeDone = True 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') G = self.getCodeInt(line, 'G')
if G is not None: if G is not None:
if G == 0 or G == 1: #Move if G == 0 or G == 1: #Move

View File

@ -28,6 +28,9 @@ class preferencesDialog(configBase.configWindowBase):
configBase.TitleRow(left, 'Communication settings') 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, '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') 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) self.MakeModal(True)
main.Fit() main.Fit()

View File

@ -5,6 +5,7 @@ import __init__
import ConfigParser import ConfigParser
import os import os
import traceback import traceback
import math
#Single place to store the defaults, so we have a consistent set of default settings. #Single place to store the defaults, so we have a consistent set of default settings.
profileDefaultSettings = { profileDefaultSettings = {
@ -63,6 +64,7 @@ preferencesDefaultSettings = {
'steps_per_e': '0', 'steps_per_e': '0',
'serial_port': 'AUTO', 'serial_port': 'AUTO',
'serial_baud': '250000', 'serial_baud': '250000',
'slicer': 'Cura (Skeinforge based)',
} }
def getDefaultProfilePath(): def getDefaultProfilePath():
@ -146,3 +148,39 @@ def putPreference(name, value):
globalPreferenceParser.add_section('preference') globalPreferenceParser.add_section('preference')
globalPreferenceParser.set('preference', name, str(value)) globalPreferenceParser.set('preference', name, str(value))
globalPreferenceParser.write(open(getPreferencePath(), 'w')) 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 import platform, os, subprocess, sys
from skeinforge_application.skeinforge_utilities import skeinforge_craft from skeinforge_application.skeinforge_utilities import skeinforge_craft
from newui import profile
def getPyPyExe(): def getPyPyExe():
"Return the path to the pypy executable if we can find it. Else return False" "Return the path to the pypy executable if we can find it. Else return False"
@ -23,6 +24,25 @@ def getPyPyExe():
return pypyExe return pypyExe
return False 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): 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." "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() pypyExe = getPyPyExe()
@ -41,7 +61,60 @@ def runSlice(fileNames):
subprocess.call([pypyExe, os.path.join(sys.path[0], sys.argv[0]), fileName]) subprocess.call([pypyExe, os.path.join(sys.path[0], sys.argv[0]), fileName])
def getSliceCommand(filename): def getSliceCommand(filename):
pypyExe = getPyPyExe() if profile.getPreference('slicer').startswith('Slic3r'):
if pypyExe == False: slic3rExe = getSlic3rExe()
pypyExe = sys.executable if slic3rExe == False:
return [pypyExe, os.path.join(sys.path[0], os.path.split(sys.argv[0])[1]), filename] 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]