Fix dae matrix and instance_node support. Which makes sketchup exports working.

master
daid303 2012-10-19 15:47:00 +02:00
parent 53a98146f5
commit b854558d38
3 changed files with 178 additions and 50 deletions

View 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)

View File

@ -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):

View 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])