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
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
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
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
\r
self.listbox.SetSelection(len(self.list)-1)\r
self.OnListSelect(None)\r
+ self.preview.Refresh()\r
\r
dlg.Destroy()\r
\r
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
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
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
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
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