chiark / gitweb /
Fixed the imports.
[cura.git] / Cura / util / dae.py
1 from __future__ import absolute_import
2
3 from  xml.parsers.expat import ParserCreate
4
5 from Cura.util import mesh
6
7 class daeModel(mesh.mesh):
8         def __init__(self):
9                 super(daeModel, self).__init__()
10
11         def load(self, filename):
12                 r = ParserCreate()
13                 r.StartElementHandler = self._StartElementHandler
14                 r.EndElementHandler = self._EndElementHandler
15                 r.CharacterDataHandler = self._CharacterDataHandler
16
17                 self._base = {}
18                 self._cur = self._base
19                 self._idMap = {}
20                 self._geometryList = []
21                 r.ParseFile(open(filename, "r"))
22                 
23                 self.vertexCount = 0
24                 for instance_visual_scene in self._base['collada'][0]['scene'][0]['instance_visual_scene']:
25                         for node in self._idMap[instance_visual_scene['_url']]['node']:
26                                 self._ProcessNode1(node)
27                 self._prepareVertexCount(self.vertexCount)
28                 for instance_visual_scene in self._base['collada'][0]['scene'][0]['instance_visual_scene']:
29                         for node in self._idMap[instance_visual_scene['_url']]['node']:
30                                 self._ProcessNode2(node)
31
32                 scale = float(self._base['collada'][0]['asset'][0]['unit'][0]['_meter']) * 1000
33                 self.origonalVertexes *= scale
34                 
35                 self._base = None
36                 self._cur = None
37                 self._idMap = None
38                 
39                 self._postProcessAfterLoad()
40                 return self
41         
42         def _ProcessNode1(self, node):
43                 if 'node' in node:
44                         for n in node['node']:
45                                 self._ProcessNode1(n)
46                 if 'instance_geometry' in node:
47                         for instance_geometry in node['instance_geometry']:
48                                 mesh = self._idMap[instance_geometry['_url']]['mesh'][0]
49                                 if 'triangles' in mesh:
50                                         for triangles in mesh['triangles']:
51                                                 self.vertexCount += int(triangles['_count']) * 3
52                                 elif 'lines' in mesh:
53                                         pass #Ignore lines
54                                 else:
55                                         print mesh.keys()
56                 if 'instance_node' in node:
57                         for instance_node in node['instance_node']:
58                                 self._ProcessNode1(self._idMap[instance_node['_url']])
59
60         def _ProcessNode2(self, node, matrix = None):
61                 if 'matrix' in node:
62                         oldMatrix = matrix
63                         matrix = map(float, node['matrix'][0]['__data'].split())
64                         if oldMatrix != None:
65                                 newMatrix = [0]*16
66                                 newMatrix[0] = oldMatrix[0] * matrix[0] + oldMatrix[1] * matrix[4] + oldMatrix[2] * matrix[8] + oldMatrix[3] * matrix[12]
67                                 newMatrix[1] = oldMatrix[0] * matrix[1] + oldMatrix[1] * matrix[5] + oldMatrix[2] * matrix[9] + oldMatrix[3] * matrix[13]
68                                 newMatrix[2] = oldMatrix[0] * matrix[2] + oldMatrix[1] * matrix[6] + oldMatrix[2] * matrix[10] + oldMatrix[3] * matrix[14]
69                                 newMatrix[3] = oldMatrix[0] * matrix[3] + oldMatrix[1] * matrix[7] + oldMatrix[2] * matrix[11] + oldMatrix[3] * matrix[15]
70                                 newMatrix[4] = oldMatrix[4] * matrix[0] + oldMatrix[5] * matrix[4] + oldMatrix[6] * matrix[8] + oldMatrix[7] * matrix[12]
71                                 newMatrix[5] = oldMatrix[4] * matrix[1] + oldMatrix[5] * matrix[5] + oldMatrix[6] * matrix[9] + oldMatrix[7] * matrix[13]
72                                 newMatrix[6] = oldMatrix[4] * matrix[2] + oldMatrix[5] * matrix[6] + oldMatrix[6] * matrix[10] + oldMatrix[7] * matrix[14]
73                                 newMatrix[7] = oldMatrix[4] * matrix[3] + oldMatrix[5] * matrix[7] + oldMatrix[6] * matrix[11] + oldMatrix[7] * matrix[15]
74                                 newMatrix[8] = oldMatrix[8] * matrix[0] + oldMatrix[9] * matrix[4] + oldMatrix[10] * matrix[8] + oldMatrix[11] * matrix[12]
75                                 newMatrix[9] = oldMatrix[8] * matrix[1] + oldMatrix[9] * matrix[5] + oldMatrix[10] * matrix[9] + oldMatrix[11] * matrix[13]
76                                 newMatrix[10] = oldMatrix[8] * matrix[2] + oldMatrix[9] * matrix[6] + oldMatrix[10] * matrix[10] + oldMatrix[11] * matrix[14]
77                                 newMatrix[11] = oldMatrix[8] * matrix[3] + oldMatrix[9] * matrix[7] + oldMatrix[10] * matrix[11] + oldMatrix[11] * matrix[15]
78                                 newMatrix[12] = oldMatrix[12] * matrix[0] + oldMatrix[13] * matrix[4] + oldMatrix[14] * matrix[8] + oldMatrix[15] * matrix[12]
79                                 newMatrix[13] = oldMatrix[12] * matrix[1] + oldMatrix[13] * matrix[5] + oldMatrix[14] * matrix[9] + oldMatrix[15] * matrix[13]
80                                 newMatrix[14] = oldMatrix[12] * matrix[2] + oldMatrix[13] * matrix[6] + oldMatrix[14] * matrix[10] + oldMatrix[15] * matrix[14]
81                                 newMatrix[15] = oldMatrix[12] * matrix[3] + oldMatrix[13] * matrix[7] + oldMatrix[14] * matrix[11] + oldMatrix[15] * matrix[15]
82                                 matrix = newMatrix
83                 if 'node' in node:
84                         for n in node['node']:
85                                 self._ProcessNode2(n, matrix)
86                 if 'instance_geometry' in node:
87                         for instance_geometry in node['instance_geometry']:
88                                 mesh = self._idMap[instance_geometry['_url']]['mesh'][0]
89                                 
90                                 if 'triangles' in mesh:
91                                         for triangles in mesh['triangles']:
92                                                 for input in triangles['input']:
93                                                         if input['_semantic'] == 'VERTEX':
94                                                                 vertices = self._idMap[input['_source']]
95                                                 for input in vertices['input']:
96                                                         if input['_semantic'] == 'POSITION':
97                                                                 vertices = self._idMap[input['_source']]
98                                                 indexList = map(int, triangles['p'][0]['__data'].split())
99                                                 positionList = map(float, vertices['float_array'][0]['__data'].split())
100
101                                                 vertexCount = int(triangles['_count']) * 3
102                                                 stepSize = len(indexList) / vertexCount
103                                                 for i in xrange(0, vertexCount):
104                                                         idx = indexList[i * stepSize]
105                                                         if matrix != None:
106                                                                 x = positionList[idx*3]
107                                                                 y = positionList[idx*3+1]
108                                                                 z = positionList[idx*3+2]
109                                                                 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])
110                                                         else:
111                                                                 self.addVertex(positionList[idx*3], positionList[idx*3+1], positionList[idx*3+2])
112                 if 'instance_node' in node:
113                         for instance_node in node['instance_node']:
114                                 self._ProcessNode2(self._idMap[instance_node['_url']], matrix)
115         
116         def _StartElementHandler(self, name, attributes):
117                 name = name.lower()
118                 if not name in self._cur:
119                         self._cur[name] = []
120                 new = {'__name': name, '__parent': self._cur}
121                 self._cur[name].append(new)
122                 self._cur = new
123                 for k in attributes.keys():
124                         self._cur['_' + k] = attributes[k]
125                 
126                 if 'id' in attributes:
127                         self._idMap['#' + attributes['id']] = self._cur
128                 
129         def _EndElementHandler(self, name):
130                 self._cur = self._cur['__parent']
131
132         def _CharacterDataHandler(self, data):
133                 if len(data.strip()) < 1:
134                         return
135                 if '__data' in self._cur:
136                         self._cur['__data'] += data
137                 else:
138                         self._cur['__data'] = data
139         
140         def _GetWithKey(self, item, basename, key, value):
141                 input = basename
142                 while input in item:
143                         if item[basename]['_'+key] == value:
144                                 return self._idMap[item[input]['_source']]
145                         basename += "!"