chiark / gitweb /
Add option to save GCode file. Re-center the objects on the bed when you add a new...
authordaid303 <daid303@gmail.com>
Wed, 3 Apr 2013 06:54:39 +0000 (08:54 +0200)
committerdaid303 <daid303@gmail.com>
Wed, 3 Apr 2013 06:54:39 +0000 (08:54 +0200)
Cura/gui/sceneView.py
Cura/gui/util/openglGui.py
Cura/util/meshLoader.py
Cura/util/meshLoaders/obj.py
Cura/util/meshLoaders/stl.py
Cura/util/objectScene.py

index c1a91d628f8dfc9ae591f6f682a7a848bfc8f279..5796e13533f7456413f5f70ab52bec336f073e98 100644 (file)
@@ -4,6 +4,8 @@ import wx
 import numpy
 import time
 import os
+import traceback
+import shutil
 
 import OpenGL
 OpenGL.ERROR_CHECKING = False
@@ -74,23 +76,42 @@ class SceneView(openglGui.glGuiPanel):
                self.updateProfileToControls()
                wx.EVT_IDLE(self, self.OnIdle)
 
-       def ShowLoadModel(self):
-               dlg=wx.FileDialog(self, 'Open 3D model', os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST)
-               dlg.SetWildcard(meshLoader.wildcardFilter())
-               if dlg.ShowModal() != wx.ID_OK:
+       def ShowLoadModel(self, button):
+               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)
+                       dlg.SetWildcard(meshLoader.wildcardFilter())
+                       if dlg.ShowModal() != wx.ID_OK:
+                               dlg.Destroy()
+                               return
+                       filename = dlg.GetPath()
                        dlg.Destroy()
-                       return
-               filename = dlg.GetPath()
-               dlg.Destroy()
-               if not(os.path.exists(filename)):
-                       return False
-               profile.putPreference('lastFile', filename)
-               self.GetParent().GetParent().GetParent().addToModelMRU(filename)
-               self.loadScene([filename])
-
-       def ShowPrintWindow(self):
-               if machineCom.machineIsConnected():
-                       printWindow.printFile(self._slicer.getGCodeFilename())
+                       if not(os.path.exists(filename)):
+                               return False
+                       profile.putPreference('lastFile', filename)
+                       self.GetParent().GetParent().GetParent().addToModelMRU(filename)
+                       self.loadScene([filename])
+
+       def ShowPrintWindow(self, button):
+               if button == 1:
+                       if machineCom.machineIsConnected():
+                               printWindow.printFile(self._slicer.getGCodeFilename())
+                       elif len(removableStorage.getPossibleSDcardDrives()) > 0:
+                               drives = removableStorage.getPossibleSDcardDrives()
+                               if len(drives) > 1:
+                                       pass
+                       else:
+                               defPath = profile.getPreference('lastFile')
+                               defPath = defPath[0:defPath.rfind('.')] + '.gcode'
+                               dlg=wx.FileDialog(self, 'Save toolpath', defPath, style=wx.FD_SAVE)
+                               dlg.SetFilename(defPath)
+                               dlg.SetWildcard('Toolpath (*.gcode)|*.gcode;*.g')
+                               if dlg.ShowModal() != wx.ID_OK:
+                                       dlg.Destroy()
+                                       return
+                               filename = dlg.GetPath()
+                               dlg.Destroy()
+
+                               shutil.copy(self._slicer.getGCodeFilename(), filename)
 
        def OnIdle(self, e):
                if self._animView is not None or self._animZoom is not None:
@@ -113,10 +134,16 @@ class SceneView(openglGui.glGuiPanel):
 
        def loadScene(self, fileList):
                for filename in fileList:
-                       for obj in meshLoader.loadMeshes(filename):
-                               obj._loadAnim = anim(1, 0, 1.5)
-                               self._scene.add(obj)
-                               self._selectObject(obj)
+                       try:
+                               objList = meshLoader.loadMeshes(filename)
+                       except:
+                               traceback.print_exc()
+                       else:
+                               for obj in objList:
+                                       obj._loadAnim = anim(1, 0, 1.5)
+                                       self._scene.add(obj)
+                                       self._scene.centerAll()
+                                       self._selectObject(obj)
                self.sceneUpdated()
 
        def _deleteObject(self, obj):
@@ -276,10 +303,13 @@ class SceneView(openglGui.glGuiPanel):
        def OnPaint(self,e):
                if machineCom.machineIsConnected():
                        self.printButton._imageID = 6
+                       self.printButton._tooltip = 'Print'
                elif len(removableStorage.getPossibleSDcardDrives()) > 0:
                        self.printButton._imageID = 2
+                       self.printButton._tooltip = 'Toolpath to SD'
                else:
                        self.printButton._imageID = 3
+                       self.printButton._tooltip = 'Save toolpath'
 
                if self._animView is not None:
                        self._viewTarget = self._animView.getPosition()
index 72da49d2433672d797b778feb8367aee62cf527f..f4fd3707e3aae322b198ceb56b9377fa93c6e6e4 100644 (file)
@@ -71,9 +71,9 @@ class glGuiContainer(glGuiControl):
                self._glGuiControlList.append(ctrl)
                self.updateLayout()
 
-       def OnMouseDown(self, x, y):
+       def OnMouseDown(self, x, y, button):
                for ctrl in self._glGuiControlList:
-                       if ctrl.OnMouseDown(x, y):
+                       if ctrl.OnMouseDown(x, y, button):
                                return True
                return False
 
@@ -101,7 +101,7 @@ class glGuiContainer(glGuiControl):
 
 class glGuiPanel(glcanvas.GLCanvas):
        def __init__(self, parent):
-               attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 24, glcanvas.WX_GL_STENCIL_SIZE, 8)
+               attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 32, glcanvas.WX_GL_STENCIL_SIZE, 8)
                glcanvas.GLCanvas.__init__(self, parent, style=wx.WANTS_CHARS, attribList = attribList)
                self._base = self
                self._focus = None
@@ -145,7 +145,7 @@ class glGuiPanel(glcanvas.GLCanvas):
 
        def _OnGuiMouseDown(self,e):
                self.SetFocus()
-               if self._container.OnMouseDown(e.GetX(), e.GetY()):
+               if self._container.OnMouseDown(e.GetX(), e.GetY(), e.Button):
                        self.Refresh()
                        return
                self.OnMouseDown(e)
@@ -442,9 +442,9 @@ class glButton(glGuiControl):
                self._focus = False
                return False
 
-       def OnMouseDown(self, x, y):
+       def OnMouseDown(self, x, y, button):
                if self._checkHit(x, y):
-                       self._callback()
+                       self._callback(button)
                        return True
                return False
 
@@ -533,7 +533,7 @@ class glComboButton(glButton):
                self._imageID = self._imageIDs[self._selection]
                self._comboCallback()
 
-       def OnMouseDown(self, x, y):
+       def OnMouseDown(self, x, y, button):
                if self._hidden or self._disabled:
                        return False
                if self.hasFocus():
@@ -545,7 +545,7 @@ class glComboButton(glButton):
                                self._base._focus = None
                                self._comboCallback()
                                return True
-               return super(glComboButton, self).OnMouseDown(x, y)
+               return super(glComboButton, self).OnMouseDown(x, y, button)
 
 class glFrame(glGuiContainer):
        def __init__(self, parent, pos):
@@ -704,9 +704,9 @@ class glFrame(glGuiContainer):
                self._focus = False
                return False
 
-       def OnMouseDown(self, x, y):
+       def OnMouseDown(self, x, y, button):
                if self._checkHit(x, y):
-                       super(glFrame, self).OnMouseDown(x, y)
+                       super(glFrame, self).OnMouseDown(x, y, button)
                        return True
                return False
 
@@ -752,7 +752,7 @@ class glLabel(glGuiControl):
        def OnMouseMotion(self, x, y):
                return False
 
-       def OnMouseDown(self, x, y):
+       def OnMouseDown(self, x, y, button):
                return False
 
 class glNumberCtrl(glGuiControl):
@@ -813,7 +813,7 @@ class glNumberCtrl(glGuiControl):
        def OnMouseMotion(self, x, y):
                return False
 
-       def OnMouseDown(self, x, y):
+       def OnMouseDown(self, x, y, button):
                if self._checkHit(x, y):
                        self.setFocus()
                        return True
@@ -914,7 +914,7 @@ class glCheckbox(glGuiControl):
        def OnMouseMotion(self, x, y):
                return False
 
-       def OnMouseDown(self, x, y):
+       def OnMouseDown(self, x, y, button):
                if self._checkHit(x, y):
                        self._value = not self._value
                        return True
@@ -1032,7 +1032,7 @@ class glSlider(glGuiControl):
                self._focus = False
                return False
 
-       def OnMouseDown(self, x, y):
+       def OnMouseDown(self, x, y, button):
                if self._checkHit(x, y):
                        self.setFocus()
                        self.OnMouseMotion(x, y)
index f533a056395fe079ba84456744eccd245bbf03dc..bc5141508acad823da83cd10ae9a68f71d387ada 100644 (file)
@@ -21,9 +21,9 @@ def wildcardFilter():
 def loadMeshes(filename):
        ext = filename[filename.rfind('.'):].lower()
        if ext == '.stl':
-               return stl.loadSTLscene(filename)
+               return stl.loadScene(filename)
        if ext == '.obj':
-               return obj.objModel().load(filename)
+               return obj.loadScene(filename)
        if ext == '.dae':
                return dae.daeModel().load(filename)
        if ext == '.amf':
index e8c7dfa77a2ba6f4387393a44beacc256e79f3cb..dab9ddc253e64d5d4fb01fc3c44b6e7056b54d7c 100644 (file)
@@ -2,42 +2,38 @@ from __future__ import absolute_import
 
 from Cura.util import mesh
 
-class objModel(mesh.mesh):
-       def __init__(self):
-               super(objModel, self).__init__()
+def loadScene(filename):
+       obj = mesh.printableObject()
+       m = obj._addMesh()
 
-       def load(self, filename):
-               vertexList = []
-               faceList = []
-               
-               f = open(filename, "r")
-               for line in f:
-                       parts = line.split()
-                       if len(parts) < 1:
-                               continue
-                       if parts[0] == 'v':
-                               vertexList.append([float(parts[1]), float(parts[2]), float(parts[3])])
-                       if parts[0] == 'f':
-                               parts = map(lambda p: p.split('/')[0], parts)
-                               for idx in xrange(1, len(parts)-2):
-                                       faceList.append([int(parts[1]), int(parts[idx+1]), int(parts[idx+2])])
-               f.close()
-               
-               self._prepareVertexCount(len(faceList) * 3)
-               for f in faceList:
-                       i = f[0] - 1
-                       if i < 0 or i >= len(vertexList):
-                               i = 0
-                       self.addVertex(vertexList[i][0], vertexList[i][1], vertexList[i][2])
-                       i = f[1] - 1
-                       if i < 0 or i >= len(vertexList):
-                               i = 0
-                       self.addVertex(vertexList[i][0], vertexList[i][1], vertexList[i][2])
-                       i = f[2] - 1
-                       if i < 0 or i >= len(vertexList):
-                               i = 0
-                       self.addVertex(vertexList[i][0], vertexList[i][1], vertexList[i][2])
-               
-               self._postProcessAfterLoad()
-               return self
-       
+       vertexList = []
+       faceList = []
+
+       f = open(filename, "r")
+       for line in f:
+               parts = line.split()
+               if len(parts) < 1:
+                       continue
+               if parts[0] == 'v':
+                       vertexList.append([float(parts[1]), float(parts[2]), float(parts[3])])
+               if parts[0] == 'f':
+                       parts = map(lambda p: p.split('/')[0], parts)
+                       for idx in xrange(1, len(parts)-2):
+                               faceList.append([int(parts[1]), int(parts[idx+1]), int(parts[idx+2])])
+       f.close()
+
+       m._prepareFaceCount(len(faceList))
+       for f in faceList:
+               i = f[0] - 1
+               j = f[1] - 1
+               k = f[2] - 1
+               if i < 0 or i >= len(vertexList):
+                       i = 0
+               if j < 0 or j >= len(vertexList):
+                       j = 0
+               if k < 0 or k >= len(vertexList):
+                       k = 0
+               m._addFace(vertexList[i][0], vertexList[i][1], vertexList[i][2], vertexList[j][0], vertexList[j][1], vertexList[j][2], vertexList[k][0], vertexList[k][1], vertexList[k][2])
+
+       obj._postProcessAfterLoad()
+       return [obj]
index 068154ece4c5f08b2d5efee8622b72168c4fa072..ab9c935400a2f13db3d58b326836a117f1a539f4 100644 (file)
@@ -35,7 +35,7 @@ def _loadBinary(m, f):
                data = struct.unpack("<ffffffffffffH", f.read(50))
                m._addFace(data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11])
 
-def loadSTLscene(filename):
+def loadScene(filename):
        obj = mesh.printableObject()
        m = obj._addMesh()
 
index 1070cb76ce8eb2b42c89a3151d3a25ceedf73e6e..2b2bd813e85317f6ed9bb2254d63a75b18c46469 100644 (file)
@@ -6,6 +6,7 @@ class Scene():
                self._objectList = []
                self._sizeOffsets = numpy.array([3.0,3.0], numpy.float32)
                self._machineSize = numpy.array([100,100,100], numpy.float32)
+               self._headOffsets = numpy.array([18.0,18.0], numpy.float32)
 
        def setMachineSize(self, machineSize):
                self._machineSize = machineSize
@@ -35,6 +36,20 @@ class Scene():
                        obj.setPosition(numpy.array([0,0], numpy.float32))
                        self.add(obj)
 
+       def centerAll(self):
+               minPos = numpy.array([9999999,9999999], numpy.float32)
+               maxPos = numpy.array([-9999999,-9999999], numpy.float32)
+               for obj in self._objectList:
+                       pos = obj.getPosition()
+                       size = obj.getSize()
+                       minPos[0] = min(minPos[0], pos[0] - size[0] / 2)
+                       minPos[1] = min(minPos[1], pos[1] - size[1] / 2)
+                       maxPos[0] = max(maxPos[0], pos[0] + size[0] / 2)
+                       maxPos[1] = max(maxPos[1], pos[1] + size[1] / 2)
+               offset = -(maxPos + minPos) / 2
+               for obj in self._objectList:
+                       obj.setPosition(obj.getPosition() + offset)
+
        def _pushFree(self):
                for a in self._objectList:
                        for b in self._objectList:
@@ -50,7 +65,7 @@ class Scene():
                                aPos = a.getPosition()
                                bPos = b.getPosition()
                                center = (aPos[axis] + bPos[axis]) / 2
-                               distance = (a.getSize()[axis] + b.getSize()[axis]) / 2 + 0.1 + self._sizeOffsets[axis] * 2
+                               distance = (a.getSize()[axis] + b.getSize()[axis]) / 2 + 0.1 + self._sizeOffsets[axis] + self._headOffsets[axis]
                                if posDiff[axis] < 0:
                                        distance = -distance
                                aPos[axis] = center + distance / 2
@@ -64,8 +79,9 @@ class Scene():
                if a == b:
                        return False
                posDiff = a.getPosition() - b.getPosition()
-               if abs(posDiff[0]) < (a.getSize()[0] + b.getSize()[0]) / 2 + self._sizeOffsets[0] * 2 and abs(posDiff[1]) < (a.getSize()[1] + b.getSize()[1]) / 2 + self._sizeOffsets[1] * 2:
-                       return True
+               if abs(posDiff[0]) < (a.getSize()[0] + b.getSize()[0]) / 2 + self._sizeOffsets[0] + self._headOffsets[0]:
+                       if abs(posDiff[1]) < (a.getSize()[1] + b.getSize()[1]) / 2 + self._sizeOffsets[1] + self._headOffsets[1]:
+                               return True
                return False
 
        def checkPlatform(self, obj):
@@ -85,7 +101,7 @@ class Scene():
                posList = []
                for a in self._objectList:
                        p = a.getPosition()
-                       s = (a.getSize()[0:2] + obj.getSize()[0:2]) / 2 + self._sizeOffsets * 2
+                       s = (a.getSize()[0:2] + obj.getSize()[0:2]) / 2 + self._sizeOffsets + self._headOffsets
                        posList.append(p + s * ( 1, 1))
                        posList.append(p + s * ( 0, 1))
                        posList.append(p + s * (-1, 1))