For what i can say to you from my experience, the best way to store object data is with .obj files. They are smaller and can be modified by whatever program. If you look at the example used by ideasman42 while presenting a video using the Dynamic Loading feature he implemented you’ll understand what i mean.
Here the script (it’s outdated, and i haven’t corrected it to work properly, but i’ll do in a few time)
def import_obj_file(file, data_name="MyMesh"):
verts, faces = [], []
for line in file.readlines():
words = line.split()
if len(words) == 0 or words[0].startswith(b'#'):
pass
elif words[0] == b'v':
verts.append( (float(words[1]), float(words[2]), float(words[3])) )
elif words[0] == b'f':
faces.append( [int(vi)-1 for vi in words[1:]] )
file.close()
# create the mesh
import bpy
def flatten_list(list_of_tuples):
return [i for t in list_of_tuples for i in t]
def unpack_face_list(list_of_tuples):
l = []
for t in list_of_tuples:
if len(t)==3:
l.extend([t[0], t[1], t[2], 0])
else:
l.extend([t[0],t[1],t[2],0, t[0],t[2],t[3],0])
return l
verts_flat = flatten_list(verts)
faces_flat = unpack_face_list(faces)
me= bpy.data.meshes.new(data_name)
me.add_geometry(len(verts), 0, int(len(faces_flat)/4))
me.verts.foreach_set("co", verts_flat)
me.faces.foreach_set("verts", faces_flat)
me.update()
me.name = data_name
print (" ", data_name, "faces:", len(me.faces))
def import_obj_gz(path, data_name):
import_obj_file(gzip.open(path, 'r'), data_name) # for non gz open(path, 'r')
import gzip, os, GameLogic
sce = GameLogic.getCurrentScene()
own = GameLogic.getCurrentController().owner
dummy = sce.objectsInactive["DUMMY"]
path = GameLogic.expandPath("//") + "/"
def main():
OBJ_INDEX = GameLogic.OBJ_INDEX = getattr(GameLogic, 'OBJ_INDEX', -1) + 1
#print(OBJ_INDEX)
if OBJ_INDEX == 0:
OBJ_FILES = GameLogic.OBJ_FILES = [f for f in os.listdir(path) if f.endswith('.gz')]
OBJ_FILES.sort()
OBJ_FILES.reverse() # smallest first.
else:
OBJ_FILES = GameLogic.OBJ_FILES
if OBJ_INDEX < len(OBJ_FILES):
f = OBJ_FILES[OBJ_INDEX]
id = f.split('.')[0]
import_obj_gz(path+f, id)
ob = sce.addObject(dummy, own)
# ob.localPosition.x += OBJ_INDEX*0.1
ob.replaceMesh(GameLogic.LibNew(f, 'Mesh', [id])[0])
m = ob.meshes[0]
print(m.numPolygons, m.getVertexArrayLength(0))
'''
if m.numPolygons:
print("OK")
ob.reinstancePhysicsMesh()
'''
else:
OBJ_INDEX = OBJ_INDEX % len(OBJ_FILES)
if GameLogic.LibFree(OBJ_FILES[OBJ_INDEX]):
print(" ", "freeing:", OBJ_FILES[OBJ_INDEX])
else:
GameLogic.OBJ_INDEX = -1 # none left, restart
With the script he reads from the obj file the data about vertices and faces, and then creates the mesh (Just look at the obj_importer script to get an idea of how this can be done, even loading the material) and creates a new Lib. Then uses this new lib to assign the new mesh to a “dummy” object… May be a bit tricky, but i found it’s the best way to handle lots of objects…