Added compression support to wavefront loader.

Removed massive generated C file.
This commit is contained in:
Quantum 2013-11-23 12:12:48 -05:00
parent 6138402b01
commit d1599eb511
2 changed files with 62 additions and 12995 deletions

File diff suppressed because it is too large Load diff

View file

@ -7,6 +7,20 @@ from punyverse.texture import load_texture
include "_cyopengl.pxi" include "_cyopengl.pxi"
from uuid import uuid4 from uuid import uuid4
import os import os
import gzip
import bz2
import zipfile
def zip_open(file):
zip = zipfile.ZipFile(file)
return zip.open(zip.namelist()[0])
openers = {
'gz': gzip.open,
'bz2': bz2.BZ2File,
'zip': zip_open,
}
cdef enum: cdef enum:
FACE_TRIANGLES FACE_TRIANGLES
@ -85,7 +99,7 @@ cdef class WavefrontObject(object):
self.textures = [] self.textures = []
self.groups = [] self.groups = []
self.materials = {} self.materials = {}
self.perform_io(self.path) self.perform_io(self.path)
cdef void new_material(self, list words): cdef void new_material(self, list words):
@ -178,8 +192,8 @@ cdef class WavefrontObject(object):
group.faces.append(Face(type, vindices, nindices, tindices, face_vertices, face_normals, face_textures)) group.faces.append(Face(type, vindices, nindices, tindices, face_vertices, face_normals, face_textures))
cdef void material(self, list words): cdef bint material(self, list words) except False:
self.perform_io(os.path.join(self.root, words[1])) return self.perform_io(os.path.join(self.root, words[1]))
cdef void use_material(self, list words): cdef void use_material(self, list words):
mat = words[1] mat = words[1]
@ -199,63 +213,54 @@ cdef class WavefrontObject(object):
self.groups.append(group) self.groups.append(group)
self.current_group = group self.current_group = group
cdef inline void perform_io(self, unicode file): cdef inline bint perform_io(self, unicode file) except False:
mbcsfile = file.encode('mbcs') cdef const char *type
cdef char* fname = mbcsfile
cdef FILE* cfile
cfile = fopen(fname, 'rb')
if cfile == NULL:
raise IOError(2, "No such file or directory: '%s'" % file)
cdef size_t bufsize = 2048
cdef char *buf = <char*>malloc(bufsize)
cdef ssize_t read
cdef char *type
cdef list words cdef list words
cdef int hash, length cdef int hash, length
while fgets(buf, bufsize, cfile):
if buf[0] in (0, 10, 13, 35):
continue # Empty or comment
words = buf.split()
type = words[0]
length = strlen(type) ext = os.path.splitext(file)[1].lstrip('.')
if not length: reader = openers.get(ext, open)(file)
continue with reader:
elif length < 3: for buf in reader:
hash = type[0] << 8 | type[1] if not buf or buf.startswith(('\r', '\n', '#')):
if hash == 0x7600: # v\0 continue # Empty or comment
self.vertex(words) words = buf.split()
elif hash == 0x766e: # vn type = words[0]
self.normal(words)
elif hash == 0x7674: # vt length = strlen(type)
self.texture(words) if not length:
elif hash == 0x6600: # f continue
self.face(words) elif length < 3:
elif hash == 0x6700: # g hash = type[0] << 8 | type[1]
self.group(words) if hash == 0x7600: # v\0
elif hash == 0x6f00: # o self.vertex(words)
self.group(words) elif hash == 0x766e: # vn
elif hash == 0x4b61: # Ka self.normal(words)
self.Ka(words) elif hash == 0x7674: # vt
elif hash == 0x4b64: # Kd self.texture(words)
self.Kd(words) elif hash == 0x6600: # f
elif hash == 0x4b73: # Ks self.face(words)
self.Ks(words) elif hash == 0x6700: # g
elif hash == 0x4e73: # Ns self.group(words)
self.material_shininess(words) elif hash == 0x6f00: # o
elif strcmp(type, b'mtllib') == 0: self.group(words)
self.material(words) elif hash == 0x4b61: # Ka
elif strcmp(type, b'usemtl') == 0: self.Ka(words)
self.use_material(words) elif hash == 0x4b64: # Kd
elif strcmp(type, b'newmtl') == 0: self.Kd(words)
self.new_material(words) elif hash == 0x4b73: # Ks
elif strcmp(type, b'map_Kd') == 0: self.Ks(words)
self.material_texture(words) elif hash == 0x4e73: # Ns
free(buf) self.material_shininess(words)
fclose(cfile) elif strcmp(type, b'mtllib') == 0:
self.material(words)
elif strcmp(type, b'usemtl') == 0:
self.use_material(words)
elif strcmp(type, b'newmtl') == 0:
self.new_material(words)
elif strcmp(type, b'map_Kd') == 0:
self.material_texture(words)
return True
model_base = None model_base = None