1 from __future__ import absolute_import
7 numpy.seterr(all='ignore')
9 from Cura.util import util3d
14 self.matrix = numpy.matrix([[1,0,0], [0,1,0], [0,0,1]], numpy.float32);
17 def addVertex(self, x, y, z):
19 self.vertexes[n][0] = x
20 self.vertexes[n][1] = y
21 self.vertexes[n][2] = z
24 def _prepareVertexCount(self, vertexNumber):
25 #Set the amount of faces before loading data in them. This way we can create the numpy arrays before we fill them.
26 self.vertexes = numpy.zeros((vertexNumber, 3), numpy.float32)
27 self.normal = numpy.zeros((vertexNumber, 3), numpy.float32)
30 def _postProcessAfterLoad(self):
32 self._calculateNormals()
34 def processMatrix(self):
35 transformedVertexes = (numpy.matrix(self.vertexes, copy = False) * self.matrix).getA()
36 self.transformedMin = transformedVertexes.min(0)
37 self.transformedMax = transformedVertexes.max(0)
38 self.transformedSize = self.transformedMax - self.transformedMin
40 #Calculate the boundery circle
41 center = self.transformedMin + self.transformedSize / 2.0
42 self.bounderyCircleSize = round(math.sqrt(numpy.max(((transformedVertexes[::,0] - center[0]) * (transformedVertexes[::,0] - center[0])) + ((transformedVertexes[::,1] - center[1]) * (transformedVertexes[::,1] - center[1])))), 3)
45 return self.transformedMax
47 return self.transformedMin
49 return self.transformedSize
51 def _calculateNormals(self):
52 #Calculate the normals
53 tris = self.vertexes.reshape(self.vertexCount / 3, 3, 3)
54 normals = numpy.cross( tris[::,1 ] - tris[::,0] , tris[::,2 ] - tris[::,0] )
55 lens = numpy.sqrt( normals[:,0]**2 + normals[:,1]**2 + normals[:,2]**2 )
60 n = numpy.zeros((self.vertexCount / 3, 9), numpy.float32)
64 self.normal = n.reshape(self.vertexCount, 3)
65 self.invNormal = -self.normal
67 def splitToParts(self, callback = None):
70 #print "%f: " % (time.time() - t0), "Splitting a model with %d vertexes." % (len(self.vertexes))
72 tree = util3d.AABBTree()
73 off = numpy.array([0.0001,0.0001,0.0001])
74 for idx in xrange(0, self.vertexCount):
75 v = self.vertexes[idx]
76 e = util3d.AABB(v-off, v+off)
82 removeDict[idx] = q[0].idx
83 if callback is not None and (idx % 100) == 0:
85 #print "%f: " % (time.time() - t0), "Marked %d duplicate vertexes for removal." % (len(removeDict))
88 for idx in xrange(0, self.vertexCount, 3):
89 f = [idx, idx + 1, idx + 2]
90 if removeDict.has_key(f[0]):
91 f[0] = removeDict[f[0]]
92 if removeDict.has_key(f[1]):
93 f[1] = removeDict[f[1]]
94 if removeDict.has_key(f[2]):
95 f[2] = removeDict[f[2]]
98 #print "%f: " % (time.time() - t0), "Building face lists after vertex removal."
100 for idx in xrange(0, self.vertexCount):
101 vertexFaceList.append([])
102 for idx in xrange(0, len(faceList)):
104 vertexFaceList[f[0]].append(idx)
105 vertexFaceList[f[1]].append(idx)
106 vertexFaceList[f[2]].append(idx)
108 #print "%f: " % (time.time() - t0), "Building parts."
109 self._vertexFaceList = vertexFaceList
110 self._faceList = faceList
113 for idx in xrange(0, len(faceList)):
114 if not idx in doneSet:
115 partList.append(self._createPartFromFacewalk(idx, doneSet))
116 #print "%f: " % (time.time() - t0), "Split into %d parts" % (len(partList))
117 self._vertexFaceList = None
118 self._faceList = None
121 def _createPartFromFacewalk(self, startFaceIdx, doneSet):
123 m._prepareVertexCount(self.vertexCount)
124 todoList = [startFaceIdx]
125 doneSet.add(startFaceIdx)
126 while len(todoList) > 0:
127 faceIdx = todoList.pop()
128 self._partAddFacewalk(m, faceIdx, doneSet, todoList)
131 def _partAddFacewalk(self, part, faceIdx, doneSet, todoList):
132 f = self._faceList[faceIdx]
133 v0 = self.vertexes[f[0]]
134 v1 = self.vertexes[f[1]]
135 v2 = self.vertexes[f[2]]
136 part.addVertex(v0[0], v0[1], v0[2])
137 part.addVertex(v1[0], v1[1], v1[2])
138 part.addVertex(v2[0], v2[1], v2[2])
139 for f1 in self._vertexFaceList[f[0]]:
140 if f1 not in doneSet:
143 for f1 in self._vertexFaceList[f[1]]:
144 if f1 not in doneSet:
147 for f1 in self._vertexFaceList[f[2]]:
148 if f1 not in doneSet: