Thanks again for the test models guys, helped bunches. I've got all the data in correctly for all the test cases. Or as Jim would say... "Is everybody in? The ceremony is about to begin..."
I might get serious on this tonight and try and get the models built. That should be the fun part. Another look at marstone's blender 2.4 version should help. (and the stock lwo and 3ds imports...)
the data import (may need tidying up as I build the model... its simple enough not to need its own classes and object oriented design... I think I can get away with a one, two procedural punch for this task):
bl_addon_info= {
"name": "Import StarFleet Command Models",
"author": "Bonk",
"version": (0, 1),
"blender": (2, 5, 5),
"api": 31847,
"location": "File > Import > StarFleet Command Model (.mod)",
"description": "Imports a StarFleet Command model file.",
"warning": "The universe may implode at any moment.",
"wiki_url": "http://www.dynaverse.net/wiki/index.php?title=Blender:SFC_Models",
"category": "Import/Export"}
import os
import io
import time
import struct
import chunk
# import array
import bpy
import math
import mathutils
def decodeAsc(byteStr):
print (byteStr.decode("ascii"))
def import_mod(filename,context):
print (filename)
name, ext= os.path.splitext(os.path.basename(filename))
file= open(filename, 'rb')
# Header
try:
modHdrTag, \
modHdrFileSize, \
modHdrVersion, \
modHdrRadius, \
modHdrTotalLODs, \
modHdrLODHyst \
= struct.unpack("<4siIfif", file.read(24))
print ("modHdrTag: " + modHdrTag.decode("ascii"))
print ("modHdrFileSize: %d" % modHdrFileSize)
print ("modHdrVersion: %d" % modHdrVersion)
print ("modHdrRadius: %f" % modHdrRadius)
print ("modHdrTotalLODs: %d" % modHdrTotalLODs)
print ("modHdrLODHyst: %f " % modHdrLODHyst)
modHdrLODTrans \
= struct.unpack("<%df" % modHdrLODHyst, file.read(int(modHdrLODHyst)*4))
print ("modHdrLODTrans:")
print (modHdrLODTrans)
except:
print("Error parsing file header. Boo!")
file.close()
return
if modHdrTag != b'MDLS':
print("Error parsing file header. Boo!")
file.close()
return
modMeshesParsed = 0
modMeshes = list()
while modMeshesParsed < modHdrTotalLODs:
modChnkTag, \
modChnkSize \
= struct.unpack("<4si", file.read(8))
# Strings
if modChnkTag == b'STRS':
modStrSizePadded = 4*(math.ceil(modChnkSize/4))
print ("modChnkTag: " + modChnkTag.decode("ascii"))
print ("modChnkSize: %d" % modChnkSize)
print ("modStrSizePadded: %d" % modStrSizePadded)
modStrPool \
= struct.unpack("<%ds" % modStrSizePadded, file.read(modStrSizePadded))
modStrStrings = modStrPool[0].split(b'\x00')
modStrList = [x.decode("ascii") for x in modStrStrings]
print ("modStrList: ")
print (modStrList)
# Named Points
elif modChnkTag == b'PNTS':
modPtsStart = file.tell()
print ("modChnkTag: " + modChnkTag.decode("ascii"))
print ("modChnkSize: %d" % modChnkSize)
modPtsNum = modChnkSize / 16
print ("modPtsNum: %d" % modPtsNum)
modPts = list()
while (file.tell() - modPtsStart < modChnkSize):
modPts.append(struct.unpack("<fffi", file.read(16)))
print ("(last)modPts:")
print (modPts[-1])
# Materials (aieee!)
elif modChnkTag == b'MATS':
modMtsStart = file.tell()
print ("modChnkTag: " + modChnkTag.decode("ascii"))
print ("modChnkSize: %d" % modChnkSize)
modMtsFlags = list()
modMts = list()
while (file.tell() - modMtsStart < modChnkSize):
modMtsFlags.append(struct.unpack("<i", file.read(4)))
if modMtsFlags[-1][0] > 20:
modMts.append(struct.unpack("<Ifffiiii", file.read(32)))
else:
modMts.append(struct.unpack("<Ifffii", file.read(24)))
print ("modMtsFlags:")
print (modMtsFlags)
print ("(last)modMts:")
print (modMts[-1])
# Geometries
elif modChnkTag == b'MOD0':
modModVerticesNum, \
modModFacesNum \
= struct.unpack("<ii", file.read(8))
print ("modChnkTag: " + modChnkTag.decode("ascii"))
print ("modChnkSize: %d" % modChnkSize)
print ("modModVerticesNum: %d" % modModVerticesNum)
print ("modModFacesNum: %d" % modModFacesNum)
modVtxTag, \
modVtxSize \
= struct.unpack("<4si", file.read(8))
modVtxStart = file.tell()
print ("modVtxTag: " + modVtxTag.decode("ascii"))
print ("modVtxSize: %d" % modVtxSize)
modVtx = list()
while (file.tell() - modVtxStart < modVtxSize):
modVtx.append(struct.unpack("<fff", file.read(12)))
print ("(last)modVtx: ")
print (modVtx[-1])
modPlysStart = file.tell()
modPlys = list()
modPlysCount = 0
while (modPlysCount < modModFacesNum):
modPly = list()
modPlyTag, \
modPlySize, \
modPlyVtxCount, \
modPlyMtlIdx \
= struct.unpack("<4siii", file.read(16))
# print ("modPlyTag: " + modPlyTag.decode("ascii"))
# print ("modPlySize: %d" % modPlySize)
# print ("modPlyVtxCount: %d" % modPlyVtxCount)
# print ("modPlyMtlIdx: %d" % modPlyMtlIdx)
modPlyNorm \
= struct.unpack("<fff", file.read(12))
# print ("modPlyNorm:")
# print (modPlyNorm)
modPlyVtxsStart = file.tell()
modPlyVtxs = list()
while (file.tell() - modPlyVtxsStart < modPlyVtxCount*28):
modPlyVtxs.append(struct.unpack("<HHffffff", file.read(28)))
# print ("modPlyVtxs:")
# print (modPlyVtxs)
modPly.append(modPlyTag)
modPly.append(modPlySize)
modPly.append(modPlyVtxCount)
modPly.append(modPlyMtlIdx)
modPly.append(modPlyNorm)
modPly.append(modPlyVtxs)
modPlys.append(modPly)
modPlysCount += 1
modMeshes.append(modModVerticesNum)
modMeshes.append(modModFacesNum)
modMeshes.append(modVtx)
modMeshes.append(modPlys)
print ("(last)modPlys:")
print (modMeshes[-1][3][-1])
print (file.tell())
modMeshesParsed += 1
file.close()
from bpy.props import *
class IMPORT_OT_mod(bpy.types.Operator):
'''Import MOD Operator.'''
bl_idname= "import.mod"
bl_label= "Import MOD"
bl_description= "Import a StarFleet Command model."
bl_options= {'REGISTER', 'UNDO'}
filepath= StringProperty(name="File Path", description="Filepath used for importing the model file", maxlen=1024, default="")
def execute(self, context):
import_mod(self.filepath,
context)
return {'FINISHED'}
def invoke(self, context, event):
wm= context.window_manager
wm.add_fileselect(self)
return {'RUNNING_MODAL'}
def menu_func(self, context):
self.layout.operator(IMPORT_OT_mod.bl_idname, text="StarFleet Command Model (.mod)")
def register():
bpy.types.INFO_MT_file_import.append(menu_func)
def unregister():
bpy.types.INFO_MT_file_import.remove(menu_func)
if __name__ == "__main__":
register()