Added my own STL loader, no longer using the one from Skeinforge. This one is 3 to 4 times faster.

master
daid 2012-03-28 16:53:08 +02:00
parent 405f4880cd
commit 0834aec2d2
5 changed files with 111 additions and 21 deletions

View File

@ -1,7 +1,3 @@
"""
This page is in the table of contents.
This is required to workaround the python import bug where relative imports don't work if the module is imported as a main module.
"""
import os
import sys

View File

@ -19,11 +19,9 @@ except:
from util import profile
from util import gcodeInterpreter
from util import stl
from util import util3d
from fabmetheus_utilities.fabmetheus_tools import fabmetheus_interpret
from fabmetheus_utilities.vector3 import Vector3
class previewPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent,-1)
@ -38,8 +36,8 @@ class previewPanel(wx.Panel):
self.modelFilename = None
self.loadingProgressAmount = 0
self.loadThread = None
self.machineSize = Vector3(float(profile.getPreference('machine_width')), float(profile.getPreference('machine_depth')), float(profile.getPreference('machine_height')))
self.machineCenter = Vector3(0, 0, 0)
self.machineSize = util3d.Vector3(float(profile.getPreference('machine_width')), float(profile.getPreference('machine_depth')), float(profile.getPreference('machine_height')))
self.machineCenter = util3d.Vector3(0, 0, 0)
self.toolbar = wx.ToolBar( self, -1 )
self.toolbar.SetToolBitmapSize( ( 21, 21 ) )
@ -215,7 +213,8 @@ class previewPanel(wx.Panel):
def doFileLoadThread(self):
if os.path.isfile(self.modelFilename) and self.modelFileTime != os.stat(self.modelFilename).st_mtime:
self.modelFileTime = os.stat(self.modelFilename).st_mtime
triangleMesh = fabmetheus_interpret.getCarving(self.modelFilename)
triangleMesh = stl.stlModel()
triangleMesh.load(self.modelFilename)
triangleMesh.origonalVertexes = list(triangleMesh.vertexes)
for i in xrange(0, len(triangleMesh.origonalVertexes)):
triangleMesh.origonalVertexes[i] = triangleMesh.origonalVertexes[i].copy()
@ -297,9 +296,9 @@ class previewPanel(wx.Panel):
self.triangleMesh.vertexes[i].z = self.triangleMesh.origonalVertexes[i].z * scaleZ
for face in self.triangleMesh.faces:
v1 = self.triangleMesh.vertexes[face.vertexIndexes[0]]
v2 = self.triangleMesh.vertexes[face.vertexIndexes[1]]
v3 = self.triangleMesh.vertexes[face.vertexIndexes[2]]
v1 = face.v[0]
v2 = face.v[1]
v3 = face.v[2]
face.normal = (v2 - v1).cross(v3 - v1)
face.normal.normalize()
@ -309,8 +308,8 @@ class previewPanel(wx.Panel):
if self.triangleMesh == None:
return
minZ = self.triangleMesh.getMinimumZ()
min = self.triangleMesh.getCarveCornerMinimum()
max = self.triangleMesh.getCarveCornerMaximum()
min = self.triangleMesh.getMinimum()
max = self.triangleMesh.getMaximum()
for v in self.triangleMesh.vertexes:
v.z -= minZ
v.x -= min.x + (max.x - min.x) / 2
@ -525,7 +524,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
self.parent.modelDirty = False
multiX = int(profile.getProfileSetting('model_multiply_x'))
multiY = int(profile.getProfileSetting('model_multiply_y'))
modelSize = self.parent.triangleMesh.getCarveCornerMaximum() - self.parent.triangleMesh.getCarveCornerMinimum()
modelSize = self.parent.triangleMesh.getMaximum() - self.parent.triangleMesh.getMinimum()
glNewList(self.modelDisplayList, GL_COMPILE)
glPushMatrix()
glTranslate(-(modelSize.x+10)*(multiX-1)/2,-(modelSize.y+10)*(multiY-1)/2, 0)
@ -535,9 +534,9 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glPushMatrix()
glTranslate((modelSize.x+10)*mx,(modelSize.y+10)*my, 0)
glBegin(GL_TRIANGLES)
v1 = self.parent.triangleMesh.vertexes[face.vertexIndexes[0]]
v2 = self.parent.triangleMesh.vertexes[face.vertexIndexes[1]]
v3 = self.parent.triangleMesh.vertexes[face.vertexIndexes[2]]
v1 = face.v[0]
v2 = face.v[1]
v3 = face.v[2]
glNormal3f(face.normal.x, face.normal.y, face.normal.z)
glVertex3f(v1.x, v1.y, v1.z)
glVertex3f(v2.x, v2.y, v2.z)
@ -664,7 +663,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glRotate(-self.pitch, 1,0,0)
glRotate(self.yaw, 0,0,1)
if self.parent.triangleMesh != None:
glTranslate(0,0,-self.parent.triangleMesh.getCarveCornerMaximum().z / 2)
glTranslate(0,0,-self.parent.triangleMesh.getMaximum().z / 2)
else:
glTranslate(self.offsetX, self.offsetY, 0)

View File

@ -0,0 +1,9 @@
import os
import sys
numberOfLevelsDeepInPackageHierarchy = 1
packageFilePath = os.path.abspath(__file__)
for level in range( numberOfLevelsDeepInPackageHierarchy + 1 ):
packageFilePath = os.path.dirname( packageFilePath )
if packageFilePath not in sys.path:
sys.path.insert( 0, packageFilePath )

View File

@ -3,7 +3,6 @@ import __init__
import sys
import math
import threading
import re
import os

87
Cura/util/stl.py Normal file
View File

@ -0,0 +1,87 @@
from __future__ import absolute_import
import __init__
import sys
import math
import re
import os
import struct
from util import util3d
class stlFace():
def __init__(self, v0, v1, v2):
self.v = [v0, v1, v2]
class stlModel():
def __init__(self):
self.faces = []
self.vertexes = []
def load(self, filename):
f = open(filename, "rb")
if f.read(6).lower() == "solid ":
self._loadAscii(f)
if len(self.faces) < 1:
f.seek(6, os.SEEK_SET)
self._loadBinary(f)
else:
self._loadBinary(f)
f.close()
def _loadAscii(self, f):
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.faces.append(stlFace(v0, v1, v2))
self.vertexes.append(v0)
self.vertexes.append(v1)
self.vertexes.append(v2)
cnt = 0
def _loadBinary(self, f):
#Skip the header
f.read(80-6)
faceCount = struct.unpack('<I', f.read(4))[0]
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.faces.append(stlFace(v0, v1, v2))
self.vertexes.append(v0)
self.vertexes.append(v1)
self.vertexes.append(v2)
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
return self.min.z
def getMaximum(self):
return self.max
def getMinimum(self):
return self.min
if __name__ == '__main__':
for filename in sys.argv[1:]:
stlModel().load(filename)