1 from __future__ import absolute_import
7 numpy.seterr(all='ignore')
9 from Cura.util import util3d
11 class printableObject(object):
14 self._position = numpy.array([0.0, 0.0])
15 self._matrix = numpy.matrix([[1,0,0],[0,1,0],[0,0,1]], numpy.float64)
16 self._transformedMin = None
17 self._transformedMax = None
18 self._boundaryCircleSize = None
22 self._meshList.append(m)
25 def _postProcessAfterLoad(self):
26 for m in self._meshList:
30 def processMatrix(self):
31 self._transformedMin = numpy.array([999999999999,999999999999,999999999999], numpy.float64)
32 self._transformedMax = numpy.array([-999999999999,-999999999999,-999999999999], numpy.float64)
33 self._boundaryCircleSize = 0
35 for m in self._meshList:
36 transformedVertexes = (numpy.matrix(m.vertexes, copy = False) * self._matrix).getA()
37 transformedMin = transformedVertexes.min(0)
38 transformedMax = transformedVertexes.max(0)
39 for n in xrange(0, 3):
40 self._transformedMin[n] = min(transformedMin[n], self._transformedMin[n])
41 self._transformedMax[n] = max(transformedMax[n], self._transformedMax[n])
43 #Calculate the boundary circle
44 transformedSize = transformedMax - transformedMin
45 center = transformedMin + transformedSize / 2.0
46 boundaryCircleSize = round(math.sqrt(numpy.max(((transformedVertexes[::,0] - center[0]) * (transformedVertexes[::,0] - center[0])) + ((transformedVertexes[::,1] - center[1]) * (transformedVertexes[::,1] - center[1])) + ((transformedVertexes[::,2] - center[2]) * (transformedVertexes[::,2] - center[2])))), 3)
47 self._boundaryCircleSize = max(self._boundaryCircleSize, boundaryCircleSize)
48 self._transformedSize = self._transformedMax - self._transformedMin
49 self._drawOffset = (self._transformedMax + self._transformedMin) / 2
50 self._drawOffset[2] = self._transformedMin[2]
51 self._transformedMax -= self._drawOffset
52 self._transformedMin -= self._drawOffset
54 def getPosition(self):
56 def setPosition(self, newPos):
57 self._position = newPos
60 return self._transformedMax
62 return self._transformedMin
64 return self._transformedSize
65 def getDrawOffset(self):
66 return self._drawOffset
67 def getBoundaryCircle(self):
68 return self._boundaryCircleSize
76 def _addFace(self, x0, y0, z0, x1, y1, z1, x2, y2, z2):
78 self.vertexes[n][0] = x0
79 self.vertexes[n][1] = y0
80 self.vertexes[n][2] = z0
82 self.vertexes[n][0] = x1
83 self.vertexes[n][1] = y1
84 self.vertexes[n][2] = z1
86 self.vertexes[n][0] = x2
87 self.vertexes[n][1] = y2
88 self.vertexes[n][2] = z2
91 def _prepareFaceCount(self, faceNumber):
92 #Set the amount of faces before loading data in them. This way we can create the numpy arrays before we fill them.
93 self.vertexes = numpy.zeros((faceNumber*3, 3), numpy.float32)
94 self.normal = numpy.zeros((faceNumber*3, 3), numpy.float32)
97 def _calculateNormals(self):
98 #Calculate the normals
99 tris = self.vertexes.reshape(self.vertexCount / 3, 3, 3)
100 normals = numpy.cross( tris[::,1 ] - tris[::,0] , tris[::,2 ] - tris[::,0] )
101 lens = numpy.sqrt( normals[:,0]**2 + normals[:,1]**2 + normals[:,2]**2 )
106 n = numpy.zeros((self.vertexCount / 3, 9), numpy.float32)
110 self.normal = n.reshape(self.vertexCount, 3)
111 self.invNormal = -self.normal
113 def splitToParts(self, callback = None):
116 #print "%f: " % (time.time() - t0), "Splitting a model with %d vertexes." % (len(self.vertexes))
118 tree = util3d.AABBTree()
119 off = numpy.array([0.0001,0.0001,0.0001])
120 for idx in xrange(0, self.vertexCount):
121 v = self.vertexes[idx]
122 e = util3d.AABB(v-off, v+off)
128 removeDict[idx] = q[0].idx
129 if callback is not None and (idx % 100) == 0:
131 #print "%f: " % (time.time() - t0), "Marked %d duplicate vertexes for removal." % (len(removeDict))
134 for idx in xrange(0, self.vertexCount, 3):
135 f = [idx, idx + 1, idx + 2]
136 if removeDict.has_key(f[0]):
137 f[0] = removeDict[f[0]]
138 if removeDict.has_key(f[1]):
139 f[1] = removeDict[f[1]]
140 if removeDict.has_key(f[2]):
141 f[2] = removeDict[f[2]]
144 #print "%f: " % (time.time() - t0), "Building face lists after vertex removal."
146 for idx in xrange(0, self.vertexCount):
147 vertexFaceList.append([])
148 for idx in xrange(0, len(faceList)):
150 vertexFaceList[f[0]].append(idx)
151 vertexFaceList[f[1]].append(idx)
152 vertexFaceList[f[2]].append(idx)
154 #print "%f: " % (time.time() - t0), "Building parts."
155 self._vertexFaceList = vertexFaceList
156 self._faceList = faceList
159 for idx in xrange(0, len(faceList)):
160 if not idx in doneSet:
161 partList.append(self._createPartFromFacewalk(idx, doneSet))
162 #print "%f: " % (time.time() - t0), "Split into %d parts" % (len(partList))
163 self._vertexFaceList = None
164 self._faceList = None
167 def _createPartFromFacewalk(self, startFaceIdx, doneSet):
169 m._prepareVertexCount(self.vertexCount)
170 todoList = [startFaceIdx]
171 doneSet.add(startFaceIdx)
172 while len(todoList) > 0:
173 faceIdx = todoList.pop()
174 self._partAddFacewalk(m, faceIdx, doneSet, todoList)
177 def _partAddFacewalk(self, part, faceIdx, doneSet, todoList):
178 f = self._faceList[faceIdx]
179 v0 = self.vertexes[f[0]]
180 v1 = self.vertexes[f[1]]
181 v2 = self.vertexes[f[2]]
182 part.addVertex(v0[0], v0[1], v0[2])
183 part.addVertex(v1[0], v1[1], v1[2])
184 part.addVertex(v2[0], v2[1], v2[2])
185 for f1 in self._vertexFaceList[f[0]]:
186 if f1 not in doneSet:
189 for f1 in self._vertexFaceList[f[1]]:
190 if f1 not in doneSet:
193 for f1 in self._vertexFaceList[f[2]]:
194 if f1 not in doneSet: