From: Daid Date: Fri, 18 May 2012 08:10:51 +0000 (+0200) Subject: Abstract the 3D model related functions into a seperate class, and remove some duplic... X-Git-Tag: RC4~5 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=d03d4ac4004bb740456d833248447fa7ad4c2cd3;p=cura.git Abstract the 3D model related functions into a seperate class, and remove some duplicate code from the project planner and the 3D preview. --- diff --git a/Cura/gui/preview3d.py b/Cura/gui/preview3d.py index 50133cfb..8a1f7409 100644 --- a/Cura/gui/preview3d.py +++ b/Cura/gui/preview3d.py @@ -287,48 +287,20 @@ class previewPanel(wx.Panel): self.glCanvas.Refresh() def updateModelTransform(self, f=0): - rotate = profile.getProfileSettingFloat('model_rotate_base') / 180.0 * math.pi - scaleX = 1.0 - scaleY = 1.0 - scaleZ = 1.0 - if profile.getProfileSetting('flip_x') == 'True': - scaleX = -scaleX - if profile.getProfileSetting('flip_y') == 'True': - scaleY = -scaleY - if profile.getProfileSetting('flip_z') == 'True': - scaleZ = -scaleZ - swapXZ = profile.getProfileSetting('swap_xz') == 'True' - swapYZ = profile.getProfileSetting('swap_yz') == 'True' - mat00 = math.cos(rotate) * scaleX - mat01 =-math.sin(rotate) * scaleY - mat10 = math.sin(rotate) * scaleX - mat11 = math.cos(rotate) * scaleY - if len(self.objectList) < 1 or self.objectList[0].mesh == None: return + + rotate = profile.getProfileSettingFloat('model_rotate_base') + mirrorX = profile.getProfileSetting('flip_x') == 'True' + mirrorY = profile.getProfileSetting('flip_y') == 'True' + mirrorZ = profile.getProfileSetting('flip_z') == 'True' + swapXZ = profile.getProfileSetting('swap_xz') == 'True' + swapYZ = profile.getProfileSetting('swap_yz') == 'True' for obj in self.objectList: if obj.mesh == None: continue - - for i in xrange(0, len(obj.mesh.origonalVertexes)): - x = obj.mesh.origonalVertexes[i].x - y = obj.mesh.origonalVertexes[i].y - z = obj.mesh.origonalVertexes[i].z - if swapXZ: - x, z = z, x - if swapYZ: - y, z = z, y - obj.mesh.vertexes[i].x = x * mat00 + y * mat01 - obj.mesh.vertexes[i].y = x * mat10 + y * mat11 - obj.mesh.vertexes[i].z = z * scaleZ - - for face in obj.mesh.faces: - v1 = face.v[0] - v2 = face.v[1] - v3 = face.v[2] - face.normal = (v2 - v1).cross(v3 - v1) - face.normal.normalize() + obj.mesh.setRotateMirror(rotate, mirrorX, mirrorY, mirrorZ, swapXZ, swapYZ) minV = self.objectList[0].mesh.getMinimum() maxV = self.objectList[0].mesh.getMaximum() diff --git a/Cura/gui/projectPlanner.py b/Cura/gui/projectPlanner.py index f2dec95b..9322eef9 100644 --- a/Cura/gui/projectPlanner.py +++ b/Cura/gui/projectPlanner.py @@ -90,50 +90,7 @@ class ProjectObject(stl.stlModel): return True 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.setRotateMirror(self.rotate, self.flipX, self.flipY, self.flipZ, self.swapXZ, self.swapYZ) self.modelDirty = True def clone(self): diff --git a/Cura/util/mesh.py b/Cura/util/mesh.py new file mode 100644 index 00000000..63c105d4 --- /dev/null +++ b/Cura/util/mesh.py @@ -0,0 +1,101 @@ +from __future__ import absolute_import +import __init__ + +import sys +import math +import re +import os +import struct + +from util import util3d + +class meshFace(object): + def __init__(self, v0, v1, v2): + self.v = [v0, v1, v2] + +class mesh(object): + def __init__(self): + self.faces = [] + self.vertexes = [] + + def addFace(self, v0, v1, v2): + self.faces.append(meshFace(v0, v1, v2)) + self.vertexes.append(v0) + self.vertexes.append(v1) + self.vertexes.append(v2) + + def _createOrigonalVertexCopy(self): + self.origonalVertexes = list(self.vertexes) + for i in xrange(0, len(self.origonalVertexes)): + self.origonalVertexes[i] = self.origonalVertexes[i].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 + + def getMaximum(self): + return self.max + def getMinimum(self): + return self.min + def getSize(self): + return self.size + + def setRotateMirror(self, rotate, mirrorX, mirrorY, mirrorZ, swapXZ, swapYZ): + rotate = rotate / 180.0 * math.pi + scaleX = 1.0 + scaleY = 1.0 + scaleZ = 1.0 + if mirrorX: + scaleX = -scaleX + if mirrorY: + scaleY = -scaleY + if mirrorZ: + scaleZ = -scaleZ + 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() + +if __name__ == '__main__': + for filename in sys.argv[1:]: + stlModel().load(filename) diff --git a/Cura/util/stl.py b/Cura/util/stl.py index bf7558b4..8ba47a3d 100644 --- a/Cura/util/stl.py +++ b/Cura/util/stl.py @@ -8,15 +8,11 @@ import os import struct from util import util3d +from util import mesh -class stlFace(object): - def __init__(self, v0, v1, v2): - self.v = [v0, v1, v2] - -class stlModel(object): +class stlModel(mesh.mesh): def __init__(self): - self.faces = [] - self.vertexes = [] + super(stlModel, self).__init__() def load(self, filename): f = open(filename, "rb") @@ -44,10 +40,7 @@ class stlModel(object): 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) + self.addFace(v0, v1, v2) cnt = 0 def _loadBinary(self, f): @@ -59,38 +52,7 @@ class stlModel(object): 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 _createOrigonalVertexCopy(self): - self.origonalVertexes = list(self.vertexes) - for i in xrange(0, len(self.origonalVertexes)): - self.origonalVertexes[i] = self.origonalVertexes[i].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 - - def getMaximum(self): - return self.max - def getMinimum(self): - return self.min - def getSize(self): - return self.size + self.addFace(v0, v1, v2) if __name__ == '__main__': for filename in sys.argv[1:]: