Skip to content

Instantly share code, notes, and snippets.

@jterrace
Created November 1, 2011 18:47
Show Gist options
  • Save jterrace/1331508 to your computer and use it in GitHub Desktop.
Save jterrace/1331508 to your computer and use it in GitHub Desktop.
Aggregate vertex data with pycollada
import collada
import sys
import os.path
from itertools import chain
import numpy
def uniqify_multidim_indexes(sourcedata, indices, return_map=False):
"""Just like numpy.unique except that it works with multi-dimensional arrays.
Given a source array and indexes into the source array, will keep only unique
indices into the source array, rewriting the indices to point to the new
compressed source array"""
unique_data, index_map = numpy.unique(sourcedata.view([('',sourcedata.dtype)]*sourcedata.shape[1]), return_inverse=True)
index_map = numpy.cast['int32'](index_map)
if return_map:
return unique_data.view(sourcedata.dtype).reshape(-1,sourcedata.shape[1]), index_map[indices], index_map
return unique_data.view(sourcedata.dtype).reshape(-1,sourcedata.shape[1]), index_map[indices]
def aggregate_dae(mesh):
all_vertices = []
all_vert_indices = []
vertex_offset = 0
num_prims = 0
for boundgeom in chain(mesh.scene.objects('geometry'), mesh.scene.objects('controller')):
if isinstance(boundgeom, collada.controller.BoundController):
boundgeom = boundgeom.geometry
for boundprim in boundgeom.primitives():
if boundprim.vertex_index is None or len(boundprim.vertex_index) == 0:
continue
if not isinstance(boundprim, collada.triangleset.BoundTriangleSet):
continue
print 'Adding primitive', boundprim
all_vertices.append(boundprim.vertex)
all_vert_indices.append(boundprim.vertex_index + vertex_offset)
vertex_offset += len(boundprim.vertex)
num_prims += 1
all_vertices = numpy.concatenate(all_vertices)
all_vert_indices = numpy.concatenate(all_vert_indices)
print
print 'Concatenated source data is shape', all_vertices.shape
print 'Concatenated indices is shape', all_vert_indices.shape
all_vertices, all_vert_indices = uniqify_multidim_indexes(all_vertices, all_vert_indices)
print
print 'After compression...'
print 'Concatenated source data is shape', all_vertices.shape
print 'Concatenated indices is shape', all_vert_indices.shape
if __name__ == '__main__':
if len(sys.argv) != 2:
print >> sys.stderr, 'Usage: python aggregate_mesh.py file.dae'
sys.exit(1)
aggregate_dae(collada.Collada(sys.argv[1]))
# $ python ~/test/aggregate_mesh.py TwinBridge.dae
# Adding primitive <BoundTriangleSet length=310>
# Adding primitive <BoundTriangleSet length=376>
# Adding primitive <BoundTriangleSet length=33>
# Adding primitive <BoundTriangleSet length=77>
# Adding primitive <BoundTriangleSet length=13>
# Adding primitive <BoundTriangleSet length=15>
# Adding primitive <BoundTriangleSet length=4>
# Adding primitive <BoundTriangleSet length=2>
#
# Concatenated source data is shape (1630, 3)
# Concatenated indices is shape (830, 3)
#
# After compression...
# Concatenated source data is shape (415, 3)
# Concatenated indices is shape (830, 3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment