Merge branch 'master' of github.com:daid/Cura

This commit is contained in:
Daid 2012-05-08 23:04:40 +02:00
commit df5414a452
15 changed files with 324 additions and 232 deletions

View File

@ -138,7 +138,7 @@ def getProfileInformation():
'Widen_Width_over_Edge_Width_ratio': DEFSET,
},'inset': {
'Add_Custom_Code_for_Temperature_Reading': "False",
'Infill_in_Direction_of_Bridge': "True",
'Infill_in_Direction_of_Bridge': ifSettingAboveZero('fill_density'),
'Infill_Width': storedSettingFloat("nozzle_size"),
'Loop_Order_Choice': DEFSET,
'Overlap_Removal_Width_over_Perimeter_Width_ratio': DEFSET,

View File

@ -9,6 +9,8 @@ class alterationPanel(wx.Panel):
wx.Panel.__init__(self, parent,-1)
self.alterationFileList = ['start.gcode', 'end.gcode', 'support_start.gcode', 'support_end.gcode', 'nextobject.gcode', 'replace.csv']
if int(profile.getPreference('extruder_amount')) > 1:
self.alterationFileList.append('switchExtruder.gcode')
self.currentFile = None
#self.textArea = wx.TextCtrl(self, style=wx.TE_MULTILINE|wx.TE_DONTWRAP|wx.TE_PROCESS_TAB)

View File

@ -64,7 +64,7 @@ class configWindowBase(wx.Frame):
self.popup.text.SetLabel(setting.helpText)
self.popup.text.Wrap(350)
self.popup.Fit()
if os.name == 'darwin':
if sys.platform == 'darwin':
x, y = self.ClientToScreenXY(0, 0)
sx, sy = self.GetClientSizeTuple()
else:

View File

@ -180,11 +180,13 @@ class UltimakerCheckupPage(InfoPage):
wx.CallAfter(self.AddProgressText, "Error: Missing start message.")
self.comm.close()
return
#Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
time.sleep(3)
wx.CallAfter(self.AddProgressText, "Disabling step motors...")
if self.DoCommCommandWithTimeout('M84') == False:
wx.CallAfter(self.AddProgressText, "Error: Missing reply to Deactivate steppers (M84).")
wx.CallAfter(self.AddProgressText, "Possible cause: Temperature MIN/MAX.\nCheck temperature sensor connections.")
self.comm.close()
return
@ -289,6 +291,7 @@ class UltimakerCheckupPage(InfoPage):
if line == '':
self.comm.close()
return False
print line
if line.startswith(replyStart):
break
t.cancel()
@ -372,6 +375,9 @@ class UltimakerCalibrateStepsPerEPage(InfoPage):
return
if line.startswith('start'):
break
#Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
time.sleep(3)
self.sendGCommand('M302') #Disable cold extrusion protection
self.sendGCommand("M92 E%f" % (currentEValue));
self.sendGCommand("G92 E0");
@ -392,6 +398,9 @@ class UltimakerCalibrateStepsPerEPage(InfoPage):
return
if line.startswith('start'):
break
#Wait 3 seconds for the SD card init to timeout if we have SD in our firmware but there is no SD card found.
time.sleep(3)
self.sendGCommand('M104 S200') #Set the temperature to 200C, should be enough to get PLA and ABS out.
wx.MessageBox('Wait till you can remove the filament from the machine, and press OK.\n(Temperature is set to 200C)', 'Machine heatup', wx.OK | wx.ICON_INFORMATION)
self.sendGCommand('M104 S0')

View File

@ -3,101 +3,109 @@ import sys,math,os
from util import profile
class GcodeTextArea(wx.stc.StyledTextCtrl):
def __init__(self, parent):
super(GcodeTextArea, self).__init__(parent)
self.SetLexer(wx.stc.STC_LEX_CONTAINER)
self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyle)
fontSize = wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize()
fontName = wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL).GetFaceName()
self.SetStyleBits(5)
self.StyleSetSpec(0, "face:%s,size:%d" % (fontName, fontSize))
self.StyleSetSpec(1, "fore:#006000,face:%s,size:%d" % (fontName, fontSize))
self.IndicatorSetStyle(0, wx.stc.STC_INDIC_TT)
self.IndicatorSetForeground(0, "#0000FF")
self.IndicatorSetStyle(1, wx.stc.STC_INDIC_SQUIGGLE)
self.IndicatorSetForeground(1, "#FF0000")
self.SetWrapMode(wx.stc.STC_WRAP_NONE)
self.SetScrollWidth(1000)
#GCodes and MCodes as supported by Marlin
#GCode 21 is not really supported by Marlin, but we still do not report it as error as it's often used.
self.supportedGCodes = [0,1,2,3,4,21,28,90,91,92]
self.supportedMCodes = [17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,42,80,81,82,83,84,85,92,104,105,106,107,109,114,115,117,119,140,190,201,202,203,204,205,206,220,221,240,301,302,303,400,500,501,502,503,999]
def OnStyle(self, e):
lineNr = self.LineFromPosition(self.GetEndStyled())
while self.PositionFromLine(lineNr) > -1:
line = self.GetLine(lineNr)
start = self.PositionFromLine(lineNr)
length = self.LineLength(lineNr)
self.StartStyling(start, 255)
self.SetStyling(length, 0)
if ';' in line:
pos = line.index(';')
self.StartStyling(start + pos, 31)
self.SetStyling(length - pos, 1)
length = pos
if sys.platform == 'darwin':
class GcodeTextArea(wx.TextCtrl):
def __init__(self, parent):
super(GcodeTextArea, self).__init__(parent, style=wx.TE_MULTILINE|wx.TE_DONTWRAP|wx.TE_PROCESS_TAB)
pos = 0
while pos < length:
if line[pos] in " \t\n\r":
while pos < length and line[pos] in " \t\n\r":
pos += 1
else:
end = pos
while end < length and not line[end] in " \t\n\r":
end += 1
if self.checkGCodePart(line[pos:end], start + pos):
self.StartStyling(start + pos, 0x20)
self.SetStyling(end - pos, 0x20)
pos = end
lineNr += 1
self.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
def checkGCodePart(self, part, pos):
if len(part) < 2:
self.StartStyling(pos, 0x40)
self.SetStyling(1, 0x40)
return True
if not part[0] in "GMXYZFESTBPIDCJ":
self.StartStyling(pos, 0x40)
self.SetStyling(1, 0x40)
return True
if part[1] == '{':
if part[-1] != '}':
return True
tag = part[2:-1]
if not profile.isProfileSetting(tag) and not profile.isPreference(tag):
self.StartStyling(pos + 2, 0x40)
self.SetStyling(len(tag), 0x40)
return True
elif part[0] in "GM":
try:
code = int(part[1:])
except (ValueError):
self.StartStyling(pos + 1, 0x40)
self.SetStyling(len(part) - 1, 0x40)
return True
if part[0] == 'G':
if not code in self.supportedGCodes:
return True
if part[0] == 'M':
if not code in self.supportedMCodes:
return True
else:
try:
float(part[1:])
except (ValueError):
self.StartStyling(pos + 1, 0x40)
self.SetStyling(len(part) - 1, 0x40)
return True
return False
else:
class GcodeTextArea(wx.stc.StyledTextCtrl):
def __init__(self, parent):
super(GcodeTextArea, self).__init__(parent)
def GetValue(self):
return self.GetText()
self.SetLexer(wx.stc.STC_LEX_CONTAINER)
self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyle)
fontSize = wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize()
fontName = wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL).GetFaceName()
self.SetStyleBits(5)
self.StyleSetSpec(0, "face:%s,size:%d" % (fontName, fontSize))
self.StyleSetSpec(1, "fore:#006000,face:%s,size:%d" % (fontName, fontSize))
self.IndicatorSetStyle(0, wx.stc.STC_INDIC_TT)
self.IndicatorSetForeground(0, "#0000FF")
self.IndicatorSetStyle(1, wx.stc.STC_INDIC_SQUIGGLE)
self.IndicatorSetForeground(1, "#FF0000")
self.SetWrapMode(wx.stc.STC_WRAP_NONE)
self.SetScrollWidth(1000)
#GCodes and MCodes as supported by Marlin
#GCode 21 is not really supported by Marlin, but we still do not report it as error as it's often used.
self.supportedGCodes = [0,1,2,3,4,21,28,90,91,92]
self.supportedMCodes = [17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,42,80,81,82,83,84,85,92,104,105,106,107,109,114,115,117,119,140,190,201,202,203,204,205,206,220,221,240,301,302,303,400,500,501,502,503,999]
def OnStyle(self, e):
lineNr = self.LineFromPosition(self.GetEndStyled())
while self.PositionFromLine(lineNr) > -1:
line = self.GetLine(lineNr)
start = self.PositionFromLine(lineNr)
length = self.LineLength(lineNr)
self.StartStyling(start, 255)
self.SetStyling(length, 0)
if ';' in line:
pos = line.index(';')
self.StartStyling(start + pos, 31)
self.SetStyling(length - pos, 1)
length = pos
pos = 0
while pos < length:
if line[pos] in " \t\n\r":
while pos < length and line[pos] in " \t\n\r":
pos += 1
else:
end = pos
while end < length and not line[end] in " \t\n\r":
end += 1
if self.checkGCodePart(line[pos:end], start + pos):
self.StartStyling(start + pos, 0x20)
self.SetStyling(end - pos, 0x20)
pos = end
lineNr += 1
def checkGCodePart(self, part, pos):
if len(part) < 2:
self.StartStyling(pos, 0x40)
self.SetStyling(1, 0x40)
return True
if not part[0] in "GMXYZFESTBPIDCJ":
self.StartStyling(pos, 0x40)
self.SetStyling(1, 0x40)
return True
if part[1] == '{':
if part[-1] != '}':
return True
tag = part[2:-1]
if not profile.isProfileSetting(tag) and not profile.isPreference(tag):
self.StartStyling(pos + 2, 0x40)
self.SetStyling(len(tag), 0x40)
return True
elif part[0] in "GM":
try:
code = int(part[1:])
except (ValueError):
self.StartStyling(pos + 1, 0x40)
self.SetStyling(len(part) - 1, 0x40)
return True
if part[0] == 'G':
if not code in self.supportedGCodes:
return True
if part[0] == 'M':
if not code in self.supportedMCodes:
return True
else:
try:
float(part[1:])
except (ValueError):
self.StartStyling(pos + 1, 0x40)
self.SetStyling(len(part) - 1, 0x40)
return True
return False
def GetValue(self):
return self.GetText()
def SetValue(self, s):
self.SetText(s)
def SetValue(self, s):
self.SetText(s)

View File

@ -41,7 +41,7 @@ class mainWindow(configBase.configWindowBase):
menubar = wx.MenuBar()
fileMenu = wx.Menu()
i = fileMenu.Append(-1, 'Load model file...')
self.Bind(wx.EVT_MENU, self.OnLoadModel, i)
self.Bind(wx.EVT_MENU, lambda e: self._showModelLoadDialog(1), i)
fileMenu.AppendSeparator()
i = fileMenu.Append(-1, 'Open Profile...')
self.Bind(wx.EVT_MENU, self.OnLoadProfile, i)
@ -189,23 +189,23 @@ class mainWindow(configBase.configWindowBase):
loadButton = wx.Button(self, -1, 'Load Model')
sliceButton = wx.Button(self, -1, 'Slice to GCode')
printButton = wx.Button(self, -1, 'Print GCode')
self.Bind(wx.EVT_BUTTON, self.OnLoadModel, loadButton)
self.Bind(wx.EVT_BUTTON, lambda e: self._showModelLoadDialog(1), loadButton)
self.Bind(wx.EVT_BUTTON, self.OnSlice, sliceButton)
self.Bind(wx.EVT_BUTTON, self.OnPrint, printButton)
extruderCount = int(profile.getPreference('extruder_amount'))
if extruderCount > 1:
loadButton2 = wx.Button(self, -1, 'Load Dual')
self.Bind(wx.EVT_BUTTON, self.OnLoadModel2, loadButton2)
self.Bind(wx.EVT_BUTTON, lambda e: self._showModelLoadDialog(2), loadButton2)
if extruderCount > 2:
loadButton3 = wx.Button(self, -1, 'Load Tripple')
self.Bind(wx.EVT_BUTTON, self.OnLoadModel3, loadButton3)
self.Bind(wx.EVT_BUTTON, lambda e: self._showModelLoadDialog(3), loadButton3)
if extruderCount > 2:
loadButton4 = wx.Button(self, -1, 'Load Quad')
self.Bind(wx.EVT_BUTTON, self.OnLoadModel4, loadButton4)
self.Bind(wx.EVT_BUTTON, lambda e: self._showModelLoadDialog(4), loadButton4)
#Also bind double clicking the 3D preview to load an STL file.
self.preview3d.glCanvas.Bind(wx.EVT_LEFT_DCLICK, self.OnLoadModel, self.preview3d.glCanvas)
self.preview3d.glCanvas.Bind(wx.EVT_LEFT_DCLICK, lambda e: self._showModelLoadDialog(1), self.preview3d.glCanvas)
#Main sizer, to position the preview window, buttons and tab control
sizer = wx.GridBagSizer()
@ -236,21 +236,19 @@ class mainWindow(configBase.configWindowBase):
self.Show(True)
def OnLoadProfile(self, e):
dlg=wx.FileDialog(self, "Select profile file to load", self.lastPath, style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg=wx.FileDialog(self, "Select profile file to load", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard("ini files (*.ini)|*.ini")
if dlg.ShowModal() == wx.ID_OK:
profileFile = dlg.GetPath()
self.lastPath = os.path.split(profileFile)[0]
profile.loadGlobalProfile(profileFile)
self.updateProfileToControls()
dlg.Destroy()
def OnSaveProfile(self, e):
dlg=wx.FileDialog(self, "Select profile file to save", self.lastPath, style=wx.FD_SAVE)
dlg=wx.FileDialog(self, "Select profile file to save", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE)
dlg.SetWildcard("ini files (*.ini)|*.ini")
if dlg.ShowModal() == wx.ID_OK:
profileFile = dlg.GetPath()
self.lastPath = os.path.split(profileFile)[0]
profile.saveGlobalProfile(profileFile)
dlg.Destroy()
@ -268,7 +266,7 @@ class mainWindow(configBase.configWindowBase):
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)
dlg=wx.FileDialog(self, "Open firmware to upload", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard("HEX file (*.hex)|*.hex;*.HEX")
if dlg.ShowModal() == wx.ID_OK:
filename = dlg.GetPath()

View File

@ -1,3 +1,7 @@
import math
from util import util3d
from util import profile
try:
import OpenGL
@ -215,3 +219,84 @@ def DrawSTL(mesh):
glVertex3f(v3.x, v3.y, v3.z)
glVertex3f(v2.x, v2.y, v2.z)
glEnd()
def DrawGCodeLayer(layer):
filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
filamentArea = math.pi * filamentRadius * filamentRadius
lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
fillCycle = 0
fillColorCycle = [[0.5,0.5,0.0],[0.0,0.5,0.5],[0.5,0.0,0.5]]
glDisable(GL_CULL_FACE)
for path in layer:
if path.type == 'move':
glColor3f(0,0,1)
if path.type == 'extrude':
if path.pathType == 'FILL':
glColor3fv(fillColorCycle[fillCycle])
fillCycle = (fillCycle + 1) % len(fillColorCycle)
elif path.pathType == 'WALL-INNER':
glColor3fv([0,1,0])
elif path.pathType == 'SUPPORT':
glColor3fv([0,1,1])
elif path.pathType == 'SKIRT':
glColor3fv([0,0.5,0.5])
else:
glColor3fv([1,0,0])
if path.type == 'retract':
glColor3fv([0,1,1])
if path.type == 'extrude':
drawLength = 0.0
prevNormal = None
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 path.layerThickness > 0:
extrusionMMperDist = (v1.e - v0.e) / dist
lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2
drawLength += (v0 - v1).vsize()
normal = (v0 - v1).cross(util3d.Vector3(0,0,1))
normal.normalize()
vv2 = v0 + normal * lineWidth
vv3 = v1 + normal * lineWidth
vv0 = v0 - normal * lineWidth
vv1 = v1 - normal * lineWidth
glBegin(GL_QUADS)
glVertex3f(vv0.x, vv0.y, vv0.z - 0.01)
glVertex3f(vv1.x, vv1.y, vv1.z - 0.01)
glVertex3f(vv3.x, vv3.y, vv3.z - 0.01)
glVertex3f(vv2.x, vv2.y, vv2.z - 0.01)
glEnd()
if prevNormal != None:
n = (normal + prevNormal)
n.normalize()
vv4 = v0 + n * lineWidth
vv5 = v0 - n * lineWidth
glBegin(GL_QUADS)
glVertex3f(vv2.x, vv2.y, vv2.z)
glVertex3f(vv4.x, vv4.y, vv4.z)
glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z)
glVertex3f(v0.x, v0.y, v0.z)
glVertex3f(vv0.x, vv0.y, vv0.z)
glVertex3f(vv5.x, vv5.y, vv5.z)
glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z)
glVertex3f(v0.x, v0.y, v0.z)
glEnd()
prevNormal = normal
prevVv1 = vv1
prevVv3 = vv3
else:
glBegin(GL_LINE_STRIP)
for v in path.list:
glVertex3f(v.x, v.y, v.z)
glEnd()
glEnable(GL_CULL_FACE)

View File

@ -372,6 +372,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
self.offsetY = 0
self.view3D = True
self.gcodeDisplayList = None
self.gcodeDisplayListMade = None
self.gcodeDisplayListCount = 0
self.objColor = [[1.0, 0.8, 0.6, 1.0], [0.2, 1.0, 0.1, 1.0], [1.0, 0.2, 0.1, 1.0], [0.1, 0.2, 1.0, 1.0]]
@ -446,93 +447,23 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
self.gcodeDisplayList = glGenLists(len(self.parent.gcode.layerList));
self.gcodeDisplayListCount = len(self.parent.gcode.layerList)
self.parent.gcodeDirty = False
prevLayerZ = 0.0
curLayerZ = 0.0
layerThickness = 0.0
filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
filamentArea = math.pi * filamentRadius * filamentRadius
lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
curLayerNum = 0
for layer in self.parent.gcode.layerList:
glNewList(self.gcodeDisplayList + curLayerNum, GL_COMPILE)
glDisable(GL_CULL_FACE)
curLayerZ = layer[0].list[1].z
layerThickness = curLayerZ - prevLayerZ
prevLayerZ = layer[-1].list[-1].z
for path in layer:
if path.type == 'move':
glColor3f(0,0,1)
if path.type == 'extrude':
if path.pathType == 'FILL':
glColor3f(0.5,0.5,0)
elif path.pathType == 'WALL-INNER':
glColor3f(0,1,0)
elif path.pathType == 'SUPPORT':
glColor3f(0,1,1)
elif path.pathType == 'SKIRT':
glColor3f(0,0.5,0.5)
else:
glColor3f(1,0,0)
if path.type == 'retract':
glColor3f(0,1,1)
if path.type == 'extrude':
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) / dist
lineWidth = extrusionMMperDist * filamentArea / layerThickness / 2
normal = (v0 - v1).cross(util3d.Vector3(0,0,1))
normal.normalize()
v2 = v0 + normal * lineWidth
v3 = v1 + normal * lineWidth
v0 = v0 - normal * lineWidth
v1 = v1 - normal * lineWidth
glBegin(GL_QUADS)
if path.pathType == 'FILL': #Remove depth buffer fighting on infill/wall overlap
glVertex3f(v0.x, v0.y, v0.z - 0.02)
glVertex3f(v1.x, v1.y, v1.z - 0.02)
glVertex3f(v3.x, v3.y, v3.z - 0.02)
glVertex3f(v2.x, v2.y, v2.z - 0.02)
else:
glVertex3f(v0.x, v0.y, v0.z - 0.01)
glVertex3f(v1.x, v1.y, v1.z - 0.01)
glVertex3f(v3.x, v3.y, v3.z - 0.01)
glVertex3f(v2.x, v2.y, v2.z - 0.01)
glEnd()
#for v in path['list']:
# glBegin(GL_TRIANGLE_FAN)
# glVertex3f(v.x, v.y, v.z - 0.001)
# for i in xrange(0, 16+1):
# if path['pathType'] == 'FILL': #Remove depth buffer fighting on infill/wall overlap
# glVertex3f(v.x + math.cos(math.pi*2/16*i) * lineWidth, v.y + math.sin(math.pi*2/16*i) * lineWidth, v.z - 0.02)
# else:
# glVertex3f(v.x + math.cos(math.pi*2/16*i) * lineWidth, v.y + math.sin(math.pi*2/16*i) * lineWidth, v.z - 0.01)
# glEnd()
else:
glBegin(GL_LINE_STRIP)
for v in path.list:
glVertex3f(v.x, v.y, v.z)
glEnd()
curLayerNum += 1
glEnable(GL_CULL_FACE)
glEndList()
self.gcodeDisplayListMade = 0
if self.parent.gcode != None and self.gcodeDisplayListMade < len(self.parent.gcode.layerList):
glNewList(self.gcodeDisplayList + self.gcodeDisplayListMade, GL_COMPILE)
opengl.DrawGCodeLayer(self.parent.gcode.layerList[self.gcodeDisplayListMade])
glEndList()
self.gcodeDisplayListMade += 1
self.Refresh()
if self.parent.gcode != None and (self.viewMode == "GCode" or self.viewMode == "Mixed"):
glEnable(GL_COLOR_MATERIAL)
glEnable(GL_LIGHTING)
for i in xrange(0, self.parent.layerSpin.GetValue() + 1):
drawUpToLayer = min(self.gcodeDisplayListMade, self.parent.layerSpin.GetValue() + 1)
for i in xrange(0, drawUpToLayer):
c = 1.0
if i < self.parent.layerSpin.GetValue():
c = 0.9 - (self.parent.layerSpin.GetValue() - i) * 0.1
c = 0.9 - (drawUpToLayer - i) * 0.1
if c < 0.4:
c = (0.4 + c) / 2
if c < 0.1:

View File

@ -19,6 +19,8 @@ except:
from gui import opengl
from gui import toolbarUtil
from gui import icon
from gui import configBase
from gui import validators
from util import profile
from util import util3d
from util import stl
@ -29,11 +31,12 @@ class Action(object):
pass
class ProjectObject(stl.stlModel):
def __init__(self, filename):
def __init__(self, parent, filename):
super(ProjectObject, self).__init__()
self.load(filename)
self.parent = parent
self.filename = filename
self.scale = 1.0
self.rotate = 0.0
@ -108,7 +111,7 @@ class ProjectObject(stl.stlModel):
self.modelDirty = True
def clone(self):
p = ProjectObject(self.filename)
p = ProjectObject(self.parent, self.filename)
p.centerX = self.centerX + 5
p.centerY = self.centerY + 5
@ -126,6 +129,16 @@ class ProjectObject(stl.stlModel):
p.updateModelTransform()
return p
def clampXY(self):
if self.centerX < -self.getMinimum().x * self.scale + self.parent.extruderOffset[self.extruder].x:
self.centerX = -self.getMinimum().x * self.scale + self.parent.extruderOffset[self.extruder].x
if self.centerY < -self.getMinimum().y * self.scale + self.parent.extruderOffset[self.extruder].y:
self.centerY = -self.getMinimum().y * self.scale + self.parent.extruderOffset[self.extruder].y
if self.centerX > self.parent.machineSize.x + self.parent.extruderOffset[self.extruder].x - self.getMaximum().x * self.scale:
self.centerX = self.parent.machineSize.x + self.parent.extruderOffset[self.extruder].x - self.getMaximum().x * self.scale
if self.centerY > self.parent.machineSize.y + self.parent.extruderOffset[self.extruder].y - self.getMaximum().y * self.scale:
self.centerY = self.parent.machineSize.y + self.parent.extruderOffset[self.extruder].y - self.getMaximum().y * self.scale
class projectPlanner(wx.Frame):
"Main user interface window"
@ -159,6 +172,8 @@ class projectPlanner(wx.Frame):
toolbarUtil.RadioButton(self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick).SetValue(True)
self.toolbar.AddSeparator()
toolbarUtil.NormalButton(self.toolbar, self.OnQuit, 'exit.png', 'Close project planner')
self.toolbar.AddSeparator()
toolbarUtil.NormalButton(self.toolbar, self.OnPreferences, 'preferences.png', 'Project planner preferences')
self.toolbar.Realize()
@ -228,6 +243,11 @@ class projectPlanner(wx.Frame):
def OnQuit(self, e):
self.Close()
def OnPreferences(self, e):
prefDialog = preferencesDialog(self)
prefDialog.Centre()
prefDialog.Show(True)
def OnSaveProject(self, e):
dlg=wx.FileDialog(self, "Save project file", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE)
dlg.SetWildcard("Project files (*.curaproject)|*.curaproject")
@ -264,7 +284,7 @@ class projectPlanner(wx.Frame):
while cp.has_section('model_%d' % (i)):
section = 'model_%d' % (i)
item = ProjectObject(unicode(cp.get(section, 'filename'), "utf-8"))
item = ProjectObject(self, unicode(cp.get(section, 'filename'), "utf-8"))
item.centerX = float(cp.get(section, 'centerX'))
item.centerY = float(cp.get(section, 'centerY'))
item.scale = float(cp.get(section, 'scale'))
@ -317,7 +337,7 @@ class projectPlanner(wx.Frame):
dlg.SetWildcard("STL files (*.stl)|*.stl;*.STL")
if dlg.ShowModal() == wx.ID_OK:
for filename in dlg.GetPaths():
item = ProjectObject(filename)
item = ProjectObject(self, filename)
profile.putPreference('lastFile', item.filename)
self.list.append(item)
self.selection = item
@ -387,6 +407,8 @@ class projectPlanner(wx.Frame):
bestAllowedSize = i
bestArea = area
self._doAutoPlace(bestAllowedSize)
for item in self.list:
item.clampXY()
self.preview.Refresh()
def _doAutoPlace(self, allowedSizeY):
@ -537,14 +559,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
if item != None:
item.centerX += float(e.GetX() - self.oldX) * self.zoom / self.GetSize().GetHeight() * 2
item.centerY -= float(e.GetY() - self.oldY) * self.zoom / self.GetSize().GetHeight() * 2
if item.centerX < -item.getMinimum().x * item.scale + self.parent.extruderOffset[item.extruder].x:
item.centerX = -item.getMinimum().x * item.scale + self.parent.extruderOffset[item.extruder].x
if item.centerY < -item.getMinimum().y * item.scale + self.parent.extruderOffset[item.extruder].y:
item.centerY = -item.getMinimum().y * item.scale + self.parent.extruderOffset[item.extruder].y
if item.centerX > self.parent.machineSize.x + self.parent.extruderOffset[item.extruder].x - item.getMaximum().x * item.scale:
item.centerX = self.parent.machineSize.x + self.parent.extruderOffset[item.extruder].x - item.getMaximum().x * item.scale
if item.centerY > self.parent.machineSize.y + self.parent.extruderOffset[item.extruder].y - item.getMaximum().y * item.scale:
item.centerY = self.parent.machineSize.y + self.parent.extruderOffset[item.extruder].y - item.getMaximum().y * item.scale
item.clampXY()
self.Refresh()
else:
self.allowDrag = False
@ -821,6 +836,41 @@ class ProjectSliceProgressWindow(wx.Frame):
wx.CallAfter(self.abortButton.SetLabel, 'Close')
class preferencesDialog(configBase.configWindowBase):
def __init__(self, parent):
super(preferencesDialog, self).__init__(title="Project Planner Preferences")
self.parent = parent
wx.EVT_CLOSE(self, self.OnClose)
extruderAmount = int(profile.getPreference('extruder_amount'))
left, right, main = self.CreateConfigPanel(self)
configBase.TitleRow(left, 'Machine head size')
c = configBase.SettingRow(left, 'Head size - X towards home (mm)', 'extruder_head_size_min_x', '0', 'Size of your printer head in the X direction, on the Ultimaker your fan is in this direction.', type = 'preference')
validators.validFloat(c, 0.1)
c = configBase.SettingRow(left, 'Head size - X towards end (mm)', 'extruder_head_size_max_x', '0', 'Size of your printer head in the X direction.', type = 'preference')
validators.validFloat(c, 0.1)
c = configBase.SettingRow(left, 'Head size - Y towards home (mm)', 'extruder_head_size_min_y', '0', 'Size of your printer head in the Y direction.', type = 'preference')
validators.validFloat(c, 0.1)
c = configBase.SettingRow(left, 'Head size - Y towards end (mm)', 'extruder_head_size_max_y', '0', 'Size of your printer head in the Y direction.', type = 'preference')
validators.validFloat(c, 0.1)
self.okButton = wx.Button(left, -1, 'Ok')
left.GetSizer().Add(self.okButton, (left.GetSizer().GetRows(), 1))
self.okButton.Bind(wx.EVT_BUTTON, self.OnClose)
self.MakeModal(True)
main.Fit()
self.Fit()
def OnClose(self, e):
self.parent.headSizeMin = util3d.Vector3(profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0)
self.parent.headSizeMax = util3d.Vector3(profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_max_y'),0)
self.MakeModal(False)
self.Destroy()
def main():
app = wx.App(False)
projectPlanner().Show(True)

View File

@ -51,8 +51,11 @@ class simpleModeWindow(configBase.configWindowBase):
menubar.Append(helpMenu, 'Help')
self.SetMenuBar(menubar)
self.lastPath = ""
self.filename = profile.getPreference('lastFile')
if profile.getPreference('lastFile') != '':
self.filelist = profile.getPreference('lastFile').split(';')
self.SetTitle(self.filelist[-1] + ' - Cura - ' + version.getVersion())
else:
self.filelist = []
self.progressPanelList = []
#Preview window
@ -116,9 +119,8 @@ class simpleModeWindow(configBase.configWindowBase):
sizer.Add(printButton, (1,3), flag=wx.RIGHT, border=5)
self.sizer = sizer
if self.filename != "None":
self.preview3d.loadModelFiles([self.filename])
self.lastPath = os.path.split(self.filename)[0]
if len(self.filelist) > 0:
self.preview3d.loadModelFiles(self.filelist)
self.updateProfileToControls()
@ -136,7 +138,7 @@ class simpleModeWindow(configBase.configWindowBase):
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)
dlg=wx.FileDialog(self, "Open firmware to upload", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard("HEX file (*.hex)|*.hex;*.HEX")
if dlg.ShowModal() == wx.ID_OK:
filename = dlg.GetPath()
@ -150,20 +152,17 @@ class simpleModeWindow(configBase.configWindowBase):
self.updateProfileToControls()
def OnLoadModel(self, e):
dlg=wx.FileDialog(self, "Open file to print", self.lastPath, style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg=wx.FileDialog(self, "Open file to print", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
dlg.SetWildcard("STL files (*.stl)|*.stl;*.STL")
if dlg.ShowModal() == wx.ID_OK:
self.filename=dlg.GetPath()
profile.putPreference('lastFile', self.filename)
if not(os.path.exists(self.filename)):
return
self.lastPath = os.path.split(self.filename)[0]
self.preview3d.loadModelFiles([self.filename])
self.filelist = [dlg.GetPath()]
profile.putPreference('lastFile', ';'.join(self.filelist))
self.preview3d.loadModelFiles(self.filelist)
self.preview3d.setViewMode("Normal")
dlg.Destroy()
def OnSlice(self, e):
if self.filename == None:
if len(self.filelist) < 1:
wx.MessageBox('You need to load a file before you can slice it.', 'Print error', wx.OK | wx.ICON_INFORMATION)
return
#save the current profile so we can put it back latter
@ -262,7 +261,7 @@ class simpleModeWindow(configBase.configWindowBase):
put('bottom_thickness', '0.0')
#Create a progress panel and add it to the window. The progress panel will start the Skein operation.
spp = sliceProgessPanel.sliceProgessPanel(self, self, self.filename)
spp = sliceProgessPanel.sliceProgessPanel(self, self, self.filelist)
self.sizer.Add(spp, (len(self.progressPanelList)+2,0), span=(1,4), flag=wx.EXPAND)
self.sizer.Layout()
newSize = self.GetSize();
@ -274,13 +273,13 @@ class simpleModeWindow(configBase.configWindowBase):
profile.loadGlobalProfileFromString(oldProfile)
def OnPrint(self, e):
if self.filename == None:
if len(self.filelist) < 1:
wx.MessageBox('You need to load a file and slice it before you can print it.', 'Print error', wx.OK | wx.ICON_INFORMATION)
return
if not os.path.exists(self.filename[: self.filename.rfind('.')] + "_export.gcode"):
if not os.path.exists(self.filelist[0][: self.filelist[0].rfind('.')] + "_export.gcode"):
wx.MessageBox('You need to slice the file to GCode before you can print it.', 'Print error', wx.OK | wx.ICON_INFORMATION)
return
printWindow.printFile(self.filename[: self.filename.rfind('.')] + "_export.gcode")
printWindow.printFile(self.filelist[0][: self.filelist[0].rfind('.')] + "_export.gcode")
def OnNormalSwitch(self, e):
from gui import mainWindow

View File

@ -190,11 +190,10 @@ class WorkerThread(threading.Thread):
resultFile.write(';LAYER:%d\n' % (layerNr))
resultFile.write(';EXTRUDER:%d\n' % (nextExtruder))
if nextExtruder != currentExtruder:
resultFile.write("G1 E-5 F5000\n")
resultFile.write("G92 E0\n")
resultFile.write("T%d\n" % (nextExtruder))
resultFile.write("G1 E5 F5000\n")
resultFile.write("G92 E0\n")
resultFile.write(';TYPE:CUSTOM\n')
profile.setTempOverride('extruder', nextExtruder)
resultFile.write(profile.getAlterationFileContents('switchExtruder.gcode'))
profile.resetTempOverride()
currentExtruder = nextExtruder
layerHasLine = True
resultFile.write(line)

View File

@ -1,6 +1,6 @@
from __future__ import division
import os
import os, sys
import wx
from wx.lib import buttons
@ -41,7 +41,7 @@ class Toolbar(wx.ToolBar):
popup.text.SetLabel(control.helpText)
popup.text.Wrap(350)
popup.Fit();
if os.name == 'darwin':
if sys.platform == 'darwin':
x, y = self.GetParent().ClientToScreenXY(0, 0)
sx, sy = self.GetParent().GetClientSizeTuple()
else:

BIN
Cura/images/preferences.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 B

View File

@ -10,9 +10,10 @@ from util import util3d
from util import profile
class gcodePath(object):
def __init__(self, newType, pathType, startPoint):
def __init__(self, newType, pathType, layerThickness, startPoint):
self.type = newType
self.pathType = pathType
self.layerThickness = layerThickness
self.list = [startPoint]
class gcode(object):
@ -61,10 +62,11 @@ class gcode(object):
scale = 1.0
posAbs = True
feedRate = 3600
layerThickness = 0.1
pathType = 'CUSTOM';
startCodeDone = False
currentLayer = []
currentPath = gcodePath('move', pathType, pos.copy())
currentPath = gcodePath('move', pathType, layerThickness, pos.copy())
currentPath.list[0].e = totalExtrusion
currentLayer.append(currentPath)
for line in gcodeFile:
@ -88,6 +90,9 @@ class gcode(object):
pathType = 'WALL-INNER'
elif comment == 'skirt':
pathType = 'SKIRT'
if comment.startswith('LAYER:'):
self.layerList.append(currentLayer)
currentLayer = []
if pathType != "CUSTOM":
startCodeDone = True
line = line[0:line.find(';')]
@ -126,9 +131,8 @@ class gcode(object):
else:
pos.z += z * scale
#Check if we have a new layer.
if oldPos.z < pos.z and startCodeDone and len(currentLayer) > 0:
self.layerList.append(currentLayer)
currentLayer = []
if oldPos.z != pos.z:
layerThickness = abs(oldPos.z - pos.z)
if f is not None:
feedRate = f
if x is not None or y is not None or z is not None:
@ -152,7 +156,7 @@ class gcode(object):
if totalExtrusion > maxExtrusion:
maxExtrusion = totalExtrusion
if currentPath.type != moveType or currentPath.pathType != pathType:
currentPath = gcodePath(moveType, pathType, currentPath.list[-1])
currentPath = gcodePath(moveType, pathType, layerThickness, currentPath.list[-1])
currentLayer.append(currentPath)
newPos = pos.copy()
newPos.e = totalExtrusion

View File

@ -122,6 +122,13 @@ G92 E0
G1 Z0 F{max_z_speed}
""",
#######################################################################################
'switchExtruder.gcode': """;Switch between the current extruder and the next extruder, when printing with multiple extruders.
G1 E-5 F5000
G92 E0
T{extruder}
G1 E5 F5000
G92 E0
""",
}
preferencesDefaultSettings = {
'wizardDone': 'False',