chiark / gitweb /
Fix dae matrix and instance_node support. Which makes sketchup exports working.
authordaid303 <daid303@gmail.com>
Fri, 19 Oct 2012 13:47:00 +0000 (15:47 +0200)
committerdaid303 <daid303@gmail.com>
Fri, 19 Oct 2012 13:47:00 +0000 (15:47 +0200)
Cura/cura_sf/fabmetheus_utilities/fabmetheus_tools/interpret_plugins/dae.py
Cura/gui/preview3d.py
Cura/util/dae.py

index 49569bca85ab0a2c1cf6735f42e2a38f3efdac55..c51e026e11c9a300b68ae3d89279178428b30766 100644 (file)
@@ -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)
index 47f39a120790235aa9751725b46e222d54e26e82..889a0d8330fa603aa56e634c48fc181bdb5963ce 100644 (file)
@@ -483,6 +483,8 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
                        self.zoom += e.GetY() - self.oldY\r
                        if self.zoom < 1:\r
                                self.zoom = 1\r
+                       if self.zoom > 500:\r
+                               self.zoom = 500\r
                        self.Refresh()\r
                self.oldX = e.GetX()\r
                self.oldY = e.GetY()\r
@@ -494,6 +496,8 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
                self.zoom *= 1.0 - float(e.GetWheelRotation() / e.GetWheelDelta()) / 10.0\r
                if self.zoom < 1.0:\r
                        self.zoom = 1.0\r
+               if self.zoom > 500:\r
+                       self.zoom = 500\r
                self.Refresh()\r
        \r
        def OnEraseBackground(self,event):\r
index 3c01046fd2da5a8b30278e14d726a8a53ca0cbc8..d694b46505f506af6b925634fc5ba91fff7f2dad 100644 (file)
@@ -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])