Added research data, testing blender mesh generation
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 2
|
||||
@@ -18,8 +18,8 @@
|
||||
from .msh2 import msh2
|
||||
|
||||
|
||||
msh = msh2.MSH2(None)
|
||||
bl_info = {
|
||||
msh_handler = msh2.MSH2(None)
|
||||
bl_info = {
|
||||
"name": "Zero Editor MSH2 format",
|
||||
"author": "Maxim Stewart",
|
||||
"version": (0, 0, 1),
|
||||
@@ -100,8 +100,49 @@ class ImportMSH2(bpy.types.Operator, ImportHelper, IOOBJOrientationHelper):
|
||||
import os
|
||||
keywords["relpath"] = os.path.dirname(bpy.data.filepath)
|
||||
|
||||
data = {**keywords}
|
||||
msh.import_file(data["filepath"])
|
||||
data = {**keywords}
|
||||
msh_handler.import_file(data["filepath"])
|
||||
msh = msh_handler.get_mesh_obj()
|
||||
sceen = bpy.context.scene
|
||||
|
||||
# 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))
|
||||
|
||||
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))
|
||||
|
||||
sfaces = segment.faces
|
||||
for face in sfaces:
|
||||
'''Using CCW order for importing.'''
|
||||
faces.append(face.SIindices())
|
||||
|
||||
# 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("{}_obj".format(name), mesh2)
|
||||
|
||||
# Link the object to the scene
|
||||
sceen.objects.link(myobj)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
|
||||
@@ -6,8 +6,12 @@
|
||||
from msh2 import msh2
|
||||
|
||||
|
||||
msh = msh2.MSH2(None)
|
||||
msh_wrapper = msh2.MSH2(None)
|
||||
|
||||
msh.import_file("../../msh/all_weap_inf_lightsabre.msh")
|
||||
# /home/abaddon/Downloads/my-py-msh-parser/msh/KAS/msh
|
||||
msh_wrapper.import_file("../../msh/KAS/msh/kas2_prop_rock_L.msh")
|
||||
msh_wrapper.export_file("kas2_prop_rock_L.msh")
|
||||
|
||||
# msh.export_file("all_weap_inf_lightsabre.msh")
|
||||
|
||||
# msh_wrapper.import_file("../../msh/uta1_prop_gunship.msh")
|
||||
# msh_wrapper.export_file("uta1_prop_gunship.msh")
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# Python imports
|
||||
import faulthandler
|
||||
import traceback
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
# Gtk imports
|
||||
|
||||
@@ -18,15 +20,31 @@ class MSH2():
|
||||
self.msh = None
|
||||
|
||||
|
||||
def get_mesh_obj(self):
|
||||
return self.msh
|
||||
|
||||
def import_file(self, file_name):
|
||||
try:
|
||||
self.msh = msh2_unpack.MSHUnpack(file_name, self.msh_config).unpack()
|
||||
unpacker = msh2_unpack.MSHUnpack(file_name, self.msh_config)
|
||||
self.msh = unpacker.unpack()
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
|
||||
def export_file(self, file_name):
|
||||
def export_file(self, file):
|
||||
logging.info('==========================================')
|
||||
logging.info('Starting export at {0}.'.format(datetime.now()))
|
||||
logging.info('.msh file path: {0}'.format(file))
|
||||
try:
|
||||
self.msh.save(file_name)
|
||||
# Convert materials from Blender to msh2.
|
||||
# self.msh.materials = msh2.MaterialCollection(self.msh)
|
||||
# self.msh.materials.replace([])
|
||||
|
||||
self.msh.models.assign_indices()
|
||||
self.msh.models.assign_parents()
|
||||
self.msh.models.remove_multi([])
|
||||
self.msh.models.assign_cloth_collisions()
|
||||
|
||||
self.msh.save(file)
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
@@ -131,10 +131,17 @@ def return_lowest_bits(n):
|
||||
return n & 0xFFFFFFFF
|
||||
|
||||
|
||||
def crc(string):
|
||||
def crc(_string):
|
||||
'''Calculate the Zero CRC from string and return it as number.'''
|
||||
crc_ = 0
|
||||
crc_ = return_lowest_bits(~crc_)
|
||||
crc_ = 0
|
||||
crc_ = return_lowest_bits(~crc_)
|
||||
# string = _string.decode("ascii")
|
||||
string = _string.decode("utf-8")
|
||||
print("")
|
||||
print("")
|
||||
print(string)
|
||||
print("")
|
||||
print("")
|
||||
if string:
|
||||
for char in string:
|
||||
ind = (crc_ >> 24)
|
||||
|
||||
@@ -7,7 +7,13 @@
|
||||
for more information regarding the file format.
|
||||
'''
|
||||
import os
|
||||
import itertools
|
||||
# import itertools
|
||||
# iZip is only available in 2.x
|
||||
try:
|
||||
from itertools import izip as zip
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
import struct
|
||||
import math
|
||||
# import logging
|
||||
@@ -16,9 +22,9 @@ import math
|
||||
from .Logger import Logger
|
||||
logging = Logger("Msh2").get_logger()
|
||||
|
||||
# import json
|
||||
try:
|
||||
import bson
|
||||
json = bson
|
||||
import bson as json
|
||||
except Exception as e:
|
||||
import json
|
||||
|
||||
@@ -120,6 +126,10 @@ class Msh(Packer):
|
||||
with open(filepath, 'wb') as fh:
|
||||
fh.write(self.pack())
|
||||
|
||||
def save_unchanged(self, filepath):
|
||||
with open(filepath, 'wb') as fh:
|
||||
fh.write(self.repack())
|
||||
|
||||
def save_json(self, filepath):
|
||||
'''Saves the .msh in JSON format.'''
|
||||
data = {
|
||||
@@ -326,7 +336,7 @@ class SceneInfo(Packer):
|
||||
def pack(self):
|
||||
'''Packs the scene information data.'''
|
||||
data = [b'SINF']
|
||||
data.append('size_ind')
|
||||
data.append('size')
|
||||
data.append(self.pack_NAME())
|
||||
data.append(self.pack_FRAM())
|
||||
data.append(self.bbox.pack())
|
||||
@@ -459,7 +469,7 @@ class Material(Packer):
|
||||
def pack(self):
|
||||
'''Packs the material into a MATD chunk.'''
|
||||
data = [b'MATD']
|
||||
data.append('size_indicator')
|
||||
data.append('size')
|
||||
data.append(self.pack_NAME())
|
||||
data.append(self.pack_DATA())
|
||||
data.append(self.pack_ATRB())
|
||||
@@ -660,7 +670,7 @@ class Model(Packer):
|
||||
|
||||
@classmethod
|
||||
def load_segmented_json(cls, folder, name):
|
||||
logging.debug('LOADING SEGMENTED MODEL %s %s', folder, name)
|
||||
# logging.debug('LOADING SEGMENTED MODEL %s %s', folder, name)
|
||||
with open(os.path.join(folder, '{0}.txt'.format(name)), 'r') as fh:
|
||||
model = Model.from_json(json.loads(fh.read()))
|
||||
seg_start = '{0} seg '.format(name)
|
||||
@@ -734,7 +744,7 @@ class Model(Packer):
|
||||
|
||||
def pack(self):
|
||||
'''Packs the MODL chunk. This should be used to retrieve the model in packed form.'''
|
||||
data = [b'MODL', 'sizeind']
|
||||
data = [b'MODL', 'size']
|
||||
data.append(self.pack_MTYP())
|
||||
data.append(self.pack_MNDX())
|
||||
data.append(self.pack_NAME())
|
||||
@@ -797,7 +807,7 @@ class Model(Packer):
|
||||
|
||||
def repack(self):
|
||||
'''Repacks the MODL chunk. This should be used to retrieve the model in packed form.'''
|
||||
data = [b'MODL', 'sizeind']
|
||||
data = [b'MODL', 'size']
|
||||
data.append(self.pack_MTYP())
|
||||
data.append(self.pack_MNDX())
|
||||
data.append(self.pack_NAME())
|
||||
@@ -915,7 +925,7 @@ class ModelCollection(object):
|
||||
'''Get model.index for model with name modelname.'''
|
||||
for model in self.models:
|
||||
if model.name == modelname:
|
||||
logging.debug('ModelCollection.get_index: {0} - {1}'.format(model.name, model.index))
|
||||
# logging.debug('ModelCollection.get_index: {0} - {1}'.format(model.name, model.index))
|
||||
return model.index
|
||||
return 0
|
||||
|
||||
@@ -1085,14 +1095,14 @@ class SegmentCollection(object):
|
||||
|
||||
def pack(self):
|
||||
data = []
|
||||
logging.debug(type(self.segments))
|
||||
logging.debug(self.segments)
|
||||
# logging.debug(type(self.segments))
|
||||
# logging.debug(self.segments)
|
||||
for segment in self.segments:
|
||||
data.append(segment.pack())
|
||||
return b''.join(data)
|
||||
|
||||
def repack(self):
|
||||
data = [bsegment.repack() for segment in self.segments]
|
||||
data = [segment.repack() for segment in self.segments]
|
||||
return b''.join(data)
|
||||
|
||||
|
||||
@@ -1156,7 +1166,7 @@ class SegmentGeometry(Packer):
|
||||
len_new_verts += 1
|
||||
self.vertices.vertices = new_vertices
|
||||
|
||||
logging.debug('Cleared %s doubles.', num_cleared_vertices)
|
||||
# logging.debug('Cleared %s doubles.', num_cleared_vertices)
|
||||
|
||||
def dump(self, fh):
|
||||
'''Dump information to open filehandler fileh.'''
|
||||
@@ -1190,7 +1200,7 @@ class ShadowGeometry(Packer):
|
||||
def __init__(self, collection=None):
|
||||
self.collection = collection
|
||||
self.classname = 'ShadowGeometry'
|
||||
self.data = ''
|
||||
self.data = b''
|
||||
self.positions = []
|
||||
self.edges = []
|
||||
|
||||
@@ -1218,7 +1228,7 @@ class ShadowGeometry(Packer):
|
||||
fh.write('\t\t\t\tNo data available.\n')
|
||||
|
||||
def repack(self):
|
||||
data = [b'SHDW', 'size', self.data]
|
||||
data = [b'SHDW', 'size', self.data.encode("ascii")]
|
||||
data[1] = struct.pack('<L', len(self.data))
|
||||
return b''.join(data)
|
||||
|
||||
@@ -1612,35 +1622,36 @@ class Face(object):
|
||||
|
||||
def pack(self):
|
||||
'''Packs the vertex indices for the STRP chunk.'''
|
||||
# index_map = self.collection.segment.index_map
|
||||
index_map = None
|
||||
if self.collection:
|
||||
if self.collection.segment:
|
||||
index_map = self.collection.segment.index_map
|
||||
|
||||
if (self.sides == 4) and (index_map is not None):
|
||||
logging.debug(f"Vertex indices for the STRP index_map chunk are: {self.sides}...")
|
||||
# logging.debug(f"Vertex indices for the STRP index_map chunk are: {self.sides}...")
|
||||
return struct.pack('<HHHH', index_map[self.vertices[0]] + 0x8000,
|
||||
index_map[self.vertices[1]] + 0x8000,
|
||||
index_map[self.vertices[2]],
|
||||
index_map[self.vertices[3]])
|
||||
elif (self.sides == 3) and (index_map is not None):
|
||||
logging.debug(f"Vertex indices for the STRP index_map chunk are: {self.sides}...")
|
||||
# logging.debug(f"Vertex indices for the STRP index_map chunk are: {self.sides}...")
|
||||
return struct.pack('<HHH', index_map[self.vertices[0]] + 0x8000,
|
||||
index_map[self.vertices[1]] + 0x8000,
|
||||
index_map[self.vertices[2]])
|
||||
elif (self.sides == 4) and (index_map is None):
|
||||
logging.debug(f"Vertex indices for the STRP chunk are: {self.sides}...")
|
||||
# logging.debug(f"Vertex indices for the STRP chunk are: {self.sides}...")
|
||||
return struct.pack('<HHHH', self.vertices[0] + 0x8000,
|
||||
self.vertices[1] + 0x8000,
|
||||
self.vertices[2],
|
||||
self.vertices[3])
|
||||
elif (self.sides == 3) and (index_map is None):
|
||||
logging.debug(f"Vertex indices for the STRP chunk are: {self.sides}...")
|
||||
# logging.debug(f"Vertex indices for the STRP chunk are: {self.sides}...")
|
||||
return struct.pack('<HHH', self.vertices[0] + 0x8000,
|
||||
self.vertices[1] + 0x8000,
|
||||
self.vertices[2])
|
||||
else:
|
||||
logging.debug("Vertex indices for the STRP chunk are empty...")
|
||||
# logging.debug("Vertex indices for the STRP chunk are empty...")
|
||||
return b''
|
||||
|
||||
def pack_tris(self):
|
||||
@@ -1976,7 +1987,7 @@ class Vertex(object):
|
||||
|
||||
def pack_weights(self):
|
||||
data = []
|
||||
for index, weight in itertools.izip(self.deformer_indices, self.weights):
|
||||
for index, weight in zip(self.deformer_indices, self.weights):
|
||||
data.append(struct.pack('<Lf', index, weight))
|
||||
return b''.join(data)
|
||||
|
||||
@@ -2073,7 +2084,7 @@ class VertexCollection(object):
|
||||
return b''.join(data)
|
||||
|
||||
def set_uvs(self, uv_list):
|
||||
for uv, vertex in itertools.izip(uv_list, self.vertices):
|
||||
for uv, vertex in zip(uv_list, self.vertices):
|
||||
vertex.u = uv[0]
|
||||
vertex.v = uv[1]
|
||||
|
||||
@@ -2083,7 +2094,7 @@ class VertexCollection(object):
|
||||
yield vertex.color.get()
|
||||
|
||||
def set_colors(self, color_list):
|
||||
for color, vertex in itertools.izip(color_list, self.vertices):
|
||||
for color, vertex in zip(color_list, self.vertices):
|
||||
vertex.color = color
|
||||
|
||||
def pack_colors(self):
|
||||
@@ -2108,7 +2119,7 @@ class VertexCollection(object):
|
||||
return weights
|
||||
|
||||
def set_weights(self, weights, deformers, indices):
|
||||
for weight, deformer_tuple, index_tpl, vertex in itertools.izip(weights, deformers, indices, self.vertices):
|
||||
for weight, deformer_tuple, index_tpl, vertex in zip(weights, deformers, indices, self.vertices):
|
||||
vertex.weights = weight
|
||||
vertex.deformers = deformer_tuple
|
||||
vertex.deformer_indices = index_tpl
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user