chiark / gitweb /
Added experimental Slic3r option as backend. This does not support all options.
authordaid <daid303@gmail.com>
Mon, 26 Mar 2012 13:03:26 +0000 (15:03 +0200)
committerdaid <daid303@gmail.com>
Mon, 26 Mar 2012 13:03:26 +0000 (15:03 +0200)
Cura/fabmetheus_utilities/settings.py
Cura/newui/gcodeInterpreter.py
Cura/newui/preferencesDialog.py
Cura/newui/profile.py
Cura/newui/sliceRun.py

index 75556f9636a970130e1e1dc27b703665600d5362..d9573c3fbde3a5b122dfca1f3950174e97227920 100644 (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'))
index cd10cdfa793c5aeea066046436369876f9cbb40e..bc591cf96ba3354a7c1f2f379b0e5d4a4c4fe888 100644 (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
index 493807be14ec78545e04fc78bb8607156df686f4..0cf19c72ac2986fa7e5394f065d3bf560e39d9bc 100644 (file)
@@ -28,6 +28,9 @@ class preferencesDialog(configBase.configWindowBase):
                configBase.TitleRow(left, 'Communication settings')\r
                c = configBase.SettingRow(left, 'Serial port', 'serial_port', ['AUTO'] + machineCom.serialList(), 'Serial port to use for communication with the printer', type = 'preference')\r
                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')\r
+\r
+               configBase.TitleRow(left, 'Slicer settings')\r
+               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')\r
                \r
                self.MakeModal(True)\r
                main.Fit()\r
index 481932db62dfb18b6438a8cb8087e529efb0848a..96e56ad37a7a92fc78bd2aeffc302f08436ebdc7 100644 (file)
@@ -5,6 +5,7 @@ import __init__
 import ConfigParser\r
 import os\r
 import traceback\r
+import math\r
 \r
 #Single place to store the defaults, so we have a consistent set of default settings.\r
 profileDefaultSettings = {\r
@@ -63,6 +64,7 @@ preferencesDefaultSettings = {
        'steps_per_e': '0',\r
        'serial_port': 'AUTO',\r
        'serial_baud': '250000',\r
+       'slicer': 'Cura (Skeinforge based)',\r
 }\r
 \r
 def getDefaultProfilePath():\r
@@ -146,3 +148,39 @@ def putPreference(name, value):
                globalPreferenceParser.add_section('preference')\r
        globalPreferenceParser.set('preference', name, str(value))\r
        globalPreferenceParser.write(open(getPreferencePath(), 'w'))\r
+\r
+## Utility functions to calculate common profile values\r
+\r
+def calculateEdgeWidth():\r
+       wallThickness = float(getProfileSetting('wall_thickness'))\r
+       nozzleSize = float(getProfileSetting('nozzle_size'))\r
+       \r
+       if wallThickness < nozzleSize:\r
+               return wallThickness\r
+\r
+       lineCount = int(wallThickness / nozzleSize)\r
+       lineWidth = wallThickness / lineCount\r
+       lineWidthAlt = wallThickness / (lineCount + 1)\r
+       if lineWidth > nozzleSize * 1.5:\r
+               return lineWidthAlt\r
+       return lineWidth\r
+\r
+def calculateLineCount():\r
+       wallThickness = float(getProfileSetting('wall_thickness'))\r
+       nozzleSize = float(getProfileSetting('nozzle_size'))\r
+       \r
+       if wallThickness < nozzleSize:\r
+               return 1\r
+\r
+       lineCount = int(wallThickness / nozzleSize + 0.0001)\r
+       lineWidth = wallThickness / lineCount\r
+       lineWidthAlt = wallThickness / (lineCount + 1)\r
+       if lineWidth > nozzleSize * 1.5:\r
+               return lineCount + 1\r
+       return lineCount\r
+\r
+def calculateSolidLayerCount():\r
+       layerHeight = float(getProfileSetting('layer_height'))\r
+       solidThickness = float(getProfileSetting('solid_layer_thickness'))\r
+       return int(math.ceil(solidThickness / layerHeight - 0.0001))\r
+\r
index 22327682d61dd272f7bf4eb17a34897e2fd46194..b8c420dd34c87521f59f1e6e6cf20ed36db0fc16 100644 (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]
+