Added experimental Slic3r option as backend. This does not support all options.
parent
3f0c86d1d9
commit
22291be50e
|
@ -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'))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue