import traceback
import threading
import math
+import platform
import OpenGL
OpenGL.ERROR_CHECKING = False
from Cura.gui.util import opengl
from Cura.gui.util import openglGui
from Cura.gui.tools import youmagineGui
+from Cura.gui.tools import imageToMesh
class SceneView(openglGui.glGuiPanel):
def __init__(self, parent):
self.updateToolButtons()
self.updateProfileToControls()
+ def loadGCodeFile(self, filename):
+ self.OnDeleteAll(None)
+ if self._gcode is not None:
+ self._gcode = None
+ for layerVBOlist in self._gcodeVBOs:
+ for vbo in layerVBOlist:
+ self.glReleaseList.append(vbo)
+ self._gcodeVBOs = []
+ self._gcode = gcodeInterpreter.gcode()
+ self._gcodeFilename = filename
+ self.printButton.setBottomText('')
+ self.viewSelection.setValue(4)
+ self.printButton.setDisabled(False)
+ self.youMagineButton.setDisabled(True)
+ self.OnViewChange()
+
+ def loadSceneFiles(self, filenames):
+ self.youMagineButton.setDisabled(False)
+ #if self.viewSelection.getValue() == 4:
+ # self.viewSelection.setValue(0)
+ # self.OnViewChange()
+ self.loadScene(filenames)
+
+ def loadFiles(self, filenames):
+ mainWindow = self.GetParent().GetParent().GetParent()
+ # only one GCODE file can be active
+ # so if single gcode file, process this
+ # otherwise ignore all gcode files
+ gcodeFilename = None
+ if len(filenames) == 1:
+ filename = filenames[0]
+ ext = os.path.splitext(filename)[1].lower()
+ if ext == '.g' or ext == '.gcode':
+ gcodeFilename = filename
+ mainWindow.addToModelMRU(filename)
+ if gcodeFilename is not None:
+ self.loadGCodeFile(gcodeFilename)
+ else:
+ # process directories and special file types
+ # and keep scene files for later processing
+ scene_filenames = []
+ ignored_types = dict()
+ # use file list as queue
+ # pop first entry for processing and append new files at end
+ while filenames:
+ filename = filenames.pop(0)
+ if os.path.isdir(filename):
+ # directory: queue all included files and directories
+ filenames.extend(os.path.join(filename, f) for f in os.listdir(filename))
+ else:
+ ext = os.path.splitext(filename)[1].lower()
+ if ext == '.ini':
+ profile.loadProfile(filename)
+ mainWindow.addToProfileMRU(filename)
+ elif ext in meshLoader.loadSupportedExtensions() or ext in imageToMesh.supportedExtensions():
+ scene_filenames.append(filename)
+ mainWindow.addToModelMRU(filename)
+ else:
+ ignored_types[ext] = 1
+ if ignored_types:
+ ignored_types = ignored_types.keys()
+ ignored_types.sort()
+ self.notification.message("ignored: " + " ".join("*" + type for type in ignored_types))
+ mainWindow.updateProfileToAllControls()
+ # now process all the scene files
+ if scene_filenames:
+ self.loadSceneFiles(scene_filenames)
+ self._selectObject(None)
+ self.sceneUpdated()
+ newZoom = numpy.max(self._machineSize)
+ self._animView = openglGui.animation(self, self._viewTarget.copy(), numpy.array([0,0,0], numpy.float32), 0.5)
+ self._animZoom = openglGui.animation(self, self._zoom, newZoom, 0.5)
+
def showLoadModel(self, button = 1):
if button == 1:
dlg=wx.FileDialog(self, _("Open 3D model"), os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST|wx.FD_MULTIPLE)
- dlg.SetWildcard(meshLoader.loadWildcardFilter() + "|GCode file (*.gcode)|*.g;*.gcode;*.G;*.GCODE")
+ dlg.SetWildcard(meshLoader.loadWildcardFilter() + imageToMesh.wildcardList() + "|GCode file (*.gcode)|*.g;*.gcode;*.G;*.GCODE")
if dlg.ShowModal() != wx.ID_OK:
dlg.Destroy()
return
if len(filenames) < 1:
return False
profile.putPreference('lastFile', filenames[0])
- gcodeFilename = None
- for filename in filenames:
- self.GetParent().GetParent().GetParent().addToModelMRU(filename)
- ext = filename[filename.rfind('.')+1:].upper()
- if ext == 'G' or ext == 'GCODE':
- gcodeFilename = filename
- if gcodeFilename is not None:
- if self._gcode is not None:
- self._gcode = None
- for layerVBOlist in self._gcodeVBOs:
- for vbo in layerVBOlist:
- self.glReleaseList.append(vbo)
- self._gcodeVBOs = []
- self._gcode = gcodeInterpreter.gcode()
- self._gcodeFilename = gcodeFilename
- self.printButton.setBottomText('')
- self.viewSelection.setValue(4)
- self.printButton.setDisabled(False)
- self.youMagineButton.setDisabled(True)
- self.OnViewChange()
- else:
- self.youMagineButton.setDisabled(False)
- if self.viewSelection.getValue() == 4:
- self.viewSelection.setValue(0)
- self.OnViewChange()
- self.loadScene(filenames)
+ self.loadFiles(filenames)
def showSaveModel(self):
if len(self._scene.objects()) < 1:
self._slicer.submitSliceInfoOnline()
def showSaveGCode(self):
- defPath = profile.getPreference('lastFile')
- defPath = defPath[0:defPath.rfind('.')] + '.gcode'
- dlg=wx.FileDialog(self, _("Save toolpath"), defPath, style=wx.FD_SAVE)
- dlg.SetFilename(self._scene._objectList[0].getName())
+ if len(self._scene._objectList) < 1:
+ return
+ dlg=wx.FileDialog(self, _("Save toolpath"), os.path.dirname(profile.getPreference('lastFile')), style=wx.FD_SAVE)
+ filename = self._scene._objectList[0].getName() + '.gcode'
+ dlg.SetFilename(filename)
dlg.SetWildcard('Toolpath (*.gcode)|*.gcode;*.g')
if dlg.ShowModal() != wx.ID_OK:
dlg.Destroy()
if self._focusObj is None:
return
obj = self._focusObj
- dlg = wx.NumberEntryDialog(self, "How many copies do you want?", "Copies", "Multiply", 1, 1, 100)
+ dlg = wx.NumberEntryDialog(self, _("How many copies do you want?"), _("Number of copies"), _("Multiply"), 1, 1, 100)
if dlg.ShowModal() != wx.ID_OK:
dlg.Destroy()
return
self._selectObject(None)
self.sceneUpdated()
+ def OnCenter(self, e):
+ if self._focusObj is None:
+ return
+ self._focusObj.setPosition(numpy.array([0.0, 0.0]))
+ self._scene.pushFree()
+ newViewPos = numpy.array([self._focusObj.getPosition()[0], self._focusObj.getPosition()[1], self._focusObj.getSize()[2] / 2])
+ self._animView = openglGui.animation(self, self._viewTarget.copy(), newViewPos, 0.5)
+ self.sceneUpdated()
+
def _splitCallback(self, progress):
print progress
self._gcode.load(self._gcodeFilename)
def _gcodeLoadCallback(self, progress):
- if self._gcode is None:
+ if not self or self._gcode is None:
return True
if len(self._gcode.layerList) % 15 == 0:
time.sleep(0.1)
def loadScene(self, fileList):
for filename in fileList:
try:
- objList = meshLoader.loadMeshes(filename)
+ ext = os.path.splitext(filename)[1].lower()
+ if ext in imageToMesh.supportedExtensions():
+ imageToMesh.convertImageDialog(self, filename).Show()
+ objList = []
+ else:
+ objList = meshLoader.loadMeshes(filename)
except:
traceback.print_exc()
else:
self.updateProfileToControls()
self.updateToolButtons()
if zoom and obj is not None:
- newViewPos = numpy.array([obj.getPosition()[0], obj.getPosition()[1], obj.getMaximum()[2] / 2])
+ newViewPos = numpy.array([obj.getPosition()[0], obj.getPosition()[1], obj.getSize()[2] / 2])
self._animView = openglGui.animation(self, self._viewTarget.copy(), newViewPos, 0.5)
newZoom = obj.getBoundaryCircle() * 6
if newZoom > numpy.max(self._machineSize) * 3:
self.scaleZmmctrl.setValue(round(size[2], 2))
def OnKeyChar(self, keyCode):
- if keyCode == wx.WXK_DELETE or keyCode == wx.WXK_NUMPAD_DELETE:
+ if keyCode == wx.WXK_DELETE or keyCode == wx.WXK_NUMPAD_DELETE or (keyCode == wx.WXK_BACK and platform.system() == "Darwin"):
if self._selectedObj is not None:
self._deleteObject(self._selectedObj)
self.QueueRefresh()
if e.GetButton() == 3:
menu = wx.Menu()
if self._focusObj is not None:
- self.Bind(wx.EVT_MENU, lambda e: self._deleteObject(self._focusObj), menu.Append(-1, _("Delete")))
- self.Bind(wx.EVT_MENU, self.OnMultiply, menu.Append(-1, _("Multiply")))
- self.Bind(wx.EVT_MENU, self.OnSplitObject, menu.Append(-1, _("Split")))
+ self.Bind(wx.EVT_MENU, lambda e: self._deleteObject(self._focusObj), menu.Append(-1, _("Delete object")))
+ self.Bind(wx.EVT_MENU, self.OnCenter, menu.Append(-1, _("Center on platform")))
+ self.Bind(wx.EVT_MENU, self.OnMultiply, menu.Append(-1, _("Multiply object")))
+ self.Bind(wx.EVT_MENU, self.OnSplitObject, menu.Append(-1, _("Split object into parts")))
if ((self._selectedObj != self._focusObj and self._focusObj is not None and self._selectedObj is not None) or len(self._scene.objects()) == 2) and int(profile.getMachineSetting('extruder_amount')) > 1:
self.Bind(wx.EVT_MENU, self.OnMergeObjects, menu.Append(-1, _("Dual extrusion merge")))
if len(self._scene.objects()) > 0:
- self.Bind(wx.EVT_MENU, self.OnDeleteAll, menu.Append(-1, _("Delete all")))
+ self.Bind(wx.EVT_MENU, self.OnDeleteAll, menu.Append(-1, _("Delete all objects")))
if menu.MenuItemCount > 0:
self.PopupMenu(menu)
menu.Destroy()
gl_FragColor = vec4(gl_Color.xyz * light_amount, 1.0-intensity);
}
""")
- if self._objectShader == None or not self._objectShader.isValid():
+ if self._objectShader is None or not self._objectShader.isValid():
self._objectShader = opengl.GLFakeShader()
self._objectOverhangShader = opengl.GLFakeShader()
self._objectLoadShader = None
self._platformMesh[machine] = meshes[0]
else:
self._platformMesh[machine] = None
- if profile.getMachineSetting('machine_type') == 'ultimaker2':
+ if machine == 'ultimaker2':
self._platformMesh[machine]._drawOffset = numpy.array([0,-37,145], numpy.float32)
else:
self._platformMesh[machine]._drawOffset = numpy.array([0,0,2.5], numpy.float32)
self._objectShader.bind()
self._renderObject(self._platformMesh[machine], False, False)
self._objectShader.unbind()
+
+ #For the Ultimaker 2 render the texture on the back plate to show the Ultimaker2 text.
+ if machine == 'ultimaker2':
+ if not hasattr(self._platformMesh[machine], 'texture'):
+ self._platformMesh[machine].texture = opengl.loadGLTexture('Ultimaker2backplate.png')
+ glBindTexture(GL_TEXTURE_2D, self._platformMesh[machine].texture)
+ glEnable(GL_TEXTURE_2D)
+ glPushMatrix()
+ glColor4f(1,1,1,1)
+
+ glTranslate(0,150,-5)
+ h = 50
+ d = 8
+ w = 100
+ glEnable(GL_BLEND)
+ glBlendFunc(GL_DST_COLOR, GL_ZERO)
+ glBegin(GL_QUADS)
+ glTexCoord2f(1, 0)
+ glVertex3f( w, 0, h)
+ glTexCoord2f(0, 0)
+ glVertex3f(-w, 0, h)
+ glTexCoord2f(0, 1)
+ glVertex3f(-w, 0, 0)
+ glTexCoord2f(1, 1)
+ glVertex3f( w, 0, 0)
+
+ glTexCoord2f(1, 0)
+ glVertex3f(-w, d, h)
+ glTexCoord2f(0, 0)
+ glVertex3f( w, d, h)
+ glTexCoord2f(0, 1)
+ glVertex3f( w, d, 0)
+ glTexCoord2f(1, 1)
+ glVertex3f(-w, d, 0)
+ glEnd()
+ glDisable(GL_TEXTURE_2D)
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
+ glPopMatrix()
else:
glColor4f(0,0,0,1)
glLineWidth(3)