123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- import ctypes
- import os, sys
- sys.path.append(
- os.path.abspath(
- os.path.join(
- os.path.dirname(__file__), "../../")))
- from lib3ddevil1.bindings import libc
- del os, sys
- #--------------------------------------+
- # Basic Struct
- #--------------------------------------+
- class Header(ctypes.Structure):
- _pack_ = 1
- _fields_ = [
- ("numMesh", ctypes.c_ubyte),
- ("unknownNumberB", ctypes.c_ubyte),
- ("unknownNumberC", ctypes.c_ubyte),
- ("unknownNumberD", ctypes.c_ubyte),
- ("padding", ctypes.c_int),
- ("unknownOffset", ctypes.c_ulonglong)
- ]
- class MeshHeader(ctypes.Structure):
- _pack_ = 1
- _fields_ = [
- ("numBatch", ctypes.c_short),
- ("numVertex", ctypes.c_short),
- ("u", ctypes.c_uint),
- ("offsetBatches", ctypes.c_ulonglong),
- ("flags", ctypes.c_ulonglong)
- ]
- class Coordinate(ctypes.Structure):
- _pack_ = 1
- _fields_ = [
- ("x", ctypes.c_float),
- ("y", ctypes.c_float),
- ("z", ctypes.c_float)
- ]
- def __str__(self):
- return "(%s, %s, %s)" % (str(self.x), str(self.y), str(self.z))
- class UVs(ctypes.Structure):
- _pack_ = 1
- _fields_ = [
- ("u", ctypes.c_short),
- ("v", ctypes.c_short)
- ]
- def __str__(self):
- return "(%s, %s)" % (str(self.u), str(self.v))
- class BoneIndexes(ctypes.Structure):
- _pack_ = 1
- _fields_ = [
- ("indexes", ctypes.c_ubyte * 4),
- ]
- class BoneWeights(ctypes.Structure):
- _pack_ = 1
- _fields_ = [
- ("weights", ctypes.c_short)
- ]
- class BatchData(ctypes.Structure):
- _pack_ = 1
- _fields_ = [
- ("numVertex", ctypes.c_short),
- ("uB", ctypes.c_short),
- ("padding", ctypes.c_uint),
- ("offsetPositions", ctypes.c_ulonglong),
- ("offsetNormals", ctypes.c_ulonglong),
- ("offsetUVs", ctypes.c_ulonglong),
- ("offsetBoneIndexes", ctypes.c_ulonglong),
- ("offsetBoneWeights", ctypes.c_ulonglong),
- ("offsets", ctypes.c_ulonglong)
- ]
- class VertexData(ctypes.Structure):
- _pack_ = 1
- _fields_ = [
- ("positions", ctypes.POINTER(Coordinate)),
- ("normals", ctypes.POINTER(Coordinate)),
- ("u", ctypes.POINTER(UVs)),
- ("bi", ctypes.POINTER(BoneIndexes)),
- ("bw", ctypes.POINTER(BoneWeights))
- ]
- class Batch(ctypes.Structure):
- _pack_ = 1
- _fields_ = [
- ("bd", ctypes.POINTER(BatchData)),
- ("vd", VertexData)
- ]
- class Mesh(ctypes.Structure):
- _pack_ = 1
- _fields_ = [
- ("b", ctypes.POINTER(Batch))
- ]
- class Devil1GEO_FN(ctypes.Structure):
- _fields_ = [
- ("printheader", ctypes.CFUNCTYPE(
- None,
- ctypes.POINTER(Header))),
- ("printmeshheader", ctypes.CFUNCTYPE(
- None,
- ctypes.POINTER(MeshHeader))),
- ("printbatch", ctypes.CFUNCTYPE(
- None,
- ctypes.POINTER(Batch))),
- ("printcoordinate", ctypes.CFUNCTYPE(
- None,
- ctypes.POINTER(Coordinate))),
- ("getheader", ctypes.CFUNCTYPE(
- ctypes.c_bool,
- ctypes.POINTER(ctypes.POINTER(Header)),
- ctypes.c_char_p)),
- ("getmeshheader", ctypes.CFUNCTYPE(
- ctypes.c_bool,
- ctypes.POINTER(ctypes.POINTER(MeshHeader)),
- ctypes.c_uint,
- ctypes.c_char_p)),
- ("getbatch", ctypes.CFUNCTYPE(
- ctypes.c_bool,
- ctypes.POINTER(Batch),
- ctypes.c_uint,
- ctypes.c_char_p)),
- ("getmesh", ctypes.CFUNCTYPE(
- ctypes.c_bool,
- ctypes.POINTER(Mesh),
- ctypes.c_uint,
- ctypes.c_char_p,
- ctypes.c_uint))
- ]
- devil1geo = Devil1GEO_FN.in_dll(libc, "DEVIL1GEO")
- del libc
- #--------------------------------------+
- # Pythonic Object
- #--------------------------------------+
- class pyGeoHeader:
- def __init__(self, filedata):
- self.cstruct = ctypes.pointer(Header())
- ptrofptr = ctypes.byref(self.cstruct)
- if filedata:
- if not devil1geo.getheader(ptrofptr, filedata):
- raise RuntimeError("failed to get geometry file header")
- return
- def show(self):
- devil1geo.printheader(self.cstruct)
- def getnummesh(self):
- return self.cstruct.contents.numMesh
- def getunknownb(self):
- return self.cstruct.contents.unknownNumberB
- def getunknownc(self):
- return self.cstruct.contents.unknownNumberC
-
- def getunknownd(self):
- return self.cstruct.contents.unknownNumberD
- def getpadding(self):
- return hex(self.cstruct.contents.padding)
- def getunknownoffset(self):
- return hex(self.cstruct.contents.unknownOffset)
- class pyMeshHeader:
- def __init__(self, i, filedata):
- self.cstruct = ctypes.pointer(MeshHeader())
- ptrofptr = ctypes.byref(self.cstruct)
- if filedata:
- if not devil1geo.getmeshheader(ptrofptr, i, filedata):
- raise RuntimeError("failed to get mesh header #" + str(i))
- return
- pass
- def show(self):
- devil1geo.printmeshheader(self.cstruct)
- def getnumbatch(self):
- return self.cstruct.contents.numBatch
- def getnumvertex(self):
- return self.cstruct.contents.numVertex
- def getunknown(self):
- return hex(self.cstruct.contents.u)
- def getoffsetbatches(self):
- return self.cstruct.contents.offsetBatches
- def getflags(self):
- return self.cstruct.contents.flags
- class pyMesh:
- def __init__(self, i, filedata):
- self.cstruct = Mesh()
- if filedata:
- mh = pyMeshHeader(i, filedata)
- # allocate memory for the size of batch * number of batches
- memsize = ctypes.sizeof(Batch) * mh.getnumbatch()
- self.cstruct.b = ctypes.cast(
- ctypes.create_string_buffer(memsize),
- ctypes.POINTER(Batch))
- if not devil1geo.getmesh(
- ctypes.byref(self.cstruct),
- i,
- filedata,
- len(filedata)):
- raise RuntimeError("failed to get mesh")
- del mh, memsize
- return
- def show(self):
- if self.cstruct.b:
- devil1geo.printbatch(self.cstruct.b)
- else:
- print("nothing to show")
- def getbatchdata(self):
- return self.cstruct.b.contents.bd.contents
- def getpositions(self):
- length = self.cstruct.b.contents.bd.contents.numVertex
- return self.cstruct.b.contents.vd.positions[:length]
- def getnormals(self):
- length = self.cstruct.b.contents.bd.contents.numVertex
- return self.cstruct.b.contents.vd.normals[:length]
- def getuvs(self):
- length = self.cstruct.b.contents.bd.contents.numVertex
- return self.cstruct.b.contents.vd.u[:length]
- def getboneindexes(self):
- length = self.cstruct.b.contents.bd.contents.numVertex
- return self.cstruct.b.contents.vd.bi[:length]
- def getboneweights(self):
- length = self.cstruct.b.contents.bd.contents.numVertex
- return self.cstruct.b.contents.vd.bw[:length]
|