chiark / gitweb /
Added copy button to project planner, and cleaned up project planner code a bit.
authordaid <daid303@gmail.com>
Fri, 4 May 2012 15:57:24 +0000 (17:57 +0200)
committerdaid <daid303@gmail.com>
Fri, 4 May 2012 15:57:24 +0000 (17:57 +0200)
Cura/gui/projectPlanner.py
Cura/gui/validators.py
Cura/util/gcodeInterpreter.py
Cura/util/stl.py
Cura/util/util3d.py

index 2095042f9029fa885d037925467895368e1baced..5d4bd80b5bc1258e314b51068347089e652c1f36 100644 (file)
@@ -24,9 +24,108 @@ from util import util3d
 from util import stl\r
 from util import sliceRun\r
 \r
-class Action():\r
+class Action(object):\r
        pass\r
 \r
+class ProjectObject(stl.stlModel):\r
+       def __init__(self, filename):\r
+               super(ProjectObject, self).__init__()\r
+\r
+               self.load(filename)\r
+\r
+               self.filename = filename\r
+               self.scale = 1.0\r
+               self.rotate = 0.0\r
+               self.flipX = False\r
+               self.flipY = False\r
+               self.flipZ = False\r
+               self.swapXZ = False\r
+               self.swapYZ = False\r
+               self.extruder = 0\r
+               \r
+               self.modelDisplayList = None\r
+               self.modelDirty = False\r
+\r
+               self.origonalVertexes = list(self.vertexes)\r
+               for i in xrange(0, len(self.origonalVertexes)):\r
+                       self.origonalVertexes[i] = self.origonalVertexes[i].copy()\r
+               self.getMinimumZ()\r
+               \r
+               self.centerX = -self.getMinimum().x + 5\r
+               self.centerY = -self.getMinimum().y + 5\r
+               \r
+               self.updateModelTransform()\r
+\r
+               self.centerX = -self.getMinimum().x + 5\r
+               self.centerY = -self.getMinimum().y + 5\r
+\r
+       def updateModelTransform(self):\r
+               rotate = self.rotate / 180.0 * math.pi\r
+               scaleX = 1.0\r
+               scaleY = 1.0\r
+               scaleZ = 1.0\r
+               if self.flipX:\r
+                       scaleX = -scaleX\r
+               if self.flipY:\r
+                       scaleY = -scaleY\r
+               if self.flipZ:\r
+                       scaleZ = -scaleZ\r
+               swapXZ = self.swapXZ\r
+               swapYZ = self.swapYZ\r
+               mat00 = math.cos(rotate) * scaleX\r
+               mat01 =-math.sin(rotate) * scaleY\r
+               mat10 = math.sin(rotate) * scaleX\r
+               mat11 = math.cos(rotate) * scaleY\r
+               \r
+               for i in xrange(0, len(self.origonalVertexes)):\r
+                       x = self.origonalVertexes[i].x\r
+                       y = self.origonalVertexes[i].y\r
+                       z = self.origonalVertexes[i].z\r
+                       if swapXZ:\r
+                               x, z = z, x\r
+                       if swapYZ:\r
+                               y, z = z, y\r
+                       self.vertexes[i].x = x * mat00 + y * mat01\r
+                       self.vertexes[i].y = x * mat10 + y * mat11\r
+                       self.vertexes[i].z = z * scaleZ\r
+\r
+               for face in self.faces:\r
+                       v1 = face.v[0]\r
+                       v2 = face.v[1]\r
+                       v3 = face.v[2]\r
+                       face.normal = (v2 - v1).cross(v3 - v1)\r
+                       face.normal.normalize()\r
+\r
+               minZ = self.getMinimumZ()\r
+               minV = self.getMinimum()\r
+               maxV = self.getMaximum()\r
+               for v in self.vertexes:\r
+                       v.z -= minZ\r
+                       v.x -= minV.x + (maxV.x - minV.x) / 2\r
+                       v.y -= minV.y + (maxV.y - minV.y) / 2\r
+               self.getMinimumZ()\r
+               self.modelDirty = True\r
+       \r
+       def clone(self):\r
+               p = ProjectObject(self.filename)\r
+\r
+               p.centerX = self.centerX + 5\r
+               p.centerY = self.centerY + 5\r
+               \r
+               p.filename = self.filename\r
+               p.scale = self.scale\r
+               p.rotate = self.rotate\r
+               p.flipX = self.flipX\r
+               p.flipY = self.flipY\r
+               p.flipZ = self.flipZ\r
+               p.swapXZ = self.swapXZ\r
+               p.swapYZ = self.swapYZ\r
+               p.extruder = self.extruder\r
+               \r
+               p.updateModelTransform()\r
+               \r
+               return p\r
+\r
 class projectPlanner(wx.Frame):\r
        "Main user interface window"\r
        def __init__(self):\r
@@ -67,6 +166,7 @@ class projectPlanner(wx.Frame):
                toolbarUtil.NormalButton(self.toolbar2, self.OnRemModel, 'object-remove.png', 'Remove model')\r
                toolbarUtil.NormalButton(self.toolbar2, self.OnMoveUp, 'move-up.png', 'Move model up in print list')\r
                toolbarUtil.NormalButton(self.toolbar2, self.OnMoveDown, 'move-down.png', 'Move model down in print list')\r
+               toolbarUtil.NormalButton(self.toolbar2, self.OnCopy, 'copy.png', 'Make a copy of the current selected object')\r
                self.toolbar2.Realize()\r
                \r
                sizer = wx.GridBagSizer(2,2)\r
@@ -163,9 +263,7 @@ class projectPlanner(wx.Frame):
                        while cp.has_section('model_%d' % (i)):\r
                                section = 'model_%d' % (i)\r
                                \r
-                               item = stl.stlModel()\r
-                               item.filename = unicode(cp.get(section, 'filename'), "utf-8")\r
-                               self.loadModelFile(item)\r
+                               item = ProjectObject(unicode(cp.get(section, 'filename'), "utf-8"))\r
                                item.centerX = float(cp.get(section, 'centerX'))\r
                                item.centerY = float(cp.get(section, 'centerY'))\r
                                item.scale = float(cp.get(section, 'scale'))\r
@@ -177,7 +275,7 @@ class projectPlanner(wx.Frame):
                                item.swapYZ = cp.get(section, 'swapYZ') == 'True'\r
                                if cp.has_option(section, 'extruder'):\r
                                        item.extuder = int(cp.get(section, 'extruder'))-1\r
-                               self.updateModelTransform(item)\r
+                               item.updateModelTransform()\r
                                i += 1\r
                                \r
                                self.list.append(item)\r
@@ -185,6 +283,7 @@ class projectPlanner(wx.Frame):
                        \r
                        self.listbox.SetSelection(len(self.list)-1)\r
                        self.OnListSelect(None)\r
+                       self.preview.Refresh()\r
 \r
                dlg.Destroy()\r
 \r
@@ -217,29 +316,19 @@ class projectPlanner(wx.Frame):
                dlg.SetWildcard("STL files (*.stl)|*.stl;*.STL")\r
                if dlg.ShowModal() == wx.ID_OK:\r
                        for filename in dlg.GetPaths():\r
-                               item = stl.stlModel()\r
-                               item.filename=filename\r
+                               item = ProjectObject(filename)\r
                                profile.putPreference('lastFile', item.filename)\r
-                               if not(os.path.exists(item.filename)):\r
-                                       return\r
-                               self.loadModelFile(item)\r
                                self.list.append(item)\r
-                               self.listbox.AppendAndEnsureVisible(os.path.split(item.filename)[1])\r
-                               self.listbox.SetSelection(len(self.list)-1)\r
-                               self.OnListSelect(None)\r
+                               self.selection = item\r
+                               self._updateListbox()\r
+               self.preview.Refresh()\r
                dlg.Destroy()\r
        \r
        def OnRemModel(self, e):\r
                if self.selection == None:\r
                        return\r
                self.list.remove(self.selection)\r
-               i = self.listbox.GetSelection()\r
-               self.listbox.Delete(i)\r
-               if len(self.list) > i:\r
-                       self.listbox.SetSelection(i)\r
-               elif len(self.list) > 0:\r
-                       self.listbox.SetSelection(len(self.list) - 1)\r
-               self.selection = None\r
+               self._updateListbox()\r
                self.preview.Refresh()\r
        \r
        def OnMoveUp(self, e):\r
@@ -264,11 +353,29 @@ class projectPlanner(wx.Frame):
                self._updateListbox()\r
                self.preview.Refresh()\r
        \r
+       def OnCopy(self, e):\r
+               if self.selection == None:\r
+                       return\r
+               \r
+               item = self.selection.clone()\r
+               self.list.append(item)\r
+               self.selection = item\r
+               \r
+               self._updateListbox()\r
+               self.preview.Refresh()\r
+       \r
        def _updateListbox(self):\r
                self.listbox.Clear()\r
                for item in self.list:\r
                        self.listbox.AppendAndEnsureVisible(os.path.split(item.filename)[1])\r
-               self.listbox.SetSelection(self.list.index(self.selection))\r
+               if self.selection in self.list:\r
+                       self.listbox.SetSelection(self.list.index(self.selection))\r
+               elif len(self.list) > 0:\r
+                       self.selection = self.list[0]\r
+                       self.listbox.SetSelection(0)\r
+               else:\r
+                       self.selection = None\r
+                       self.listbox.SetSelection(-1)\r
 \r
        def OnAutoPlace(self, e):\r
                bestAllowedSize = int(self.machineSize.y)\r
@@ -368,32 +475,6 @@ class projectPlanner(wx.Frame):
                pspw.Centre()\r
                pspw.Show(True)\r
        \r
-       def loadModelFile(self, item):\r
-               item.load(item.filename)\r
-               item.origonalVertexes = list(item.vertexes)\r
-               for i in xrange(0, len(item.origonalVertexes)):\r
-                       item.origonalVertexes[i] = item.origonalVertexes[i].copy()\r
-               item.getMinimumZ()\r
-               \r
-               item.centerX = -item.getMinimum().x + 5\r
-               item.centerY = -item.getMinimum().y + 5\r
-               item.scale = 1.0\r
-               item.rotate = 0.0\r
-               item.flipX = False\r
-               item.flipY = False\r
-               item.flipZ = False\r
-               item.swapXZ = False\r
-               item.swapYZ = False\r
-               item.extruder = 0\r
-               \r
-               item.modelDisplayList = None\r
-               item.modelDirty = False\r
-               \r
-               self.updateModelTransform(item)\r
-\r
-               item.centerX = -item.getMinimum().x + 5\r
-               item.centerY = -item.getMinimum().y + 5\r
-\r
        def OnScaleChange(self, e):\r
                if self.selection == None:\r
                        return\r
@@ -407,7 +488,8 @@ class projectPlanner(wx.Frame):
                if self.selection == None:\r
                        return\r
                self.selection.rotate = float(self.rotateCtrl.GetValue())\r
-               self.updateModelTransform(self.selection)\r
+               self.selection.updateModelTransform()\r
+               self.preview.Refresh()\r
 \r
        def OnExtruderChange(self, e):\r
                if self.selection == None:\r
@@ -415,57 +497,6 @@ class projectPlanner(wx.Frame):
                self.selection.extruder = int(self.extruderCtrl.GetValue()) - 1\r
                self.preview.Refresh()\r
 \r
-       def updateModelTransform(self, item):\r
-               rotate = item.rotate / 180.0 * math.pi\r
-               scaleX = 1.0\r
-               scaleY = 1.0\r
-               scaleZ = 1.0\r
-               if item.flipX:\r
-                       scaleX = -scaleX\r
-               if item.flipY:\r
-                       scaleY = -scaleY\r
-               if item.flipZ:\r
-                       scaleZ = -scaleZ\r
-               swapXZ = item.swapXZ\r
-               swapYZ = item.swapYZ\r
-               mat00 = math.cos(rotate) * scaleX\r
-               mat01 =-math.sin(rotate) * scaleY\r
-               mat10 = math.sin(rotate) * scaleX\r
-               mat11 = math.cos(rotate) * scaleY\r
-               \r
-               for i in xrange(0, len(item.origonalVertexes)):\r
-                       x = item.origonalVertexes[i].x\r
-                       y = item.origonalVertexes[i].y\r
-                       z = item.origonalVertexes[i].z\r
-                       if swapXZ:\r
-                               x, z = z, x\r
-                       if swapYZ:\r
-                               y, z = z, y\r
-                       item.vertexes[i].x = x * mat00 + y * mat01\r
-                       item.vertexes[i].y = x * mat10 + y * mat11\r
-                       item.vertexes[i].z = z * scaleZ\r
-\r
-               for face in item.faces:\r
-                       v1 = face.v[0]\r
-                       v2 = face.v[1]\r
-                       v3 = face.v[2]\r
-                       face.normal = (v2 - v1).cross(v3 - v1)\r
-                       face.normal.normalize()\r
-\r
-               self.moveModel(item)\r
-       \r
-       def moveModel(self, item):\r
-               minZ = item.getMinimumZ()\r
-               min = item.getMinimum()\r
-               max = item.getMaximum()\r
-               for v in item.vertexes:\r
-                       v.z -= minZ\r
-                       v.x -= min.x + (max.x - min.x) / 2\r
-                       v.y -= min.y + (max.y - min.y) / 2\r
-               item.getMinimumZ()\r
-               item.modelDirty = True\r
-               self.preview.Refresh()\r
-\r
 class PreviewGLCanvas(glcanvas.GLCanvas):\r
        def __init__(self, parent):\r
                attribList = (glcanvas.WX_GL_RGBA, glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 24, glcanvas.WX_GL_STENCIL_SIZE, 8)\r
index b1da7783a363945f8383ecb8c0bb5bd6e9ebdb5a..f29e8d1eb9cfb8e065415dc5374577f5b60a2340 100644 (file)
@@ -11,7 +11,7 @@ SUCCESS = 0
 WARNING = 1
 ERROR   = 2
 
-class validFloat():
+class validFloat(object):
        def __init__(self, setting, minValue = None, maxValue = None):
                self.setting = setting
                self.setting.validators.append(self)
@@ -29,7 +29,7 @@ class validFloat():
                except (ValueError, SyntaxError):
                        return ERROR, '"' + str(self.setting.GetValue()) + '" is not a valid number or expression'
 
-class validInt():
+class validInt(object):
        def __init__(self, setting, minValue = None, maxValue = None):
                self.setting = setting
                self.setting.validators.append(self)
@@ -47,7 +47,7 @@ class validInt():
                except (ValueError, SyntaxError):
                        return ERROR, '"' + str(self.setting.GetValue()) + '" is not a valid whole number or expression'
 
-class warningAbove():
+class warningAbove(object):
        def __init__(self, setting, minValueForWarning, warningMessage):
                self.setting = setting
                self.setting.validators.append(self)
@@ -68,7 +68,7 @@ class warningAbove():
                        #We already have an error by the int/float validator in this case.
                        return SUCCESS, ''
 
-class wallThicknessValidator():
+class wallThicknessValidator(object):
        def __init__(self, setting):
                self.setting = setting
                self.setting.validators.append(self)
@@ -94,7 +94,7 @@ class wallThicknessValidator():
                        #We already have an error by the int/float validator in this case.
                        return SUCCESS, ''
 
-class printSpeedValidator():
+class printSpeedValidator(object):
        def __init__(self, setting):
                self.setting = setting
                self.setting.validators.append(self)
index 3af69bb48e43de4268f4ad4d9d5ddac481d03469..5714972cae3ff0472d63d7739e71e2f722baa842 100644 (file)
@@ -9,13 +9,13 @@ import os
 from util import util3d
 from util import profile
 
-class gcodePath():
+class gcodePath(object):
        def __init__(self, newType, pathType, startPoint):
                self.type = newType
                self.pathType = pathType
                self.list = [startPoint]
 
-class gcode():
+class gcode(object):
        def __init__(self):
                self.regMatch = {}
                self.layerList = []
index 9b1323a294237880f6e61ca31d1f95b4d2ba76ea..bf7558b4974d0945ba81abffb59f20e3124279a1 100644 (file)
@@ -9,11 +9,11 @@ import struct
 
 from util import util3d
 
-class stlFace():
+class stlFace(object):
        def __init__(self, v0, v1, v2):
                self.v = [v0, v1, v2]
 
-class stlModel():
+class stlModel(object):
        def __init__(self):
                self.faces = []
                self.vertexes = []
index 30b25159d6221d1bfd3770d25c69855cc948179a..d5411fc9c493e623ef82689242e591b422f96953 100644 (file)
@@ -1,7 +1,7 @@
 
 import math
 
-class Vector3():
+class Vector3(object):
        def __init__(self, x=0.0, y=0.0, z=0.0):
                self.x = x
                self.y = y