From b854558d3828efa7aeddf88a274feff6c29eebc3 Mon Sep 17 00:00:00 2001 From: daid303 Date: Fri, 19 Oct 2012 15:47:00 +0200 Subject: [PATCH] Fix dae matrix and instance_node support. Which makes sketchup exports working. --- .../fabmetheus_tools/interpret_plugins/dae.py | 108 +++++++++++----- Cura/gui/preview3d.py | 4 + Cura/util/dae.py | 116 ++++++++++++++---- 3 files changed, 178 insertions(+), 50 deletions(-) diff --git a/Cura/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/dae.py b/Cura/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/dae.py index 49569bc..c51e026 100644 --- a/Cura/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/dae.py +++ b/Cura/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/dae.py @@ -27,37 +27,104 @@ class daeModel(triangle_mesh.TriangleMesh): self._idMap = {} self._geometryList = [] r.ParseFile(open(filename, "r")) - for geo in self._geometryList: - self._ParseGeometry(self._idMap[geo['_url']]) + + for instance_visual_scene in self._base['collada'][0]['scene'][0]['instance_visual_scene']: + for node in self._idMap[instance_visual_scene['_url']]['node']: + self._ProcessNode2(node) + self._base = None self._cur = None self._idMap = None + return self + def _ProcessNode2(self, node, matrix = None): + if 'matrix' in node: + oldMatrix = matrix + matrix = map(float, node['matrix'][0]['__data'].split()) + if oldMatrix != None: + newMatrix = [0]*16 + newMatrix[0] = oldMatrix[0] * matrix[0] + oldMatrix[1] * matrix[4] + oldMatrix[2] * matrix[8] + oldMatrix[3] * matrix[12] + newMatrix[1] = oldMatrix[0] * matrix[1] + oldMatrix[1] * matrix[5] + oldMatrix[2] * matrix[9] + oldMatrix[3] * matrix[13] + newMatrix[2] = oldMatrix[0] * matrix[2] + oldMatrix[1] * matrix[6] + oldMatrix[2] * matrix[10] + oldMatrix[3] * matrix[14] + newMatrix[3] = oldMatrix[0] * matrix[3] + oldMatrix[1] * matrix[7] + oldMatrix[2] * matrix[11] + oldMatrix[3] * matrix[15] + newMatrix[4] = oldMatrix[4] * matrix[0] + oldMatrix[5] * matrix[4] + oldMatrix[6] * matrix[8] + oldMatrix[7] * matrix[12] + newMatrix[5] = oldMatrix[4] * matrix[1] + oldMatrix[5] * matrix[5] + oldMatrix[6] * matrix[9] + oldMatrix[7] * matrix[13] + newMatrix[6] = oldMatrix[4] * matrix[2] + oldMatrix[5] * matrix[6] + oldMatrix[6] * matrix[10] + oldMatrix[7] * matrix[14] + newMatrix[7] = oldMatrix[4] * matrix[3] + oldMatrix[5] * matrix[7] + oldMatrix[6] * matrix[11] + oldMatrix[7] * matrix[15] + newMatrix[8] = oldMatrix[8] * matrix[0] + oldMatrix[9] * matrix[4] + oldMatrix[10] * matrix[8] + oldMatrix[11] * matrix[12] + newMatrix[9] = oldMatrix[8] * matrix[1] + oldMatrix[9] * matrix[5] + oldMatrix[10] * matrix[9] + oldMatrix[11] * matrix[13] + newMatrix[10] = oldMatrix[8] * matrix[2] + oldMatrix[9] * matrix[6] + oldMatrix[10] * matrix[10] + oldMatrix[11] * matrix[14] + newMatrix[11] = oldMatrix[8] * matrix[3] + oldMatrix[9] * matrix[7] + oldMatrix[10] * matrix[11] + oldMatrix[11] * matrix[15] + newMatrix[12] = oldMatrix[12] * matrix[0] + oldMatrix[13] * matrix[4] + oldMatrix[14] * matrix[8] + oldMatrix[15] * matrix[12] + newMatrix[13] = oldMatrix[12] * matrix[1] + oldMatrix[13] * matrix[5] + oldMatrix[14] * matrix[9] + oldMatrix[15] * matrix[13] + newMatrix[14] = oldMatrix[12] * matrix[2] + oldMatrix[13] * matrix[6] + oldMatrix[14] * matrix[10] + oldMatrix[15] * matrix[14] + newMatrix[15] = oldMatrix[12] * matrix[3] + oldMatrix[13] * matrix[7] + oldMatrix[14] * matrix[11] + oldMatrix[15] * matrix[15] + matrix = newMatrix + if 'node' in node: + for n in node['node']: + self._ProcessNode2(n, matrix) + if 'instance_geometry' in node: + for instance_geometry in node['instance_geometry']: + mesh = self._idMap[instance_geometry['_url']]['mesh'][0] + + if 'triangles' in mesh: + for triangles in mesh['triangles']: + for input in triangles['input']: + if input['_semantic'] == 'VERTEX': + vertices = self._idMap[input['_source']] + for input in vertices['input']: + if input['_semantic'] == 'POSITION': + vertices = self._idMap[input['_source']] + indexList = map(int, triangles['p'][0]['__data'].split()) + positionList = map(float, vertices['float_array'][0]['__data'].split()) + + startIndex = len(self.vertexes) + for idx in xrange(0, len(positionList)/3): + x = positionList[idx*3] + y = positionList[idx*3+1] + z = positionList[idx*3+2] + if matrix != None: + self.vertexes.append(Vector3(x * matrix[0] + y * matrix[1] + z * matrix[2] + matrix[3], x * matrix[4] + y * matrix[5] + z * matrix[6] + matrix[7], x * matrix[8] + y * matrix[9] + z * matrix[10] + matrix[11])) + else: + self.vertexes.append(Vector3(x, y, z)) + stepSize = len(indexList) / (int(triangles['_count']) * 3) + for i in xrange(0, int(triangles['_count'])): + idx = i * stepSize * 3 + f = face.Face() + f.index = len(self.faces) + f.vertexIndexes.append(startIndex + indexList[idx]) + f.vertexIndexes.append(startIndex + indexList[idx+stepSize]) + f.vertexIndexes.append(startIndex + indexList[idx+stepSize*2]) + self.faces.append(f) + + if 'instance_node' in node: + for instance_node in node['instance_node']: + self._ProcessNode2(self._idMap[instance_node['_url']], matrix) + def _StartElementHandler(self, name, attributes): - while name in self._cur: - name += "!" - self._cur[name] = {'_parent': self._cur} - self._cur = self._cur[name] + name = name.lower() + if not name in self._cur: + self._cur[name] = [] + new = {'__name': name, '__parent': self._cur} + self._cur[name].append(new) + self._cur = new for k in attributes.keys(): self._cur['_' + k] = attributes[k] if 'id' in attributes: self._idMap['#' + attributes['id']] = self._cur - if name == 'instance_geometry': - self._geometryList.append(self._cur) - def _EndElementHandler(self, name): - self._cur = self._cur['_parent'] + self._cur = self._cur['__parent'] def _CharacterDataHandler(self, data): if len(data.strip()) < 1: return - if '_data' in self._cur: - self._cur['_data'] += data + if '__data' in self._cur: + self._cur['__data'] += data else: - self._cur['_data'] = data + self._cur['__data'] = data def _GetWithKey(self, item, basename, key, value): input = basename @@ -65,18 +132,3 @@ class daeModel(triangle_mesh.TriangleMesh): if item[basename]['_'+key] == value: return self._idMap[item[input]['_source']] basename += "!" - - def _ParseGeometry(self, geo): - indexList = map(int, geo['mesh']['triangles']['p']['_data'].split()) - vertex = self._GetWithKey(geo['mesh']['triangles'], 'input', 'semantic', 'VERTEX') - positionList = map(float, self._GetWithKey(vertex, 'input', 'semantic', 'POSITION')['float_array']['_data'].split()) - - for idx in xrange(0, len(positionList), 3): - self.vertexes.append(Vector3(positionList[idx], positionList[idx+1], positionList[idx+2])) - for idx in xrange(0, len(indexList), 3): - f = face.Face() - f.index = len(self.faces) - f.vertexIndexes.append(indexList[idx]) - f.vertexIndexes.append(indexList[idx+1]) - f.vertexIndexes.append(indexList[idx+2]) - self.faces.append(f) diff --git a/Cura/gui/preview3d.py b/Cura/gui/preview3d.py index 47f39a1..889a0d8 100644 --- a/Cura/gui/preview3d.py +++ b/Cura/gui/preview3d.py @@ -483,6 +483,8 @@ class PreviewGLCanvas(glcanvas.GLCanvas): self.zoom += e.GetY() - self.oldY if self.zoom < 1: self.zoom = 1 + if self.zoom > 500: + self.zoom = 500 self.Refresh() self.oldX = e.GetX() self.oldY = e.GetY() @@ -494,6 +496,8 @@ class PreviewGLCanvas(glcanvas.GLCanvas): self.zoom *= 1.0 - float(e.GetWheelRotation() / e.GetWheelDelta()) / 10.0 if self.zoom < 1.0: self.zoom = 1.0 + if self.zoom > 500: + self.zoom = 500 self.Refresh() def OnEraseBackground(self,event): diff --git a/Cura/util/dae.py b/Cura/util/dae.py index 3c01046..d694b46 100644 --- a/Cura/util/dae.py +++ b/Cura/util/dae.py @@ -18,8 +18,16 @@ class daeModel(mesh.mesh): self._idMap = {} self._geometryList = [] r.ParseFile(open(filename, "r")) - for geo in self._geometryList: - self._ParseGeometry(self._idMap[geo['_url']]) + + self.vertexCount = 0 + for instance_visual_scene in self._base['collada'][0]['scene'][0]['instance_visual_scene']: + for node in self._idMap[instance_visual_scene['_url']]['node']: + self._ProcessNode1(node) + self._prepareVertexCount(self.vertexCount) + for instance_visual_scene in self._base['collada'][0]['scene'][0]['instance_visual_scene']: + for node in self._idMap[instance_visual_scene['_url']]['node']: + self._ProcessNode2(node) + self._base = None self._cur = None self._idMap = None @@ -27,30 +35,103 @@ class daeModel(mesh.mesh): self._postProcessAfterLoad() return self + def _ProcessNode1(self, node): + if 'node' in node: + for n in node['node']: + self._ProcessNode1(n) + if 'instance_geometry' in node: + for instance_geometry in node['instance_geometry']: + mesh = self._idMap[instance_geometry['_url']]['mesh'][0] + if 'triangles' in mesh: + for triangles in mesh['triangles']: + self.vertexCount += int(triangles['_count']) * 3 + elif 'lines' in mesh: + pass #Ignore lines + else: + print mesh.keys() + if 'instance_node' in node: + for instance_node in node['instance_node']: + self._ProcessNode1(self._idMap[instance_node['_url']]) + + def _ProcessNode2(self, node, matrix = None): + if 'matrix' in node: + oldMatrix = matrix + matrix = map(float, node['matrix'][0]['__data'].split()) + if oldMatrix != None: + newMatrix = [0]*16 + newMatrix[0] = oldMatrix[0] * matrix[0] + oldMatrix[1] * matrix[4] + oldMatrix[2] * matrix[8] + oldMatrix[3] * matrix[12] + newMatrix[1] = oldMatrix[0] * matrix[1] + oldMatrix[1] * matrix[5] + oldMatrix[2] * matrix[9] + oldMatrix[3] * matrix[13] + newMatrix[2] = oldMatrix[0] * matrix[2] + oldMatrix[1] * matrix[6] + oldMatrix[2] * matrix[10] + oldMatrix[3] * matrix[14] + newMatrix[3] = oldMatrix[0] * matrix[3] + oldMatrix[1] * matrix[7] + oldMatrix[2] * matrix[11] + oldMatrix[3] * matrix[15] + newMatrix[4] = oldMatrix[4] * matrix[0] + oldMatrix[5] * matrix[4] + oldMatrix[6] * matrix[8] + oldMatrix[7] * matrix[12] + newMatrix[5] = oldMatrix[4] * matrix[1] + oldMatrix[5] * matrix[5] + oldMatrix[6] * matrix[9] + oldMatrix[7] * matrix[13] + newMatrix[6] = oldMatrix[4] * matrix[2] + oldMatrix[5] * matrix[6] + oldMatrix[6] * matrix[10] + oldMatrix[7] * matrix[14] + newMatrix[7] = oldMatrix[4] * matrix[3] + oldMatrix[5] * matrix[7] + oldMatrix[6] * matrix[11] + oldMatrix[7] * matrix[15] + newMatrix[8] = oldMatrix[8] * matrix[0] + oldMatrix[9] * matrix[4] + oldMatrix[10] * matrix[8] + oldMatrix[11] * matrix[12] + newMatrix[9] = oldMatrix[8] * matrix[1] + oldMatrix[9] * matrix[5] + oldMatrix[10] * matrix[9] + oldMatrix[11] * matrix[13] + newMatrix[10] = oldMatrix[8] * matrix[2] + oldMatrix[9] * matrix[6] + oldMatrix[10] * matrix[10] + oldMatrix[11] * matrix[14] + newMatrix[11] = oldMatrix[8] * matrix[3] + oldMatrix[9] * matrix[7] + oldMatrix[10] * matrix[11] + oldMatrix[11] * matrix[15] + newMatrix[12] = oldMatrix[12] * matrix[0] + oldMatrix[13] * matrix[4] + oldMatrix[14] * matrix[8] + oldMatrix[15] * matrix[12] + newMatrix[13] = oldMatrix[12] * matrix[1] + oldMatrix[13] * matrix[5] + oldMatrix[14] * matrix[9] + oldMatrix[15] * matrix[13] + newMatrix[14] = oldMatrix[12] * matrix[2] + oldMatrix[13] * matrix[6] + oldMatrix[14] * matrix[10] + oldMatrix[15] * matrix[14] + newMatrix[15] = oldMatrix[12] * matrix[3] + oldMatrix[13] * matrix[7] + oldMatrix[14] * matrix[11] + oldMatrix[15] * matrix[15] + matrix = newMatrix + if 'node' in node: + for n in node['node']: + self._ProcessNode2(n, matrix) + if 'instance_geometry' in node: + for instance_geometry in node['instance_geometry']: + mesh = self._idMap[instance_geometry['_url']]['mesh'][0] + + if 'triangles' in mesh: + for triangles in mesh['triangles']: + for input in triangles['input']: + if input['_semantic'] == 'VERTEX': + vertices = self._idMap[input['_source']] + for input in vertices['input']: + if input['_semantic'] == 'POSITION': + vertices = self._idMap[input['_source']] + indexList = map(int, triangles['p'][0]['__data'].split()) + positionList = map(float, vertices['float_array'][0]['__data'].split()) + + vertexCount = int(triangles['_count']) * 3 + stepSize = len(indexList) / vertexCount + for i in xrange(0, vertexCount): + idx = indexList[i * stepSize] + if matrix != None: + x = positionList[idx*3] + y = positionList[idx*3+1] + z = positionList[idx*3+2] + self.addVertex(x * matrix[0] + y * matrix[1] + z * matrix[2] + matrix[3], x * matrix[4] + y * matrix[5] + z * matrix[6] + matrix[7], x * matrix[8] + y * matrix[9] + z * matrix[10] + matrix[11]) + else: + self.addVertex(positionList[idx*3], positionList[idx*3+1], positionList[idx*3+2]) + if 'instance_node' in node: + for instance_node in node['instance_node']: + self._ProcessNode2(self._idMap[instance_node['_url']], matrix) + def _StartElementHandler(self, name, attributes): - while name in self._cur: - name += "!" - self._cur[name] = {'_parent': self._cur} - self._cur = self._cur[name] + name = name.lower() + if not name in self._cur: + self._cur[name] = [] + new = {'__name': name, '__parent': self._cur} + self._cur[name].append(new) + self._cur = new for k in attributes.keys(): self._cur['_' + k] = attributes[k] if 'id' in attributes: self._idMap['#' + attributes['id']] = self._cur - if name == 'instance_geometry': - self._geometryList.append(self._cur) - def _EndElementHandler(self, name): - self._cur = self._cur['_parent'] + self._cur = self._cur['__parent'] def _CharacterDataHandler(self, data): if len(data.strip()) < 1: return - if '_data' in self._cur: - self._cur['_data'] += data + if '__data' in self._cur: + self._cur['__data'] += data else: - self._cur['_data'] = data + self._cur['__data'] = data def _GetWithKey(self, item, basename, key, value): input = basename @@ -58,12 +139,3 @@ class daeModel(mesh.mesh): if item[basename]['_'+key] == value: return self._idMap[item[input]['_source']] basename += "!" - - def _ParseGeometry(self, geo): - indexList = map(int, geo['mesh']['triangles']['p']['_data'].split()) - vertex = self._GetWithKey(geo['mesh']['triangles'], 'input', 'semantic', 'VERTEX') - positionList = map(float, self._GetWithKey(vertex, 'input', 'semantic', 'POSITION')['float_array']['_data'].split()) - - self._prepareVertexCount(len(indexList)) - for idx in indexList: - self.addVertex(positionList[idx*3], positionList[idx*3+1], positionList[idx*3+2])