From 93f8d13b0a7d09b1fc1c9a514a916e975fae1086 Mon Sep 17 00:00:00 2001 From: Daid Date: Sun, 18 Mar 2012 23:00:33 +0100 Subject: [PATCH 01/19] Add proper line width calculation to GCode preview. Added raft settings. --- SkeinPyPy/fabmetheus_utilities/settings.py | 9 +++-- SkeinPyPy/newui/mainWindow.py | 4 +-- SkeinPyPy/newui/preview3d.py | 40 ++++++++++++---------- SkeinPyPy/newui/profile.py | 1 + 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/SkeinPyPy/fabmetheus_utilities/settings.py b/SkeinPyPy/fabmetheus_utilities/settings.py index daa99dc..72b5423 100644 --- a/SkeinPyPy/fabmetheus_utilities/settings.py +++ b/SkeinPyPy/fabmetheus_utilities/settings.py @@ -25,6 +25,11 @@ def ifSettingAboveZero(name): def ifSettingIs(name, value): return lambda setting: profile.getProfileSetting(name) == value +def raftLayerCount(setting): + if profile.getProfileSetting('enable_raft') == "True": + return '1' + return '0' + def storedPercentSetting(name): return lambda setting: float(profile.getProfileSetting(name)) / 100 @@ -196,7 +201,7 @@ def getSkeinPyPyProfileInformation(): 'Base_Flow_Rate_Multiplier_ratio': DEFSET, 'Base_Infill_Density_ratio': DEFSET, 'Base_Layer_Thickness_over_Layer_Thickness': DEFSET, - 'Base_Layers_integer': '0', + 'Base_Layers_integer': raftLayerCount, 'Base_Nozzle_Lift_over_Base_Layer_Thickness_ratio': DEFSET, 'Initial_Circling': DEFSET, 'Infill_Overhang_over_Extrusion_Width_ratio': DEFSET, @@ -204,7 +209,7 @@ def getSkeinPyPyProfileInformation(): 'Interface_Flow_Rate_Multiplier_ratio': DEFSET, 'Interface_Infill_Density_ratio': DEFSET, 'Interface_Layer_Thickness_over_Layer_Thickness': DEFSET, - 'Interface_Layers_integer': '0', + 'Interface_Layers_integer': raftLayerCount, 'Interface_Nozzle_Lift_over_Interface_Layer_Thickness_ratio': DEFSET, 'Name_of_Support_End_File': DEFSET, 'Name_of_Support_Start_File': DEFSET, diff --git a/SkeinPyPy/newui/mainWindow.py b/SkeinPyPy/newui/mainWindow.py index 13f0e89..3d2d0ab 100644 --- a/SkeinPyPy/newui/mainWindow.py +++ b/SkeinPyPy/newui/mainWindow.py @@ -88,7 +88,6 @@ class mainWindow(configBase.configWindowBase): c = configBase.SettingRow(left, "Wall thickness (mm)", 'wall_thickness', '0.8', 'Thickness of the walls.\nThis is used in combination with the nozzle size to define the number\nof perimeter lines and the thickness of those perimeter lines.') validators.validFloat(c, 0.0) validators.wallThicknessValidator(c) - configBase.settingNotify(c, self.preview3d.updateWallLineWidth) configBase.TitleRow(left, "Fill") c = configBase.SettingRow(left, "Bottom/Top thickness (mm)", 'solid_layer_thickness', '0.6', 'This controls the thickness of the bottom and top layers, the amount of solid layers put down is calculated by the layer thickness and this value.\nHaving this value a multiply of the layer thickness makes sense. And keep it near your wall thickness to make an evenly strong part.') @@ -114,6 +113,7 @@ class mainWindow(configBase.configWindowBase): configBase.TitleRow(right, "Support") c = configBase.SettingRow(right, "Support type", 'support', ['None', 'Exterior Only', 'Everywhere', 'Empty Layers Only'], 'Type of support structure build.\nNone does not do any support.\nExterior only only creates support on the outside.\nEverywhere creates support even on the insides of the model.\nOnly on empty layers is for stacked objects.') + c = configBase.SettingRow(right, "Add raft", 'enable_raft', False, 'A raft is a few layers of lines below the bottom of the object. It prevents warping. Full raft settings can be found in the advanced settings.\nFor PLA this is usually not required. But if you print with ABS it is almost required.') configBase.TitleRow(right, "Filament") c = configBase.SettingRow(right, "Diameter (mm)", 'filament_diameter', '2.89', 'Diameter of your filament, as accurately as possible.\nIf you cannot measure this value you will have to callibrate it, a higher number means less extrusion, a smaller number generates more extrusion.') @@ -135,8 +135,6 @@ class mainWindow(configBase.configWindowBase): configBase.TitleRow(left, "Machine nozzle") c = configBase.SettingRow(left, "Nozzle size (mm)", 'nozzle_size', '0.4', 'The nozzle size is very important, this is used to calculate the line width of the infill, and used to calculate the amount of outside wall lines and thickness for the wall thickness you entered in the print settings.') validators.validFloat(c, 0.1, 1.0) - configBase.settingNotify(c, self.preview3d.updateWallLineWidth) - configBase.settingNotify(c, self.preview3d.updateInfillLineWidth) configBase.TitleRow(left, "Retraction") c = configBase.SettingRow(left, "Minimal travel (mm)", 'retraction_min_travel', '5.0', 'Minimal amount of travel needed for a retraction to happen at all. To make sure you do not get a lot of retractions in a small area') diff --git a/SkeinPyPy/newui/preview3d.py b/SkeinPyPy/newui/preview3d.py index 7611ab2..8bdcc22 100644 --- a/SkeinPyPy/newui/preview3d.py +++ b/SkeinPyPy/newui/preview3d.py @@ -19,7 +19,6 @@ from newui import profile from newui import gcodeInterpreter from newui import util3d -from fabmetheus_utilities import settings from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret from fabmetheus_utilities.vector3 import Vector3 @@ -92,14 +91,6 @@ class previewPanel(wx.Panel): self.moveModel() self.glCanvas.Refresh() - def updateWallLineWidth(self, setting): - #TODO: this shouldn't be needed, you can calculate the line width from the E values combined with the steps_per_E and the filament diameter (reverse volumatric) - self.glCanvas.lineWidth = settings.calculateEdgeWidth(setting) - - def updateInfillLineWidth(self, setting): - #TODO: this shouldn't be needed, you can calculate the line width from the E values combined with the steps_per_E and the filament diameter (reverse volumatric) - self.glCanvas.infillLineWidth = profile.getProfileSetting('nozzle_size') - def loadModelFile(self, filename): self.modelFilename = filename self.gcodeFilename = filename[: filename.rfind('.')] + "_export.gcode" @@ -216,8 +207,6 @@ class PreviewGLCanvas(glcanvas.GLCanvas): self.zoom = 150 self.offsetX = 0 self.offsetY = 0 - self.lineWidth = 0.4 - self.fillLineWidth = 0.4 self.view3D = True self.modelDisplayList = None self.gcodeDisplayList = None @@ -315,7 +304,22 @@ class PreviewGLCanvas(glcanvas.GLCanvas): if self.parent.gcodeDirty: self.parent.gcodeDirty = False glNewList(self.gcodeDisplayList, GL_COMPILE) + prevLayerZ = 0.0 + curLayerZ = 0.0 + + layerThickness = 0.0 + filamentRadius = float(profile.getProfileSetting('filament_diameter')) / 2 + filamentArea = math.pi * filamentRadius * filamentRadius + lineWidth = float(profile.getProfileSetting('nozzle_size')) / 2 + + curLayerNum = 0 for path in self.parent.gcode.pathList: + if path['layerNr'] != curLayerNum: + prevLayerZ = curLayerZ + curLayerZ = path['list'][1].z + curLayerNum = path['layerNr'] + layerThickness = curLayerZ - prevLayerZ + c = 1.0 if path['layerNr'] != self.parent.layerSpin.GetValue(): if path['layerNr'] < self.parent.layerSpin.GetValue(): @@ -336,16 +340,14 @@ class PreviewGLCanvas(glcanvas.GLCanvas): if path['type'] == 'retract': glColor3f(0,c,c) if c > 0.4 and path['type'] == 'extrude': - if path['pathType'] == 'FILL': - lineWidth = self.fillLineWidth / 2 - else: - lineWidth = self.lineWidth / 2 for i in xrange(0, len(path['list'])-1): v0 = path['list'][i] v1 = path['list'][i+1] dist = (v0 - v1).vsize() - if dist > 0: - extrusionMMperDist = (v1.e - v0.e) / (v0 - v1).vsize() / self.parent.gcode.stepsPerE + if dist > 0 and layerThickness > 0: + extrusionMMperDist = (v1.e - v0.e) / (v0 - v1).vsize() + lineWidth = extrusionMMperDist * filamentArea / layerThickness / 2 + #TODO: Calculate line width from ePerDistance (needs layer thickness, steps_per_E and filament diameter) normal = (v0 - v1).cross(util3d.Vector3(0,0,1)) normal.normalize() @@ -394,12 +396,12 @@ class PreviewGLCanvas(glcanvas.GLCanvas): modelSize = self.parent.triangleMesh.getCarveCornerMaximum() - self.parent.triangleMesh.getCarveCornerMinimum() glNewList(self.modelDisplayList, GL_COMPILE) glPushMatrix() - glTranslate(-(modelSize.x+self.lineWidth*15)*(multiX-1)/2,-(modelSize.y+self.lineWidth*15)*(multiY-1)/2, 0) + glTranslate(-(modelSize.x+10)*(multiX-1)/2,-(modelSize.y+10)*(multiY-1)/2, 0) for mx in xrange(0, multiX): for my in xrange(0, multiY): for face in self.parent.triangleMesh.faces: glPushMatrix() - glTranslate((modelSize.x+self.lineWidth*15)*mx,(modelSize.y+self.lineWidth*15)*my, 0) + glTranslate((modelSize.x+10)*mx,(modelSize.y+10)*my, 0) glBegin(GL_TRIANGLES) v1 = self.parent.triangleMesh.vertexes[face.vertexIndexes[0]] v2 = self.parent.triangleMesh.vertexes[face.vertexIndexes[1]] diff --git a/SkeinPyPy/newui/profile.py b/SkeinPyPy/newui/profile.py index f672bc8..0f04a52 100644 --- a/SkeinPyPy/newui/profile.py +++ b/SkeinPyPy/newui/profile.py @@ -46,6 +46,7 @@ profileDefaultSettings = { 'support_rate': '100', 'support_distance': '0.5', 'joris': 'False', + 'enable_raft': 'False', } preferencesDefaultSettings = { 'wizardDone': 'False', From 8f7c0a54566bb449b851cecf37ae84b75f619582 Mon Sep 17 00:00:00 2001 From: daid Date: Mon, 19 Mar 2012 10:58:53 +0100 Subject: [PATCH 02/19] Added unexpected error handling to Serial interface --- SkeinPyPy/avr_isp/stk500v2.py | 2 ++ SkeinPyPy/newui/machineCom.py | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/SkeinPyPy/avr_isp/stk500v2.py b/SkeinPyPy/avr_isp/stk500v2.py index a420bdc..e076e66 100644 --- a/SkeinPyPy/avr_isp/stk500v2.py +++ b/SkeinPyPy/avr_isp/stk500v2.py @@ -18,6 +18,8 @@ class Stk500v2(ispBase.IspBase): self.serial = Serial(port, speed, timeout=1) except SerialException as e: raise ispBase.IspError("Failed to open serial port") + except: + raise ispBase.IspError("Unexpected error while connecting to serial port:" + port + ":" + str(sys.exc_info()[0])) self.seq = 1 #Reset the controller diff --git a/SkeinPyPy/newui/machineCom.py b/SkeinPyPy/newui/machineCom.py index 47041ed..8b7291e 100644 --- a/SkeinPyPy/newui/machineCom.py +++ b/SkeinPyPy/newui/machineCom.py @@ -111,9 +111,14 @@ class MachineCom(): break except ispBase.IspError: pass + except: + print "Unexpected error while connecting to serial port:" + port, sys.exc_info()[0] programmer.close() else: - self.serial = Serial(port, baudrate, timeout=5) + try: + self.serial = Serial(port, baudrate, timeout=5) + except: + print "Unexpected error while connecting to serial port:" + port, sys.exc_info()[0] def readline(self): if self.serial == None: From 51001d23818c33f1a835ef0ce0a4735231aa6989 Mon Sep 17 00:00:00 2001 From: daid Date: Mon, 19 Mar 2012 11:05:40 +0100 Subject: [PATCH 03/19] Always use the configured serialport/baudrate if none given as parameters --- SkeinPyPy/newui/machineCom.py | 13 +++++++++++-- SkeinPyPy/newui/mainWindow.py | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/SkeinPyPy/newui/machineCom.py b/SkeinPyPy/newui/machineCom.py index 8b7291e..5f6974d 100644 --- a/SkeinPyPy/newui/machineCom.py +++ b/SkeinPyPy/newui/machineCom.py @@ -9,6 +9,8 @@ from avr_isp import stk500v2 from avr_isp import ispBase from avr_isp import intelHex +from newui import profile + try: import _winreg except: @@ -28,8 +30,11 @@ def serialList(): return baselist+glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') +glob.glob("/dev/tty.usb*")+glob.glob("/dev/cu.*")+glob.glob("/dev/rfcomm*") class InstallFirmware(wx.Dialog): - def __init__(self, filename, port = 'AUTO'): + def __init__(self, filename, port = None): super(InstallFirmware, self).__init__(parent=None, title="Firmware install", size=(250, 100)) + if port == None: + port = profile.getPreference('serial_port') + sizer = wx.BoxSizer(wx.VERTICAL) self.progressLabel = wx.StaticText(self, -1, 'Reading firmware...') @@ -99,7 +104,11 @@ class InstallFirmware(wx.Dialog): self.Destroy() class MachineCom(): - def __init__(self, port = 'AUTO', baudrate = 250000): + def __init__(self, port = None, baudrate = None): + if port == None: + port = profile.getPreference('serial_port') + if baudrate == None: + baudrate = profile.getPreference('serial_baud') self.serial = None if port == 'AUTO': programmer = stk500v2.Stk500v2() diff --git a/SkeinPyPy/newui/mainWindow.py b/SkeinPyPy/newui/mainWindow.py index 3d2d0ab..9088888 100644 --- a/SkeinPyPy/newui/mainWindow.py +++ b/SkeinPyPy/newui/mainWindow.py @@ -239,7 +239,7 @@ class mainWindow(configBase.configWindowBase): prefDialog.Show(True) def OnDefaultMarlinFirmware(self, e): - machineCom.InstallFirmware(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../firmware/default.hex"), profile.getPreference('serial_port')) + machineCom.InstallFirmware(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../firmware/default.hex")) def OnCustomFirmware(self, e): dlg=wx.FileDialog(self, "Open firmware to upload", self.lastPath, style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST) @@ -249,7 +249,7 @@ class mainWindow(configBase.configWindowBase): if not(os.path.exists(filename)): return #For some reason my Ubuntu 10.10 crashes here. - machineCom.InstallFirmware(filename, profile.getPreference('serial_port')) + machineCom.InstallFirmware(filename) def OnFirstRunWizard(self, e): configWizard.configWizard() From 4c176dc72819180df9592cf3219e049d1f7de94a Mon Sep 17 00:00:00 2001 From: daid Date: Mon, 19 Mar 2012 11:45:40 +0100 Subject: [PATCH 04/19] Changed layer height warning to use nozzle size. Added max volume extrusion per second check for speed. --- SkeinPyPy/newui/mainWindow.py | 3 ++- SkeinPyPy/newui/preview3d.py | 3 ++- SkeinPyPy/newui/validators.py | 35 +++++++++++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/SkeinPyPy/newui/mainWindow.py b/SkeinPyPy/newui/mainWindow.py index 9088888..65ca69b 100644 --- a/SkeinPyPy/newui/mainWindow.py +++ b/SkeinPyPy/newui/mainWindow.py @@ -84,7 +84,7 @@ class mainWindow(configBase.configWindowBase): configBase.TitleRow(left, "Accuracy") c = configBase.SettingRow(left, "Layer height (mm)", 'layer_height', '0.2', 'Layer height in millimeters.\n0.2 is a good value for quick prints.\n0.1 gives high quality prints.') validators.validFloat(c, 0.0) - validators.warningAbove(c, 0.31, "Thicker layers then 0.3mm usually give bad results and are not recommended.") + validators.warningAbove(c, lambda : (float(profile.getProfileSetting('nozzle_size')) * 80 / 100), "Thicker layers then %.2fmm (80%% nozzle size) usually give bad results and are not recommended.") c = configBase.SettingRow(left, "Wall thickness (mm)", 'wall_thickness', '0.8', 'Thickness of the walls.\nThis is used in combination with the nozzle size to define the number\nof perimeter lines and the thickness of those perimeter lines.') validators.validFloat(c, 0.0) validators.wallThicknessValidator(c) @@ -105,6 +105,7 @@ class mainWindow(configBase.configWindowBase): c = configBase.SettingRow(right, "Print speed (mm/s)", 'print_speed', '50', 'Speed at which printing happens. A well adjusted Ultimaker can reach 150mm/s, but for good quality prints you want to print slower. Printing speed depends on a lot of factors. So you will be experimenting with optimal settings for this.') validators.validFloat(c, 1.0) validators.warningAbove(c, 150.0, "It is highly unlikely that your machine can achieve a printing speed above 150mm/s") + validators.printSpeedValidator(c) configBase.TitleRow(right, "Temperature") c = configBase.SettingRow(right, "Printing temperature", 'print_temperature', '0', 'Temperature used for printing. Set at 0 to pre-heat yourself') diff --git a/SkeinPyPy/newui/preview3d.py b/SkeinPyPy/newui/preview3d.py index 8bdcc22..14d3b0e 100644 --- a/SkeinPyPy/newui/preview3d.py +++ b/SkeinPyPy/newui/preview3d.py @@ -343,12 +343,13 @@ class PreviewGLCanvas(glcanvas.GLCanvas): for i in xrange(0, len(path['list'])-1): v0 = path['list'][i] v1 = path['list'][i+1] + + # Calculate line width from ePerDistance (needs layer thickness and filament diameter) dist = (v0 - v1).vsize() if dist > 0 and layerThickness > 0: extrusionMMperDist = (v1.e - v0.e) / (v0 - v1).vsize() lineWidth = extrusionMMperDist * filamentArea / layerThickness / 2 - #TODO: Calculate line width from ePerDistance (needs layer thickness, steps_per_E and filament diameter) normal = (v0 - v1).cross(util3d.Vector3(0,0,1)) normal.normalize() v2 = v0 + normal * lineWidth diff --git a/SkeinPyPy/newui/validators.py b/SkeinPyPy/newui/validators.py index d9d141a..7a2bedb 100644 --- a/SkeinPyPy/newui/validators.py +++ b/SkeinPyPy/newui/validators.py @@ -1,6 +1,9 @@ from __future__ import absolute_import import __init__ +import types +import math + from newui import profile SUCCESS = 0 @@ -53,8 +56,12 @@ class warningAbove(): def validate(self): try: f = float(self.setting.GetValue()) - if f >= self.minValueForWarning: - return WARNING, self.warningMessage + if isinstance(self.minValueForWarning, types.FunctionType): + if f >= self.minValueForWarning(): + return WARNING, self.warningMessage % (self.minValueForWarning()) + else: + if f >= self.minValueForWarning: + return WARNING, self.warningMessage return SUCCESS, '' except ValueError: #We already have an error by the int/float validator in this case. @@ -86,3 +93,27 @@ class wallThicknessValidator(): #We already have an error by the int/float validator in this case. return SUCCESS, '' +class printSpeedValidator(): + def __init__(self, setting): + self.setting = setting + self.setting.validators.append(self) + + def validate(self): + try: + nozzleSize = float(profile.getProfileSetting('nozzle_size')) + layerHeight = float(profile.getProfileSetting('layer_height')) + printSpeed = float(profile.getProfileSetting('print_speed')) + + printVolumePerMM = layerHeight * nozzleSize + printVolumePerSecond = printVolumePerMM * printSpeed + #Using 10mm3 per second with a 0.4mm nozzle (normal max according to Joergen Geerds) + maxPrintVolumePerSecond = 10 / (math.pi*(0.2*0.2)) * (math.pi*(nozzleSize/2*nozzleSize/2)) + + if printVolumePerSecond > maxPrintVolumePerSecond: + return WARNING, 'You are trying to print more then %.1fmm^3 of filament per second. This might cause filament slipping.' % (maxPrintVolumePerSecond) + + return SUCCESS, '' + except ValueError: + #We already have an error by the int/float validator in this case. + return SUCCESS, '' + From 601f0372dfa9afa249b263303bb4107461675010 Mon Sep 17 00:00:00 2001 From: Alexandre Girard Date: Mon, 19 Mar 2012 11:45:46 +0100 Subject: [PATCH 05/19] replace build.sh by package.sh in README --- README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index 20f2b20..d371684 100644 --- a/README +++ b/README @@ -17,12 +17,12 @@ SkeinPyPy: BUILDING ======== - ./build.sh + ./package.sh The build script defaults to building for Windows. If you want to build for Mac OS X or Linux, choose one of: - ./build.sh osx64 - ./build.sh linux + ./package.sh osx64 + ./package.sh linux Note that Mac OS X currently requires the manual installation of wxPython, PySerial, and PyOpenGL: From 871b0426eb5739bcbde2f3adadd0a01f758c0850 Mon Sep 17 00:00:00 2001 From: daid Date: Mon, 19 Mar 2012 11:49:16 +0100 Subject: [PATCH 06/19] Added current print speed volume to warning --- SkeinPyPy/newui/validators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SkeinPyPy/newui/validators.py b/SkeinPyPy/newui/validators.py index 7a2bedb..6352deb 100644 --- a/SkeinPyPy/newui/validators.py +++ b/SkeinPyPy/newui/validators.py @@ -110,7 +110,7 @@ class printSpeedValidator(): maxPrintVolumePerSecond = 10 / (math.pi*(0.2*0.2)) * (math.pi*(nozzleSize/2*nozzleSize/2)) if printVolumePerSecond > maxPrintVolumePerSecond: - return WARNING, 'You are trying to print more then %.1fmm^3 of filament per second. This might cause filament slipping.' % (maxPrintVolumePerSecond) + return WARNING, 'You are trying to print more then %.1fmm^3 of filament per second. This might cause filament slipping. (You are printing at %0.1fmm^3 per second)' % (maxPrintVolumePerSecond, printVolumePerSecond) return SUCCESS, '' except ValueError: From 41adf54d0c0917e5ab63a5b684f2b00d8a015d6b Mon Sep 17 00:00:00 2001 From: daid Date: Mon, 19 Mar 2012 12:09:50 +0100 Subject: [PATCH 07/19] Updated osx scripts not to use 2.7 version of python, but whatever is available --- scripts/osx64/pronterface.sh | 8 ++++---- scripts/osx64/skeinpypy.sh | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/scripts/osx64/pronterface.sh b/scripts/osx64/pronterface.sh index 83896aa..86e7c29 100755 --- a/scripts/osx64/pronterface.sh +++ b/scripts/osx64/pronterface.sh @@ -1,19 +1,19 @@ #!/bin/bash -python2.7 -c 'import wx' +python -c 'import wx' if [ $? != 0 ]; then echo "Requires wx. Download and install (the Cocoa/64-bit variant) from:" echo " http://www.wxpython.org/download.php" exit 1 fi -python2.7 -c 'import serial' +python -c 'import serial' if [ $? != 0 ]; then echo "Requires pyserial." - echo " sudo easy_install-2.7 pyserial" + echo " sudo easy_install pyserial" exit 1 fi SCRIPT_DIR=`dirname $0` -python2.7 ${SCRIPT_DIR}/Printrun/pronterface.py +python ${SCRIPT_DIR}/Printrun/pronterface.py diff --git a/scripts/osx64/skeinpypy.sh b/scripts/osx64/skeinpypy.sh index 736b301..14e10fb 100755 --- a/scripts/osx64/skeinpypy.sh +++ b/scripts/osx64/skeinpypy.sh @@ -1,26 +1,26 @@ #!/bin/bash -python2.7 -c 'import OpenGL' +python -c 'import OpenGL' if [ $? != 0 ]; then echo "Requires PyOpenGL" - echo " sudo easy_install-2.7 PyOpenGL" + echo " sudo easy_install PyOpenGL" exit 1 fi -python2.7 -c 'import wx' +python -c 'import wx' if [ $? != 0 ]; then echo "Requires wx. Download and install (the Cocoa/64-bit variant) from:" echo " http://www.wxpython.org/download.php" exit 1 fi -python2.7 -c 'import serial' +python -c 'import serial' if [ $? != 0 ]; then echo "Requires pyserial." - echo " sudo easy_install-2.7 pyserial" + echo " sudo easy_install pyserial" exit 1 fi SCRIPT_DIR=`dirname $0` -python2.7 ${SCRIPT_DIR}/SkeinPyPy/skeinpypy.py +python ${SCRIPT_DIR}/SkeinPyPy/skeinpypy.py From 09a4f0847c1f56db35cf5d053fc7052ddde82809 Mon Sep 17 00:00:00 2001 From: daid Date: Mon, 19 Mar 2012 16:15:16 +0100 Subject: [PATCH 08/19] Only reload model/gcode if they have changed. Renambed "open gcode" button to "show result" --- .../fonts/gentium_basic_regular.svg | 104 ------------------ .../images/display_line.ppm | 5 - .../fabmetheus_utilities/images/dive.ppm | 5 - .../fabmetheus_utilities/images/soar.ppm | 5 - .../fabmetheus_utilities/images/stop.ppm | 5 - .../fabmetheus_utilities/images/view_move.ppm | Bin 2245 -> 0 bytes .../images/view_rotate.ppm | Bin 2245 -> 0 bytes .../fabmetheus_utilities/images/zoom_in.ppm | 5 - .../fabmetheus_utilities/images/zoom_out.ppm | 5 - SkeinPyPy/newui/preview3d.py | 64 +++++------ SkeinPyPy/newui/sliceProgessPanel.py | 3 +- 11 files changed, 33 insertions(+), 168 deletions(-) delete mode 100644 SkeinPyPy/fabmetheus_utilities/fonts/gentium_basic_regular.svg delete mode 100644 SkeinPyPy/fabmetheus_utilities/images/display_line.ppm delete mode 100644 SkeinPyPy/fabmetheus_utilities/images/dive.ppm delete mode 100644 SkeinPyPy/fabmetheus_utilities/images/soar.ppm delete mode 100644 SkeinPyPy/fabmetheus_utilities/images/stop.ppm delete mode 100644 SkeinPyPy/fabmetheus_utilities/images/view_move.ppm delete mode 100644 SkeinPyPy/fabmetheus_utilities/images/view_rotate.ppm delete mode 100644 SkeinPyPy/fabmetheus_utilities/images/zoom_in.ppm delete mode 100644 SkeinPyPy/fabmetheus_utilities/images/zoom_out.ppm diff --git a/SkeinPyPy/fabmetheus_utilities/fonts/gentium_basic_regular.svg b/SkeinPyPy/fabmetheus_utilities/fonts/gentium_basic_regular.svg deleted file mode 100644 index 418f023..0000000 --- a/SkeinPyPy/fabmetheus_utilities/fonts/gentium_basic_regular.svg +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/SkeinPyPy/fabmetheus_utilities/images/display_line.ppm b/SkeinPyPy/fabmetheus_utilities/images/display_line.ppm deleted file mode 100644 index 4738d03..0000000 --- a/SkeinPyPy/fabmetheus_utilities/images/display_line.ppm +++ /dev/null @@ -1,5 +0,0 @@ -P6 -# CREATOR: The GIMP's PNM Filter Version 1.0 -27 27 -255 -ZHMPRRcޫCHMRV\k\T@EKPV~~TR@FLS\\\:@GMTkYkQ:@FLS\\Q9?EKPV~~VP⿾6=BHMRV\k\VRKⱯ4:?DIMPSTSPME⢢C7<@DHKLMLKHGƩ28raz+6vx5r&3LmHW*cN=X(DE?Mm7@Hu@@pC(>TIqLbeQCrf3;8SfRii7Xd@i z&;o^8M$09%rBF6;&Ohhyi&-_hN9`I57Wii`aN0xl&bapLdd;zK#INtf$m ze}7uAIoTuKH-QO>iJ*NF7>NDr(9k0Z903P7Vz*Oo1cYts?BtXj?y`Yx1_L7oim~ku z2V);;5b(*=RM5$jK0ZE-o@0L(83_%OJ;YdCS@}LL4(0SPO1NyBvNyA{=a-k6_*;$7 zgM)p2eW8DE|ABELCCq*ZL$O5B!DKMI zJT1zkDVv?1*x1?Okl8@cx_Wx(bjObE4Hi%C#nTMuO{1;8WO;234Kq!$foQBYH{rt% z-Uo+(d_KQb-%ybjQ+4aAvN&BP+UvPgcvex6Qg-be@fDfz6HgrLTU*pB19ZC{%Y+fo z*@GgntTSXEcN_j z=NR+^)R(1GiLRl#v%7oPZvWK(cvEHG{K7Mg9SgTW0_=vr)F`jI`IE!xe7dmE-PTAc zWq#7k+#G=8Ll%nE+|4j{bT}s`Jzg)axKS#;uPUxDOmYlc&ANLGuwL?;TABrSaAX9p z<*L`Kl^pcb-mC(!Rgp_#v^Q+CEqOc`1tOT+AK8hN!sN-oelPoHZABi8-hlyhxV5|M zbPQ2eS(prPVD;l*b|4Og5qvv6_(bV4dphZ=11)2s)hS|_sbL$tL=0BUqJtfI_6MBn!QPhH^j{ATe>+{=V+&yh~Jj z_%6@-v87pKwpj2VfkMy#VFQVYFZ9dBo!o%qU8SA0y?_g`g^^mVipW&Uuu7w-Q1*lb!j_0^3MdUUA;iiS zNXUeQAZZZ;VNJ9YNGZiYL7-um0s}}Hpu~TmKjzSHGKe8_=FB- zH*YW|CMQk({rL|blvP&FE-Y;A>}>ArU{)xV+Q!D$8ygrz^U(R#(h@g0IU*{`#nsi( z(b3D>duVhNG>p~t^l&9x=|NlZ5jOn>Ka%=aI zRx3D}+1b&tv2uk1?>rQUXW;8jPEJ5NI5@C59GvXC1uKd~qFZ5M&$_$!iQe9BTdh;G zv&7iz9IyrEGm|pPms+P+k{cCCp)*YyZ!{L`N;mNkn&UY!0^9hS3p3O#XkPz5W9=BK$ zlafSYv3<>%`S~~&OQ}+AY;W74L4;gI4qOWjg&}q{;pFs;i~@ncjt&vQ8^@iU1wx@^ zcGiwEf+Cg4kP=k-*((3NFf(TEH8hm9swLc*>qn0r`&p}*nVx_-?=l=flm_B^FE5XZ z2snV0rv(b5&tMcqewpZh!qxfc&1->03H~@KO$}&Ol}t~L{j;^Tj|?C__e7^-#m6Ii z@jRopoNzFUou)?=_0KexH2wA!_iHyPL0{9|DRwIVFXcmQpF;Yh}eoV^@Q$7#xt1=c-5fgb70i z`i!V1FbVMW`f3>u=6oe)T~f*`R2mIjS}v8M+q@Va9_-dr7aJ<>H%JSy1$l62sH?T9 zn00aY6I|avM~1*8z=o1Eaz&$*ws&=nPE1thL^R94pMNz6Z(tw_L;-V4qZ-#MGIq;w zesR&Dt0SW7+*q^)0EbPTTVf)kwxGG6D5!udFg*uLThOin2&4;zI{{RVPeB?BFiUwlopbtG>1hhhX-YOsEAaZ)?Qa9R>q{cr*N< z5~h-i%A#bb!Ee~g3pib!ddx&rnjNiCE6BE~UjF;wV4GS(MAAH#POpc70OHMH!o5K4 zNwdR|SH#tb-E%|Rv*!kVYqPFNi!F3u2ogqiFOulPb-I=o_#Y4g1QTY$!$>otgIRu` zN!g2_JWBQ>A{aypp)D7hkZcePsDw3WyLZ*4JV`e bI*mr$ZSCm5zye!Rl4#vfgEB&Zi)8!<_CWYS diff --git a/SkeinPyPy/fabmetheus_utilities/images/zoom_in.ppm b/SkeinPyPy/fabmetheus_utilities/images/zoom_in.ppm deleted file mode 100644 index 6f4767f..0000000 --- a/SkeinPyPy/fabmetheus_utilities/images/zoom_in.ppm +++ /dev/null @@ -1,5 +0,0 @@ -P6 -# CREATOR: The GIMP's PNM Filter Version 1.0 -16 16 -255 -ÑҮmϩeΧcШjٻܿ԰p׷}ѯάҭw̡gӺ԰pϩţɛc‘׶}ͤqҮҭlѮħÒ[Ϩcg\aW\R⿋Pͦb_V՝SK⾇Mͧh̬cY^TvmѕkcD=>7عѪv\Rҗϒ}ʈƃ5y0ʟeģSKMEe^DžZS3v..o)ͻѹȚ`ʠoç>7}2t,̙čOѫZML5y00q+*k&գץڻe?˹XŏӠǓɛaaFɸQ׵}ֵÑV{QɸmHHyR \ No newline at end of file diff --git a/SkeinPyPy/fabmetheus_utilities/images/zoom_out.ppm b/SkeinPyPy/fabmetheus_utilities/images/zoom_out.ppm deleted file mode 100644 index 108f893..0000000 --- a/SkeinPyPy/fabmetheus_utilities/images/zoom_out.ppm +++ /dev/null @@ -1,5 +0,0 @@ -P6 -# CREATOR: The GIMP's PNM Filter Version 1.0 -16 16 -255 -ÑҮmϩeΧcШjٻܿ԰p׷}ѯάҭw̡gӺ԰pϩţɛc‘׶}ͤqҮҭlѮħÒ[Ϩc⿋Pͦb⾇Mͧh̬xtomcbTVEH5:&.عѪvomȿ#ʟeģcbTVEH5:&.#ͻѹȚ`ʠoçܾSִy̙čOѫZMLRLۿգץڻe?˹XŏӠǓɛaaFɸQ׵}ֵÑVrEǶ\3HsK \ No newline at end of file diff --git a/SkeinPyPy/newui/preview3d.py b/SkeinPyPy/newui/preview3d.py index 14d3b0e..51ba092 100644 --- a/SkeinPyPy/newui/preview3d.py +++ b/SkeinPyPy/newui/preview3d.py @@ -33,6 +33,7 @@ class previewPanel(wx.Panel): self.init = 0 self.triangleMesh = None self.gcode = None + self.modelFilename = None self.machineSize = Vector3(float(profile.getPreference('machine_width')), float(profile.getPreference('machine_depth')), float(profile.getPreference('machine_height'))) self.machineCenter = Vector3(0, 0, 0) @@ -92,40 +93,39 @@ class previewPanel(wx.Panel): self.glCanvas.Refresh() def loadModelFile(self, filename): - self.modelFilename = filename - self.gcodeFilename = filename[: filename.rfind('.')] + "_export.gcode" - #Do the STL file loading in a background thread so we don't block the UI. - thread = threading.Thread(target=self.DoModelLoad) - thread.start() - - def loadGCodeFile(self, filename): - self.gcodeFilename = filename - #Do the STL file loading in a background thread so we don't block the UI. - thread = threading.Thread(target=self.DoGCodeLoad) - thread.start() - - def DoModelLoad(self): - self.modelDirty = False - triangleMesh = fabmetheus_interpret.getCarving(self.modelFilename) - triangleMesh.origonalVertexes = list(triangleMesh.vertexes) - for i in xrange(0, len(triangleMesh.origonalVertexes)): - triangleMesh.origonalVertexes[i] = triangleMesh.origonalVertexes[i].copy() - triangleMesh.getMinimumZ() - self.triangleMesh = triangleMesh - self.updateModelTransform() - wx.CallAfter(self.updateToolbar) - wx.CallAfter(self.glCanvas.Refresh) + gcodeFilename = filename[: filename.rfind('.')] + "_export.gcode" + if self.modelFilename != filename: + self.modelFileTime = None + self.gcodeFileTime = None - if os.path.isfile(self.gcodeFilename): - self.DoGCodeLoad() + self.modelFilename = filename + self.gcodeFilename = gcodeFilename + #Do the STL file loading in a background thread so we don't block the UI. + thread = threading.Thread(target=self.doFileLoad) + thread.start() - def DoGCodeLoad(self): - gcode = gcodeInterpreter.gcode(self.gcodeFilename) - self.gcodeDirty = False - self.gcode = gcode - self.gcodeDirty = True - wx.CallAfter(self.updateToolbar) - wx.CallAfter(self.glCanvas.Refresh) + def doFileLoad(self): + if os.path.isfile(self.modelFilename) and self.modelFileTime != os.stat(self.modelFilename).st_mtime: + self.modelFileTime = os.stat(self.modelFilename).st_mtime + triangleMesh = fabmetheus_interpret.getCarving(self.modelFilename) + triangleMesh.origonalVertexes = list(triangleMesh.vertexes) + for i in xrange(0, len(triangleMesh.origonalVertexes)): + triangleMesh.origonalVertexes[i] = triangleMesh.origonalVertexes[i].copy() + triangleMesh.getMinimumZ() + self.modelDirty = False + self.triangleMesh = triangleMesh + self.updateModelTransform() + wx.CallAfter(self.updateToolbar) + wx.CallAfter(self.glCanvas.Refresh) + + if os.path.isfile(self.gcodeFilename) and self.gcodeFileTime != os.stat(self.gcodeFilename).st_mtime: + self.gcodeFileTime = os.stat(self.gcodeFilename).st_mtime + gcode = gcodeInterpreter.gcode(self.gcodeFilename) + self.gcodeDirty = False + self.gcode = gcode + self.gcodeDirty = True + wx.CallAfter(self.updateToolbar) + wx.CallAfter(self.glCanvas.Refresh) def updateToolbar(self): self.layerSpin.Show(self.gcode != None) diff --git a/SkeinPyPy/newui/sliceProgessPanel.py b/SkeinPyPy/newui/sliceProgessPanel.py index 59b095a..f9d33a9 100644 --- a/SkeinPyPy/newui/sliceProgessPanel.py +++ b/SkeinPyPy/newui/sliceProgessPanel.py @@ -82,7 +82,7 @@ class sliceProgessPanel(wx.Panel): self.sizer.Add(self.logButton, 0) if result.returnCode == 0: self.statusText.SetLabel("Ready.") - self.showButton = wx.Button(self, -1, "Show GCode") + self.showButton = wx.Button(self, -1, "Show result") self.Bind(wx.EVT_BUTTON, self.OnShowGCode, self.showButton) self.sizer.Add(self.showButton, 0) else: @@ -133,7 +133,6 @@ class WorkerThread(threading.Thread): return line = p.stdout.readline() self.returnCode = p.wait() - self.gcodeFilename = self.filename[: self.filename.rfind('.')] + "_export.gcode" logfile = open(self.filename[: self.filename.rfind('.')] + "_export.log", "w") for logLine in self.progressLog: logfile.write(logLine) From a4c7ee8c4de6d2a0907e088b97d2bf22dba0669e Mon Sep 17 00:00:00 2001 From: daid Date: Mon, 19 Mar 2012 17:11:50 +0100 Subject: [PATCH 09/19] Add error lines to 3D model preview after slicing --- SkeinPyPy/newui/preview3d.py | 30 +++++++++++++++++-- .../skeinforge_plugins/craft_plugins/carve.py | 10 +++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/SkeinPyPy/newui/preview3d.py b/SkeinPyPy/newui/preview3d.py index 51ba092..dc663b6 100644 --- a/SkeinPyPy/newui/preview3d.py +++ b/SkeinPyPy/newui/preview3d.py @@ -93,13 +93,14 @@ class previewPanel(wx.Panel): self.glCanvas.Refresh() def loadModelFile(self, filename): - gcodeFilename = filename[: filename.rfind('.')] + "_export.gcode" if self.modelFilename != filename: self.modelFileTime = None self.gcodeFileTime = None + self.logFileTime = None self.modelFilename = filename - self.gcodeFilename = gcodeFilename + self.gcodeFilename = filename[: filename.rfind('.')] + "_export.gcode" + self.logFilename = filename[: filename.rfind('.')] + "_export.log" #Do the STL file loading in a background thread so we don't block the UI. thread = threading.Thread(target=self.doFileLoad) thread.start() @@ -113,6 +114,7 @@ class previewPanel(wx.Panel): triangleMesh.origonalVertexes[i] = triangleMesh.origonalVertexes[i].copy() triangleMesh.getMinimumZ() self.modelDirty = False + self.errorList = [] self.triangleMesh = triangleMesh self.updateModelTransform() wx.CallAfter(self.updateToolbar) @@ -122,10 +124,24 @@ class previewPanel(wx.Panel): self.gcodeFileTime = os.stat(self.gcodeFilename).st_mtime gcode = gcodeInterpreter.gcode(self.gcodeFilename) self.gcodeDirty = False + self.errorList = [] self.gcode = gcode self.gcodeDirty = True wx.CallAfter(self.updateToolbar) wx.CallAfter(self.glCanvas.Refresh) + elif not os.path.isfile(self.gcodeFilename): + self.gcode = None + + if os.path.isfile(self.logFilename): + errorList = [] + for line in open(self.logFilename, "rt"): + res = re.search('Model error\(([a-z ]*)\): \(([0-9\.\-e]*), ([0-9\.\-e]*), ([0-9\.\-e]*)\) \(([0-9\.\-e]*), ([0-9\.\-e]*), ([0-9\.\-e]*)\)', line) + if res != None: + v1 = util3d.Vector3(float(res.group(2)), float(res.group(3)), float(res.group(4))) + v2 = util3d.Vector3(float(res.group(5)), float(res.group(6)), float(res.group(7))) + errorList.append([v1, v2]) + self.errorList = errorList + wx.CallAfter(self.glCanvas.Refresh) def updateToolbar(self): self.layerSpin.Show(self.gcode != None) @@ -478,6 +494,16 @@ class PreviewGLCanvas(glcanvas.GLCanvas): elif self.viewMode == "Model - Normal": glEnable(GL_LIGHTING) glCallList(self.modelDisplayList) + + glDisable(GL_LIGHTING) + glDisable(GL_DEPTH_TEST) + glColor3f(1,0,0) + glTranslate(self.parent.machineCenter.x, self.parent.machineCenter.y, 0) + glBegin(GL_LINES) + for err in self.parent.errorList: + glVertex3f(err[0].x, err[0].y, err[0].z) + glVertex3f(err[1].x, err[1].y, err[1].z) + glEnd() glFlush() def InitGL(self): diff --git a/SkeinPyPy/skeinforge_application/skeinforge_plugins/craft_plugins/carve.py b/SkeinPyPy/skeinforge_application/skeinforge_plugins/craft_plugins/carve.py index 5a01ede..af138a9 100644 --- a/SkeinPyPy/skeinforge_application/skeinforge_plugins/craft_plugins/carve.py +++ b/SkeinPyPy/skeinforge_application/skeinforge_plugins/craft_plugins/carve.py @@ -214,6 +214,16 @@ class CarveSkein: mat01 =-math.sin(rotate) * scaleY mat10 = math.sin(rotate) * scaleX mat11 = math.cos(rotate) * scaleY + + minZ = carving.getMinimumZ() + minSize = carving.getCarveCornerMinimum() + maxSize = carving.getCarveCornerMaximum() + for v in carving.vertexes: + v.z -= minZ + v.x -= minSize.x + (maxSize.x - minSize.x) / 2 + v.y -= minSize.y + (maxSize.y - minSize.y) / 2 + #v.x += self.machineCenter.x + #v.y += self.machineCenter.y for i in xrange(0, len(carving.vertexes)): carving.vertexes[i] = Vector3( From f6eca8e28085b0cce647b55e93b7d1e4488eb51d Mon Sep 17 00:00:00 2001 From: daid Date: Mon, 19 Mar 2012 17:58:30 +0100 Subject: [PATCH 10/19] Add layer number to output comments --- .../export_plugins/static_plugins/gcode_small.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SkeinPyPy/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins/gcode_small.py b/SkeinPyPy/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins/gcode_small.py index a09e0a0..8837e37 100644 --- a/SkeinPyPy/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins/gcode_small.py +++ b/SkeinPyPy/skeinforge_application/skeinforge_plugins/craft_plugins/export_plugins/static_plugins/gcode_small.py @@ -68,6 +68,7 @@ class GcodeSmallSkein: self.lastFeedRateString = None self.lastZString = None self.output = cStringIO.StringIO() + self.layerNr = 0 def getCraftedGcode( self, gcodeText ): "Parse gcode text and store the gcode." @@ -125,4 +126,7 @@ class GcodeSmallSkein: self.output.write(';TYPE:FILL\n'); elif line.startswith('('): self.output.write(';TYPE:CUSTOM\n'); + elif line.startswith('('): + self.output.write(';LAYER:%d\n' % (self.layerNr)); + self.layerNr += 1 From b3888e441018c6a290b2bee4a43c0918da516bcc Mon Sep 17 00:00:00 2001 From: daid Date: Mon, 19 Mar 2012 18:15:44 +0100 Subject: [PATCH 11/19] Added minimal feedrate setting to cool settings (enhancing skeinforge!) --- SkeinPyPy/fabmetheus_utilities/settings.py | 1 + SkeinPyPy/newui/advancedConfig.py | 9 ++++++--- .../skeinforge_plugins/craft_plugins/cool.py | 6 +++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/SkeinPyPy/fabmetheus_utilities/settings.py b/SkeinPyPy/fabmetheus_utilities/settings.py index 72b5423..783dde0 100644 --- a/SkeinPyPy/fabmetheus_utilities/settings.py +++ b/SkeinPyPy/fabmetheus_utilities/settings.py @@ -283,6 +283,7 @@ def getSkeinPyPyProfileInformation(): 'Orbital_Outset_millimeters': DEFSET, 'Turn_Fan_On_at_Beginning': DEFSET, 'Turn_Fan_Off_at_Ending': DEFSET, + 'Minimum_feed_rate_mm/s': storedSetting("cool_min_feedrate"), },'hop': { 'Activate_Hop': "False", 'Hop_Over_Layer_Thickness_ratio': DEFSET, diff --git a/SkeinPyPy/newui/advancedConfig.py b/SkeinPyPy/newui/advancedConfig.py index bb2beac..e9ccbca 100644 --- a/SkeinPyPy/newui/advancedConfig.py +++ b/SkeinPyPy/newui/advancedConfig.py @@ -26,6 +26,12 @@ class advancedConfigWindow(configBase.configWindowBase): c = configBase.SettingRow(left, "Print order sequence", 'sequence', ['Loops > Perimeter > Infill', 'Loops > Infill > Perimeter', 'Infill > Loops > Perimeter', 'Infill > Perimeter > Loops', 'Perimeter > Infill > Loops', 'Perimeter > Loops > Infill'], 'Sequence of printing. The perimeter is the outer print edge, the loops are the insides of the walls, and the infill is the insides.'); c = configBase.SettingRow(left, "Force first layer sequence", 'force_first_layer_sequence', True, 'This setting forces the order of the first layer to be \'Perimeter > Loops > Infill\'') + configBase.TitleRow(left, "Cool") + c = configBase.SettingRow(left, "Minimum feedrate (mm/s)", 'cool_min_feedrate', False, 'The minimal layer time can cause the print to slow down so much it starts to ooze. The minimal feedrate protects against this. Even if a print gets slown down it will never be slower then this minimal feedrate.') + + configBase.TitleRow(left, "Joris") + c = configBase.SettingRow(left, "Joris the outer edge", 'joris', False, '[Joris] is a code name for smoothing out the Z move of the outer edge. This will create a steady Z increase over the whole print. It is intended to be used with a single walled wall thickness to make cups/vases.') + configBase.TitleRow(right, "Infill") c = configBase.SettingRow(right, "Infill pattern", 'infill_type', ['Line', 'Grid Circular', 'Grid Hexagonal', 'Grid Rectangular'], 'Pattern of the none-solid infill. Line is default, but grids can provide a strong print.') c = configBase.SettingRow(right, "Solid infill top", 'solid_top', True, 'Create a solid top surface, if set to false the top is filled with the fill percentage. Useful for cups/vases.') @@ -35,9 +41,6 @@ class advancedConfigWindow(configBase.configWindowBase): c = configBase.SettingRow(right, "Support material amount (%)", 'support_rate', '100', 'Amount of material used for support, less material gives a weaker support structure which is easier to remove.') c = configBase.SettingRow(right, "Support distance from object (mm)", 'support_distance', '0.5', 'Distance between the support structure and the object.') - configBase.TitleRow(left, "Joris") - c = configBase.SettingRow(left, "Joris the outer edge", 'joris', False, '[Joris] is a code name for smoothing out the Z move of the outer edge. This will create a steady Z increase over the whole print. It is intended to be used with a single walled wall thickness to make cups/vases.') - main.Fit() self.Fit() diff --git a/SkeinPyPy/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py b/SkeinPyPy/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py index d8572d3..419eab9 100644 --- a/SkeinPyPy/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py +++ b/SkeinPyPy/skeinforge_application/skeinforge_plugins/craft_plugins/cool.py @@ -161,6 +161,8 @@ class CoolRepository: self.turnFanOnAtBeginning = settings.BooleanSetting().getFromValue('Turn Fan On at Beginning', self, True) self.turnFanOffAtEnding = settings.BooleanSetting().getFromValue('Turn Fan Off at Ending', self, True) self.executeTitle = 'Cool' + + self.minimumFeedRate = settings.FloatSpin().getFromValue(0.0, 'Minimum feed rate (mm/s):', self, 10.0, 5.0) def execute(self): 'Cool button has been clicked.' @@ -188,6 +190,7 @@ class CoolSkein: self.oldFlowRateString = None self.oldLocation = None self.oldTemperature = None + self.minFeedrate = 0 def addCoolOrbits(self, remainingOrbitTime): 'Add the minimum radius cool orbits.' @@ -245,7 +248,7 @@ class CoolSkein: def getCoolMove(self, line, location, splitLine): 'Get cool line according to time spent on layer.' self.feedRateMinute = gcodec.getFeedRateMinute(self.feedRateMinute, splitLine) - return self.distanceFeedRate.getLineWithFeedRate(self.multiplier * self.feedRateMinute, line, splitLine) + return self.distanceFeedRate.getLineWithFeedRate(max(self.minFeedrate, self.multiplier * self.feedRateMinute), line, splitLine) def getCraftedGcode(self, gcodeText, repository): 'Parse gcode text and store the cool gcode.' @@ -255,6 +258,7 @@ class CoolSkein: self.halfCorner = complex(repository.minimumOrbitalRadius.value, repository.minimumOrbitalRadius.value) self.lines = archive.getTextLines(gcodeText) self.minimumArea = 4.0 * repository.minimumOrbitalRadius.value * repository.minimumOrbitalRadius.value + self.minFeedrate = repository.minimumFeedRate.value * 60 self.parseInitialization() self.boundingRectangle = gcodec.BoundingRectangle().getFromGcodeLines(self.lines[self.lineIndex :], 0.5 * self.edgeWidth) margin = 0.2 * self.edgeWidth From 4764e793d7350cdb7a1ef94d91ac26d09d5e2704 Mon Sep 17 00:00:00 2001 From: Daid Date: Mon, 19 Mar 2012 23:10:47 +0100 Subject: [PATCH 12/19] Wrong type for minimum feedrate fix --- SkeinPyPy/newui/advancedConfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SkeinPyPy/newui/advancedConfig.py b/SkeinPyPy/newui/advancedConfig.py index e9ccbca..668ab23 100644 --- a/SkeinPyPy/newui/advancedConfig.py +++ b/SkeinPyPy/newui/advancedConfig.py @@ -27,7 +27,7 @@ class advancedConfigWindow(configBase.configWindowBase): c = configBase.SettingRow(left, "Force first layer sequence", 'force_first_layer_sequence', True, 'This setting forces the order of the first layer to be \'Perimeter > Loops > Infill\'') configBase.TitleRow(left, "Cool") - c = configBase.SettingRow(left, "Minimum feedrate (mm/s)", 'cool_min_feedrate', False, 'The minimal layer time can cause the print to slow down so much it starts to ooze. The minimal feedrate protects against this. Even if a print gets slown down it will never be slower then this minimal feedrate.') + c = configBase.SettingRow(left, "Minimum feedrate (mm/s)", 'cool_min_feedrate', '5', 'The minimal layer time can cause the print to slow down so much it starts to ooze. The minimal feedrate protects against this. Even if a print gets slown down it will never be slower then this minimal feedrate.') configBase.TitleRow(left, "Joris") c = configBase.SettingRow(left, "Joris the outer edge", 'joris', False, '[Joris] is a code name for smoothing out the Z move of the outer edge. This will create a steady Z increase over the whole print. It is intended to be used with a single walled wall thickness to make cups/vases.') From 135d5492bd5095084e691b4d4cbcffe560768533 Mon Sep 17 00:00:00 2001 From: daid Date: Tue, 20 Mar 2012 10:31:19 +0100 Subject: [PATCH 13/19] End code adjustment, suggested by rpulkrabek --- SkeinPyPy/skeinforge_application/alterations/end.gcode | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SkeinPyPy/skeinforge_application/alterations/end.gcode b/SkeinPyPy/skeinforge_application/alterations/end.gcode index 7d83d9b..7131e56 100644 --- a/SkeinPyPy/skeinforge_application/alterations/end.gcode +++ b/SkeinPyPy/skeinforge_application/alterations/end.gcode @@ -1,7 +1,8 @@ M104 S0 ;extruder heat off -M106 ;fan on G91 ;relative positioning G1 Z+10 E-5 F400 ;move Z up a bit and retract filament by 5mm G28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way M84 ;steppers off G90 ;absolute positioning +M107 ;fan off + From 7659bfe1a517b23253bb240eb7573ed99f4b6378 Mon Sep 17 00:00:00 2001 From: daid Date: Tue, 20 Mar 2012 11:01:47 +0100 Subject: [PATCH 14/19] Add bridge settings to advanced config. Issue #18 --- SkeinPyPy/fabmetheus_utilities/settings.py | 4 ++-- SkeinPyPy/newui/advancedConfig.py | 4 ++++ SkeinPyPy/newui/profile.py | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/SkeinPyPy/fabmetheus_utilities/settings.py b/SkeinPyPy/fabmetheus_utilities/settings.py index 783dde0..c7bd1e5 100644 --- a/SkeinPyPy/fabmetheus_utilities/settings.py +++ b/SkeinPyPy/fabmetheus_utilities/settings.py @@ -166,8 +166,8 @@ def getSkeinPyPyProfileInformation(): },'speed': { 'Activate_Speed': "True", 'Add_Flow_Rate': "True", - 'Bridge_Feed_Rate_Multiplier_ratio': DEFSET, - 'Bridge_Flow_Rate_Multiplier_ratio': DEFSET, + 'Bridge_Feed_Rate_Multiplier_ratio': storedPercentSetting('bridge_speed'), + 'Bridge_Flow_Rate_Multiplier_ratio': storedPercentSetting('bridge_material_amount'), 'Duty_Cyle_at_Beginning_portion': DEFSET, 'Duty_Cyle_at_Ending_portion': DEFSET, 'Feed_Rate_mm/s': storedSetting("print_speed"), diff --git a/SkeinPyPy/newui/advancedConfig.py b/SkeinPyPy/newui/advancedConfig.py index 668ab23..3855046 100644 --- a/SkeinPyPy/newui/advancedConfig.py +++ b/SkeinPyPy/newui/advancedConfig.py @@ -41,6 +41,10 @@ class advancedConfigWindow(configBase.configWindowBase): c = configBase.SettingRow(right, "Support material amount (%)", 'support_rate', '100', 'Amount of material used for support, less material gives a weaker support structure which is easier to remove.') c = configBase.SettingRow(right, "Support distance from object (mm)", 'support_distance', '0.5', 'Distance between the support structure and the object.') + configBase.TitleRow(right, "Bridge") + c = configBase.SettingRow(right, "Bridge speed (%)", 'bridge_speed', '100', 'Speed at which bridges are printed, compared to normal printing speed.') + c = configBase.SettingRow(right, "Bridge material (%)", 'bridge_material_amount', '100', 'Amount of material used for bridges, increase go extrude more material when printing a bridge.') + main.Fit() self.Fit() diff --git a/SkeinPyPy/newui/profile.py b/SkeinPyPy/newui/profile.py index 0f04a52..54489c3 100644 --- a/SkeinPyPy/newui/profile.py +++ b/SkeinPyPy/newui/profile.py @@ -47,6 +47,9 @@ profileDefaultSettings = { 'support_distance': '0.5', 'joris': 'False', 'enable_raft': 'False', + 'cool_min_feedrate': '5', + 'bridge_speed': '100', + 'bridge_material_amount': '100', } preferencesDefaultSettings = { 'wizardDone': 'False', From c9bd9940c170e8a587160ca49a06a53db3a90dae Mon Sep 17 00:00:00 2001 From: daid Date: Tue, 20 Mar 2012 12:22:44 +0100 Subject: [PATCH 15/19] Load GCode file after slicing if we still have the same model loaded --- SkeinPyPy/newui/preview3d.py | 9 +++++++-- SkeinPyPy/newui/sliceProgessPanel.py | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/SkeinPyPy/newui/preview3d.py b/SkeinPyPy/newui/preview3d.py index dc663b6..040579a 100644 --- a/SkeinPyPy/newui/preview3d.py +++ b/SkeinPyPy/newui/preview3d.py @@ -102,8 +102,13 @@ class previewPanel(wx.Panel): self.gcodeFilename = filename[: filename.rfind('.')] + "_export.gcode" self.logFilename = filename[: filename.rfind('.')] + "_export.log" #Do the STL file loading in a background thread so we don't block the UI. - thread = threading.Thread(target=self.doFileLoad) - thread.start() + threading.Thread(target=self.doFileLoad).start() + + def loadReModelFile(self, filename): + #Only load this again if the filename matches the file we have already loaded (for auto loading GCode after slicing) + if self.modelFilename != filename: + return + threading.Thread(target=self.doFileLoad).start() def doFileLoad(self): if os.path.isfile(self.modelFilename) and self.modelFileTime != os.stat(self.modelFilename).st_mtime: diff --git a/SkeinPyPy/newui/sliceProgessPanel.py b/SkeinPyPy/newui/sliceProgessPanel.py index f9d33a9..6b45a12 100644 --- a/SkeinPyPy/newui/sliceProgessPanel.py +++ b/SkeinPyPy/newui/sliceProgessPanel.py @@ -91,6 +91,7 @@ class sliceProgessPanel(wx.Panel): self.sizer.Layout() self.Layout() self.abort = True + self.mainWindow.preview3d.loadReModelFile(self.filename) def SetProgress(self, stepName, layer, maxLayer): if self.prevStep != stepName: From bc121033e86988403558bc7b49441045f2307d57 Mon Sep 17 00:00:00 2001 From: daid Date: Tue, 20 Mar 2012 14:50:22 +0100 Subject: [PATCH 16/19] Maybe solve issue #13. But most likely not. --- SkeinPyPy/newui/sliceProgessPanel.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SkeinPyPy/newui/sliceProgessPanel.py b/SkeinPyPy/newui/sliceProgessPanel.py index 6b45a12..8d2a83e 100644 --- a/SkeinPyPy/newui/sliceProgessPanel.py +++ b/SkeinPyPy/newui/sliceProgessPanel.py @@ -75,10 +75,12 @@ class sliceProgessPanel(wx.Panel): def OnSliceDone(self, result): self.progressGauge.Destroy() + self.abortButton.Destroy() self.progressLog = result.progressLog - self.sizer.Remove(self.abortButton) self.logButton = wx.Button(self, -1, "Show Log") + self.abortButton = wx.Button(self, -1, "X", style=wx.BU_EXACTFIT) self.Bind(wx.EVT_BUTTON, self.OnShowLog, self.logButton) + self.Bind(wx.EVT_BUTTON, self.OnAbort, self.abortButton) self.sizer.Add(self.logButton, 0) if result.returnCode == 0: self.statusText.SetLabel("Ready.") From d60d30a1d2e4b5743d61b75debf77dfe40973d4d Mon Sep 17 00:00:00 2001 From: daid Date: Tue, 20 Mar 2012 15:59:31 +0100 Subject: [PATCH 17/19] Added raft settings for #24 --- SkeinPyPy/fabmetheus_utilities/settings.py | 8 ++++---- SkeinPyPy/newui/advancedConfig.py | 5 +++++ SkeinPyPy/newui/profile.py | 3 +++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/SkeinPyPy/fabmetheus_utilities/settings.py b/SkeinPyPy/fabmetheus_utilities/settings.py index c7bd1e5..7678b59 100644 --- a/SkeinPyPy/fabmetheus_utilities/settings.py +++ b/SkeinPyPy/fabmetheus_utilities/settings.py @@ -198,7 +198,7 @@ def getSkeinPyPyProfileInformation(): 'Activate_Raft': "True", 'Add_Raft,_Elevate_Nozzle,_Orbit': DEFSET, 'Base_Feed_Rate_Multiplier_ratio': DEFSET, - 'Base_Flow_Rate_Multiplier_ratio': DEFSET, + 'Base_Flow_Rate_Multiplier_ratio': storedPercentSetting('raft_base_material_amount'), 'Base_Infill_Density_ratio': DEFSET, 'Base_Layer_Thickness_over_Layer_Thickness': DEFSET, 'Base_Layers_integer': raftLayerCount, @@ -206,7 +206,7 @@ def getSkeinPyPyProfileInformation(): 'Initial_Circling': DEFSET, 'Infill_Overhang_over_Extrusion_Width_ratio': DEFSET, 'Interface_Feed_Rate_Multiplier_ratio': DEFSET, - 'Interface_Flow_Rate_Multiplier_ratio': DEFSET, + 'Interface_Flow_Rate_Multiplier_ratio': storedPercentSetting('raft_interface_material_amount'), 'Interface_Infill_Density_ratio': DEFSET, 'Interface_Layer_Thickness_over_Layer_Thickness': DEFSET, 'Interface_Layers_integer': raftLayerCount, @@ -215,11 +215,11 @@ def getSkeinPyPyProfileInformation(): 'Name_of_Support_Start_File': DEFSET, 'Operating_Nozzle_Lift_over_Layer_Thickness_ratio': DEFSET, 'Raft_Additional_Margin_over_Length_%': DEFSET, - 'Raft_Margin_mm': DEFSET, + 'Raft_Margin_mm': storedSetting('raft_margin'), 'Support_Cross_Hatch': 'False', 'Support_Flow_Rate_over_Operating_Flow_Rate_ratio': storedPercentSetting('support_rate'), 'Support_Gap_over_Perimeter_Extrusion_Width_ratio': calcSupportDistanceRatio, - 'Support_Material_Choice_': storedSetting("support"), + 'Support_Material_Choice_': storedSetting('support'), 'Support_Minimum_Angle_degrees': DEFSET, },'skirt': { 'Skirt_line_count': storedSetting("skirt_line_count"), diff --git a/SkeinPyPy/newui/advancedConfig.py b/SkeinPyPy/newui/advancedConfig.py index 3855046..8312e8b 100644 --- a/SkeinPyPy/newui/advancedConfig.py +++ b/SkeinPyPy/newui/advancedConfig.py @@ -32,6 +32,11 @@ class advancedConfigWindow(configBase.configWindowBase): configBase.TitleRow(left, "Joris") c = configBase.SettingRow(left, "Joris the outer edge", 'joris', False, '[Joris] is a code name for smoothing out the Z move of the outer edge. This will create a steady Z increase over the whole print. It is intended to be used with a single walled wall thickness to make cups/vases.') + configBase.TitleRow(left, "Raft (if enabled)") + c = configBase.SettingRow(left, "Raft extra margin (mm)", 'raft_margin', '3.0', 'If the raft is enabled, this is the extra raft area around the object which is also rafted. Increasing this margin will create a stronger raft.') + c = configBase.SettingRow(left, "Raft base material amount (%)", 'raft_base_material_amount', '100', 'The base layer is the first layer put down as a raft. This layer has thick strong lines and is put firmly on the bed to prevent warping. This setting adjust the amount of material used for the base layer.') + c = configBase.SettingRow(left, "Raft interface material amount (%)", 'raft_interface_material_amount', '100', 'The interface layer is a weak thin layer between the base layer and the printed object. It is designed to has little material to make it easy to break the base off the printed object. This setting adjusts the amount of material used for the interface layer.') + configBase.TitleRow(right, "Infill") c = configBase.SettingRow(right, "Infill pattern", 'infill_type', ['Line', 'Grid Circular', 'Grid Hexagonal', 'Grid Rectangular'], 'Pattern of the none-solid infill. Line is default, but grids can provide a strong print.') c = configBase.SettingRow(right, "Solid infill top", 'solid_top', True, 'Create a solid top surface, if set to false the top is filled with the fill percentage. Useful for cups/vases.') diff --git a/SkeinPyPy/newui/profile.py b/SkeinPyPy/newui/profile.py index 54489c3..ec415b7 100644 --- a/SkeinPyPy/newui/profile.py +++ b/SkeinPyPy/newui/profile.py @@ -50,6 +50,9 @@ profileDefaultSettings = { 'cool_min_feedrate': '5', 'bridge_speed': '100', 'bridge_material_amount': '100', + 'raft_margin': '5', + 'raft_base_material_amount': '100', + 'raft_interface_material_amount': '100', } preferencesDefaultSettings = { 'wizardDone': 'False', From c71bc3e9e0a4d72def9ad9319000de3427e5dd10 Mon Sep 17 00:00:00 2001 From: daid Date: Tue, 20 Mar 2012 16:09:25 +0100 Subject: [PATCH 18/19] Moved "nozzle size" to preferences, as it is not something that really belongs are you current setting, but is a configuration option for your machine, and never really changes unless you switch machine. --- SkeinPyPy/fabmetheus_utilities/settings.py | 8 +++++--- SkeinPyPy/newui/configWizard.py | 6 +++--- SkeinPyPy/newui/mainWindow.py | 6 +----- SkeinPyPy/newui/preferencesDialog.py | 8 +++++--- SkeinPyPy/newui/preview3d.py | 2 +- SkeinPyPy/newui/profile.py | 2 +- SkeinPyPy/newui/validators.py | 4 ++-- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/SkeinPyPy/fabmetheus_utilities/settings.py b/SkeinPyPy/fabmetheus_utilities/settings.py index 7678b59..ce6f48b 100644 --- a/SkeinPyPy/fabmetheus_utilities/settings.py +++ b/SkeinPyPy/fabmetheus_utilities/settings.py @@ -18,6 +18,8 @@ def DEFSET(setting): def storedSetting(name): return lambda setting: profile.getProfileSetting(name) +def storedPreference(name): + return lambda setting: profile.getPreference(name) def ifSettingAboveZero(name): return lambda setting: float(profile.getProfileSetting(name)) > 0 @@ -35,7 +37,7 @@ def storedPercentSetting(name): def calculateEdgeWidth(setting): wallThickness = float(profile.getProfileSetting('wall_thickness')) - nozzleSize = float(profile.getProfileSetting('nozzle_size')) + nozzleSize = float(profile.getPreference('nozzle_size')) if wallThickness < nozzleSize: return wallThickness @@ -54,7 +56,7 @@ 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')) + nozzleSize = float(profile.getPreference('nozzle_size')) if wallThickness < nozzleSize: return 0 @@ -150,7 +152,7 @@ def getSkeinPyPyProfileInformation(): 'Line': ifSettingIs('infill_type', 'Line'), 'Infill_Perimeter_Overlap_ratio': storedPercentSetting('fill_overlap'), 'Infill_Solidity_ratio': storedPercentSetting('fill_density'), - 'Infill_Width': storedSetting("nozzle_size"), + 'Infill_Width': storedPreference("nozzle_size"), 'Solid_Surface_Thickness_layers': calculateSolidLayerCount, 'Start_From_Choice': DEFSET, 'Surrounding_Angle_degrees': DEFSET, diff --git a/SkeinPyPy/newui/configWizard.py b/SkeinPyPy/newui/configWizard.py index 1b6f2f6..7070158 100644 --- a/SkeinPyPy/newui/configWizard.py +++ b/SkeinPyPy/newui/configWizard.py @@ -97,17 +97,17 @@ class MachineSelectPage(InfoPage): profile.putPreference('machine_width', '205') profile.putPreference('machine_depth', '205') profile.putPreference('machine_height', '200') - profile.putProfileSetting('nozzle_size', '0.4') + profile.putPreference('nozzle_size', '0.4') profile.putProfileSetting('machine_center_x', '100') profile.putProfileSetting('machine_center_y', '100') else: profile.putPreference('machine_width', '80') profile.putPreference('machine_depth', '80') profile.putPreference('machine_height', '60') - profile.putProfileSetting('nozzle_size', '0.5') + profile.putPreference('nozzle_size', '0.5') profile.putProfileSetting('machine_center_x', '40') profile.putProfileSetting('machine_center_y', '40') - profile.putProfileSetting('wall_thickness', float(profile.getProfileSetting('nozzle_size')) * 2) + profile.putProfileSetting('wall_thickness', float(profile.getPreference('nozzle_size')) * 2) class FirmwareUpgradePage(InfoPage): def __init__(self, parent): diff --git a/SkeinPyPy/newui/mainWindow.py b/SkeinPyPy/newui/mainWindow.py index 65ca69b..fc7e4c8 100644 --- a/SkeinPyPy/newui/mainWindow.py +++ b/SkeinPyPy/newui/mainWindow.py @@ -84,7 +84,7 @@ class mainWindow(configBase.configWindowBase): configBase.TitleRow(left, "Accuracy") c = configBase.SettingRow(left, "Layer height (mm)", 'layer_height', '0.2', 'Layer height in millimeters.\n0.2 is a good value for quick prints.\n0.1 gives high quality prints.') validators.validFloat(c, 0.0) - validators.warningAbove(c, lambda : (float(profile.getProfileSetting('nozzle_size')) * 80 / 100), "Thicker layers then %.2fmm (80%% nozzle size) usually give bad results and are not recommended.") + validators.warningAbove(c, lambda : (float(profile.getPreference('nozzle_size')) * 80 / 100), "Thicker layers then %.2fmm (80%% nozzle size) usually give bad results and are not recommended.") c = configBase.SettingRow(left, "Wall thickness (mm)", 'wall_thickness', '0.8', 'Thickness of the walls.\nThis is used in combination with the nozzle size to define the number\nof perimeter lines and the thickness of those perimeter lines.') validators.validFloat(c, 0.0) validators.wallThicknessValidator(c) @@ -133,10 +133,6 @@ class mainWindow(configBase.configWindowBase): validators.validInt(c, 10) configBase.settingNotify(c, self.preview3d.updateCenterY) - configBase.TitleRow(left, "Machine nozzle") - c = configBase.SettingRow(left, "Nozzle size (mm)", 'nozzle_size', '0.4', 'The nozzle size is very important, this is used to calculate the line width of the infill, and used to calculate the amount of outside wall lines and thickness for the wall thickness you entered in the print settings.') - validators.validFloat(c, 0.1, 1.0) - configBase.TitleRow(left, "Retraction") c = configBase.SettingRow(left, "Minimal travel (mm)", 'retraction_min_travel', '5.0', 'Minimal amount of travel needed for a retraction to happen at all. To make sure you do not get a lot of retractions in a small area') validators.validFloat(c, 0.0) diff --git a/SkeinPyPy/newui/preferencesDialog.py b/SkeinPyPy/newui/preferencesDialog.py index 11369d3..539a69a 100644 --- a/SkeinPyPy/newui/preferencesDialog.py +++ b/SkeinPyPy/newui/preferencesDialog.py @@ -16,13 +16,15 @@ class preferencesDialog(configBase.configWindowBase): left, right, main = self.CreateConfigPanel(self) configBase.TitleRow(left, 'Machine settings') + c = configBase.SettingRow(left, "Nozzle size (mm)", 'nozzle_size', '0.4', 'The nozzle size is very important, this is used to calculate the line width of the infill, and used to calculate the amount of outside wall lines and thickness for the wall thickness you entered in the print settings.', type = 'preference') + validators.validFloat(c, 0.1, 1.0) c = configBase.SettingRow(left, 'Steps per E', 'steps_per_e', '0', 'Amount of steps per mm filament extrusion', type = 'preference') validators.validFloat(c, 0.1) - c = configBase.SettingRow(left, 'Machine width', 'machine_width', '205', 'Size of the machine in mm', type = 'preference') + c = configBase.SettingRow(left, 'Machine width (mm)', 'machine_width', '205', 'Size of the machine in mm', type = 'preference') validators.validFloat(c, 10.0) - c = configBase.SettingRow(left, 'Machine depth', 'machine_depth', '205', 'Size of the machine in mm', type = 'preference') + c = configBase.SettingRow(left, 'Machine depth (mm)', 'machine_depth', '205', 'Size of the machine in mm', type = 'preference') validators.validFloat(c, 10.0) - c = configBase.SettingRow(left, 'Machine height', 'machine_height', '200', 'Size of the machine in mm', type = 'preference') + c = configBase.SettingRow(left, 'Machine height (mm)', 'machine_height', '200', 'Size of the machine in mm', type = 'preference') validators.validFloat(c, 10.0) configBase.TitleRow(left, 'Communication settings') diff --git a/SkeinPyPy/newui/preview3d.py b/SkeinPyPy/newui/preview3d.py index 040579a..483af4d 100644 --- a/SkeinPyPy/newui/preview3d.py +++ b/SkeinPyPy/newui/preview3d.py @@ -331,7 +331,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas): layerThickness = 0.0 filamentRadius = float(profile.getProfileSetting('filament_diameter')) / 2 filamentArea = math.pi * filamentRadius * filamentRadius - lineWidth = float(profile.getProfileSetting('nozzle_size')) / 2 + lineWidth = float(profile.getPreference('nozzle_size')) / 2 curLayerNum = 0 for path in self.parent.gcode.pathList: diff --git a/SkeinPyPy/newui/profile.py b/SkeinPyPy/newui/profile.py index ec415b7..3c1ec2a 100644 --- a/SkeinPyPy/newui/profile.py +++ b/SkeinPyPy/newui/profile.py @@ -21,7 +21,6 @@ profileDefaultSettings = { 'filament_density': '1.00', 'machine_center_x': '100', 'machine_center_y': '100', - 'nozzle_size': '0.4', 'retraction_min_travel': '5.0', 'retraction_speed': '13.5', 'retraction_amount': '0.0', @@ -60,6 +59,7 @@ preferencesDefaultSettings = { 'machine_width': '205', 'machine_depth': '205', 'machine_height': '200', + 'nozzle_size': '0.4', 'steps_per_e': '0', 'serial_port': 'AUTO', 'serial_baud': '250000', diff --git a/SkeinPyPy/newui/validators.py b/SkeinPyPy/newui/validators.py index 6352deb..79a3d31 100644 --- a/SkeinPyPy/newui/validators.py +++ b/SkeinPyPy/newui/validators.py @@ -75,7 +75,7 @@ class wallThicknessValidator(): def validate(self): try: wallThickness = float(self.setting.GetValue()) - nozzleSize = float(profile.getProfileSetting('nozzle_size')) + nozzleSize = float(profile.getPreference('nozzle_size')) if wallThickness <= nozzleSize * 0.5: return ERROR, 'Trying to print walls thinner then the half of your nozzle size, this will not produce anything usable' if wallThickness <= nozzleSize * 0.85: @@ -100,7 +100,7 @@ class printSpeedValidator(): def validate(self): try: - nozzleSize = float(profile.getProfileSetting('nozzle_size')) + nozzleSize = float(profile.getPreference('nozzle_size')) layerHeight = float(profile.getProfileSetting('layer_height')) printSpeed = float(profile.getProfileSetting('print_speed')) From e9c7135f5c71cf7342518cd8071e7b2531463b8d Mon Sep 17 00:00:00 2001 From: daid Date: Tue, 20 Mar 2012 16:23:00 +0100 Subject: [PATCH 19/19] Force minimal size to fix issue #16 --- SkeinPyPy/newui/mainWindow.py | 1 + 1 file changed, 1 insertion(+) diff --git a/SkeinPyPy/newui/mainWindow.py b/SkeinPyPy/newui/mainWindow.py index fc7e4c8..84f025a 100644 --- a/SkeinPyPy/newui/mainWindow.py +++ b/SkeinPyPy/newui/mainWindow.py @@ -208,6 +208,7 @@ class mainWindow(configBase.configWindowBase): self.updateProfileToControls() self.Fit() + self.SetMinSize(self.GetSize()) self.Centre() self.Show(True)