From 8119a2ac0b44b06b8009a45a8bb43cedd3ffd48b Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Sun, 23 May 2021 23:18:37 -0500 Subject: [PATCH] improving test import; applying zeroedit import logic but for blender --- src/blender_addon/io_mesh_msh2/export_msh2.py | 2 +- src/blender_addon/io_mesh_msh2/import_msh2.py | 455 ++++++++++++++++-- 2 files changed, 427 insertions(+), 30 deletions(-) diff --git a/src/blender_addon/io_mesh_msh2/export_msh2.py b/src/blender_addon/io_mesh_msh2/export_msh2.py index 43c76c2..d54c23d 100644 --- a/src/blender_addon/io_mesh_msh2/export_msh2.py +++ b/src/blender_addon/io_mesh_msh2/export_msh2.py @@ -53,7 +53,7 @@ def save(context, ): msh_handler.export_file(filepath) - return {'FINISHED'} + return {'FINISHED'} # # _write(context, filepath, # EXPORT_TRI=use_triangles, diff --git a/src/blender_addon/io_mesh_msh2/import_msh2.py b/src/blender_addon/io_mesh_msh2/import_msh2.py index c12ce3a..ed4a29f 100644 --- a/src/blender_addon/io_mesh_msh2/import_msh2.py +++ b/src/blender_addon/io_mesh_msh2/import_msh2.py @@ -29,6 +29,376 @@ from .msh2 import msh2 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, filepath, *, @@ -51,6 +421,14 @@ def load(context, This function passes the file and sends the data off 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 = msh_handler.get_mesh_obj() sceen = bpy.context.scene @@ -58,39 +436,58 @@ def load(context, # Test adding mesh2 to blender for model in msh.models: name = model.name.decode("utf-8") - # print(model) - # print(model.name) - # print(model.index) - # print(model.collection) - # print("") - # Create a mesh data block - mesh2 = bpy.data.meshes.new("{}".format(name)) + type = model.model_type + if 'geo' in type: + if model.collprim: + continue + # self.build_prim() + elif name.startswith('c_'): # and self.get_c_prim_data(): + 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 = [] - edges = [] - faces = [] - segments = model.segments - for segment in segments: - if segment.classname == "SegmentGeometry": - vertices = segment.vertices - for vert in vertices: - x = vert.x - y = vert.y - z = vert.z - verts.append((x, y, z)) + verts = [] + edges = [] + faces = [] + offset = 0 + segments = model.segments + for segment in segments: + if segment.classname == "SegmentGeometry": + vertices = segment.vertices + for vert in vertices: + x = vert.x + y = vert.y + z = vert.z + verts.append((x, y, z)) - sfaces = segment.faces - for face in sfaces: - '''Using CCW order for importing.''' - faces.append(face.SIindices()) + sfaces = segment.faces + for face in sfaces: + '''Using CCW order for importing.''' + 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 - mesh2.from_pydata(verts, edges, faces) + faces.append(sii) - # Create an object that uses the mesh data - myobj = bpy.data.objects.new("{}_obj".format(name), mesh2) + offset += len(segment.vertices) - # Link the object to the scene - sceen.objects.link(myobj) + # 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) return {'FINISHED'}