improving test import; applying zeroedit import logic but for blender

This commit is contained in:
itdominator 2021-05-23 23:18:37 -05:00
parent 7e88fcc785
commit 8119a2ac0b
2 changed files with 427 additions and 30 deletions

View File

@ -53,7 +53,7 @@ def save(context,
): ):
msh_handler.export_file(filepath) msh_handler.export_file(filepath)
return {'FINISHED'} return {'FINISHED'}
# #
# _write(context, filepath, # _write(context, filepath,
# EXPORT_TRI=use_triangles, # EXPORT_TRI=use_triangles,

View File

@ -29,6 +29,376 @@ from .msh2 import msh2
msh_handler = msh2.MSH2(None) msh_handler = msh2.MSH2(None)
from .msh2 import msh2_unpack
from .msh2 import msh2_crc
class MshImportError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return str(self.msg)
# class MaterialBuilder(object):
#
# def __init__(self, imp, msh):
# self.msh = msh
# self.imp = imp
# # self.xsi = self.imp.xsi
# # self.pb = self.imp.pb
#
# def build(self):
# logging.info('Building {0} materials.'.format(len(self.msh.materials)))
# coll = self.msh.materials
# if len(coll) < 1:
# logging.debug('No materials in collection.')
# return ()
# matlib = self.xsi.ActiveProject.ActiveScene.ActiveMaterialLibrary
# materials = {}
# for mat in coll:
# logging.info('Building Material {0}.'.format(mat.name))
# simat = matlib.CreateMaterial('Phong', mat.name)
# # Colors.
# shader = simat.Shaders(0)
# col = shader.Parameters('diffuse').Value
# col.Red = mat.diff_color.red
# col.Green = mat.diff_color.green
# col.Blue = mat.diff_color.blue
# col.Alpha = mat.diff_color.alpha
#
# col = shader.Parameters('ambient').Value
# col.Red = mat.ambt_color.red
# col.Green = mat.ambt_color.green
# col.Blue = mat.ambt_color.blue
# col.Alpha = mat.ambt_color.alpha
#
# col = shader.Parameters('specular').Value
# col.Red = mat.spec_color.red
# col.Green = mat.spec_color.green
# col.Blue = mat.spec_color.blue
# col.Alpha = mat.spec_color.alpha
#
# shader.Parameters('shiny').Value = mat.gloss
#
# # Image.
# if mat.tex0:
# if self.imp.config.get('btexpath'):
# imgfolder = self.imp.config.get('texpath')
# else:
# imgfolder = os.path.dirname(self.imp.config.get('path'))
# imgshader = self.xsi.CreateShaderFromPreset('$XSI_DSPRESETS\\Shaders\\Texture\\Image.Preset', simat)
# imgpath = os.path.join(imgfolder, mat.tex0)
# img_clip = self.xsi.SICreateImageClip2(imgpath)
# self.xsi.SIConnectShaderToCnxPoint(img_clip, imgshader.tex, False)
# self.xsi.SIConnectShaderToCnxPoint(imgshader, simat.Shaders(0).Parameters('diffuse'), False)
# # ZEFlags.
# simat2 = self.get_si_mat(mat)
# if simat2:
# self.add_flag_prop(simat2, mat)
# materials[mat.name] = simat
# logging.info('Finished building {0}.'.format(mat.name))
# logging.info('Finished building materials.')
# return materials
#
# def get_si_mat(self, mat):
# name = mat.name
# mats = self.imp.material_name_dict()
# try:
# mat = mats[name]
# return mat
# except KeyError:
# logging.exception('Couldnt find material {0}.'.format(name))
# return None
#
# def add_flag_prop(self, simat, mat):
# pset = simat.AddProperty('CustomProperty', False, 'ZeroEngine Flags')
# pset.AddParameter3('tex1', const.siString, mat.tex1)
# pset.AddParameter3('tex2', const.siString, mat.tex2)
# pset.AddParameter3('tex3', const.siString, mat.tex3)
#
# if mat.flags[4][1]:
# transp = 2
# elif mat.flags[5][1]:
# transp = 1
# else:
# transp = 0
# pset.AddParameter3('emissive', const.siBool, mat.flags[7][1], '', '', 0)
# pset.AddParameter3('glow', const.siBool, mat.flags[6][1], '', '', 0)
# pset.AddParameter3('transparency', const.siInt4, transp, 0, 2, 0)
# pset.AddParameter3('hardedged', const.siBool, mat.flags[3][1], '', '', 0)
# pset.AddParameter3('perpixel', const.siBool, mat.flags[2][1], '', '', 0)
# pset.AddParameter3('additive', const.siBool, mat.flags[1][1], '', '', 0)
# pset.AddParameter3('specular', const.siBool, mat.flags[0][1], '', '', 0)
# pset.AddParameter3('rendertype', const.siInt4, mat.render_type, 0, 31, 0)
# pset.AddParameter3('data0', const.siInt4, mat.data0, 0, 255, 0)
# pset.AddParameter3('data1', const.siInt4, mat.data1, 0, 255, 0)
#
# lay = pset.PPGLayout
#
# lay.AddGroup('ZeroEngine Material Flags', 1)
# lay.AddGroup('Additional Textures', 1)
# lay.AddItem('tex1', 'Texture 1')
# lay.AddItem('tex2', 'Texture 2')
# lay.AddItem('tex3', 'Texture 3')
# lay.EndGroup()
# lay.AddGroup('Flags', 1)
# lay.AddItem('emissive', 'Emissive')
# lay.AddItem('glow', 'Glow')
# lay.AddItem('transparency', 'Transparency')
# lay.AddItem('hardedged', 'Hardedged Transparency')
# lay.AddItem('perpixel', 'Per-Pixel Lighting')
# lay.AddItem('additive', 'Additive Transparency')
# lay.AddItem('specular', 'Specular')
# lay.AddItem('rendertype', 'RenderType')
# lay.AddItem('data0', 'Data0')
# lay.AddItem('data1', 'Data1')
# lay.EndGroup()
# lay.EndGroup()
class ChainItemBuilder:
prim_types = {0: 'Sphere',
1: 'Sphere',
2: 'Cylinder',
4: 'Cube'}
cloth_prim_types = {0: 'Sphere',
1: 'Cylinder',
2: 'Cube'}
def __init__(self, model, chainbuilder):
self.model = model
# Will be set in build() after the model is built.
self.si_model = None
self.chainbuilder = chainbuilder
self.geo = None
def build(self):
'''Builds an object depending on the model type.'''
if 'geo' in self.model.model_type:
if self.model.collprim:
pass
# self.build_prim()
elif self.model.name.startswith(b'c_'): # and self.get_c_prim_data():
pass
# self.build_c_prim()
else:
self.build_geo()
# if self.model.model_type == 'null' or self.model.model_type == 'bone':
# self.build_null()
# elif self.model.model_type == 'geoshadow':
# self.build_shadow()
# elif 'geo' in self.model.model_type:
# if self.model.collprim:
# self.build_prim()
# elif self.model.name.startswith('c_') and self.get_c_prim_data():
# self.build_c_prim()
# else:
# self.build_geo()
# elif self.model.model_type == 'cloth':
# self.build_cloth()
# else:
# raise MshImportError('Unsupported model type {0} on {1}.'.format(self.model.model_type,
# self.model.name))
return self.si_model
def build_geo(self):
# logging.info('Building {0} as polymesh(originally {1}).'.format(self.model.name, self.model.model_type))
# verts = self.get_vertex_positions()
vertices = self.get_vertex_positions()
faces = self.get_faces()
verts = []
edges = []
name = self.model.name.decode("utf-8")
# print(verts)
# print(faces)
# print("")
mesh2 = bpy.data.meshes.new("{}_obj".format(name))
# Add the vertices to the mesh
mesh2.from_pydata(verts, edges, faces)
# Create an object that uses the mesh data
myobj = bpy.data.objects.new("{}".format(name), mesh2)
# Link the object to the scene
sceen.objects.link(myobj)
# logging.info('Building {0} as polymesh(originally {1}).'.format(self.model.name, self.model.model_type))
# vertex_positions = self.get_vertex_positions()
# faces = self.get_faces()
# if self.model.parent_name:
# parent = self.chainbuilder.name_dict[self.model.parent_name]
# else:
# parent = self.xsi.ActiveSceneRoot
# if not parent:
# logging.error('Cant find parent {0} for {1}.'.format(self.model.parent_name,
# self.model.name))
# if len(vertex_positions) == 0:
# logging.info('Building {0} as null (originally {1}) because no geometry information was found.'.format(self.model.name, self.model.model_type))
# self.build_null()
# return
# try:
# with zetcore.Timer('Built polygon mesh in %ss %sms.'):
# self.si_model = parent.AddPolygonMesh(vertex_positions,
# faces,
# self.model.name)
# except com_error:
# logging.exception('verts: {0}, faces: {1}, name: {2}.'.format(vertex_positions,
# faces, self.model.name))
# self.imp.abort_checklog()
# self.geo = self.si_model.ActivePrimitive.GetGeometry2(0)
#
# # if self.model.vis == 1:
# # self.xsi.ToggleVisibility(self.si_model, None, None)
#
# self.process_normals()
# self.process_uvs()
# self.process_colors()
#
# with zetcore.Timer('Creating segments in %ss %sms.'):
# if len(self.model.segments) > 1:
# logging.debug('Model {0} has {1} segments, creating poly clusters.'.format(self.model.name, len(self.model.segments)))
# self.create_poly_clusters()
# else:
# self.xsi.SIAssignMaterial(self.si_model,
# self.chainbuilder.materials[self.model.segments[0].material.name])
#
# self.set_transform()
# self.set_vis()
def get_vertex_positions(self):
v_pos = []
for segment in self.model.segments:
for vert in segment.vertices:
v_pos.append(vert.pos)
return v_pos
def get_faces(self):
faces = []
offset = 0
numfaces = 0
for segment in self.model.segments:
for face in segment.faces:
numfaces += 1
# faces.append(face.sides)
sii = face.SIindices()
print(sii)
if len(sii) == 4:
sii = (sii[0] + offset, sii[1] + offset,
sii[2] + offset, sii[3] + offset)
else:
sii = (sii[0] + offset, sii[1] + offset, sii[2] + offset)
print("")
print(sii)
faces.append(sii)
offset += len(segment.vertices)
return faces
class ChainBuilder(object):
def __init__(self, imp, msh, materials=None):
self.msh = msh
self.imp = imp
self.materials = materials
self.scn = bpy.context.scene
self.name_dict = {}
def build(self):
coll = self.msh.models
lencoll = len(coll)
chain = []
for ind, model in enumerate(coll):
builder = ChainItemBuilder(model, self)
item = builder.build()
self.name_dict[model.name] = item
chain.append(item)
return chain
class Import:
def __init__(self, config = None):
self.msh = None
self.config = config
def do_import(self, path):
'''Actual import function.'''
unpacker = msh2_unpack.MSHUnpack(path)
try:
self.msh = unpacker.unpack()
except (msh2_crc.CRCError, msh2_unpack.UnpackError):
pass
ignoregeo = False
ignoreanim = True
if not ignoregeo:
# matbuilder = MaterialBuilder(self, self.msh)
# materials = matbuilder.build()
materials = {}
builder = ChainBuilder(self, self.msh, materials)
else:
builder = ChainBuilder(self, self.msh)
try:
self.chain = builder.build()
except MshImportError:
enveloper = Enveloper(self, self.msh, self.chain)
enveloper.envelope()
if not self.msh.animation.empty and not ignoreanim:
anim = AnimationImport(self, self.chain, self.msh.animation.bones)
anim.import_()
def load(context, def load(context,
filepath, filepath,
*, *,
@ -51,6 +421,14 @@ def load(context,
This function passes the file and sends the data off This function passes the file and sends the data off
to be split into objects and then converted into mesh objects to be split into objects and then converted into mesh objects
""" """
# ZEROEDIT IMPORTER CONVERSION TO BLENDER
# importer = Import()
# importer.do_import(filepath)
# return {'FINISHED'}
# TEST IMPORT TO BLENDER
msh_handler.import_file(filepath) msh_handler.import_file(filepath)
msh = msh_handler.get_mesh_obj() msh = msh_handler.get_mesh_obj()
sceen = bpy.context.scene sceen = bpy.context.scene
@ -58,39 +436,58 @@ def load(context,
# Test adding mesh2 to blender # Test adding mesh2 to blender
for model in msh.models: for model in msh.models:
name = model.name.decode("utf-8") name = model.name.decode("utf-8")
# print(model) type = model.model_type
# print(model.name) if 'geo' in type:
# print(model.index) if model.collprim:
# print(model.collection) continue
# print("") # self.build_prim()
# Create a mesh data block elif name.startswith('c_'): # and self.get_c_prim_data():
mesh2 = bpy.data.meshes.new("{}".format(name)) continue
# self.build_c_prim()
else:
# print(model)
# print(model.name)
# print(model.index)
# print(model.collection)
# print("")
# Create a mesh data block
mesh2 = bpy.data.meshes.new("{}_obj".format(name))
verts = [] verts = []
edges = [] edges = []
faces = [] faces = []
segments = model.segments offset = 0
for segment in segments: segments = model.segments
if segment.classname == "SegmentGeometry": for segment in segments:
vertices = segment.vertices if segment.classname == "SegmentGeometry":
for vert in vertices: vertices = segment.vertices
x = vert.x for vert in vertices:
y = vert.y x = vert.x
z = vert.z y = vert.y
verts.append((x, y, z)) z = vert.z
verts.append((x, y, z))
sfaces = segment.faces sfaces = segment.faces
for face in sfaces: for face in sfaces:
'''Using CCW order for importing.''' '''Using CCW order for importing.'''
faces.append(face.SIindices()) sii = face.SIindices()
if len(sii) == 4:
sii = (sii[0] + offset, sii[1] + offset,
sii[2] + offset, sii[3] + offset)
else:
sii = (sii[0] + offset, sii[1] + offset, sii[2] + offset)
# Add the vertices to the mesh faces.append(sii)
mesh2.from_pydata(verts, edges, faces)
# Create an object that uses the mesh data offset += len(segment.vertices)
myobj = bpy.data.objects.new("{}_obj".format(name), mesh2)
# Link the object to the scene # Add the vertices to the mesh
sceen.objects.link(myobj) mesh2.from_pydata(verts, edges, faces)
# Create an object that uses the mesh data
myobj = bpy.data.objects.new("{}".format(name), mesh2)
# Link the object to the scene
sceen.objects.link(myobj)
return {'FINISHED'} return {'FINISHED'}