Merge remote-tracking branch 'upstream/master' into macosx

Conflicts:
	Cura/gui/configWizard.py
	Cura/gui/mainWindow.py
	Cura/gui/opengl.py
	Cura/gui/printWindow.py
	scripts/osx64/Cura.app/Contents/MacOS/Cura
master
Ilya Kulakov 2012-12-06 00:33:55 +07:00
commit 9f3d727817
26 changed files with 1487 additions and 1277 deletions

View File

@ -10,8 +10,9 @@ class Stk500v2(ispBase.IspBase):
self.serial = None self.serial = None
self.seq = 1 self.seq = 1
self.lastAddr = -1 self.lastAddr = -1
self.progressCallback = None
def connect(self, port = 'COM31', speed = 115200): def connect(self, port = 'COM22', speed = 115200):
if self.serial != None: if self.serial != None:
self.close() self.close()
try: try:
@ -145,8 +146,8 @@ class Stk500v2(ispBase.IspBase):
def main(): def main():
programmer = Stk500v2() programmer = Stk500v2()
programmer.connect() programmer.connect(port = sys.argv[1])
programmer.programChip(intelHex.readHex("cfg_4f55234def059.hex")) programmer.programChip(intelHex.readHex(sys.argv[2]))
sys.exit(1) sys.exit(1)
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -28,6 +28,8 @@ class daeModel(triangle_mesh.TriangleMesh):
self._geometryList = [] self._geometryList = []
r.ParseFile(open(filename, "r")) r.ParseFile(open(filename, "r"))
self._scale = float(self._base['collada'][0]['asset'][0]['unit'][0]['_meter']) * 1000
for instance_visual_scene in self._base['collada'][0]['scene'][0]['instance_visual_scene']: for instance_visual_scene in self._base['collada'][0]['scene'][0]['instance_visual_scene']:
for node in self._idMap[instance_visual_scene['_url']]['node']: for node in self._idMap[instance_visual_scene['_url']]['node']:
self._ProcessNode2(node) self._ProcessNode2(node)
@ -81,9 +83,9 @@ class daeModel(triangle_mesh.TriangleMesh):
startIndex = len(self.vertexes) startIndex = len(self.vertexes)
for idx in xrange(0, len(positionList)/3): for idx in xrange(0, len(positionList)/3):
x = positionList[idx*3] x = positionList[idx*3] * self._scale
y = positionList[idx*3+1] y = positionList[idx*3+1] * self._scale
z = positionList[idx*3+2] z = positionList[idx*3+2] * self._scale
if matrix != None: if matrix != None:
self.vertexes.append(Vector3(x * matrix[0] + y * matrix[1] + z * matrix[2] + matrix[3], x * matrix[4] + y * matrix[5] + z * matrix[6] + matrix[7], x * matrix[8] + y * matrix[9] + z * matrix[10] + matrix[11])) self.vertexes.append(Vector3(x * matrix[0] + y * matrix[1] + z * matrix[2] + matrix[3], x * matrix[4] + y * matrix[5] + z * matrix[6] + matrix[7], x * matrix[8] + y * matrix[9] + z * matrix[10] + matrix[11]))
else: else:

View File

@ -114,8 +114,8 @@ def getProfileInformation():
'SwapYZ': storedSetting("swap_yz"), 'SwapYZ': storedSetting("swap_yz"),
'Scale': storedSettingFloat("model_scale"), 'Scale': storedSettingFloat("model_scale"),
'Rotate': storedSettingFloat("model_rotate_base"), 'Rotate': storedSettingFloat("model_rotate_base"),
'CenterX': storedSettingFloat("machine_center_x"), 'CenterX': lambda setting: profile.getProfileSettingFloat('object_center_x') if profile.getProfileSettingFloat('object_center_x') > 0 else profile.getPreferenceFloat("machine_width") / 2,
'CenterY': storedSettingFloat("machine_center_y"), 'CenterY': lambda setting: profile.getProfileSettingFloat('object_center_y') if profile.getProfileSettingFloat('object_center_y') > 0 else profile.getPreferenceFloat("machine_depth") / 2,
'AlternativeCenterFile': storedSetting("alternative_center"), 'AlternativeCenterFile': storedSetting("alternative_center"),
},'scale': { },'scale': {
'Activate_Scale': "False", 'Activate_Scale': "False",
@ -176,8 +176,8 @@ def getProfileInformation():
'Thread_Sequence_Choice': storedSetting('sequence'), 'Thread_Sequence_Choice': storedSetting('sequence'),
},'multiply': { },'multiply': {
'Activate_Multiply': "False", 'Activate_Multiply': "False",
'Center_X_mm': storedSettingFloat("machine_center_x"), 'Center_X_mm': lambda setting: profile.getProfileSettingFloat('object_center_x') if profile.getProfileSettingFloat('object_center_x') > 0 else profile.getPreferenceFloat("machine_width") / 2,
'Center_Y_mm': storedSettingFloat("machine_center_y"), 'Center_Y_mm': lambda setting: profile.getProfileSettingFloat('object_center_y') if profile.getProfileSettingFloat('object_center_y') > 0 else profile.getPreferenceFloat("machine_depth") / 2,
'Number_of_Columns_integer': storedSetting('model_multiply_x'), 'Number_of_Columns_integer': storedSetting('model_multiply_x'),
'Number_of_Rows_integer': storedSetting('model_multiply_y'), 'Number_of_Rows_integer': storedSetting('model_multiply_y'),
'Reverse_Sequence_every_Odd_Layer': DEFSET, 'Reverse_Sequence_every_Odd_Layer': DEFSET,
@ -311,8 +311,8 @@ def getProfileInformation():
'Fan_speed_min_%': storedSettingInt('fan_speed'), 'Fan_speed_min_%': storedSettingInt('fan_speed'),
'Fan_speed_max_%': storedSettingInt('fan_speed_max'), 'Fan_speed_max_%': storedSettingInt('fan_speed_max'),
},'hop': { },'hop': {
'Activate_Hop': "False", 'Activate_Hop': storedSetting('hop_on_move'),
'Hop_Over_Layer_Thickness_ratio': DEFSET, 'Hop_Over_Layer_Thickness_ratio': lambda setting: 0.2 / profile.getProfileSettingFloat('layer_height'),
'Minimum_Hop_Angle_degrees': DEFSET, 'Minimum_Hop_Angle_degrees': DEFSET,
},'wipe': { },'wipe': {
'Activate_Wipe': "False", 'Activate_Wipe': "False",

View File

@ -266,7 +266,7 @@ def writeOutput(fileName, shouldAnalyze=True):
repository = ExportRepository() repository = ExportRepository()
settings.getReadRepository(repository) settings.getReadRepository(repository)
startTime = time.time() startTime = time.time()
print('File ' + archive.getSummarizedFileName(fileName) + ' is being chain exported.') print('File ' + archive.getSummarizedFileName(fileName.encode('ascii', 'replace')) + ' is being chain exported.')
fileNameSuffix = fileName[: fileName.rfind('.')] fileNameSuffix = fileName[: fileName.rfind('.')]
if repository.addExportSuffix.value: if repository.addExportSuffix.value:
fileNameSuffix += '_export' fileNameSuffix += '_export'

View File

@ -10,6 +10,7 @@ import wx.wizard
from gui import firmwareInstall from gui import firmwareInstall
from gui import toolbarUtil from gui import toolbarUtil
from gui import printWindow
from util import machineCom from util import machineCom
from util import profile from util import profile
from util.resources import getPathForImage from util.resources import getPathForImage
@ -34,28 +35,40 @@ class InfoBox(wx.Panel):
self.bitmap = wx.StaticBitmap(self, -1, wx.EmptyBitmapRGBA(24, 24, red=255, green=255, blue=255, alpha=1)) self.bitmap = wx.StaticBitmap(self, -1, wx.EmptyBitmapRGBA(24, 24, red=255, green=255, blue=255, alpha=1))
self.text = wx.StaticText(self, -1, '') self.text = wx.StaticText(self, -1, '')
self.extraInfoButton = wx.Button(self, -1, 'i', style=wx.BU_EXACTFIT)
self.sizer.Add(self.bitmap, pos=(0, 0), flag=wx.ALL, border=5) self.sizer.Add(self.bitmap, pos=(0, 0), flag=wx.ALL, border=5)
self.sizer.Add(self.text, pos=(0, 1), flag=wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, border=5) self.sizer.Add(self.text, pos=(0, 1), flag=wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER_VERTICAL, border=5)
self.sizer.Add(self.extraInfoButton, pos=(0,2), flag=wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, border=5)
self.sizer.AddGrowableCol(1)
self.extraInfoButton.Show(False)
self.extraInfoUrl = ''
self.busyState = None self.busyState = None
self.timer = wx.Timer(self) self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.doBusyUpdate, self.timer) self.Bind(wx.EVT_TIMER, self.doBusyUpdate, self.timer)
self.Bind(wx.EVT_BUTTON, self.doExtraInfo, self.extraInfoButton)
self.timer.Start(100) self.timer.Start(100)
def SetInfo(self, info): def SetInfo(self, info):
self.SetBackgroundColour('#FFFF80') self.SetBackgroundColour('#FFFF80')
self.text.SetLabel(info) self.text.SetLabel(info)
self.extraInfoButton.Show(False)
self.Refresh() self.Refresh()
def SetError(self, info): def SetError(self, info, extraInfoUrl):
self.extraInfoUrl = extraInfoUrl
self.SetBackgroundColour('#FF8080') self.SetBackgroundColour('#FF8080')
self.text.SetLabel(info) self.text.SetLabel(info)
self.extraInfoButton.Show(True)
self.Layout()
self.SetErrorIndicator() self.SetErrorIndicator()
self.Refresh() self.Refresh()
def SetAttention(self, info): def SetAttention(self, info):
self.SetBackgroundColour('#FFFF80') self.SetBackgroundColour('#FFFF80')
self.text.SetLabel(info) self.text.SetLabel(info)
self.extraInfoButton.Show(False)
self.SetAttentionIndicator() self.SetAttentionIndicator()
self.Refresh() self.Refresh()
@ -63,6 +76,9 @@ class InfoBox(wx.Panel):
self.busyState = 0 self.busyState = 0
self.bitmap.SetBitmap(self.busyBitmap[self.busyState]) self.bitmap.SetBitmap(self.busyBitmap[self.busyState])
def doExtraInfo(self, e):
webbrowser.open(self.extraInfoUrl)
def doBusyUpdate(self, e): def doBusyUpdate(self, e):
if self.busyState == None: if self.busyState == None:
return return
@ -225,8 +241,6 @@ class RepRapInfoPage(InfoPage):
profile.putPreference('machine_depth', self.machineDepth.GetValue()) profile.putPreference('machine_depth', self.machineDepth.GetValue())
profile.putPreference('machine_height', self.machineHeight.GetValue()) profile.putPreference('machine_height', self.machineHeight.GetValue())
profile.putProfileSetting('nozzle_size', self.nozzleSize.GetValue()) profile.putProfileSetting('nozzle_size', self.nozzleSize.GetValue())
profile.putProfileSetting('machine_center_x', profile.getPreferenceFloat('machine_width') / 2)
profile.putProfileSetting('machine_center_y', profile.getPreferenceFloat('machine_depth') / 2)
profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2) profile.putProfileSetting('wall_thickness', float(profile.getProfileSettingFloat('nozzle_size')) * 2)
profile.putPreference('has_heated_bed', str(self.heatedBed.GetValue())) profile.putPreference('has_heated_bed', str(self.heatedBed.GetValue()))
@ -255,8 +269,6 @@ class MachineSelectPage(InfoPage):
profile.putPreference('machine_height', '200') profile.putPreference('machine_height', '200')
profile.putPreference('machine_type', 'ultimaker') profile.putPreference('machine_type', 'ultimaker')
profile.putProfileSetting('nozzle_size', '0.4') profile.putProfileSetting('nozzle_size', '0.4')
profile.putProfileSetting('machine_center_x', '100')
profile.putProfileSetting('machine_center_y', '100')
else: else:
profile.putPreference('machine_width', '80') profile.putPreference('machine_width', '80')
profile.putPreference('machine_depth', '80') profile.putPreference('machine_depth', '80')
@ -264,11 +276,31 @@ class MachineSelectPage(InfoPage):
profile.putPreference('machine_type', 'reprap') profile.putPreference('machine_type', 'reprap')
profile.putPreference('startMode', 'Normal') profile.putPreference('startMode', 'Normal')
profile.putProfileSetting('nozzle_size', '0.5') profile.putProfileSetting('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.getProfileSetting('nozzle_size')) * 2)
class SelectParts(InfoPage):
def __init__(self, parent):
super(SelectParts, self).__init__(parent, "Select upgraded parts you have")
self.AddText('To assist you in having better default settings for your Ultimaker\nCura would like to know which upgrades you have in your machine.')
self.AddSeperator()
self.springExtruder = self.AddCheckbox('Extruder drive upgrade')
self.heatedBed = self.AddCheckbox('Heated printer bed (self build)')
self.dualExtrusion = self.AddCheckbox('Dual extrusion (experimental)')
self.AddSeperator()
self.AddText('If you have an Ultimaker bought after october 2012 you will have the\nExtruder drive upgrade. If you do not have this upgrade,\nit is highly recommended to improve reliablity.')
self.AddText('This upgrade can be bought from the Ultimaker webshop shop\nor found on thingiverse as thing:26094')
self.springExtruder.SetValue(True)
def StoreData(self):
profile.putPreference('ultimaker_extruder_upgrade', str(self.springExtruder.GetValue()))
profile.putPreference('has_heated_bed', str(self.heatedBed.GetValue()))
if self.dualExtrusion.GetValue():
profile.putPreference('extruder_amount', '2')
if getPreference('ultimaker_extruder_upgrade') == 'True':
putProfileSetting('retraction_enable', 'True')
class FirmwareUpgradePage(InfoPage): class FirmwareUpgradePage(InfoPage):
def __init__(self, parent): def __init__(self, parent):
super(FirmwareUpgradePage, self).__init__(parent, "Upgrade Ultimaker Firmware") super(FirmwareUpgradePage, self).__init__(parent, "Upgrade Ultimaker Firmware")
@ -332,6 +364,8 @@ class UltimakerCheckupPage(InfoPage):
self.infoBox = self.AddInfoBox() self.infoBox = self.AddInfoBox()
self.machineState = self.AddText('') self.machineState = self.AddText('')
self.temperatureLabel = self.AddText('') self.temperatureLabel = self.AddText('')
self.errorLogButton = self.AddButton('Show error log')
self.errorLogButton.Show(False)
self.AddSeperator() self.AddSeperator()
self.endstopBitmap = self.AddBitmap(self.endStopNoneBitmap) self.endstopBitmap = self.AddBitmap(self.endStopNoneBitmap)
self.comm = None self.comm = None
@ -342,6 +376,8 @@ class UltimakerCheckupPage(InfoPage):
self.zMinStop = False self.zMinStop = False
self.zMaxStop = False self.zMaxStop = False
self.Bind(wx.EVT_BUTTON, self.OnErrorLog, self.errorLogButton)
def __del__(self): def __del__(self):
if self.comm != None: if self.comm != None:
self.comm.close() self.comm.close()
@ -354,6 +390,7 @@ class UltimakerCheckupPage(InfoPage):
self.GetParent().FindWindowById(wx.ID_FORWARD).Enable() self.GetParent().FindWindowById(wx.ID_FORWARD).Enable()
def OnCheckClick(self, e=None): def OnCheckClick(self, e=None):
self.errorLogButton.Show(False)
if self.comm != None: if self.comm != None:
self.comm.close() self.comm.close()
del self.comm del self.comm
@ -368,6 +405,9 @@ class UltimakerCheckupPage(InfoPage):
self.checkupState = 0 self.checkupState = 0
self.comm = machineCom.MachineCom(callbackObject=self) self.comm = machineCom.MachineCom(callbackObject=self)
def OnErrorLog(self, e):
printWindow.LogWindow('\n'.join(self.comm.getLog()))
def mcLog(self, message): def mcLog(self, message):
pass pass
@ -410,7 +450,7 @@ class UltimakerCheckupPage(InfoPage):
if self.tempCheckTimeout < 1: if self.tempCheckTimeout < 1:
self.checkupState = -1 self.checkupState = -1
wx.CallAfter(self.tempState.SetBitmap, self.crossBitmap) wx.CallAfter(self.tempState.SetBitmap, self.crossBitmap)
wx.CallAfter(self.infoBox.SetError, 'Temperature measurement FAILED!') wx.CallAfter(self.infoBox.SetError, 'Temperature measurement FAILED!', 'http://wiki.ultimaker.com/Cura/Temperature_measurement_problems')
self.comm.sendCommand('M104 S0') self.comm.sendCommand('M104 S0')
self.comm.sendCommand('M104 S0') self.comm.sendCommand('M104 S0')
wx.CallAfter(self.temperatureLabel.SetLabel, 'Head temperature: %d' % (temp)) wx.CallAfter(self.temperatureLabel.SetLabel, 'Head temperature: %d' % (temp))
@ -420,10 +460,15 @@ class UltimakerCheckupPage(InfoPage):
return return
if self.comm.isOperational(): if self.comm.isOperational():
wx.CallAfter(self.commState.SetBitmap, self.checkBitmap) wx.CallAfter(self.commState.SetBitmap, self.checkBitmap)
wx.CallAfter(self.machineState.SetLabel, 'Communication State: %s' % (self.comm.getStateString()))
elif self.comm.isError(): elif self.comm.isError():
wx.CallAfter(self.commState.SetBitmap, self.crossBitmap) wx.CallAfter(self.commState.SetBitmap, self.crossBitmap)
wx.CallAfter(self.infoBox.SetError, 'Failed to establish connection with the printer.') wx.CallAfter(self.infoBox.SetError, 'Failed to establish connection with the printer.', 'http://wiki.ultimaker.com/Cura/Connection_problems')
wx.CallAfter(self.endstopBitmap.Show, False) wx.CallAfter(self.endstopBitmap.Show, False)
wx.CallAfter(self.machineState.SetLabel, '%s' % (self.comm.getErrorString()))
wx.CallAfter(self.errorLogButton.Show, True)
wx.CallAfter(self.Layout)
else:
wx.CallAfter(self.machineState.SetLabel, 'Communication State: %s' % (self.comm.getStateString())) wx.CallAfter(self.machineState.SetLabel, 'Communication State: %s' % (self.comm.getStateString()))
def mcMessage(self, message): def mcMessage(self, message):
@ -638,6 +683,7 @@ class configWizard(wx.wizard.Wizard):
self.firstInfoPage = FirstInfoPage(self) self.firstInfoPage = FirstInfoPage(self)
self.machineSelectPage = MachineSelectPage(self) self.machineSelectPage = MachineSelectPage(self)
self.ultimakerSelectParts = SelectParts(self)
self.ultimakerFirmwareUpgradePage = FirmwareUpgradePage(self) self.ultimakerFirmwareUpgradePage = FirmwareUpgradePage(self)
self.ultimakerCheckupPage = UltimakerCheckupPage(self) self.ultimakerCheckupPage = UltimakerCheckupPage(self)
self.ultimakerCalibrationPage = UltimakerCalibrationPage(self) self.ultimakerCalibrationPage = UltimakerCalibrationPage(self)
@ -645,7 +691,8 @@ class configWizard(wx.wizard.Wizard):
self.repRapInfoPage = RepRapInfoPage(self) self.repRapInfoPage = RepRapInfoPage(self)
wx.wizard.WizardPageSimple.Chain(self.firstInfoPage, self.machineSelectPage) wx.wizard.WizardPageSimple.Chain(self.firstInfoPage, self.machineSelectPage)
wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimakerFirmwareUpgradePage) wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.ultimakerSelectParts)
wx.wizard.WizardPageSimple.Chain(self.ultimakerSelectParts, self.ultimakerFirmwareUpgradePage)
wx.wizard.WizardPageSimple.Chain(self.ultimakerFirmwareUpgradePage, self.ultimakerCheckupPage) wx.wizard.WizardPageSimple.Chain(self.ultimakerFirmwareUpgradePage, self.ultimakerCheckupPage)
#wx.wizard.WizardPageSimple.Chain(self.ultimakerCheckupPage, self.ultimakerCalibrationPage) #wx.wizard.WizardPageSimple.Chain(self.ultimakerCheckupPage, self.ultimakerCalibrationPage)
#wx.wizard.WizardPageSimple.Chain(self.ultimakerCalibrationPage, self.ultimakerCalibrateStepsPerEPage) #wx.wizard.WizardPageSimple.Chain(self.ultimakerCalibrationPage, self.ultimakerCalibrateStepsPerEPage)

View File

@ -67,6 +67,9 @@ class expertConfigWindow(configBase.configWindowBase):
configBase.TitleRow(right, "Retraction") configBase.TitleRow(right, "Retraction")
c = configBase.SettingRow(right, "Retract on jumps only", 'retract_on_jumps_only', True, 'Only retract when we are making a move that is over a hole in the model, else retract on every move. This effects print quality in different ways.') c = configBase.SettingRow(right, "Retract on jumps only", 'retract_on_jumps_only', True, 'Only retract when we are making a move that is over a hole in the model, else retract on every move. This effects print quality in different ways.')
configBase.TitleRow(right, "Hop")
c = configBase.SettingRow(right, "Enable hop on move", 'hop_on_move', False, 'When moving from print position to print position, raise the printer head 0.2mm so it does not knock off the print (experimental).')
main.Fit() main.Fit()
self.Fit() self.Fit()

View File

@ -84,7 +84,7 @@ class flatSlicerWindow(wx.Frame):
if dlg.ShowModal() == wx.ID_OK: if dlg.ShowModal() == wx.ID_OK:
self.filename = dlg.GetPath() self.filename = dlg.GetPath()
self.svg = svg.SVG(self.filename) self.svg = svg.SVG(self.filename)
self.svg.center(complex(profile.getProfileSettingFloat('machine_center_x'), profile.getProfileSettingFloat('machine_center_y'))) self.svg.center(complex(profile.getPreferenceFloat('machine_width')/2, profile.getPreferenceFloat('machine_depth')/2))
self.preview.Refresh() self.preview.Refresh()
dlg.Destroy() dlg.Destroy()

View File

@ -113,7 +113,7 @@ class mainWindow(configBase.configWindowBase):
helpMenu = wx.Menu() helpMenu = wx.Menu()
i = helpMenu.Append(-1, 'Online documentation...') i = helpMenu.Append(-1, 'Online documentation...')
self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://daid.github.com/Cura'), i) self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('http://daid.github.com/Cura'), i)
i = helpMenu.Append(-1, 'Report a problem...') i = helpMenu.Append(-1, 'Report a problem...')
self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://github.com/daid/Cura/issues'), i) self.Bind(wx.EVT_MENU, lambda e: webbrowser.open('https://github.com/daid/Cura/issues'), i)
menubar.Append(helpMenu, 'Help') menubar.Append(helpMenu, 'Help')
@ -134,7 +134,7 @@ class mainWindow(configBase.configWindowBase):
(left, right) = self.CreateConfigTab(nb, 'Print config') (left, right) = self.CreateConfigTab(nb, 'Print config')
configBase.TitleRow(left, "Accuracy") configBase.TitleRow(left, "Quality")
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.') 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.0001) validators.validFloat(c, 0.0001)
validators.warningAbove(c, lambda : (float(profile.getProfileSetting('nozzle_size')) * 80.0 / 100.0), "Thicker layers then %.2fmm (80%% nozzle size) usually give bad results and are not recommended.") validators.warningAbove(c, lambda : (float(profile.getProfileSetting('nozzle_size')) * 80.0 / 100.0), "Thicker layers then %.2fmm (80%% nozzle size) usually give bad results and are not recommended.")
@ -149,12 +149,6 @@ class mainWindow(configBase.configWindowBase):
c = configBase.SettingRow(left, "Fill Density (%)", 'fill_density', '20', 'This controls how densily filled the insides of your print will be. For a solid part use 100%, for an empty part use 0%. A value around 20% is usually enough') c = configBase.SettingRow(left, "Fill Density (%)", 'fill_density', '20', 'This controls how densily filled the insides of your print will be. For a solid part use 100%, for an empty part use 0%. A value around 20% is usually enough')
validators.validFloat(c, 0.0, 100.0) validators.validFloat(c, 0.0, 100.0)
configBase.TitleRow(left, "Skirt")
c = configBase.SettingRow(left, "Line count", 'skirt_line_count', '1', 'The skirt is a line drawn around the object at the first layer. This helps to prime your extruder, and to see if the object fits on your platform.\nSetting this to 0 will disable the skirt. Multiple skirt lines can help priming your extruder better for small objects.')
validators.validInt(c, 0, 10)
c = configBase.SettingRow(left, "Start distance (mm)", 'skirt_gap', '6.0', 'The distance between the skirt and the first layer.\nThis is the minimal distance, multiple skirt lines will be put outwards from this distance.')
validators.validFloat(c, 0.0)
configBase.TitleRow(right, "Speed && Temperature") configBase.TitleRow(right, "Speed && Temperature")
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.') 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.validFloat(c, 1.0)
@ -187,15 +181,15 @@ class mainWindow(configBase.configWindowBase):
configBase.TitleRow(left, "Machine size") configBase.TitleRow(left, "Machine size")
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.') 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, 10.0) validators.validFloat(c, 0.1, 10.0)
c = configBase.SettingRow(left, "Machine center X (mm)", 'machine_center_x', '100', 'The center of your machine, your print will be placed at this location')
validators.validInt(c, 10) configBase.TitleRow(left, "Skirt")
configBase.settingNotify(c, self.preview3d.updateCenterX) c = configBase.SettingRow(left, "Line count", 'skirt_line_count', '1', 'The skirt is a line drawn around the object at the first layer. This helps to prime your extruder, and to see if the object fits on your platform.\nSetting this to 0 will disable the skirt. Multiple skirt lines can help priming your extruder better for small objects.')
c = configBase.SettingRow(left, "Machine center Y (mm)", 'machine_center_y', '100', 'The center of your machine, your print will be placed at this location') validators.validInt(c, 0, 10)
validators.validInt(c, 10) c = configBase.SettingRow(left, "Start distance (mm)", 'skirt_gap', '6.0', 'The distance between the skirt and the first layer.\nThis is the minimal distance, multiple skirt lines will be put outwards from this distance.')
configBase.settingNotify(c, self.preview3d.updateCenterY) validators.validFloat(c, 0.0)
configBase.TitleRow(left, "Retraction") 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') c = configBase.SettingRow(left, "Minimum travel (mm)", 'retraction_min_travel', '5.0', 'Minimum 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) validators.validFloat(c, 0.0)
c = configBase.SettingRow(left, "Speed (mm/s)", 'retraction_speed', '40.0', 'Speed at which the filament is retracted, a higher retraction speed works better. But a very high retraction speed can lead to filament grinding.') c = configBase.SettingRow(left, "Speed (mm/s)", 'retraction_speed', '40.0', 'Speed at which the filament is retracted, a higher retraction speed works better. But a very high retraction speed can lead to filament grinding.')
validators.validFloat(c, 0.1) validators.validFloat(c, 0.1)
@ -218,11 +212,11 @@ class mainWindow(configBase.configWindowBase):
validators.validFloat(c, 0.0) validators.validFloat(c, 0.0)
c = configBase.SettingRow(right, "Enable cooling fan", 'fan_enabled', True, 'Enable the cooling fan during the print. The extra cooling from the cooling fan is essensial during faster prints.') c = configBase.SettingRow(right, "Enable cooling fan", 'fan_enabled', True, 'Enable the cooling fan during the print. The extra cooling from the cooling fan is essensial during faster prints.')
configBase.TitleRow(right, "Accuracy") configBase.TitleRow(right, "Quality")
c = configBase.SettingRow(right, "Initial layer thickness (mm)", 'bottom_thickness', '0.0', 'Layer thickness of the bottom layer. A thicker bottom layer makes sticking to the bed easier. Set to 0.0 to have the bottom layer thickness the same as the other layers.') c = configBase.SettingRow(right, "Initial layer thickness (mm)", 'bottom_thickness', '0.0', 'Layer thickness of the bottom layer. A thicker bottom layer makes sticking to the bed easier. Set to 0.0 to have the bottom layer thickness the same as the other layers.')
validators.validFloat(c, 0.0) validators.validFloat(c, 0.0)
validators.warningAbove(c, lambda : (float(profile.getProfileSetting('nozzle_size')) * 3.0 / 4.0), "A bottom layer of more then %.2fmm (3/4 nozzle size) usually give bad results and is not recommended.") validators.warningAbove(c, lambda : (float(profile.getProfileSetting('nozzle_size')) * 3.0 / 4.0), "A bottom layer of more then %.2fmm (3/4 nozzle size) usually give bad results and is not recommended.")
c = configBase.SettingRow(right, "Enable 'skin'", 'enable_skin', False, 'Skin prints the outer lines of the prints twice, each time with half the thickness. This gives the illusion of a higher print quality.') c = configBase.SettingRow(right, "Duplicate outlines", 'enable_skin', False, 'Skin prints the outer lines of the prints twice, each time with half the thickness. This gives the illusion of a higher print quality.')
#Plugin page #Plugin page
self.pluginPanel = pluginPanel.pluginPanel(nb) self.pluginPanel = pluginPanel.pluginPanel(nb)
@ -236,7 +230,7 @@ class mainWindow(configBase.configWindowBase):
nb.AddPage(self.alterationPanel, "Start/End-GCode") nb.AddPage(self.alterationPanel, "Start/End-GCode")
# load and slice buttons. # load and slice buttons.
loadButton = wx.Button(self, -1, '&Load Model') loadButton = wx.Button(self, -1, '&Load model')
sliceButton = wx.Button(self, -1, 'P&repare print') sliceButton = wx.Button(self, -1, 'P&repare print')
printButton = wx.Button(self, -1, '&Print') printButton = wx.Button(self, -1, '&Print')
self.Bind(wx.EVT_BUTTON, lambda e: self._showModelLoadDialog(1), loadButton) self.Bind(wx.EVT_BUTTON, lambda e: self._showModelLoadDialog(1), loadButton)
@ -331,10 +325,6 @@ class mainWindow(configBase.configWindowBase):
dlg.Destroy() dlg.Destroy()
if result: if result:
profile.resetGlobalProfile() profile.resetGlobalProfile()
if profile.getPreference('machine_type') == 'reprap':
profile.putProfileSetting('nozzle_size', '0.5')
profile.putProfileSetting('machine_center_x', '40')
profile.putProfileSetting('machine_center_y', '40')
self.updateProfileToControls() self.updateProfileToControls()
def OnBatchRun(self, e): def OnBatchRun(self, e):

View File

@ -357,6 +357,44 @@ def DrawMesh(mesh):
glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_NORMAL_ARRAY);
def DrawMeshSteep(mesh, angle):
cosAngle = math.sin(angle / 180.0 * math.pi)
glDisable(GL_LIGHTING)
glDepthFunc(GL_EQUAL)
for i in xrange(0, int(mesh.vertexCount), 3):
if mesh.normal[i][2] < -0.999999:
if mesh.vertexes[i + 0][2] > 0.01:
glColor3f(0.5, 0, 0)
glBegin(GL_TRIANGLES)
glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
glEnd()
elif mesh.normal[i][2] < -cosAngle:
glColor3f(-mesh.normal[i][2], 0, 0)
glBegin(GL_TRIANGLES)
glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
glEnd()
elif mesh.normal[i][2] > 0.999999:
if mesh.vertexes[i + 0][2] > 0.01:
glColor3f(0.5, 0, 0)
glBegin(GL_TRIANGLES)
glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
glEnd()
elif mesh.normal[i][2] > cosAngle:
glColor3f(mesh.normal[i][2], 0, 0)
glBegin(GL_TRIANGLES)
glVertex3f(mesh.vertexes[i + 0][0], mesh.vertexes[i + 0][1], mesh.vertexes[i + 0][2])
glVertex3f(mesh.vertexes[i + 2][0], mesh.vertexes[i + 2][1], mesh.vertexes[i + 2][2])
glVertex3f(mesh.vertexes[i + 1][0], mesh.vertexes[i + 1][1], mesh.vertexes[i + 1][2])
glEnd()
glDepthFunc(GL_LESS)
def DrawGCodeLayer(layer): def DrawGCodeLayer(layer):
filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
filamentArea = math.pi * filamentRadius * filamentRadius filamentArea = math.pi * filamentRadius * filamentRadius

View File

@ -3,6 +3,7 @@ import sys, math, threading, os, webbrowser
from wx.lib import scrolledpanel from wx.lib import scrolledpanel
from util import profile from util import profile
from util import exporer
class pluginPanel(wx.Panel): class pluginPanel(wx.Panel):
def __init__(self, parent): def __init__(self, parent):
@ -20,19 +21,23 @@ class pluginPanel(wx.Panel):
self.listbox = wx.ListBox(self, -1, choices=effectStringList) self.listbox = wx.ListBox(self, -1, choices=effectStringList)
title = wx.StaticText(self, -1, "Plugins:") title = wx.StaticText(self, -1, "Plugins:")
title.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD)) title.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD))
helpButton = wx.Button(self, -1, '?', style=wx.BU_EXACTFIT)
addButton = wx.Button(self, -1, '>', style=wx.BU_EXACTFIT) addButton = wx.Button(self, -1, '>', style=wx.BU_EXACTFIT)
openPluginLocationButton = wx.Button(self, -1, 'Open plugin location')
sb = wx.StaticBox(self, label="Enabled plugins") sb = wx.StaticBox(self, label="Enabled plugins")
boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL) boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
self.pluginEnabledPanel = scrolledpanel.ScrolledPanel(self) self.pluginEnabledPanel = scrolledpanel.ScrolledPanel(self)
self.pluginEnabledPanel.SetupScrolling(False, True) self.pluginEnabledPanel.SetupScrolling(False, True)
sizer.Add(title, (0,0), border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.TOP) sizer.Add(title, (0,0), border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.TOP)
sizer.Add(self.listbox, (1,0), span=(2,1), border=10, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM) sizer.Add(helpButton, (0,1), border=10, flag=wx.ALIGN_RIGHT|wx.RIGHT|wx.TOP)
sizer.Add(addButton, (1,1), border=5, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_BOTTOM) sizer.Add(self.listbox, (1,0), span=(2,2), border=10, flag=wx.EXPAND|wx.LEFT|wx.RIGHT)
sizer.Add(boxsizer, (1,2), span=(2,1), border=10, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM) sizer.Add(addButton, (1,2), border=5, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_BOTTOM)
sizer.Add(boxsizer, (1,3), span=(2,1), border=10, flag=wx.EXPAND|wx.LEFT|wx.RIGHT)
sizer.Add(openPluginLocationButton, (3, 0), span=(1,2), border=10, flag=wx.LEFT|wx.BOTTOM)
boxsizer.Add(self.pluginEnabledPanel, 1, flag=wx.EXPAND) boxsizer.Add(self.pluginEnabledPanel, 1, flag=wx.EXPAND)
sizer.AddGrowableCol(2) sizer.AddGrowableCol(3)
sizer.AddGrowableRow(1) sizer.AddGrowableRow(1)
sizer.AddGrowableRow(2) sizer.AddGrowableRow(2)
@ -40,6 +45,9 @@ class pluginPanel(wx.Panel):
self.pluginEnabledPanel.SetSizer(sizer) self.pluginEnabledPanel.SetSizer(sizer)
self.Bind(wx.EVT_BUTTON, self.OnAdd, addButton) self.Bind(wx.EVT_BUTTON, self.OnAdd, addButton)
self.Bind(wx.EVT_BUTTON, self.OnGeneralHelp, helpButton)
self.Bind(wx.EVT_BUTTON, self.OnOpenPluginLocation, openPluginLocationButton)
self.listbox.Bind(wx.EVT_LEFT_DCLICK, self.OnAdd)
self.panelList = [] self.panelList = []
self.updateProfileToControls() self.updateProfileToControls()
@ -151,3 +159,9 @@ class pluginPanel(wx.Panel):
fname = fname[0].upper() + fname[1:] fname = fname[0].upper() + fname[1:]
fname = fname[:fname.rfind('.')] fname = fname[:fname.rfind('.')]
webbrowser.open('http://wiki.ultimaker.com/CuraPlugin:_' + fname) webbrowser.open('http://wiki.ultimaker.com/CuraPlugin:_' + fname)
def OnGeneralHelp(self, e):
webbrowser.open('http://wiki.ultimaker.com/Category:CuraPlugin')
def OnOpenPluginLocation(self, e):
exporer.openExporerPath(profile.getPluginBasePaths()[0])

View File

@ -22,11 +22,11 @@ class preferencesDialog(configBase.configWindowBase):
configBase.TitleRow(left, 'Machine settings') configBase.TitleRow(left, 'Machine settings')
c = configBase.SettingRow(left, 'Steps per E', 'steps_per_e', '0', 'Amount of steps per mm filament extrusion', type = 'preference') 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) validators.validFloat(c, 0.1)
c = configBase.SettingRow(left, 'Machine width (mm)', 'machine_width', '205', 'Size of the machine in mm', type = 'preference') c = configBase.SettingRow(left, 'Maximum width (mm)', 'machine_width', '205', 'Size of the machine in mm', type = 'preference')
validators.validFloat(c, 10.0) validators.validFloat(c, 10.0)
c = configBase.SettingRow(left, 'Machine depth (mm)', 'machine_depth', '205', 'Size of the machine in mm', type = 'preference') c = configBase.SettingRow(left, 'Maximum depth (mm)', 'machine_depth', '205', 'Size of the machine in mm', type = 'preference')
validators.validFloat(c, 10.0) validators.validFloat(c, 10.0)
c = configBase.SettingRow(left, 'Machine height (mm)', 'machine_height', '200', 'Size of the machine in mm', type = 'preference') c = configBase.SettingRow(left, 'Maximum height (mm)', 'machine_height', '200', 'Size of the machine in mm', type = 'preference')
validators.validFloat(c, 10.0) validators.validFloat(c, 10.0)
c = configBase.SettingRow(left, 'Extruder count', 'extruder_amount', ['1', '2', '3', '4'], 'Amount of extruders in your machine.', type = 'preference') c = configBase.SettingRow(left, 'Extruder count', 'extruder_amount', ['1', '2', '3', '4'], 'Amount of extruders in your machine.', type = 'preference')
c = configBase.SettingRow(left, 'Heated bed', 'has_heated_bed', False, 'If you have an heated bed, this enabled heated bed settings', type = 'preference') c = configBase.SettingRow(left, 'Heated bed', 'has_heated_bed', False, 'If you have an heated bed, this enabled heated bed settings', type = 'preference')
@ -44,11 +44,11 @@ class preferencesDialog(configBase.configWindowBase):
c = configBase.SettingRow(left, 'Model colour (%d)' % (i+1), 'model_colour%d' % (i+1), wx.Colour(0,0,0), '', type = 'preference') c = configBase.SettingRow(left, 'Model colour (%d)' % (i+1), 'model_colour%d' % (i+1), wx.Colour(0,0,0), '', type = 'preference')
configBase.TitleRow(right, 'Filament settings') configBase.TitleRow(right, 'Filament settings')
c = configBase.SettingRow(right, 'Filament density (kg/m3)', 'filament_density', '1300', 'Weight of the filament per m3. Around 1300 for PLA. And around 1040 for ABS. This value is used to estimate the weight if the filament used for the print.', type = 'preference') c = configBase.SettingRow(right, 'Density (kg/m3)', 'filament_density', '1300', 'Weight of the filament per m3. Around 1300 for PLA. And around 1040 for ABS. This value is used to estimate the weight if the filament used for the print.', type = 'preference')
validators.validFloat(c, 500.0, 3000.0) validators.validFloat(c, 500.0, 3000.0)
c = configBase.SettingRow(right, 'Filament cost (price/kg)', 'filament_cost_kg', '0', 'Cost of your filament per kg, to estimate the cost of the final print.', type = 'preference') c = configBase.SettingRow(right, 'Cost (price/kg)', 'filament_cost_kg', '0', 'Cost of your filament per kg, to estimate the cost of the final print.', type = 'preference')
validators.validFloat(c, 0.0) validators.validFloat(c, 0.0)
c = configBase.SettingRow(right, 'Filament cost (price/m)', 'filament_cost_meter', '0', 'Cost of your filament per meter, to estimate the cost of the final print.', type = 'preference') c = configBase.SettingRow(right, 'Cost (price/m)', 'filament_cost_meter', '0', 'Cost of your filament per meter, to estimate the cost of the final print.', type = 'preference')
validators.validFloat(c, 0.0) validators.validFloat(c, 0.0)
configBase.TitleRow(right, 'Communication settings') configBase.TitleRow(right, 'Communication settings')

View File

@ -43,9 +43,10 @@ class previewPanel(wx.Panel):
self.gcode = None self.gcode = None
self.objectsMinV = None self.objectsMinV = None
self.objectsMaxV = None self.objectsMaxV = None
self.objectsBounderyCircleSize = None
self.loadThread = None self.loadThread = None
self.machineSize = util3d.Vector3(profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')) self.machineSize = util3d.Vector3(profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height'))
self.machineCenter = util3d.Vector3(float(profile.getProfileSetting('machine_center_x')), float(profile.getProfileSetting('machine_center_y')), 0) self.machineCenter = util3d.Vector3(self.machineSize.x / 2, self.machineSize.y / 2, 0)
self.glCanvas = PreviewGLCanvas(self) self.glCanvas = PreviewGLCanvas(self)
#Create the popup window #Create the popup window
@ -77,6 +78,7 @@ class previewPanel(wx.Panel):
self.toolbar.AddSeparator() self.toolbar.AddSeparator()
self.showBorderButton = toolbarUtil.ToggleButton(self.toolbar, '', 'view-border-on.png', 'view-border-off.png', 'Show model borders', callback=self.OnViewChange) self.showBorderButton = toolbarUtil.ToggleButton(self.toolbar, '', 'view-border-on.png', 'view-border-off.png', 'Show model borders', callback=self.OnViewChange)
self.showSteepOverhang = toolbarUtil.ToggleButton(self.toolbar, '', 'steepOverhang-on.png', 'steepOverhang-off.png', 'Show steep overhang', callback=self.OnViewChange)
self.toolbar.AddSeparator() self.toolbar.AddSeparator()
group = [] group = []
@ -90,18 +92,21 @@ class previewPanel(wx.Panel):
self.layerSpin = wx.SpinCtrl(self.toolbar, -1, '', size=(21*4,21), style=wx.SP_ARROW_KEYS) self.layerSpin = wx.SpinCtrl(self.toolbar, -1, '', size=(21*4,21), style=wx.SP_ARROW_KEYS)
self.toolbar.AddControl(self.layerSpin) self.toolbar.AddControl(self.layerSpin)
self.Bind(wx.EVT_SPINCTRL, self.OnLayerNrChange, self.layerSpin) self.Bind(wx.EVT_SPINCTRL, self.OnLayerNrChange, self.layerSpin)
self.toolbar.AddSeparator()
self.toolbarInfo = wx.TextCtrl(self.toolbar, -1, '', style=wx.TE_READONLY)
self.toolbar.AddControl(self.toolbarInfo)
self.toolbar2 = toolbarUtil.Toolbar(self) self.toolbar2 = toolbarUtil.Toolbar(self)
# Mirror # Mirror
self.mirrorX = toolbarUtil.ToggleButton(self.toolbar2, 'flip_x', 'object-mirror-x-on.png', 'object-mirror-x-off.png', 'Mirror X', callback=self.updateModelTransform) self.mirrorX = toolbarUtil.ToggleButton(self.toolbar2, 'flip_x', 'object-mirror-x-on.png', 'object-mirror-x-off.png', 'Mirror X', callback=self.returnToModelViewAndUpdateModel)
self.mirrorY = toolbarUtil.ToggleButton(self.toolbar2, 'flip_y', 'object-mirror-y-on.png', 'object-mirror-y-off.png', 'Mirror Y', callback=self.updateModelTransform) self.mirrorY = toolbarUtil.ToggleButton(self.toolbar2, 'flip_y', 'object-mirror-y-on.png', 'object-mirror-y-off.png', 'Mirror Y', callback=self.returnToModelViewAndUpdateModel)
self.mirrorZ = toolbarUtil.ToggleButton(self.toolbar2, 'flip_z', 'object-mirror-z-on.png', 'object-mirror-z-off.png', 'Mirror Z', callback=self.updateModelTransform) self.mirrorZ = toolbarUtil.ToggleButton(self.toolbar2, 'flip_z', 'object-mirror-z-on.png', 'object-mirror-z-off.png', 'Mirror Z', callback=self.returnToModelViewAndUpdateModel)
self.toolbar2.AddSeparator() self.toolbar2.AddSeparator()
# Swap # Swap
self.swapXZ = toolbarUtil.ToggleButton(self.toolbar2, 'swap_xz', 'object-swap-xz-on.png', 'object-swap-xz-off.png', 'Swap XZ', callback=self.updateModelTransform) self.swapXZ = toolbarUtil.ToggleButton(self.toolbar2, 'swap_xz', 'object-swap-xz-on.png', 'object-swap-xz-off.png', 'Swap XZ', callback=self.returnToModelViewAndUpdateModel)
self.swapYZ = toolbarUtil.ToggleButton(self.toolbar2, 'swap_yz', 'object-swap-yz-on.png', 'object-swap-yz-off.png', 'Swap YZ', callback=self.updateModelTransform) self.swapYZ = toolbarUtil.ToggleButton(self.toolbar2, 'swap_yz', 'object-swap-yz-on.png', 'object-swap-yz-off.png', 'Swap YZ', callback=self.returnToModelViewAndUpdateModel)
self.toolbar2.AddSeparator() self.toolbar2.AddSeparator()
# Scale # Scale
@ -136,6 +141,11 @@ class previewPanel(wx.Panel):
sizer.Add(self.toolbar2, 0, flag=wx.EXPAND|wx.BOTTOM|wx.LEFT|wx.RIGHT, border=1) sizer.Add(self.toolbar2, 0, flag=wx.EXPAND|wx.BOTTOM|wx.LEFT|wx.RIGHT, border=1)
self.SetSizer(sizer) self.SetSizer(sizer)
def returnToModelViewAndUpdateModel(self):
if self.glCanvas.viewMode == 'GCode' or self.glCanvas.viewMode == 'Mixed':
self.setViewMode('Normal')
self.updateModelTransform()
def OnMove(self, e = None): def OnMove(self, e = None):
if e != None: if e != None:
e.Skip() e.Skip()
@ -168,21 +178,34 @@ class previewPanel(wx.Panel):
if self.scale.GetValue() != '': if self.scale.GetValue() != '':
scale = self.scale.GetValue() scale = self.scale.GetValue()
profile.putProfileSetting('model_scale', scale) profile.putProfileSetting('model_scale', scale)
if self.glCanvas.viewMode == 'GCode' or self.glCanvas.viewMode == 'Mixed':
self.setViewMode('Normal')
self.glCanvas.Refresh() self.glCanvas.Refresh()
def OnScaleMax(self, e): if self.objectsMaxV != None:
size = (self.objectsMaxV - self.objectsMinV) * float(scale)
self.toolbarInfo.SetValue('%0.1f %0.1f %0.1f' % (size[0], size[1], size[2]))
def OnScaleMax(self, e = None, onlyScaleDown = False):
if self.objectsMinV == None: if self.objectsMinV == None:
return return
vMin = self.objectsMinV vMin = self.objectsMinV
vMax = self.objectsMaxV vMax = self.objectsMaxV
scaleX1 = (self.machineSize.x - self.machineCenter.x) / ((vMax[0] - vMin[0]) / 2) skirtSize = 3
scaleY1 = (self.machineSize.y - self.machineCenter.y) / ((vMax[1] - vMin[1]) / 2) if profile.getProfileSettingFloat('skirt_line_count') > 0:
scaleX2 = (self.machineCenter.x) / ((vMax[0] - vMin[0]) / 2) skirtSize = 3 + profile.getProfileSettingFloat('skirt_line_count') * profile.calculateEdgeWidth() + profile.getProfileSettingFloat('skirt_gap')
scaleY2 = (self.machineCenter.y) / ((vMax[1] - vMin[1]) / 2) scaleX1 = (self.machineSize.x - self.machineCenter.x - skirtSize) / ((vMax[0] - vMin[0]) / 2)
scaleY1 = (self.machineSize.y - self.machineCenter.y - skirtSize) / ((vMax[1] - vMin[1]) / 2)
scaleX2 = (self.machineCenter.x - skirtSize) / ((vMax[0] - vMin[0]) / 2)
scaleY2 = (self.machineCenter.y - skirtSize) / ((vMax[1] - vMin[1]) / 2)
scaleZ = self.machineSize.z / (vMax[2] - vMin[2]) scaleZ = self.machineSize.z / (vMax[2] - vMin[2])
scale = min(scaleX1, scaleY1, scaleX2, scaleY2, scaleZ) scale = min(scaleX1, scaleY1, scaleX2, scaleY2, scaleZ)
if scale > 1.0 and onlyScaleDown:
return
self.scale.SetValue(str(scale)) self.scale.SetValue(str(scale))
profile.putProfileSetting('model_scale', self.scale.GetValue()) profile.putProfileSetting('model_scale', self.scale.GetValue())
if self.glCanvas.viewMode == 'GCode' or self.glCanvas.viewMode == 'Mixed':
self.setViewMode('Normal')
self.glCanvas.Refresh() self.glCanvas.Refresh()
def OnRotateReset(self, e): def OnRotateReset(self, e):
@ -191,7 +214,7 @@ class previewPanel(wx.Panel):
def OnRotate(self, e): def OnRotate(self, e):
profile.putProfileSetting('model_rotate_base', self.rotate.GetValue()) profile.putProfileSetting('model_rotate_base', self.rotate.GetValue())
self.updateModelTransform() self.returnToModelViewAndUpdateModel()
def On3DClick(self): def On3DClick(self):
self.glCanvas.yaw = 30 self.glCanvas.yaw = 30
@ -210,14 +233,6 @@ class previewPanel(wx.Panel):
def OnLayerNrChange(self, e): def OnLayerNrChange(self, e):
self.glCanvas.Refresh() self.glCanvas.Refresh()
def updateCenterX(self):
self.machineCenter.x = profile.getProfileSettingFloat('machine_center_x')
self.glCanvas.Refresh()
def updateCenterY(self):
self.machineCenter.y = profile.getProfileSettingFloat('machine_center_y')
self.glCanvas.Refresh()
def setViewMode(self, mode): def setViewMode(self, mode):
if mode == "Normal": if mode == "Normal":
self.normalViewButton.SetValue(True) self.normalViewButton.SetValue(True)
@ -249,8 +264,8 @@ class previewPanel(wx.Panel):
self.loadThread.start() self.loadThread.start()
if showWarning: if showWarning:
if profile.getProfileSettingFloat('model_scale') != 1.0 or profile.getProfileSettingFloat('model_rotate_base') != 0 or profile.getProfileSetting('flip_x') != 'False' or profile.getProfileSetting('flip_y') != 'False' or profile.getProfileSetting('flip_z') != 'False' or profile.getProfileSetting('swap_xz') != 'False' or profile.getProfileSetting('swap_yz') != 'False': if profile.getProfileSettingFloat('model_scale') != 1.0 or profile.getProfileSettingFloat('model_rotate_base') != 0 or profile.getProfileSetting('flip_x') != 'False' or profile.getProfileSetting('flip_y') != 'False' or profile.getProfileSetting('flip_z') != 'False' or profile.getProfileSetting('swap_xz') != 'False' or profile.getProfileSetting('swap_yz') != 'False' or len(profile.getPluginConfig()) > 0:
self.ShowWarningPopup('Reset scale, rotation and mirror?', self.OnResetAll) self.ShowWarningPopup('Reset scale, rotation, mirror and plugins?', self.OnResetAll)
def loadReModelFiles(self, filelist): def loadReModelFiles(self, filelist):
#Only load this again if the filename matches the file we have already loaded (for auto loading GCode after slicing) #Only load this again if the filename matches the file we have already loaded (for auto loading GCode after slicing)
@ -268,10 +283,10 @@ class previewPanel(wx.Panel):
obj.dirty = False obj.dirty = False
obj.mesh = mesh obj.mesh = mesh
self.updateModelTransform() self.updateModelTransform()
self.OnScaleMax(None, True)
scale = profile.getProfileSettingFloat('model_scale') scale = profile.getProfileSettingFloat('model_scale')
size = (self.objectsMaxV - self.objectsMinV) * scale size = (self.objectsMaxV - self.objectsMinV) * scale
if size[0] > self.machineSize.x or size[1] > self.machineSize.y or size[2] > self.machineSize.z: self.toolbarInfo.SetValue('%0.1f %0.1f %0.1f' % (size[0], size[1], size[2]))
self.OnScaleMax(None)
self.glCanvas.zoom = numpy.max(size) * 2.5 self.glCanvas.zoom = numpy.max(size) * 2.5
self.errorList = [] self.errorList = []
wx.CallAfter(self.updateToolbar) wx.CallAfter(self.updateToolbar)
@ -311,7 +326,8 @@ class previewPanel(wx.Panel):
profile.putProfileSetting('flip_z', 'False') profile.putProfileSetting('flip_z', 'False')
profile.putProfileSetting('swap_xz', 'False') profile.putProfileSetting('swap_xz', 'False')
profile.putProfileSetting('swap_yz', 'False') profile.putProfileSetting('swap_yz', 'False')
self.updateProfileToControls() profile.setPluginConfig([])
self.GetParent().updateProfileToControls()
def ShowWarningPopup(self, text, callback = None): def ShowWarningPopup(self, text, callback = None):
self.warningPopup.text.SetLabel(text) self.warningPopup.text.SetLabel(text)
@ -358,6 +374,7 @@ class previewPanel(wx.Panel):
elif self.mixedViewButton.GetValue(): elif self.mixedViewButton.GetValue():
self.glCanvas.viewMode = "Mixed" self.glCanvas.viewMode = "Mixed"
self.glCanvas.drawBorders = self.showBorderButton.GetValue() self.glCanvas.drawBorders = self.showBorderButton.GetValue()
self.glCanvas.drawSteepOverhang = self.showSteepOverhang.GetValue()
self.updateToolbar() self.updateToolbar()
self.glCanvas.Refresh() self.glCanvas.Refresh()
@ -379,6 +396,7 @@ class previewPanel(wx.Panel):
minV = self.objectList[0].mesh.getMinimum() minV = self.objectList[0].mesh.getMinimum()
maxV = self.objectList[0].mesh.getMaximum() maxV = self.objectList[0].mesh.getMaximum()
objectsBounderyCircleSize = self.objectList[0].mesh.bounderyCircleSize
for obj in self.objectList: for obj in self.objectList:
if obj.mesh == None: if obj.mesh == None:
continue continue
@ -386,9 +404,11 @@ class previewPanel(wx.Panel):
obj.mesh.getMinimumZ() obj.mesh.getMinimumZ()
minV = numpy.minimum(minV, obj.mesh.getMinimum()) minV = numpy.minimum(minV, obj.mesh.getMinimum())
maxV = numpy.maximum(maxV, obj.mesh.getMaximum()) maxV = numpy.maximum(maxV, obj.mesh.getMaximum())
objectsBounderyCircleSize = max(objectsBounderyCircleSize, obj.mesh.bounderyCircleSize)
self.objectsMaxV = maxV self.objectsMaxV = maxV
self.objectsMinV = minV self.objectsMinV = minV
self.objectsBounderyCircleSize = objectsBounderyCircleSize
for obj in self.objectList: for obj in self.objectList:
if obj.mesh == None: if obj.mesh == None:
continue continue
@ -400,6 +420,11 @@ class previewPanel(wx.Panel):
# v[1] -= minV[1] + (maxV[1] - minV[1]) / 2 # v[1] -= minV[1] + (maxV[1] - minV[1]) / 2
obj.mesh.getMinimumZ() obj.mesh.getMinimumZ()
obj.dirty = True obj.dirty = True
scale = profile.getProfileSettingFloat('model_scale')
size = (self.objectsMaxV - self.objectsMinV) * scale
self.toolbarInfo.SetValue('%0.1f %0.1f %0.1f' % (size[0], size[1], size[2]))
self.glCanvas.Refresh() self.glCanvas.Refresh()
def updateProfileToControls(self): def updateProfileToControls(self):
@ -447,16 +472,15 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
def OnMouseMotion(self,e): def OnMouseMotion(self,e):
cursorXY = 100000 cursorXY = 100000
sizeXY = 0 radius = 0
if self.parent.objectsMaxV != None: if self.parent.objectsMaxV != None:
size = (self.parent.objectsMaxV - self.parent.objectsMinV) radius = self.parent.objectsBounderyCircleSize * profile.getProfileSettingFloat('model_scale')
sizeXY = math.sqrt((size[0] * size[0]) + (size[1] * size[1]))
p0 = numpy.array(gluUnProject(e.GetX(), self.viewport[1] + self.viewport[3] - e.GetY(), 0, self.modelMatrix, self.projMatrix, self.viewport)) p0 = numpy.array(gluUnProject(e.GetX(), self.viewport[1] + self.viewport[3] - e.GetY(), 0, self.modelMatrix, self.projMatrix, self.viewport))
p1 = numpy.array(gluUnProject(e.GetX(), self.viewport[1] + self.viewport[3] - e.GetY(), 1, self.modelMatrix, self.projMatrix, self.viewport)) p1 = numpy.array(gluUnProject(e.GetX(), self.viewport[1] + self.viewport[3] - e.GetY(), 1, self.modelMatrix, self.projMatrix, self.viewport))
cursorZ0 = p0 - (p1 - p0) * (p0[2] / (p1[2] - p0[2])) cursorZ0 = p0 - (p1 - p0) * (p0[2] / (p1[2] - p0[2]))
cursorXY = math.sqrt((cursorZ0[0] * cursorZ0[0]) + (cursorZ0[1] * cursorZ0[1])) cursorXY = math.sqrt((cursorZ0[0] * cursorZ0[0]) + (cursorZ0[1] * cursorZ0[1]))
if cursorXY >= sizeXY * 0.7 and cursorXY <= sizeXY * 0.7 + 3 and False: if cursorXY >= radius * 1.1 and cursorXY <= radius * 1.3:
self.SetCursor(wx.StockCursor(wx.CURSOR_SIZING)) self.SetCursor(wx.StockCursor(wx.CURSOR_SIZING))
else: else:
self.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT)) self.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
@ -464,7 +488,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
if e.Dragging() and e.LeftIsDown(): if e.Dragging() and e.LeftIsDown():
if self.dragType == '': if self.dragType == '':
#Define the drag type depending on the cursor position. #Define the drag type depending on the cursor position.
if cursorXY >= sizeXY * 0.7 and cursorXY <= sizeXY * 0.7 + 3 and False: if cursorXY >= radius * 1.1 and cursorXY <= radius * 1.3:
self.dragType = 'modelRotate' self.dragType = 'modelRotate'
self.dragStart = math.atan2(cursorZ0[0], cursorZ0[1]) self.dragStart = math.atan2(cursorZ0[0], cursorZ0[1])
else: else:
@ -485,6 +509,8 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
angle = math.atan2(cursorZ0[0], cursorZ0[1]) angle = math.atan2(cursorZ0[0], cursorZ0[1])
diff = self.dragStart - angle diff = self.dragStart - angle
self.tempRotate = diff * 180 / math.pi self.tempRotate = diff * 180 / math.pi
rot = profile.getProfileSettingFloat('model_rotate_base')
self.tempRotate = round((self.tempRotate + rot) / 15) * 15 - rot
#Workaround for buggy ATI cards. #Workaround for buggy ATI cards.
size = self.GetSizeTuple() size = self.GetSizeTuple()
self.SetSize((size[0]+1, size[1])) self.SetSize((size[0]+1, size[1]))
@ -492,7 +518,13 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
self.Refresh() self.Refresh()
else: else:
if self.tempRotate != 0: if self.tempRotate != 0:
profile.putProfileSetting('model_rotate_base', profile.getProfileSettingFloat('model_rotate_base') + self.tempRotate) newRotation = profile.getProfileSettingFloat('model_rotate_base') + self.tempRotate
while newRotation >= 360:
newRotation -= 360
while newRotation < 0:
newRotation += 360
profile.putProfileSetting('model_rotate_base', newRotation)
self.parent.rotate.SetValue(newRotation)
self.parent.updateModelTransform() self.parent.updateModelTransform()
self.tempRotate = 0 self.tempRotate = 0
@ -580,12 +612,16 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
if obj.mesh == None: if obj.mesh == None:
continue continue
if obj.displayList == None: if obj.displayList == None:
obj.displayList = glGenLists(1); obj.displayList = glGenLists(1)
obj.steepDisplayList = glGenLists(1)
if obj.dirty: if obj.dirty:
obj.dirty = False obj.dirty = False
glNewList(obj.displayList, GL_COMPILE) glNewList(obj.displayList, GL_COMPILE)
opengl.DrawMesh(obj.mesh) opengl.DrawMesh(obj.mesh)
glEndList() glEndList()
glNewList(obj.steepDisplayList, GL_COMPILE)
opengl.DrawMeshSteep(obj.mesh, 60)
glEndList()
if self.viewMode == "Mixed": if self.viewMode == "Mixed":
glDisable(GL_BLEND) glDisable(GL_BLEND)
@ -707,6 +743,15 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
opengl.DrawMeshOutline(obj.mesh) opengl.DrawMeshOutline(obj.mesh)
glPopMatrix() glPopMatrix()
if self.drawSteepOverhang:
glDisable(GL_LIGHTING)
glColor3f(1,1,1)
glPushMatrix()
modelScale = profile.getProfileSettingFloat('model_scale')
glScalef(modelScale, modelScale, modelScale)
glCallList(obj.steepDisplayList)
glPopMatrix()
glPopMatrix() glPopMatrix()
if self.viewMode == "Normal" or self.viewMode == "Transparent" or self.viewMode == "X-Ray": if self.viewMode == "Normal" or self.viewMode == "Transparent" or self.viewMode == "X-Ray":
glDisable(GL_LIGHTING) glDisable(GL_LIGHTING)
@ -720,30 +765,37 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glEnd() glEnd()
glEnable(GL_DEPTH_TEST) glEnable(GL_DEPTH_TEST)
opengl.DrawMachine(machineSize)
glPushMatrix() glPushMatrix()
glTranslate(self.parent.machineCenter.x, self.parent.machineCenter.y, 0) glTranslate(self.parent.machineCenter.x, self.parent.machineCenter.y, 0)
#Draw the rotate circle #Draw the rotate circle
if self.parent.objectsMaxV != None and False: if self.parent.objectsMaxV != None:
glDisable(GL_LIGHTING) glDisable(GL_LIGHTING)
glDisable(GL_CULL_FACE) glDisable(GL_CULL_FACE)
glEnable(GL_BLEND) glEnable(GL_BLEND)
glRotate(self.tempRotate + profile.getProfileSettingFloat('model_rotate_base'), 0, 0, 1)
radius = self.parent.objectsBounderyCircleSize * profile.getProfileSettingFloat('model_scale')
glScalef(radius, radius, 1)
glBegin(GL_TRIANGLE_STRIP) glBegin(GL_TRIANGLE_STRIP)
size = (self.parent.objectsMaxV - self.parent.objectsMinV)
sizeXY = math.sqrt((size[0] * size[0]) + (size[1] * size[1]))
for i in xrange(0, 64+1): for i in xrange(0, 64+1):
f = i if i < 64/2 else 64 - i f = i if i < 64/2 else 64 - i
glColor4ub(255,int(f*255/(64/2)),0,128) glColor4ub(255,int(f*255/(64/2)),0,255)
glVertex3f(sizeXY * 0.7 * math.cos(i/32.0*math.pi), sizeXY * 0.7 * math.sin(i/32.0*math.pi),0.1) glVertex3f(1.1 * math.cos(i/32.0*math.pi), 1.1 * math.sin(i/32.0*math.pi),0.1)
glColor4ub( 0,128,0,128) glColor4ub( 0,128,0,255)
glVertex3f((sizeXY * 0.7 + 3) * math.cos(i/32.0*math.pi), (sizeXY * 0.7 + 3) * math.sin(i/32.0*math.pi),0.1) glVertex3f(1.3 * math.cos(i/32.0*math.pi), 1.3 * math.sin(i/32.0*math.pi),0.1)
glEnd()
glBegin(GL_TRIANGLES)
glColor4ub(0,0,0,192)
glVertex3f(1, 0.1,0.15)
glVertex3f(1,-0.1,0.15)
glVertex3f(1.4,0,0.15)
glEnd() glEnd()
glEnable(GL_CULL_FACE) glEnable(GL_CULL_FACE)
glPopMatrix() glPopMatrix()
opengl.DrawMachine(machineSize)
glFlush() glFlush()
def drawModel(self, obj): def drawModel(self, obj):

View File

@ -134,7 +134,7 @@ class printWindow(wx.Frame):
self.powerWarningText = wx.StaticText(parent=self.panel, self.powerWarningText = wx.StaticText(parent=self.panel,
id=-1, id=-1,
label="Connect your computer to AC power\nIf it shuts down during printing, the product will be lost.", label="Your computer is running on battery power.\nConnect your computer to AC power or your print might not finish.",
style=wx.ALIGN_CENTER) style=wx.ALIGN_CENTER)
self.powerWarningText.SetBackgroundColour('red') self.powerWarningText.SetBackgroundColour('red')
self.powerWarningText.SetForegroundColour('white') self.powerWarningText.SetForegroundColour('white')
@ -309,7 +309,7 @@ class printWindow(wx.Frame):
self.camPreview.timer.Start(500) self.camPreview.timer.Start(500)
self.camPreview.Bind(wx.EVT_ERASE_BACKGROUND, self.OnCameraEraseBackground) self.camPreview.Bind(wx.EVT_ERASE_BACKGROUND, self.OnCameraEraseBackground)
self.sizer.AddGrowableRow(5) self.sizer.AddGrowableRow(6)
self.sizer.AddGrowableCol(3) self.sizer.AddGrowableCol(3)
self.Bind(wx.EVT_CLOSE, self.OnClose) self.Bind(wx.EVT_CLOSE, self.OnClose)
@ -521,9 +521,11 @@ class printWindow(wx.Frame):
type = self.powerManagement.get_providing_power_source_type() type = self.powerManagement.get_providing_power_source_type()
if type == power.POWER_TYPE_AC and self.powerWarningText.IsShown(): if type == power.POWER_TYPE_AC and self.powerWarningText.IsShown():
self.powerWarningText.Hide() self.powerWarningText.Hide()
self.panel.Layout()
self.Layout() self.Layout()
elif type != power.POWER_TYPE_AC and not self.powerWarningText.IsShown(): elif type != power.POWER_TYPE_AC and not self.powerWarningText.IsShown():
self.powerWarningText.Show() self.powerWarningText.Show()
self.panel.Layout()
self.Layout() self.Layout()
def LoadGCodeFile(self, filename): def LoadGCodeFile(self, filename):
@ -579,10 +581,11 @@ class printWindow(wx.Frame):
def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp): def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp):
self.temperatureGraph.addPoint(temp, targetTemp, bedTemp, bedTargetTemp) self.temperatureGraph.addPoint(temp, targetTemp, bedTemp, bedTargetTemp)
if self.temperatureSelect.GetValue() != targetTemp: # ToFix, this causes problems with setting the temperature with the keyboard
wx.CallAfter(self.temperatureSelect.SetValue, targetTemp) # if self.temperatureSelect.GetValue() != targetTemp:
if self.bedTemperatureSelect.GetValue() != bedTargetTemp: # wx.CallAfter(self.temperatureSelect.SetValue, targetTemp)
wx.CallAfter(self.bedTemperatureSelect.SetValue, bedTargetTemp) # if self.bedTemperatureSelect.GetValue() != bedTargetTemp:
# wx.CallAfter(self.bedTemperatureSelect.SetValue, bedTargetTemp)
def mcStateChange(self, state): def mcStateChange(self, state):
if self.machineCom != None: if self.machineCom != None:
@ -643,6 +646,7 @@ class temperatureGraph(wx.Panel):
dc = wx.MemoryDC() dc = wx.MemoryDC()
dc.SelectObject(self.backBuffer) dc.SelectObject(self.backBuffer)
dc.Clear() dc.Clear()
dc.SetFont(wx.SystemSettings.GetFont(wx.SYS_SYSTEM_FONT))
w, h = self.GetSizeTuple() w, h = self.GetSizeTuple()
bgLinePen = wx.Pen('#A0A0A0') bgLinePen = wx.Pen('#A0A0A0')
tempPen = wx.Pen('#FF4040') tempPen = wx.Pen('#FF4040')
@ -677,9 +681,12 @@ class temperatureGraph(wx.Panel):
for x in xrange(w, 0, -30): for x in xrange(w, 0, -30):
dc.SetPen(bgLinePen) dc.SetPen(bgLinePen)
dc.DrawLine(x, 0, x, h) dc.DrawLine(x, 0, x, h)
tmpNr = 0
for y in xrange(h - 1, 0, -h * 50 / 300): for y in xrange(h - 1, 0, -h * 50 / 300):
dc.SetPen(bgLinePen) dc.SetPen(bgLinePen)
dc.DrawLine(0, y, w, y) dc.DrawLine(0, y, w, y)
dc.DrawText(str(tmpNr), 0, y - dc.GetFont().GetPixelSize().GetHeight())
tmpNr += 50
dc.DrawLine(0, 0, w, 0) dc.DrawLine(0, 0, w, 0)
dc.DrawLine(0, 0, 0, h) dc.DrawLine(0, 0, 0, h)

View File

@ -153,6 +153,7 @@ class projectPlanner(wx.Frame):
self.list = [] self.list = []
self.selection = None self.selection = None
self.printMode = 0 self.printMode = 0
self.alwaysAutoPlace = True
self.machineSize = numpy.array([profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')]) self.machineSize = numpy.array([profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')])
self.headSizeMin = numpy.array([profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0]) self.headSizeMin = numpy.array([profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0])
@ -170,8 +171,8 @@ class projectPlanner(wx.Frame):
toolbarUtil.NormalButton(self.toolbar, self.OnSaveProject, 'save.png', 'Save project') toolbarUtil.NormalButton(self.toolbar, self.OnSaveProject, 'save.png', 'Save project')
self.toolbar.AddSeparator() self.toolbar.AddSeparator()
group = [] group = []
toolbarUtil.RadioButton(self.toolbar, group, 'object-3d-on.png', 'object-3d-off.png', '3D view', callback=self.On3DClick) toolbarUtil.RadioButton(self.toolbar, group, 'object-3d-on.png', 'object-3d-off.png', '3D view', callback=self.On3DClick).SetValue(self.alwaysAutoPlace)
toolbarUtil.RadioButton(self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick).SetValue(True) toolbarUtil.RadioButton(self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick).SetValue(not self.alwaysAutoPlace)
self.toolbar.AddSeparator() self.toolbar.AddSeparator()
toolbarUtil.NormalButton(self.toolbar, self.OnPreferences, 'preferences.png', 'Project planner preferences') toolbarUtil.NormalButton(self.toolbar, self.OnPreferences, 'preferences.png', 'Project planner preferences')
self.toolbar.AddSeparator() self.toolbar.AddSeparator()
@ -196,6 +197,7 @@ class projectPlanner(wx.Frame):
toolbarUtil.NormalButton(self.toolbar2, self.OnCopy, 'copy.png', 'Make a copy of the current selected object') toolbarUtil.NormalButton(self.toolbar2, self.OnCopy, 'copy.png', 'Make a copy of the current selected object')
toolbarUtil.NormalButton(self.toolbar2, self.OnSetCustomProfile, 'set-profile.png', 'Set a custom profile to be used to prepare a specific object.') toolbarUtil.NormalButton(self.toolbar2, self.OnSetCustomProfile, 'set-profile.png', 'Set a custom profile to be used to prepare a specific object.')
self.toolbar2.AddSeparator() self.toolbar2.AddSeparator()
if not self.alwaysAutoPlace:
toolbarUtil.NormalButton(self.toolbar2, self.OnAutoPlace, 'autoplace.png', 'Automaticly organize the objects on the platform.') toolbarUtil.NormalButton(self.toolbar2, self.OnAutoPlace, 'autoplace.png', 'Automaticly organize the objects on the platform.')
toolbarUtil.NormalButton(self.toolbar2, self.OnSlice, 'slice.png', 'Prepare to project into a gcode file.') toolbarUtil.NormalButton(self.toolbar2, self.OnSlice, 'slice.png', 'Prepare to project into a gcode file.')
self.toolbar2.Realize() self.toolbar2.Realize()
@ -218,6 +220,7 @@ class projectPlanner(wx.Frame):
self.addButton = wx.Button(self.panel, -1, "Add") self.addButton = wx.Button(self.panel, -1, "Add")
self.remButton = wx.Button(self.panel, -1, "Remove") self.remButton = wx.Button(self.panel, -1, "Remove")
self.sliceButton = wx.Button(self.panel, -1, "Prepare") self.sliceButton = wx.Button(self.panel, -1, "Prepare")
if not self.alwaysAutoPlace:
self.autoPlaceButton = wx.Button(self.panel, -1, "Auto Place") self.autoPlaceButton = wx.Button(self.panel, -1, "Auto Place")
sizer.Add(self.toolbar, (0,0), span=(1,1), flag=wx.EXPAND|wx.LEFT|wx.RIGHT) sizer.Add(self.toolbar, (0,0), span=(1,1), flag=wx.EXPAND|wx.LEFT|wx.RIGHT)
@ -228,6 +231,7 @@ class projectPlanner(wx.Frame):
sizer.Add(self.addButton, (3,1), span=(1,1)) sizer.Add(self.addButton, (3,1), span=(1,1))
sizer.Add(self.remButton, (3,2), span=(1,1)) sizer.Add(self.remButton, (3,2), span=(1,1))
sizer.Add(self.sliceButton, (4,1), span=(1,1)) sizer.Add(self.sliceButton, (4,1), span=(1,1))
if not self.alwaysAutoPlace:
sizer.Add(self.autoPlaceButton, (4,2), span=(1,1)) sizer.Add(self.autoPlaceButton, (4,2), span=(1,1))
sizer.AddGrowableCol(0) sizer.AddGrowableCol(0)
sizer.AddGrowableRow(1) sizer.AddGrowableRow(1)
@ -235,6 +239,7 @@ class projectPlanner(wx.Frame):
self.addButton.Bind(wx.EVT_BUTTON, self.OnAddModel) self.addButton.Bind(wx.EVT_BUTTON, self.OnAddModel)
self.remButton.Bind(wx.EVT_BUTTON, self.OnRemModel) self.remButton.Bind(wx.EVT_BUTTON, self.OnRemModel)
self.sliceButton.Bind(wx.EVT_BUTTON, self.OnSlice) self.sliceButton.Bind(wx.EVT_BUTTON, self.OnSlice)
if not self.alwaysAutoPlace:
self.autoPlaceButton.Bind(wx.EVT_BUTTON, self.OnAutoPlace) self.autoPlaceButton.Bind(wx.EVT_BUTTON, self.OnAutoPlace)
self.listbox.Bind(wx.EVT_LISTBOX, self.OnListSelect) self.listbox.Bind(wx.EVT_LISTBOX, self.OnListSelect)
@ -309,6 +314,8 @@ class projectPlanner(wx.Frame):
self.printMode = 0 self.printMode = 0
if self.printAllAtOnce.GetValue(): if self.printAllAtOnce.GetValue():
self.printMode = 1 self.printMode = 1
if self.alwaysAutoPlace:
self.OnAutoPlace(None)
self.preview.Refresh() self.preview.Refresh()
def OnSaveCombinedSTL(self, e): def OnSaveCombinedSTL(self, e):
@ -508,6 +515,8 @@ class projectPlanner(wx.Frame):
else: else:
self.selection = None self.selection = None
self.listbox.SetSelection(-1) self.listbox.SetSelection(-1)
if self.alwaysAutoPlace:
self.OnAutoPlace(None)
def OnAutoPlace(self, e): def OnAutoPlace(self, e):
bestAllowedSize = int(self.machineSize[1]) bestAllowedSize = int(self.machineSize[1])
@ -587,8 +596,8 @@ class projectPlanner(wx.Frame):
for item in self.list: for item in self.list:
if item.profile != None and os.path.isfile(item.profile): if item.profile != None and os.path.isfile(item.profile):
profile.loadGlobalProfile(item.profile) profile.loadGlobalProfile(item.profile)
put('machine_center_x', item.centerX - self.extruderOffset[item.extruder][0]) put('object_center_x', item.centerX - self.extruderOffset[item.extruder][0])
put('machine_center_y', item.centerY - self.extruderOffset[item.extruder][1]) put('object_center_y', item.centerY - self.extruderOffset[item.extruder][1])
put('model_scale', item.scale) put('model_scale', item.scale)
put('flip_x', item.flipX) put('flip_x', item.flipX)
put('flip_y', item.flipY) put('flip_y', item.flipY)
@ -630,8 +639,8 @@ class projectPlanner(wx.Frame):
action = Action() action = Action()
action.sliceCmd = sliceRun.getSliceCommand(resultFilename + "_temp_.stl") action.sliceCmd = sliceRun.getSliceCommand(resultFilename + "_temp_.stl")
action.centerX = profile.getProfileSettingFloat('machine_center_x') action.centerX = profile.getPreferenceFloat('machine_width') / 2
action.centerY = profile.getProfileSettingFloat('machine_center_y') action.centerY = profile.getPreferenceFloat('machine_depth') / 2
action.temperature = profile.getProfileSettingFloat('print_temperature') action.temperature = profile.getProfileSettingFloat('print_temperature')
action.extruder = 0 action.extruder = 0
action.filename = resultFilename + "_temp_.stl" action.filename = resultFilename + "_temp_.stl"
@ -663,6 +672,8 @@ class projectPlanner(wx.Frame):
return return
self.selection.rotate = float(self.rotateCtrl.GetValue()) self.selection.rotate = float(self.rotateCtrl.GetValue())
self.selection.updateModelTransform() self.selection.updateModelTransform()
if self.alwaysAutoPlace:
self.OnAutoPlace(None)
self.preview.Refresh() self.preview.Refresh()
def OnExtruderChange(self, e): def OnExtruderChange(self, e):
@ -680,6 +691,8 @@ class projectPlanner(wx.Frame):
self.selection.swapXZ = self.swapXZ.GetValue() self.selection.swapXZ = self.swapXZ.GetValue()
self.selection.swapYZ = self.swapYZ.GetValue() self.selection.swapYZ = self.swapYZ.GetValue()
self.selection.updateModelTransform() self.selection.updateModelTransform()
if self.alwaysAutoPlace:
self.OnAutoPlace(None)
self.preview.Refresh() self.preview.Refresh()
def getExtraHeadSize(self): def getExtraHeadSize(self):
@ -717,16 +730,24 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
wx.EVT_MOUSEWHEEL(self, self.OnMouseWheel) wx.EVT_MOUSEWHEEL(self, self.OnMouseWheel)
self.yaw = 30 self.yaw = 30
self.pitch = 60 self.pitch = 60
self.zoom = self.parent.machineSize[0] / 2 + 10
self.offsetX = 0 self.offsetX = 0
self.offsetY = 0 self.offsetY = 0
self.view3D = False self.view3D = self.parent.alwaysAutoPlace
if self.view3D:
self.zoom = 300
else:
self.zoom = self.parent.machineSize[0] / 2 + 10
self.allowDrag = False self.allowDrag = False
self.objColor = profile.getPreferenceColour('model_colour') self.objColor = profile.getPreferenceColour('model_colour')
def OnMouseLeftDown(self,e): def OnMouseLeftDown(self,e):
self.allowDrag = True self.allowDrag = True
if not self.parent.alwaysAutoPlace and not self.view3D:
#TODO: Translate mouse X/Y to 3D X/Y/Z
for item in self.parent.list:
iMin = (item.getMinimum() * item.scale) + numpy.array([item.centerX, item.centerY, 0]) - self.parent.extruderOffset[item.extruder]
iMax = (item.getMaximum() * item.scale) + numpy.array([item.centerX, item.centerY, 0]) - self.parent.extruderOffset[item.extruder]
def OnMouseMotion(self,e): def OnMouseMotion(self,e):
if self.allowDrag and e.Dragging() and e.LeftIsDown(): if self.allowDrag and e.Dragging() and e.LeftIsDown():
@ -737,7 +758,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
self.pitch = 170 self.pitch = 170
if self.pitch < 10: if self.pitch < 10:
self.pitch = 10 self.pitch = 10
else: elif not self.parent.alwaysAutoPlace:
item = self.parent.selection item = self.parent.selection
if item != None: if item != None:
item.centerX += float(e.GetX() - self.oldX) * self.zoom / self.GetSize().GetHeight() * 2 item.centerX += float(e.GetX() - self.oldX) * self.zoom / self.GetSize().GetHeight() * 2
@ -851,6 +872,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glDisable(GL_LIGHTING) glDisable(GL_LIGHTING)
if not self.parent.alwaysAutoPlace:
if self.parent.selection == item: if self.parent.selection == item:
if item.gotHit: if item.gotHit:
glColor3f(1.0,0.0,0.3) glColor3f(1.0,0.0,0.3)
@ -964,8 +986,8 @@ class ProjectSliceProgressWindow(wx.Frame):
line = p.stdout.readline() line = p.stdout.readline()
self.returnCode = p.wait() self.returnCode = p.wait()
put('machine_center_x', action.centerX - self.extruderOffset[action.extruder][0]) put('object_center_x', action.centerX - self.extruderOffset[action.extruder][0])
put('machine_center_y', action.centerY - self.extruderOffset[action.extruder][1]) put('object_center_y', action.centerY - self.extruderOffset[action.extruder][1])
put('clear_z', action.clearZ) put('clear_z', action.clearZ)
put('extruder', action.extruder) put('extruder', action.extruder)
put('print_temperature', action.temperature) put('print_temperature', action.temperature)

View File

@ -110,7 +110,7 @@ class simpleModeWindow(configBase.configWindowBase):
sizer.Add(boxsizer, (2,0), flag=wx.EXPAND) sizer.Add(boxsizer, (2,0), flag=wx.EXPAND)
# load and slice buttons. # load and slice buttons.
loadButton = wx.Button(self, -1, '&Load Model') loadButton = wx.Button(self, -1, '&Load model')
sliceButton = wx.Button(self, -1, 'P&repare print') sliceButton = wx.Button(self, -1, 'P&repare print')
printButton = wx.Button(self, -1, '&Print') printButton = wx.Button(self, -1, '&Print')
self.Bind(wx.EVT_BUTTON, self.OnLoadModel, loadButton) self.Bind(wx.EVT_BUTTON, self.OnLoadModel, loadButton)
@ -187,8 +187,6 @@ class simpleModeWindow(configBase.configWindowBase):
put('print_speed', '50') put('print_speed', '50')
put('print_temperature', '220') put('print_temperature', '220')
put('support', 'None') put('support', 'None')
#put('machine_center_x', '100')
#put('machine_center_y', '100')
put('retraction_enable', 'False') put('retraction_enable', 'False')
put('retraction_min_travel', '5.0') put('retraction_min_travel', '5.0')
put('retraction_speed', '40.0') put('retraction_speed', '40.0')

View File

@ -46,8 +46,8 @@ class sliceProgessPanel(wx.Panel):
if idx > 0: if idx > 0:
profile.setTempOverride('fan_enabled', 'False') profile.setTempOverride('fan_enabled', 'False')
profile.setTempOverride('skirt_line_count', '0') profile.setTempOverride('skirt_line_count', '0')
profile.setTempOverride('machine_center_x', profile.getProfileSettingFloat('machine_center_x') - profile.getPreferenceFloat('extruder_offset_x%d' % (idx))) profile.setTempOverride('object_center_x', profile.getPreferenceFloat('machine_width') / 2 - profile.getPreferenceFloat('extruder_offset_x%d' % (idx)))
profile.setTempOverride('machine_center_y', profile.getProfileSettingFloat('machine_center_y') - profile.getPreferenceFloat('extruder_offset_y%d' % (idx))) profile.setTempOverride('object_center_y', profile.getPreferenceFloat('machine_depth') / 2 - profile.getPreferenceFloat('extruder_offset_y%d' % (idx)))
profile.setTempOverride('alternative_center', self.filelist[0]) profile.setTempOverride('alternative_center', self.filelist[0])
if len(self.filelist) > 1: if len(self.filelist) > 1:
profile.setTempOverride('add_start_end_gcode', 'False') profile.setTempOverride('add_start_end_gcode', 'False')
@ -183,6 +183,11 @@ class WorkerThread(threading.Thread):
wx.CallAfter(self.notifyWindow.statusText.SetLabel, "Aborted by user.") wx.CallAfter(self.notifyWindow.statusText.SetLabel, "Aborted by user.")
return return
line = p.stdout.readline() line = p.stdout.readline()
line = p.stderr.readline()
while(len(line) > 0):
line = line.rstrip()
self.progressLog.append(line)
line = p.stderr.readline()
self.returnCode = p.wait() self.returnCode = p.wait()
self.fileIdx += 1 self.fileIdx += 1
if self.fileIdx == len(self.cmdList): if self.fileIdx == len(self.cmdList):
@ -220,9 +225,11 @@ class WorkerThread(threading.Thread):
resultFile.write('T%d\n' % (currentExtruder)) resultFile.write('T%d\n' % (currentExtruder))
layerNr = -1 layerNr = -1
hasLine = True hasLine = True
filesOrder = files[:]
while hasLine: while hasLine:
hasLine = False hasLine = False
for f in files: filesOrder.reverse()
for f in filesOrder:
layerHasLine = False layerHasLine = False
for line in f: for line in f:
hasLine = True hasLine = True
@ -237,7 +244,7 @@ class WorkerThread(threading.Thread):
if nextExtruder != currentExtruder: if nextExtruder != currentExtruder:
resultFile.write(';TYPE:CUSTOM\n') resultFile.write(';TYPE:CUSTOM\n')
profile.setTempOverride('extruder', nextExtruder) profile.setTempOverride('extruder', nextExtruder)
resultFile.write(profile.getAlterationFileContents('switchExtruder.gcode')) resultFile.write(profile.getAlterationFileContents('switchExtruder.gcode') + '\n')
profile.resetTempOverride() profile.resetTempOverride()
currentExtruder = nextExtruder currentExtruder = nextExtruder
layerHasLine = True layerHasLine = True

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

View File

@ -28,6 +28,9 @@ class daeModel(mesh.mesh):
for node in self._idMap[instance_visual_scene['_url']]['node']: for node in self._idMap[instance_visual_scene['_url']]['node']:
self._ProcessNode2(node) self._ProcessNode2(node)
scale = float(self._base['collada'][0]['asset'][0]['unit'][0]['_meter']) * 1000
self.origonalVertexes *= scale
self._base = None self._base = None
self._cur = None self._cur = None
self._idMap = None self._idMap = None

View File

@ -21,3 +21,14 @@ def openExporer(filename):
elif os.path.isfile('/usr/bin/dolphin'): elif os.path.isfile('/usr/bin/dolphin'):
subprocess.Popen(['/usr/bin/dolphin', os.path.split(filename)[0]]) subprocess.Popen(['/usr/bin/dolphin', os.path.split(filename)[0]])
def openExporerPath(filename):
if sys.platform == 'win32' or sys.platform == 'cygwin':
subprocess.Popen(r'explorer "%s"' % (filename))
if sys.platform == 'darwin':
subprocess.Popen(['open', filename])
if sys.platform.startswith('linux'):
if os.path.isfile('/usr/bin/nautilus'):
subprocess.Popen(['/usr/bin/nautilus', filename])
elif os.path.isfile('/usr/bin/dolphin'):
subprocess.Popen(['/usr/bin/dolphin', filename])

View File

@ -208,6 +208,9 @@ class MachineCom(object):
return self._errorValue return self._errorValue
return self._errorValue[:20] + "..." return self._errorValue[:20] + "..."
def getErrorString(self):
return self._errorValue
def isClosedOrError(self): def isClosedOrError(self):
return self._state == self.STATE_ERROR or self._state == self.STATE_CLOSED_WITH_ERROR or self._state == self.STATE_CLOSED return self._state == self.STATE_ERROR or self._state == self.STATE_CLOSED_WITH_ERROR or self._state == self.STATE_CLOSED

View File

@ -41,6 +41,7 @@ class mesh(object):
return self.size return self.size
def setRotateMirror(self, rotate, mirrorX, mirrorY, mirrorZ, swapXZ, swapYZ): def setRotateMirror(self, rotate, mirrorX, mirrorY, mirrorZ, swapXZ, swapYZ):
#Modify the vertexes with the rotation/mirror
rotate = rotate / 180.0 * math.pi rotate = rotate / 180.0 * math.pi
scaleX = 1.0 scaleX = 1.0
scaleY = 1.0 scaleY = 1.0
@ -63,6 +64,13 @@ class mesh(object):
mat = numpy.array([mat[0],mat[2],mat[1]], numpy.float32) mat = numpy.array([mat[0],mat[2],mat[1]], numpy.float32)
self.vertexes = (numpy.matrix(self.origonalVertexes, copy = False) * numpy.matrix(mat)).getA() self.vertexes = (numpy.matrix(self.origonalVertexes, copy = False) * numpy.matrix(mat)).getA()
#Calculate the boundery box of the object
self.getMinimumZ()
#Calculate the boundery circle
center = (self.max + self.min) / 2.0
self.bounderyCircleSize = round(math.sqrt(numpy.max(((self.vertexes[::,0] - center[0]) * (self.vertexes[::,0] - center[0])) + ((self.vertexes[::,1] - center[1]) * (self.vertexes[::,1] - center[1])))), 3)
#Calculate the normals
tris = self.vertexes.reshape(self.vertexCount / 3, 3, 3) tris = self.vertexes.reshape(self.vertexCount / 3, 3, 3)
normals = numpy.cross( tris[::,1 ] - tris[::,0] , tris[::,2 ] - tris[::,0] ) normals = numpy.cross( tris[::,1 ] - tris[::,0] , tris[::,2 ] - tris[::,0] )
lens = numpy.sqrt( normals[:,0]**2 + normals[:,1]**2 + normals[:,2]**2 ) lens = numpy.sqrt( normals[:,0]**2 + normals[:,1]**2 + normals[:,2]**2 )
@ -77,8 +85,6 @@ class mesh(object):
self.normal = n.reshape(self.vertexCount, 3) self.normal = n.reshape(self.vertexCount, 3)
self.invNormal = -self.normal self.invNormal = -self.normal
self.getMinimumZ()
def splitToParts(self, callback = None): def splitToParts(self, callback = None):
t0 = time.time() t0 = time.time()

View File

@ -31,8 +31,6 @@ profileDefaultSettings = {
'support': 'None', 'support': 'None',
'filament_diameter': '2.89', 'filament_diameter': '2.89',
'filament_density': '1.00', 'filament_density': '1.00',
'machine_center_x': '100',
'machine_center_y': '100',
'retraction_min_travel': '5.0', 'retraction_min_travel': '5.0',
'retraction_enable': 'False', 'retraction_enable': 'False',
'retraction_speed': '40.0', 'retraction_speed': '40.0',
@ -42,7 +40,7 @@ profileDefaultSettings = {
'travel_speed': '150', 'travel_speed': '150',
'max_z_speed': '3.0', 'max_z_speed': '3.0',
'bottom_layer_speed': '20', 'bottom_layer_speed': '20',
'cool_min_layer_time': '10', 'cool_min_layer_time': '5',
'fan_enabled': 'True', 'fan_enabled': 'True',
'fan_layer': '1', 'fan_layer': '1',
'fan_speed': '100', 'fan_speed': '100',
@ -74,6 +72,7 @@ profileDefaultSettings = {
'raft_base_material_amount': '100', 'raft_base_material_amount': '100',
'raft_interface_material_amount': '100', 'raft_interface_material_amount': '100',
'bottom_thickness': '0.3', 'bottom_thickness': '0.3',
'hop_on_move': 'False',
'plugin_config': '', 'plugin_config': '',
'add_start_end_gcode': 'True', 'add_start_end_gcode': 'True',
@ -102,9 +101,6 @@ G1 Z15.0 F{max_z_speed} ;move the platform down 15mm
G92 E0 ;zero the extruded length G92 E0 ;zero the extruded length
G1 F200 E3 ;extrude 3mm of feed stock G1 F200 E3 ;extrude 3mm of feed stock
G92 E0 ;zero the extruded length again G92 E0 ;zero the extruded length again
;go to the middle of the platform (disabled, as there is no need to go to the center)
;G1 X{machine_center_x} Y{machine_center_y} F{travel_speed}
G1 F{travel_speed} G1 F{travel_speed}
""", """,
####################################################################################### #######################################################################################
@ -137,7 +133,7 @@ G90 ;absolute positioning
G1 Z{clear_z} F{max_z_speed} G1 Z{clear_z} F{max_z_speed}
G92 E0 G92 E0
G1 X{machine_center_x} Y{machine_center_y} F{travel_speed} G1 X{object_center_x} Y{object_center_x} F{travel_speed}
G1 F200 E6 G1 F200 E6
G92 E0 G92 E0
""", """,
@ -158,6 +154,7 @@ preferencesDefaultSettings = {
'machine_depth': '205', 'machine_depth': '205',
'machine_height': '200', 'machine_height': '200',
'machine_type': 'unknown', 'machine_type': 'unknown',
'ultimaker_extruder_upgrade': 'False',
'has_heated_bed': 'False', 'has_heated_bed': 'False',
'extruder_amount': '1', 'extruder_amount': '1',
'extruder_offset_x1': '-22.0', 'extruder_offset_x1': '-22.0',
@ -219,6 +216,13 @@ def resetGlobalProfile():
global globalProfileParser global globalProfileParser
globalProfileParser = ConfigParser.ConfigParser() globalProfileParser = ConfigParser.ConfigParser()
if getPreference('machine_type') == 'ultimaker':
putProfileSetting('nozzle_size', '0.4')
if getPreference('ultimaker_extruder_upgrade') == 'True':
putProfileSetting('retraction_enable', 'True')
else:
putProfileSetting('nozzle_size', '0.5')
def saveGlobalProfile(filename): def saveGlobalProfile(filename):
#Save the current profile to an ini file #Save the current profile to an ini file
globalProfileParser.write(open(filename, 'w')) globalProfileParser.write(open(filename, 'w'))
@ -545,9 +549,10 @@ def setPluginConfig(config):
putProfileSetting('plugin_config', pickle.dumps(config)) putProfileSetting('plugin_config', pickle.dumps(config))
def getPluginBasePaths(): def getPluginBasePaths():
ret = [os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'plugins'))] ret = []
if platform.system() != "Windows": if platform.system() != "Windows":
ret.append(os.path.expanduser('~/.cura/plugins/')) ret.append(os.path.expanduser('~/.cura/plugins/'))
ret.append(os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'plugins')))
return ret return ret
def getPluginList(): def getPluginList():

View File

@ -26,6 +26,7 @@ sliceStepTimeFactor = {
'dwindle': 1.0, 'dwindle': 1.0,
'comb': 23.7805759907, 'comb': 23.7805759907,
'cool': 27.148763895, 'cool': 27.148763895,
'hop': 1.0,
'dimension': 90.4914340973 'dimension': 90.4914340973
} }
@ -114,7 +115,7 @@ def getSliceCommand(filename):
cmd = [slic3rExe, cmd = [slic3rExe,
'--output-filename-format', '[input_filename_base].gcode', '--output-filename-format', '[input_filename_base].gcode',
'--nozzle-diameter', str(profile.calculateEdgeWidth()), '--nozzle-diameter', str(profile.calculateEdgeWidth()),
'--print-center', '%s,%s' % (profile.getProfileSetting('machine_center_x'), profile.getProfileSetting('machine_center_y')), '--print-center', '%s,%s' % (profile.getPreferenceFloat('machine_width') / 2, profile.getPreferenceFloat('machine_depth') / 2),
'--z-offset', '0', '--z-offset', '0',
'--gcode-flavor', 'reprap', '--gcode-flavor', 'reprap',
'--gcode-comments', '--gcode-comments',

View File

@ -215,7 +215,7 @@ if __name__ == '__main__':
f.write(';TYPE:CUSTOM\n') f.write(';TYPE:CUSTOM\n')
f.write(profile.getAlterationFileContents('start.gcode')) f.write(profile.getAlterationFileContents('start.gcode'))
svg.center(complex(profile.getProfileSettingFloat('machine_center_x'), profile.getProfileSettingFloat('machine_center_y'))) svg.center(complex(profile.getPreferenceFloat('machine_width') / 2, profile.getPreferenceFloat('machine_depth') / 2))
layerThickness = 0.4 layerThickness = 0.4
filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2