From: daid Date: Fri, 4 May 2012 15:57:24 +0000 (+0200) Subject: Added copy button to project planner, and cleaned up project planner code a bit. X-Git-Tag: RC3~13^2~1^2~1 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=8b24d77aea8845c88590311310400a767a2372a1;p=cura.git Added copy button to project planner, and cleaned up project planner code a bit. --- diff --git a/Cura/gui/projectPlanner.py b/Cura/gui/projectPlanner.py index 2095042f..5d4bd80b 100644 --- a/Cura/gui/projectPlanner.py +++ b/Cura/gui/projectPlanner.py @@ -24,9 +24,108 @@ from util import util3d from util import stl from util import sliceRun -class Action(): +class Action(object): pass +class ProjectObject(stl.stlModel): + def __init__(self, filename): + super(ProjectObject, self).__init__() + + self.load(filename) + + self.filename = filename + self.scale = 1.0 + self.rotate = 0.0 + self.flipX = False + self.flipY = False + self.flipZ = False + self.swapXZ = False + self.swapYZ = False + self.extruder = 0 + + self.modelDisplayList = None + self.modelDirty = False + + self.origonalVertexes = list(self.vertexes) + for i in xrange(0, len(self.origonalVertexes)): + self.origonalVertexes[i] = self.origonalVertexes[i].copy() + self.getMinimumZ() + + self.centerX = -self.getMinimum().x + 5 + self.centerY = -self.getMinimum().y + 5 + + self.updateModelTransform() + + self.centerX = -self.getMinimum().x + 5 + self.centerY = -self.getMinimum().y + 5 + + def updateModelTransform(self): + rotate = self.rotate / 180.0 * math.pi + scaleX = 1.0 + scaleY = 1.0 + scaleZ = 1.0 + if self.flipX: + scaleX = -scaleX + if self.flipY: + scaleY = -scaleY + if self.flipZ: + scaleZ = -scaleZ + swapXZ = self.swapXZ + swapYZ = self.swapYZ + mat00 = math.cos(rotate) * scaleX + mat01 =-math.sin(rotate) * scaleY + mat10 = math.sin(rotate) * scaleX + mat11 = math.cos(rotate) * scaleY + + for i in xrange(0, len(self.origonalVertexes)): + x = self.origonalVertexes[i].x + y = self.origonalVertexes[i].y + z = self.origonalVertexes[i].z + if swapXZ: + x, z = z, x + if swapYZ: + y, z = z, y + self.vertexes[i].x = x * mat00 + y * mat01 + self.vertexes[i].y = x * mat10 + y * mat11 + self.vertexes[i].z = z * scaleZ + + for face in self.faces: + v1 = face.v[0] + v2 = face.v[1] + v3 = face.v[2] + face.normal = (v2 - v1).cross(v3 - v1) + face.normal.normalize() + + minZ = self.getMinimumZ() + minV = self.getMinimum() + maxV = self.getMaximum() + for v in self.vertexes: + v.z -= minZ + v.x -= minV.x + (maxV.x - minV.x) / 2 + v.y -= minV.y + (maxV.y - minV.y) / 2 + self.getMinimumZ() + self.modelDirty = True + + def clone(self): + p = ProjectObject(self.filename) + + p.centerX = self.centerX + 5 + p.centerY = self.centerY + 5 + + p.filename = self.filename + p.scale = self.scale + p.rotate = self.rotate + p.flipX = self.flipX + p.flipY = self.flipY + p.flipZ = self.flipZ + p.swapXZ = self.swapXZ + p.swapYZ = self.swapYZ + p.extruder = self.extruder + + p.updateModelTransform() + + return p + class projectPlanner(wx.Frame): "Main user interface window" def __init__(self): @@ -67,6 +166,7 @@ class projectPlanner(wx.Frame): toolbarUtil.NormalButton(self.toolbar2, self.OnRemModel, 'object-remove.png', 'Remove model') toolbarUtil.NormalButton(self.toolbar2, self.OnMoveUp, 'move-up.png', 'Move model up in print list') toolbarUtil.NormalButton(self.toolbar2, self.OnMoveDown, 'move-down.png', 'Move model down in print list') + toolbarUtil.NormalButton(self.toolbar2, self.OnCopy, 'copy.png', 'Make a copy of the current selected object') self.toolbar2.Realize() sizer = wx.GridBagSizer(2,2) @@ -163,9 +263,7 @@ class projectPlanner(wx.Frame): while cp.has_section('model_%d' % (i)): section = 'model_%d' % (i) - item = stl.stlModel() - item.filename = unicode(cp.get(section, 'filename'), "utf-8") - self.loadModelFile(item) + item = ProjectObject(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')) @@ -177,7 +275,7 @@ class projectPlanner(wx.Frame): item.swapYZ = cp.get(section, 'swapYZ') == 'True' if cp.has_option(section, 'extruder'): item.extuder = int(cp.get(section, 'extruder'))-1 - self.updateModelTransform(item) + item.updateModelTransform() i += 1 self.list.append(item) @@ -185,6 +283,7 @@ class projectPlanner(wx.Frame): self.listbox.SetSelection(len(self.list)-1) self.OnListSelect(None) + self.preview.Refresh() dlg.Destroy() @@ -217,29 +316,19 @@ class projectPlanner(wx.Frame): dlg.SetWildcard("STL files (*.stl)|*.stl;*.STL") if dlg.ShowModal() == wx.ID_OK: for filename in dlg.GetPaths(): - item = stl.stlModel() - item.filename=filename + item = ProjectObject(filename) profile.putPreference('lastFile', item.filename) - if not(os.path.exists(item.filename)): - return - self.loadModelFile(item) self.list.append(item) - self.listbox.AppendAndEnsureVisible(os.path.split(item.filename)[1]) - self.listbox.SetSelection(len(self.list)-1) - self.OnListSelect(None) + self.selection = item + self._updateListbox() + self.preview.Refresh() dlg.Destroy() def OnRemModel(self, e): if self.selection == None: return self.list.remove(self.selection) - i = self.listbox.GetSelection() - self.listbox.Delete(i) - if len(self.list) > i: - self.listbox.SetSelection(i) - elif len(self.list) > 0: - self.listbox.SetSelection(len(self.list) - 1) - self.selection = None + self._updateListbox() self.preview.Refresh() def OnMoveUp(self, e): @@ -264,11 +353,29 @@ class projectPlanner(wx.Frame): self._updateListbox() self.preview.Refresh() + def OnCopy(self, e): + if self.selection == None: + return + + item = self.selection.clone() + self.list.append(item) + self.selection = item + + self._updateListbox() + self.preview.Refresh() + def _updateListbox(self): self.listbox.Clear() for item in self.list: self.listbox.AppendAndEnsureVisible(os.path.split(item.filename)[1]) - self.listbox.SetSelection(self.list.index(self.selection)) + if self.selection in self.list: + self.listbox.SetSelection(self.list.index(self.selection)) + elif len(self.list) > 0: + self.selection = self.list[0] + self.listbox.SetSelection(0) + else: + self.selection = None + self.listbox.SetSelection(-1) def OnAutoPlace(self, e): bestAllowedSize = int(self.machineSize.y) @@ -368,32 +475,6 @@ class projectPlanner(wx.Frame): pspw.Centre() pspw.Show(True) - def loadModelFile(self, item): - item.load(item.filename) - item.origonalVertexes = list(item.vertexes) - for i in xrange(0, len(item.origonalVertexes)): - item.origonalVertexes[i] = item.origonalVertexes[i].copy() - item.getMinimumZ() - - item.centerX = -item.getMinimum().x + 5 - item.centerY = -item.getMinimum().y + 5 - item.scale = 1.0 - item.rotate = 0.0 - item.flipX = False - item.flipY = False - item.flipZ = False - item.swapXZ = False - item.swapYZ = False - item.extruder = 0 - - item.modelDisplayList = None - item.modelDirty = False - - self.updateModelTransform(item) - - item.centerX = -item.getMinimum().x + 5 - item.centerY = -item.getMinimum().y + 5 - def OnScaleChange(self, e): if self.selection == None: return @@ -407,7 +488,8 @@ class projectPlanner(wx.Frame): if self.selection == None: return self.selection.rotate = float(self.rotateCtrl.GetValue()) - self.updateModelTransform(self.selection) + self.selection.updateModelTransform() + self.preview.Refresh() def OnExtruderChange(self, e): if self.selection == None: @@ -415,57 +497,6 @@ class projectPlanner(wx.Frame): self.selection.extruder = int(self.extruderCtrl.GetValue()) - 1 self.preview.Refresh() - def updateModelTransform(self, item): - rotate = item.rotate / 180.0 * math.pi - scaleX = 1.0 - scaleY = 1.0 - scaleZ = 1.0 - if item.flipX: - scaleX = -scaleX - if item.flipY: - scaleY = -scaleY - if item.flipZ: - scaleZ = -scaleZ - swapXZ = item.swapXZ - swapYZ = item.swapYZ - mat00 = math.cos(rotate) * scaleX - mat01 =-math.sin(rotate) * scaleY - mat10 = math.sin(rotate) * scaleX - mat11 = math.cos(rotate) * scaleY - - for i in xrange(0, len(item.origonalVertexes)): - x = item.origonalVertexes[i].x - y = item.origonalVertexes[i].y - z = item.origonalVertexes[i].z - if swapXZ: - x, z = z, x - if swapYZ: - y, z = z, y - item.vertexes[i].x = x * mat00 + y * mat01 - item.vertexes[i].y = x * mat10 + y * mat11 - item.vertexes[i].z = z * scaleZ - - for face in item.faces: - v1 = face.v[0] - v2 = face.v[1] - v3 = face.v[2] - face.normal = (v2 - v1).cross(v3 - v1) - face.normal.normalize() - - self.moveModel(item) - - def moveModel(self, item): - minZ = item.getMinimumZ() - min = item.getMinimum() - max = item.getMaximum() - for v in item.vertexes: - v.z -= minZ - v.x -= min.x + (max.x - min.x) / 2 - v.y -= min.y + (max.y - min.y) / 2 - item.getMinimumZ() - item.modelDirty = True - self.preview.Refresh() - class PreviewGLCanvas(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) diff --git a/Cura/gui/validators.py b/Cura/gui/validators.py index b1da7783..f29e8d1e 100644 --- a/Cura/gui/validators.py +++ b/Cura/gui/validators.py @@ -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) diff --git a/Cura/util/gcodeInterpreter.py b/Cura/util/gcodeInterpreter.py index 3af69bb4..5714972c 100644 --- a/Cura/util/gcodeInterpreter.py +++ b/Cura/util/gcodeInterpreter.py @@ -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 = [] diff --git a/Cura/util/stl.py b/Cura/util/stl.py index 9b1323a2..bf7558b4 100644 --- a/Cura/util/stl.py +++ b/Cura/util/stl.py @@ -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 = [] diff --git a/Cura/util/util3d.py b/Cura/util/util3d.py index 30b25159..d5411fc9 100644 --- a/Cura/util/util3d.py +++ b/Cura/util/util3d.py @@ -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