chiark / gitweb /
Fix dae matrix and instance_node support. Which makes sketchup exports working.
[cura.git] / Cura / cura_sf / fabmetheus_utilities / fabmetheus_tools / interpret_plugins / dae.py
1 from __future__ import absolute_import
2 #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
3 import __init__
4
5 from fabmetheus_utilities.geometry.geometry_tools import face
6 from fabmetheus_utilities.geometry.solids import triangle_mesh
7 from fabmetheus_utilities.vector3 import Vector3
8
9 from  xml.parsers.expat import ParserCreate
10
11 def getCarving(fileName=''):
12         "Get the triangle mesh for the dae file."
13         return daeModel().load(fileName)
14
15 class daeModel(triangle_mesh.TriangleMesh):
16         def __init__(self):
17                 triangle_mesh.TriangleMesh.__init__(self)
18
19         def load(self, filename):
20                 r = ParserCreate()
21                 r.StartElementHandler = self._StartElementHandler
22                 r.EndElementHandler = self._EndElementHandler
23                 r.CharacterDataHandler = self._CharacterDataHandler
24
25                 self._base = {}
26                 self._cur = self._base
27                 self._idMap = {}
28                 self._geometryList = []
29                 r.ParseFile(open(filename, "r"))
30                 
31                 for instance_visual_scene in self._base['collada'][0]['scene'][0]['instance_visual_scene']:
32                         for node in self._idMap[instance_visual_scene['_url']]['node']:
33                                 self._ProcessNode2(node)
34                 
35                 self._base = None
36                 self._cur = None
37                 self._idMap = None
38                 
39                 return self
40         
41         def _ProcessNode2(self, node, matrix = None):
42                 if 'matrix' in node:
43                         oldMatrix = matrix
44                         matrix = map(float, node['matrix'][0]['__data'].split())
45                         if oldMatrix != None:
46                                 newMatrix = [0]*16
47                                 newMatrix[0] = oldMatrix[0] * matrix[0] + oldMatrix[1] * matrix[4] + oldMatrix[2] * matrix[8] + oldMatrix[3] * matrix[12]
48                                 newMatrix[1] = oldMatrix[0] * matrix[1] + oldMatrix[1] * matrix[5] + oldMatrix[2] * matrix[9] + oldMatrix[3] * matrix[13]
49                                 newMatrix[2] = oldMatrix[0] * matrix[2] + oldMatrix[1] * matrix[6] + oldMatrix[2] * matrix[10] + oldMatrix[3] * matrix[14]
50                                 newMatrix[3] = oldMatrix[0] * matrix[3] + oldMatrix[1] * matrix[7] + oldMatrix[2] * matrix[11] + oldMatrix[3] * matrix[15]
51                                 newMatrix[4] = oldMatrix[4] * matrix[0] + oldMatrix[5] * matrix[4] + oldMatrix[6] * matrix[8] + oldMatrix[7] * matrix[12]
52                                 newMatrix[5] = oldMatrix[4] * matrix[1] + oldMatrix[5] * matrix[5] + oldMatrix[6] * matrix[9] + oldMatrix[7] * matrix[13]
53                                 newMatrix[6] = oldMatrix[4] * matrix[2] + oldMatrix[5] * matrix[6] + oldMatrix[6] * matrix[10] + oldMatrix[7] * matrix[14]
54                                 newMatrix[7] = oldMatrix[4] * matrix[3] + oldMatrix[5] * matrix[7] + oldMatrix[6] * matrix[11] + oldMatrix[7] * matrix[15]
55                                 newMatrix[8] = oldMatrix[8] * matrix[0] + oldMatrix[9] * matrix[4] + oldMatrix[10] * matrix[8] + oldMatrix[11] * matrix[12]
56                                 newMatrix[9] = oldMatrix[8] * matrix[1] + oldMatrix[9] * matrix[5] + oldMatrix[10] * matrix[9] + oldMatrix[11] * matrix[13]
57                                 newMatrix[10] = oldMatrix[8] * matrix[2] + oldMatrix[9] * matrix[6] + oldMatrix[10] * matrix[10] + oldMatrix[11] * matrix[14]
58                                 newMatrix[11] = oldMatrix[8] * matrix[3] + oldMatrix[9] * matrix[7] + oldMatrix[10] * matrix[11] + oldMatrix[11] * matrix[15]
59                                 newMatrix[12] = oldMatrix[12] * matrix[0] + oldMatrix[13] * matrix[4] + oldMatrix[14] * matrix[8] + oldMatrix[15] * matrix[12]
60                                 newMatrix[13] = oldMatrix[12] * matrix[1] + oldMatrix[13] * matrix[5] + oldMatrix[14] * matrix[9] + oldMatrix[15] * matrix[13]
61                                 newMatrix[14] = oldMatrix[12] * matrix[2] + oldMatrix[13] * matrix[6] + oldMatrix[14] * matrix[10] + oldMatrix[15] * matrix[14]
62                                 newMatrix[15] = oldMatrix[12] * matrix[3] + oldMatrix[13] * matrix[7] + oldMatrix[14] * matrix[11] + oldMatrix[15] * matrix[15]
63                                 matrix = newMatrix
64                 if 'node' in node:
65                         for n in node['node']:
66                                 self._ProcessNode2(n, matrix)
67                 if 'instance_geometry' in node:
68                         for instance_geometry in node['instance_geometry']:
69                                 mesh = self._idMap[instance_geometry['_url']]['mesh'][0]
70                                 
71                                 if 'triangles' in mesh:
72                                         for triangles in mesh['triangles']:
73                                                 for input in triangles['input']:
74                                                         if input['_semantic'] == 'VERTEX':
75                                                                 vertices = self._idMap[input['_source']]
76                                                 for input in vertices['input']:
77                                                         if input['_semantic'] == 'POSITION':
78                                                                 vertices = self._idMap[input['_source']]
79                                                 indexList = map(int, triangles['p'][0]['__data'].split())
80                                                 positionList = map(float, vertices['float_array'][0]['__data'].split())
81
82                                                 startIndex = len(self.vertexes)
83                                                 for idx in xrange(0, len(positionList)/3):
84                                                         x = positionList[idx*3]
85                                                         y = positionList[idx*3+1]
86                                                         z = positionList[idx*3+2]
87                                                         if matrix != None:
88                                                                 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]))
89                                                         else:
90                                                                 self.vertexes.append(Vector3(x, y, z))
91                                                 stepSize = len(indexList) / (int(triangles['_count']) * 3)
92                                                 for i in xrange(0, int(triangles['_count'])):
93                                                         idx = i * stepSize * 3
94                                                         f = face.Face()
95                                                         f.index = len(self.faces)
96                                                         f.vertexIndexes.append(startIndex + indexList[idx])
97                                                         f.vertexIndexes.append(startIndex + indexList[idx+stepSize])
98                                                         f.vertexIndexes.append(startIndex + indexList[idx+stepSize*2])
99                                                         self.faces.append(f)
100
101                 if 'instance_node' in node:
102                         for instance_node in node['instance_node']:
103                                 self._ProcessNode2(self._idMap[instance_node['_url']], matrix)
104         
105         def _StartElementHandler(self, name, attributes):
106                 name = name.lower()
107                 if not name in self._cur:
108                         self._cur[name] = []
109                 new = {'__name': name, '__parent': self._cur}
110                 self._cur[name].append(new)
111                 self._cur = new
112                 for k in attributes.keys():
113                         self._cur['_' + k] = attributes[k]
114                 
115                 if 'id' in attributes:
116                         self._idMap['#' + attributes['id']] = self._cur
117                 
118         def _EndElementHandler(self, name):
119                 self._cur = self._cur['__parent']
120
121         def _CharacterDataHandler(self, data):
122                 if len(data.strip()) < 1:
123                         return
124                 if '__data' in self._cur:
125                         self._cur['__data'] += data
126                 else:
127                         self._cur['__data'] = data
128         
129         def _GetWithKey(self, item, basename, key, value):
130                 input = basename
131                 while input in item:
132                         if item[basename]['_'+key] == value:
133                                 return self._idMap[item[input]['_source']]
134                         basename += "!"