chiark / gitweb /
Increase performance and decrease memory usage by using numpy library for 3D models...
authordaid <daid303@gmail.com>
Thu, 26 Jul 2012 14:30:43 +0000 (16:30 +0200)
committerdaid <daid303@gmail.com>
Thu, 26 Jul 2012 14:30:43 +0000 (16:30 +0200)
Cura/gui/opengl.py
Cura/gui/preview3d.py
Cura/gui/projectPlanner.py
Cura/util/mesh.py
Cura/util/stl.py
Cura/util/util3d.py

index ab685d59ccd263abcb5a01530d93c46d72482462..1c385e5965d05703a29eb25c3e6cdc060c7141a0 100644 (file)
@@ -180,44 +180,44 @@ def ResetMatrixRotationAndScale():
 \r
 def DrawBox(vMin, vMax):\r
        glBegin(GL_LINE_LOOP)\r
-       glVertex3f(vMin.x, vMin.y, vMin.z)\r
-       glVertex3f(vMax.x, vMin.y, vMin.z)\r
-       glVertex3f(vMax.x, vMax.y, vMin.z)\r
-       glVertex3f(vMin.x, vMax.y, vMin.z)\r
+       glVertex3f(vMin[0], vMin[1], vMin[2])\r
+       glVertex3f(vMax[0], vMin[1], vMin[2])\r
+       glVertex3f(vMax[0], vMax[1], vMin[2])\r
+       glVertex3f(vMin[0], vMax[1], vMin[2])\r
        glEnd()\r
 \r
        glBegin(GL_LINE_LOOP)\r
-       glVertex3f(vMin.x, vMin.y, vMax.z)\r
-       glVertex3f(vMax.x, vMin.y, vMax.z)\r
-       glVertex3f(vMax.x, vMax.y, vMax.z)\r
-       glVertex3f(vMin.x, vMax.y, vMax.z)\r
+       glVertex3f(vMin[0], vMin[1], vMax[2])\r
+       glVertex3f(vMax[0], vMin[1], vMax[2])\r
+       glVertex3f(vMax[0], vMax[1], vMax[2])\r
+       glVertex3f(vMin[0], vMax[1], vMax[2])\r
        glEnd()\r
        glBegin(GL_LINES)\r
-       glVertex3f(vMin.x, vMin.y, vMin.z)\r
-       glVertex3f(vMin.x, vMin.y, vMax.z)\r
-       glVertex3f(vMax.x, vMin.y, vMin.z)\r
-       glVertex3f(vMax.x, vMin.y, vMax.z)\r
-       glVertex3f(vMax.x, vMax.y, vMin.z)\r
-       glVertex3f(vMax.x, vMax.y, vMax.z)\r
-       glVertex3f(vMin.x, vMax.y, vMin.z)\r
-       glVertex3f(vMin.x, vMax.y, vMax.z)\r
+       glVertex3f(vMin[0], vMin[1], vMin[2])\r
+       glVertex3f(vMin[0], vMin[1], vMax[2])\r
+       glVertex3f(vMax[0], vMin[1], vMin[2])\r
+       glVertex3f(vMax[0], vMin[1], vMax[2])\r
+       glVertex3f(vMax[0], vMax[1], vMin[2])\r
+       glVertex3f(vMax[0], vMax[1], vMax[2])\r
+       glVertex3f(vMin[0], vMax[1], vMin[2])\r
+       glVertex3f(vMin[0], vMax[1], vMax[2])\r
        glEnd()\r
 \r
 def DrawSTL(mesh):\r
        glEnable(GL_CULL_FACE)\r
-       for face in mesh.faces:\r
+       for i in xrange(0, mesh.vertexCount, 3):\r
                glBegin(GL_TRIANGLES)\r
-               v1 = face.v[0]\r
-               v2 = face.v[1]\r
-               v3 = face.v[2]\r
-               glNormal3f(face.normal.x, face.normal.y, face.normal.z)\r
-               glVertex3f(v1.x, v1.y, v1.z)\r
-               glVertex3f(v2.x, v2.y, v2.z)\r
-               glVertex3f(v3.x, v3.y, v3.z)\r
-               glNormal3f(-face.normal.x, -face.normal.y, -face.normal.z)\r
-               glVertex3f(v1.x, v1.y, v1.z)\r
-               glVertex3f(v3.x, v3.y, v3.z)\r
-               glVertex3f(v2.x, v2.y, v2.z)\r
+               v1 = mesh.vertexes[i]\r
+               v2 = mesh.vertexes[i+1]\r
+               v3 = mesh.vertexes[i+2]\r
+               glNormal3f(mesh.normal[i/3][0], mesh.normal[i/3][1], mesh.normal[i/3][2])\r
+               glVertex3f(v1[0], v1[1], v1[2])\r
+               glVertex3f(v2[0], v2[1], v2[2])\r
+               glVertex3f(v3[0], v3[1], v3[2])\r
+               glNormal3f(-mesh.normal[i/3][0], -mesh.normal[i/3][1], -mesh.normal[i/3][2])\r
+               glVertex3f(v1[0], v1[1], v1[2])\r
+               glVertex3f(v2[0], v2[1], v2[2])\r
+               glVertex3f(v3[0], v3[1], v3[2])\r
                glEnd()\r
 \r
 def DrawGCodeLayer(layer):\r
index 9adf007305bed2a1ee19de480b988e7ec4b26e89..ef27dc04b9ab8852e609b916d9e44b5471b25c31 100644 (file)
@@ -1,6 +1,7 @@
 from __future__ import division\r
 \r
 import sys, math, threading, re, time, os\r
+import numpy\r
 \r
 from wx import glcanvas\r
 import wx\r
@@ -170,11 +171,11 @@ class previewPanel(wx.Panel):
                        return\r
                vMin = self.objectsMinV\r
                vMax = self.objectsMaxV\r
-               scaleX1 = (self.machineSize.x - self.machineCenter.x) / ((vMax.x - vMin.x) / 2)\r
-               scaleY1 = (self.machineSize.y - self.machineCenter.y) / ((vMax.y - vMin.y) / 2)\r
-               scaleX2 = (self.machineCenter.x) / ((vMax.x - vMin.x) / 2)\r
-               scaleY2 = (self.machineCenter.y) / ((vMax.y - vMin.y) / 2)\r
-               scaleZ = self.machineSize.z / (vMax.z - vMin.z)\r
+               scaleX1 = (self.machineSize.x - self.machineCenter.x) / ((vMax[0] - vMin[0]) / 2)\r
+               scaleY1 = (self.machineSize.y - self.machineCenter.y) / ((vMax[1] - vMin[1]) / 2)\r
+               scaleX2 = (self.machineCenter.x) / ((vMax[0] - vMin[1]) / 2)\r
+               scaleY2 = (self.machineCenter.y) / ((vMax[1] - vMin[1]) / 2)\r
+               scaleZ = self.machineSize.z / (vMax[2] - vMin[2])\r
                scale = min(scaleX1, scaleY1, scaleX2, scaleY2, scaleZ)\r
                self.scale.SetValue(str(scale))\r
                profile.putProfileSetting('model_scale', self.scale.GetValue())\r
@@ -356,8 +357,8 @@ class previewPanel(wx.Panel):
                                continue\r
 \r
                        obj.mesh.getMinimumZ()\r
-                       minV = minV.min(obj.mesh.getMinimum())\r
-                       maxV = maxV.max(obj.mesh.getMaximum())\r
+                       minV = numpy.minimum(minV, obj.mesh.getMinimum())\r
+                       maxV = numpy.maximum(maxV, obj.mesh.getMaximum())\r
 \r
                self.objectsMaxV = maxV\r
                self.objectsMinV = minV\r
@@ -365,10 +366,11 @@ class previewPanel(wx.Panel):
                        if obj.mesh == None:\r
                                continue\r
 \r
-                       for v in obj.mesh.vertexes:\r
-                               v.z -= minV.z\r
-                               v.x -= minV.x + (maxV.x - minV.x) / 2\r
-                               v.y -= minV.y + (maxV.y - minV.y) / 2\r
+                       obj.mesh.vertexes -= numpy.array([minV[0] + (maxV[0] - minV[0]) / 2, minV[1] + (maxV[1] - minV[1]) / 2, minV[2]])\r
+                       #for v in obj.mesh.vertexes:\r
+                       #       v[2] -= minV[2]\r
+                       #       v[0] -= minV[0] + (maxV[0] - minV[0]) / 2\r
+                       #       v[1] -= minV[1] + (maxV[1] - minV[1]) / 2\r
                        obj.mesh.getMinimumZ()\r
                        obj.dirty = True\r
                self.glCanvas.Refresh()\r
@@ -461,7 +463,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
                                        glTranslate(0,0,-self.parent.gcode.layerList[self.parent.layerSpin.GetValue()][0].list[-1].z)\r
                        else:\r
                                if self.parent.objectsMaxV != None:\r
-                                       glTranslate(0,0,-self.parent.objectsMaxV.z * profile.getProfileSettingFloat('model_scale') / 2)\r
+                                       glTranslate(0,0,-self.parent.objectsMaxV[2] * profile.getProfileSettingFloat('model_scale') / 2)\r
                else:\r
                        glScale(1.0/self.zoom, 1.0/self.zoom, 1.0)\r
                        glTranslate(self.offsetX, self.offsetY, 0.0)\r
@@ -610,11 +612,11 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
                modelScale = profile.getProfileSettingFloat('model_scale')\r
                modelSize = (obj.mesh.getMaximum() - obj.mesh.getMinimum()) * modelScale\r
                glPushMatrix()\r
-               glTranslate(-(modelSize.x+10)*(multiX-1)/2,-(modelSize.y+10)*(multiY-1)/2, 0)\r
+               glTranslate(-(modelSize[0]+10)*(multiX-1)/2,-(modelSize[1]+10)*(multiY-1)/2, 0)\r
                for mx in xrange(0, multiX):\r
                        for my in xrange(0, multiY):\r
                                glPushMatrix()\r
-                               glTranslate((modelSize.x+10)*mx,(modelSize.y+10)*my, 0)\r
+                               glTranslate((modelSize[0]+10)*mx,(modelSize[1]+10)*my, 0)\r
                                glScalef(modelScale, modelScale, modelScale)\r
                                glCallList(obj.displayList)\r
                                glPopMatrix()\r
index 951037bd5af2810649a6fff2cbb99d674449358c..f09d999a1b47c8bf9f1a468916f3ed53cff922f9 100644 (file)
@@ -3,9 +3,9 @@ import __init__
 \r
 import wx, os, platform, types, webbrowser, math, subprocess, threading, time, re\r
 import ConfigParser\r
+import numpy\r
 \r
 from wx import glcanvas\r
-import wx\r
 try:\r
        import OpenGL\r
        OpenGL.ERROR_CHECKING = False\r
@@ -55,18 +55,15 @@ class ProjectObject(stl.stlModel):
                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
+               self.centerX = -self.getMinimum()[0] + 5\r
+               self.centerY = -self.getMinimum()[1] + 5\r
                \r
                self.updateModelTransform()\r
 \r
-               self.centerX = -self.getMinimum().x + 5\r
-               self.centerY = -self.getMinimum().y + 5\r
+               self.centerX = -self.getMinimum()[0] + 5\r
+               self.centerY = -self.getMinimum()[1] + 5\r
 \r
        def isSameExceptForPosition(self, other):\r
                if self.filename != other.filename:\r
@@ -96,10 +93,7 @@ class ProjectObject(stl.stlModel):
                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.vertexes -= numpy.array([minV[0] + (maxV[0] - minV[0]) / 2, minV[1] + (maxV[1] - minV[1]) / 2, minZ])\r
                minZ = self.getMinimumZ()\r
                self.modelDirty = True\r
        \r
@@ -125,14 +119,14 @@ class ProjectObject(stl.stlModel):
                return p\r
        \r
        def clampXY(self):\r
-               if self.centerX < -self.getMinimum().x * self.scale + self.parent.extruderOffset[self.extruder].x:\r
-                       self.centerX = -self.getMinimum().x * self.scale + self.parent.extruderOffset[self.extruder].x\r
-               if self.centerY < -self.getMinimum().y * self.scale + self.parent.extruderOffset[self.extruder].y:\r
-                       self.centerY = -self.getMinimum().y * self.scale + self.parent.extruderOffset[self.extruder].y\r
-               if self.centerX > self.parent.machineSize.x + self.parent.extruderOffset[self.extruder].x - self.getMaximum().x * self.scale:\r
-                       self.centerX = self.parent.machineSize.x + self.parent.extruderOffset[self.extruder].x - self.getMaximum().x * self.scale\r
-               if self.centerY > self.parent.machineSize.y + self.parent.extruderOffset[self.extruder].y - self.getMaximum().y * self.scale:\r
-                       self.centerY = self.parent.machineSize.y + self.parent.extruderOffset[self.extruder].y - self.getMaximum().y * self.scale\r
+               if self.centerX < -self.getMinimum()[0] * self.scale + self.parent.extruderOffset[self.extruder][0]:\r
+                       self.centerX = -self.getMinimum()[0] * self.scale + self.parent.extruderOffset[self.extruder][0]\r
+               if self.centerY < -self.getMinimum()[1] * self.scale + self.parent.extruderOffset[self.extruder][1]:\r
+                       self.centerY = -self.getMinimum()[1] * self.scale + self.parent.extruderOffset[self.extruder][1]\r
+               if self.centerX > self.parent.machineSize[0] + self.parent.extruderOffset[self.extruder][0] - self.getMaximum()[0] * self.scale:\r
+                       self.centerX = self.parent.machineSize[0] + self.parent.extruderOffset[self.extruder][0] - self.getMaximum()[0] * self.scale\r
+               if self.centerY > self.parent.machineSize[1] + self.parent.extruderOffset[self.extruder][1] - self.getMaximum()[1] * self.scale:\r
+                       self.centerY = self.parent.machineSize[1] + self.parent.extruderOffset[self.extruder][1] - self.getMaximum()[1] * self.scale\r
 \r
 class projectPlanner(wx.Frame):\r
        "Main user interface window"\r
@@ -151,15 +145,15 @@ class projectPlanner(wx.Frame):
                self.selection = None\r
                self.printMode = 0\r
 \r
-               self.machineSize = util3d.Vector3(profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height'))\r
-               self.headSizeMin = util3d.Vector3(profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0)\r
-               self.headSizeMax = util3d.Vector3(profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_max_y'),0)\r
+               self.machineSize = numpy.array([profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')])\r
+               self.headSizeMin = numpy.array([profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0])\r
+               self.headSizeMax = numpy.array([profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_max_y'),0])\r
 \r
                self.extruderOffset = [\r
-                       util3d.Vector3(0,0,0),\r
-                       util3d.Vector3(profile.getPreferenceFloat('extruder_offset_x1'), profile.getPreferenceFloat('extruder_offset_y1'), 0),\r
-                       util3d.Vector3(profile.getPreferenceFloat('extruder_offset_x2'), profile.getPreferenceFloat('extruder_offset_y2'), 0),\r
-                       util3d.Vector3(profile.getPreferenceFloat('extruder_offset_x3'), profile.getPreferenceFloat('extruder_offset_y3'), 0)]\r
+                       numpy.array([0,0,0]),\r
+                       numpy.array([profile.getPreferenceFloat('extruder_offset_x1'), profile.getPreferenceFloat('extruder_offset_y1'), 0]),\r
+                       numpy.array([profile.getPreferenceFloat('extruder_offset_x2'), profile.getPreferenceFloat('extruder_offset_y2'), 0]),\r
+                       numpy.array([profile.getPreferenceFloat('extruder_offset_x3'), profile.getPreferenceFloat('extruder_offset_y3'), 0])]\r
 \r
                self.toolbar = toolbarUtil.Toolbar(self.panel)\r
 \r
@@ -392,7 +386,7 @@ class projectPlanner(wx.Frame):
 \r
        def OnTopClick(self):\r
                self.preview.view3D = False\r
-               self.preview.zoom = self.machineSize.x / 2 + 10\r
+               self.preview.zoom = self.machineSize[0] / 2 + 10\r
                self.preview.offsetX = 0\r
                self.preview.offsetY = 0\r
                self.preview.Refresh()\r
@@ -499,9 +493,9 @@ class projectPlanner(wx.Frame):
                        self.listbox.SetSelection(-1)\r
 \r
        def OnAutoPlace(self, e):\r
-               bestAllowedSize = int(self.machineSize.y)\r
+               bestAllowedSize = int(self.machineSize[1])\r
                bestArea = self._doAutoPlace(bestAllowedSize)\r
-               for i in xrange(10, int(self.machineSize.y), 10):\r
+               for i in xrange(10, int(self.machineSize[1]), 10):\r
                        area = self._doAutoPlace(i)\r
                        if area < bestArea:\r
                                bestAllowedSize = i\r
@@ -516,18 +510,18 @@ class projectPlanner(wx.Frame):
                extraSizeMax = self.headSizeMax\r
                if profile.getProfileSettingFloat('skirt_line_count') > 0:\r
                        skirtSize = profile.getProfileSettingFloat('skirt_line_count') * profile.calculateEdgeWidth() + profile.getProfileSettingFloat('skirt_gap')\r
-                       extraSizeMin = extraSizeMin + util3d.Vector3(skirtSize, skirtSize, 0)\r
-                       extraSizeMax = extraSizeMax + util3d.Vector3(skirtSize, skirtSize, 0)\r
+                       extraSizeMin = extraSizeMin + numpy.array([skirtSize, skirtSize, 0])\r
+                       extraSizeMax = extraSizeMax + numpy.array([skirtSize, skirtSize, 0])\r
                if profile.getProfileSetting('support') != 'None':\r
-                       extraSizeMin = extraSizeMin + util3d.Vector3(3.0, 0, 0)\r
-                       extraSizeMax = extraSizeMax + util3d.Vector3(3.0, 0, 0)\r
+                       extraSizeMin = extraSizeMin + numpy.array([3.0, 0, 0])\r
+                       extraSizeMax = extraSizeMax + numpy.array([3.0, 0, 0])\r
                \r
                if self.printMode == 1:\r
-                       extraSizeMin = util3d.Vector3(6.0, 6.0, 0)\r
-                       extraSizeMax = util3d.Vector3(6.0, 6.0, 0)\r
+                       extraSizeMin = numpy.array([6.0, 6.0, 0])\r
+                       extraSizeMax = numpy.array([6.0, 6.0, 0])\r
 \r
-               if extraSizeMin.x > extraSizeMax.x:\r
-                       posX = self.machineSize.x\r
+               if extraSizeMin[0] > extraSizeMax[0]:\r
+                       posX = self.machineSize[0]\r
                        dirX = -1\r
                else:\r
                        posX = 0\r
@@ -535,35 +529,35 @@ class projectPlanner(wx.Frame):
                posY = 0\r
                dirY = 1\r
                \r
-               minX = self.machineSize.x\r
-               minY = self.machineSize.y\r
+               minX = self.machineSize[0]\r
+               minY = self.machineSize[1]\r
                maxX = 0\r
                maxY = 0\r
                for item in self.list:\r
-                       item.centerX = posX + item.getMaximum().x * item.scale * dirX\r
-                       item.centerY = posY + item.getMaximum().y * item.scale * dirY\r
-                       if item.centerY + item.getSize().y >= allowedSizeY:\r
+                       item.centerX = posX + item.getMaximum()[0] * item.scale * dirX\r
+                       item.centerY = posY + item.getMaximum()[1] * item.scale * dirY\r
+                       if item.centerY + item.getSize()[1] >= allowedSizeY:\r
                                if dirX < 0:\r
-                                       posX = minX - extraSizeMax.x - 1\r
+                                       posX = minX - extraSizeMax[0] - 1\r
                                else:\r
-                                       posX = maxX + extraSizeMin.x + 1\r
+                                       posX = maxX + extraSizeMin[0] + 1\r
                                posY = 0\r
-                               item.centerX = posX + item.getMaximum().x * item.scale * dirX\r
-                               item.centerY = posY + item.getMaximum().y * item.scale * dirY\r
-                       posY += item.getSize().y  * item.scale * dirY + extraSizeMin.y + 1\r
-                       minX = min(minX, item.centerX - item.getSize().x * item.scale / 2)\r
-                       minY = min(minY, item.centerY - item.getSize().y * item.scale / 2)\r
-                       maxX = max(maxX, item.centerX + item.getSize().x * item.scale / 2)\r
-                       maxY = max(maxY, item.centerY + item.getSize().y * item.scale / 2)\r
+                               item.centerX = posX + item.getMaximum()[0] * item.scale * dirX\r
+                               item.centerY = posY + item.getMaximum()[1] * item.scale * dirY\r
+                       posY += item.getSize()[1]  * item.scale * dirY + extraSizeMin[1] + 1\r
+                       minX = min(minX, item.centerX - item.getSize()[0] * item.scale / 2)\r
+                       minY = min(minY, item.centerY - item.getSize()[1] * item.scale / 2)\r
+                       maxX = max(maxX, item.centerX + item.getSize()[0] * item.scale / 2)\r
+                       maxY = max(maxY, item.centerY + item.getSize()[1] * item.scale / 2)\r
                \r
                for item in self.list:\r
                        if dirX < 0:\r
                                item.centerX -= minX / 2\r
                        else:\r
-                               item.centerX += (self.machineSize.x - maxX) / 2\r
-                       item.centerY += (self.machineSize.y - maxY) / 2\r
+                               item.centerX += (self.machineSize[0] - maxX) / 2\r
+                       item.centerY += (self.machineSize[1] - maxY) / 2\r
                \r
-               if minX < 0 or maxX > self.machineSize.x:\r
+               if minX < 0 or maxX > self.machineSize[0]:\r
                        return ((maxX - minX) + (maxY - minY)) * 100\r
                \r
                return (maxX - minX) + (maxY - minY)\r
@@ -590,8 +584,8 @@ class projectPlanner(wx.Frame):
                        for item in self.list:\r
                                if item.profile != None and os.path.isfile(item.profile):\r
                                        profile.loadGlobalProfile(item.profile)\r
-                               put('machine_center_x', item.centerX - self.extruderOffset[item.extruder].x)\r
-                               put('machine_center_y', item.centerY - self.extruderOffset[item.extruder].y)\r
+                               put('machine_center_x', item.centerX - self.extruderOffset[item.extruder][0])\r
+                               put('machine_center_y', item.centerY - self.extruderOffset[item.extruder][1])\r
                                put('model_scale', item.scale)\r
                                put('flip_x', item.flipX)\r
                                put('flip_y', item.flipY)\r
@@ -607,7 +601,7 @@ class projectPlanner(wx.Frame):
                                action.temperature = profile.getProfileSettingFloat('print_temperature')\r
                                action.extruder = item.extruder\r
                                action.filename = item.filename\r
-                               clearZ = max(clearZ, item.getMaximum().z * item.scale + 5.0)\r
+                               clearZ = max(clearZ, item.getMaximum()[2] * item.scale + 5.0)\r
                                action.clearZ = clearZ\r
                                action.leaveResultForNextSlice = False\r
                                action.usePreviousSlice = False\r
@@ -698,7 +692,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
                wx.EVT_MOUSEWHEEL(self, self.OnMouseWheel)\r
                self.yaw = 30\r
                self.pitch = 60\r
-               self.zoom = self.parent.machineSize.x / 2 + 10\r
+               self.zoom = self.parent.machineSize[0] / 2 + 10\r
                self.offsetX = 0\r
                self.offsetY = 0\r
                self.view3D = False\r
@@ -760,32 +754,30 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
                        glTranslate(0,0,-self.zoom)\r
                        glRotate(-self.pitch, 1,0,0)\r
                        glRotate(self.yaw, 0,0,1)\r
-                       if False: #self.parent.triangleMesh != None:\r
-                               glTranslate(0,0,-self.parent.triangleMesh.getMaximum().z / 2)\r
                else:\r
                        glScale(1.0/self.zoom, 1.0/self.zoom, 1.0)\r
                        glTranslate(self.offsetX, self.offsetY, 0.0)\r
-               glTranslate(-self.parent.machineSize.x/2, -self.parent.machineSize.y/2, 0)\r
+               glTranslate(-self.parent.machineSize[0]/2, -self.parent.machineSize[1]/2, 0)\r
 \r
                self.OnDraw()\r
                self.SwapBuffers()\r
 \r
        def OnDraw(self):\r
                machineSize = self.parent.machineSize\r
-               opengl.DrawMachine(machineSize)\r
+               opengl.DrawMachine(util3d.Vector3(machineSize[0], machineSize[1], machineSize[2]))\r
                extraSizeMin = self.parent.headSizeMin\r
                extraSizeMax = self.parent.headSizeMax\r
                if profile.getProfileSettingFloat('skirt_line_count') > 0:\r
                        skirtSize = profile.getProfileSettingFloat('skirt_line_count') * profile.calculateEdgeWidth() + profile.getProfileSettingFloat('skirt_gap')\r
-                       extraSizeMin = extraSizeMin + util3d.Vector3(skirtSize, skirtSize, 0)\r
-                       extraSizeMax = extraSizeMax + util3d.Vector3(skirtSize, skirtSize, 0)\r
+                       extraSizeMin = extraSizeMin + numpy.array([skirtSize, skirtSize, 0])\r
+                       extraSizeMax = extraSizeMax + numpy.array([skirtSize, skirtSize, 0])\r
                if profile.getProfileSetting('support') != 'None':\r
-                       extraSizeMin = extraSizeMin + util3d.Vector3(3.0, 0, 0)\r
-                       extraSizeMax = extraSizeMax + util3d.Vector3(3.0, 0, 0)\r
+                       extraSizeMin = extraSizeMin + numpy.array([3.0, 0, 0])\r
+                       extraSizeMax = extraSizeMax + numpy.array([3.0, 0, 0])\r
 \r
                if self.parent.printMode == 1:\r
-                       extraSizeMin = util3d.Vector3(6.0, 6.0, 0)\r
-                       extraSizeMax = util3d.Vector3(6.0, 6.0, 0)\r
+                       extraSizeMin = numpy.array([6.0, 6.0, 0])\r
+                       extraSizeMax = numpy.array([6.0, 6.0, 0])\r
 \r
                for item in self.parent.list:\r
                        item.validPlacement = True\r
@@ -793,13 +785,13 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
                \r
                for idx1 in xrange(0, len(self.parent.list)):\r
                        item = self.parent.list[idx1]\r
-                       iMin1 = item.getMinimum() * item.scale + util3d.Vector3(item.centerX, item.centerY, 0) - extraSizeMin - self.parent.extruderOffset[item.extruder]\r
-                       iMax1 = item.getMaximum() * item.scale + util3d.Vector3(item.centerX, item.centerY, 0) + extraSizeMax - self.parent.extruderOffset[item.extruder]\r
+                       iMin1 = (item.getMinimum() * item.scale) + numpy.array([item.centerX, item.centerY, 0]) - extraSizeMin - self.parent.extruderOffset[item.extruder]\r
+                       iMax1 = (item.getMaximum() * item.scale) + numpy.array([item.centerX, item.centerY, 0]) + extraSizeMax - self.parent.extruderOffset[item.extruder]\r
                        for idx2 in xrange(0, idx1):\r
                                item2 = self.parent.list[idx2]\r
-                               iMin2 = item2.getMinimum() * item2.scale + util3d.Vector3(item2.centerX, item2.centerY, 0)\r
-                               iMax2 = item2.getMaximum() * item2.scale + util3d.Vector3(item2.centerX, item2.centerY, 0)\r
-                               if item != item2 and iMax1.x >= iMin2.x and iMin1.x <= iMax2.x and iMax1.y >= iMin2.y and iMin1.y <= iMax2.y:\r
+                               iMin2 = (item2.getMinimum() * item2.scale) + numpy.array([item2.centerX, item2.centerY, 0])\r
+                               iMax2 = (item2.getMaximum() * item2.scale) + numpy.array([item2.centerX, item2.centerY, 0])\r
+                               if item != item2 and iMax1[0] >= iMin2[0] and iMin1[0] <= iMax2[0] and iMax1[1] >= iMin2[1] and iMin1[1] <= iMax2[1]:\r
                                        item.validPlacement = False\r
                                        item2.gotHit = True\r
                \r
@@ -959,8 +951,8 @@ class ProjectSliceProgressWindow(wx.Frame):
                                        line = p.stdout.readline()\r
                                self.returnCode = p.wait()\r
                        \r
-                       put('machine_center_x', action.centerX - self.extruderOffset[action.extruder].x)\r
-                       put('machine_center_y', action.centerY - self.extruderOffset[action.extruder].y)\r
+                       put('machine_center_x', action.centerX - self.extruderOffset[action.extruder][0])\r
+                       put('machine_center_y', action.centerY - self.extruderOffset[action.extruder][1])\r
                        put('clear_z', action.clearZ)\r
                        put('extruder', action.extruder)\r
                        put('print_temperature', action.temperature)\r
@@ -1089,8 +1081,8 @@ class preferencesDialog(configBase.configWindowBase):
                self.Fit()\r
 \r
        def OnClose(self, e):\r
-               self.parent.headSizeMin = util3d.Vector3(profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0)\r
-               self.parent.headSizeMax = util3d.Vector3(profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_max_y'),0)\r
+               self.parent.headSizeMin = numpy.array([profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0])\r
+               self.parent.headSizeMax = numpy.array([profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_max_y'),0])\r
                self.parent.Refresh()\r
 \r
                self.MakeModal(False)\r
index 30e295210b3b59dda4a31569c9e3ee1d2fa597fe..0a943b1ef9ed4b50ed1d1362843185ae39f6255b 100644 (file)
@@ -2,41 +2,36 @@ import sys, math, re, os, struct, time
 
 import util3d
 
-class meshFace(object):
-       def __init__(self, v0, v1, v2):
-               self.v = [v0, v1, v2]
+import numpy
 
 class mesh(object):
        def __init__(self):
-               self.faces = []
-               self.vertexes = []
+               self.vertexes = None
+               self.origonalVertexes = None
+               self.vertexCount = 0
 
-       def addFace(self, v0, v1, v2):
-               self.vertexes.append(v0)
-               self.vertexes.append(v1)
-               self.vertexes.append(v2)
-               self.faces.append(meshFace(v0, v1, v2))
+       def addVertex(self, x, y, z):
+               n = self.vertexCount
+               self.origonalVertexes[n][0] = x
+               self.origonalVertexes[n][1] = y
+               self.origonalVertexes[n][2] = z
+               self.vertexCount += 1
+       
+       def _prepareVertexCount(self, vertexNumber):
+               #Set the amount of faces before loading data in them. This way we can create the numpy arrays before we fill them.
+               self.origonalVertexes = numpy.zeros((vertexNumber, 3), float)
+               self.normal = numpy.zeros((vertexNumber / 3, 3))
+               self.vertexCount = 0
 
        def _postProcessAfterLoad(self):
-               self.origonalVertexes = list(self.vertexes)
-               for i in xrange(0, len(self.origonalVertexes)):
-                       self.origonalVertexes[i] = self.origonalVertexes[i].copy()
+               self.vertexes = self.origonalVertexes.copy()
                self.getMinimumZ()
 
        def getMinimumZ(self):
-               minv = self.vertexes[0].copy()
-               maxv = self.vertexes[0].copy()
-               for v in self.vertexes:
-                       minv.x = min(minv.x, v.x)
-                       minv.y = min(minv.y, v.y)
-                       minv.z = min(minv.z, v.z)
-                       maxv.x = max(maxv.x, v.x)
-                       maxv.y = max(maxv.y, v.y)
-                       maxv.z = max(maxv.z, v.z)
-               self.min = minv
-               self.max = maxv
-               self.size = maxv - minv
-               return self.min.z
+               self.min = self.vertexes.min(0)
+               self.max = self.vertexes.max(0)
+               self.size = self.max - self.min
+               return self.min[2]
        
        def getMaximum(self):
                return self.max
@@ -62,23 +57,23 @@ class mesh(object):
                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
+                       x = self.origonalVertexes[i][0]
+                       y = self.origonalVertexes[i][1]
+                       z = self.origonalVertexes[i][2]
                        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
+                       self.vertexes[i][0] = x * mat00 + y * mat01
+                       self.vertexes[i][1] = x * mat10 + y * mat11
+                       self.vertexes[i][2] = 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()
+               for i in xrange(0, len(self.origonalVertexes), 3):
+                       v1 = self.vertexes[i]
+                       v2 = self.vertexes[i+1]
+                       v3 = self.vertexes[i+2]
+                       self.normal[i/3] = numpy.cross((v2 - v1), (v3 - v1))
+                       self.normal[i/3] /= (self.normal[i/3] * self.normal[i/3]).sum()
 
                self.getMinimumZ()
 
index 72b342541fdc58b2a92750797101f67b6143fc57..7e4226793da4c9186ae4b3f6b8a4eb865be23063 100644 (file)
@@ -1,6 +1,5 @@
 import sys, math, re, os, struct, time
 
-import util3d
 import mesh
 
 class stlModel(mesh.mesh):
@@ -11,7 +10,7 @@ class stlModel(mesh.mesh):
                f = open(filename, "rb")
                if f.read(5).lower() == "solid":
                        self._loadAscii(f)
-                       if not self.faces:
+                       if self.vertexCount < 3:
                                f.seek(5, os.SEEK_SET)
                                self._loadBinary(f)
                else:
@@ -22,31 +21,28 @@ class stlModel(mesh.mesh):
                return self
        
        def _loadAscii(self, f):
+               cnt = 0
+               for line in f:
+                       if 'vertex' in line:
+                               cnt += 1
+               self._prepareVertexCount(int(cnt))
+               f.seek(5, os.SEEK_SET)
                cnt = 0
                for line in f:
                        if 'vertex' in line:
                                data = line.split()
-                               if cnt == 0:
-                                       v0 = util3d.Vector3(float(data[1]), float(data[2]), float(data[3]))
-                                       cnt = 1
-                               elif cnt == 1:
-                                       v1 = util3d.Vector3(float(data[1]), float(data[2]), float(data[3]))
-                                       cnt = 2
-                               elif cnt == 2:
-                                       v2 = util3d.Vector3(float(data[1]), float(data[2]), float(data[3]))
-                                       self.addFace(v0, v1, v2)
-                                       cnt = 0
+                               self.addVertex(float(data[1]), float(data[2]), float(data[3]))
 
        def _loadBinary(self, f):
                #Skip the header
                f.read(80-5)
                faceCount = struct.unpack('<I', f.read(4))[0]
+               self._prepareVertexCount(faceCount * 3)
                for idx in xrange(0, faceCount):
                        data = struct.unpack("<ffffffffffffH", f.read(50))
-                       v0 = util3d.Vector3(data[3], data[4], data[5])
-                       v1 = util3d.Vector3(data[6], data[7], data[8])
-                       v2 = util3d.Vector3(data[9], data[10], data[11])
-                       self.addFace(v0, v1, v2)
+                       self.addVertex(data[3], data[4], data[5])
+                       self.addVertex(data[6], data[7], data[8])
+                       self.addVertex(data[9], data[10], data[11])
 
 def saveAsSTL(mesh, filename):
        f = open(filename, 'wb')
@@ -70,8 +66,8 @@ def saveAsSTL(mesh, filename):
 if __name__ == '__main__':
        for filename in sys.argv[1:]:
                m = stlModel().load(filename)
-               print("Loaded %d faces" % (len(m.faces)))
-               parts = m.splitToParts()
-               for p in parts:
-                       saveAsSTL(p, "export_%i.stl" % parts.index(p))
+               print("Loaded %d faces" % (m.vertexCount / 3))
+#              parts = m.splitToParts()
+#              for p in parts:
+#                      saveAsSTL(p, "export_%i.stl" % parts.index(p))
 
index 217814bec83a55ebd730e181ed49da9dffcf847c..68f0123444a3b503422fa3b58b42014a4029dd27 100644 (file)
@@ -13,7 +13,7 @@ class Vector3(object):
                return Vector3(self.x, self.y, self.z)
 
        def __repr__(self):
-               return '[%s, %s, %s]' % ( self.x, self.y, self.z )
+               return 'V[%s, %s, %s]' % ( self.x, self.y, self.z )
 
        def __add__(self, v):
                return Vector3( self.x + v.x, self.y + v.y, self.z + v.z )