Skip to content

Instantly share code, notes, and snippets.

@re-polm
Last active October 24, 2019 16:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save re-polm/71ec1266574dd5333a0b4b1181b4e6e4 to your computer and use it in GitHub Desktop.
Save re-polm/71ec1266574dd5333a0b4b1181b4e6e4 to your computer and use it in GitHub Desktop.
import bpy
from bpy import context
import numpy as np
REX_BLOCK_HEADER_SIZE = 16
REX_MESH_HEADER_SIZE = 128
REX_NOT_SET = np.uint64(0x7fffffffffffffff).byteswap().tobytes()
def mesh_triangulate(me):
import bmesh
bm = bmesh.new()
bm.from_mesh(me)
bmesh.ops.triangulate(bm, faces=bm.faces)
bm.to_mesh(me)
bm.free()
filepath = "/tmp/simple_rex.rex"
print('save to {}'.format(filepath))
obj = context.object
mesh = obj.data
mesh_triangulate(mesh)
numtriangles = len(mesh.polygons)
block_byte_count = REX_BLOCK_HEADER_SIZE + REX_MESH_HEADER_SIZE \
+ len(mesh.vertices)*12 + 0*12 + 0*8 + 0*12 + numtriangles*12
version = np.uint16(1).byteswap().tobytes()
blocktype = np.uint16(3).byteswap().tobytes() # 3 = mesh
blocksize = np.uint32(block_byte_count).byteswap().tobytes()
blockid = np.uint64(0).byteswap().tobytes()
# mesh description
lod = np.uint16(1).byteswap().tobytes()
maxLod = np.uint16(1).byteswap().tobytes()
nrOfVtxCoords = np.uint32(len(mesh.vertices)).byteswap().tobytes() # number of vertex coordinates
nrOfNorCoords = np.uint32(0).byteswap().tobytes() # number of normal coordinates (can be zero)
nrOfTexCoords = np.uint32(0).byteswap().tobytes() # number of texture coordinates (can be zero)
nrOfVtxColors = np.uint32(0).byteswap().tobytes() # number of vertex colors (can be zero)
nrTriangles = np.uint32(numtriangles).byteswap().tobytes() # number of triangles
materialId = REX_NOT_SET # np.uint64(1) # id which refers to the corresponding material block in this file
name = bytearray(b'testmesh')
size = np.uint16(len(name)).byteswap().tobytes() # size of the following string name
startDataBlock = 128
startVtxCoords = np.uint32(startDataBlock).byteswap().tobytes() # start vertex coordinate block (relative to mesh block start)
startNorCoords = np.uint32(startDataBlock + len(mesh.vertices)*12).byteswap().tobytes() # start vertex normals block (relative to mesh block start)
startTexCoords = np.uint32(startDataBlock + len(mesh.vertices)*12).byteswap().tobytes() # start of texture coordinate block (relative to mesh block start)
startVtxColors = np.uint32(startDataBlock + len(mesh.vertices)*12).byteswap().tobytes() # start of colors block (relative to mesh block start)
startTriangles = np.uint32(startDataBlock + len(mesh.vertices)*12).byteswap().tobytes() # start triangle block for vertices (relative to mesh block start)
header = blocktype + version + blocksize + blockid
meshheader = lod + maxLod + nrOfVtxCoords + nrOfNorCoords + nrOfTexCoords \
+ nrOfVtxColors + nrTriangles + materialId + size + name
meshdata = bytearray()
for v in mesh.vertices:
meshdata = meshdata + np.array(v.co[:]).astype('float32').byteswap().tobytes()
for p in mesh.polygons:
for vid in p.vertices:
meshdata = meshdata + np.uint32(vid + 1).byteswap().tobytes()
with open(filepath, 'w+b') as f:
f.write(header + meshheader + meshdata)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment