fully finish bm import/export function

This commit is contained in:
yyc12345 2020-08-07 14:17:13 +08:00
parent 034f1e55aa
commit af05f2ae21
30 changed files with 219 additions and 111 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# our generated mesh should be save as binary
*.bin binary

View File

@ -45,7 +45,6 @@ class ExportBM(bpy.types.Operator, bpy_extras.io_utils.ExportHelper):
export_bm(context, self.filepath, self.export_mode, self.export_target) export_bm(context, self.filepath, self.export_mode, self.export_target)
return {'FINISHED'} return {'FINISHED'}
# ========================================== method # ========================================== method
bm_current_version = 11 bm_current_version = 11
@ -286,21 +285,19 @@ def import_bm(context,filepath,externalTexture,blenderTempFolder):
# create real object # create real object
obj = bpy.data.objects.new(item.name, neededMesh) obj = bpy.data.objects.new(item.name, neededMesh)
obj.matrix_world = object_worldMatrix if (not object_isComponent) and object_isForcedNoComponent and (forcedCollection is not None):
obj.hide_viewport = object_isHidden
if (not object_isComponent) and object_isForcedNoComponent and (forcedCollection != None):
forcedCollection.objects.link(obj) forcedCollection.objects.link(obj)
else: else:
collection.objects.link(obj) collection.objects.link(obj)
obj.matrix_world = object_worldMatrix
obj.hide_set(object_isHidden)
fobject.close() fobject.close()
view_layer.update() view_layer.update()
tempFolderObj.cleanup() tempFolderObj.cleanup()
def export_bm(context,filepath,export_mode, export_target, no_component_suffix): def export_bm(context,filepath,export_mode, export_target):
# ============================================ alloc a temp folder # ============================================ alloc a temp folder
tempFolderObj = tempfile.TemporaryDirectory() tempFolderObj = tempfile.TemporaryDirectory()
tempFolder = tempFolderObj.name tempFolder = tempFolderObj.name
@ -338,13 +335,13 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
# clean no mesh object # clean no mesh object
currentMesh = obj.data currentMesh = obj.data
if currentMesh == None: if currentMesh is None:
continue continue
# judge component # judge component
object_isComponent = is_component(obj.name) object_isComponent = is_component(obj.name)
object_isForcedNoComponent = False object_isForcedNoComponent = False
if (forcedCollection != None) and (obj.name in forcedCollection.objects): if (forcedCollection is not None) and (obj.name in forcedCollection.objects):
# change it to forced no component # change it to forced no component
object_isComponent = False object_isComponent = False
object_isForcedNoComponent = True object_isForcedNoComponent = True
@ -363,16 +360,17 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
meshId = get_component_id(obj.name) meshId = get_component_id(obj.name)
# get visibility # get visibility
object_isHidden = obj.hide_viewport object_isHidden = not obj.visible_get()
# write finfo first # write finfo first
write_string(finfo, obj.name) write_string(finfo, obj.name)
write_uint32(finfo, info_bm_type.OBJECT) write_uint8(finfo, info_bm_type.OBJECT)
write_uint64(finfo, fobject.tell()) write_uint64(finfo, fobject.tell())
# write fobject # write fobject
write_bool(fobject, object_isComponent) write_bool(fobject, object_isComponent)
write_bool(fobject, object_isForcedNoComponent) write_bool(fobject, object_isForcedNoComponent)
print(object_isHidden)
write_bool(fobject, object_isHidden) write_bool(fobject, object_isHidden)
write_worldMatrix(fobject, obj.matrix_world) write_worldMatrix(fobject, obj.matrix_world)
write_uint32(fobject, meshId) write_uint32(fobject, meshId)
@ -388,7 +386,7 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
# write finfo first # write finfo first
write_string(finfo, mesh.name) write_string(finfo, mesh.name)
write_uint32(finfo, info_bm_type.MESH) write_uint8(finfo, info_bm_type.MESH)
write_uint64(finfo, fmesh.tell()) write_uint64(finfo, fmesh.tell())
# write fmesh # write fmesh
@ -472,11 +470,10 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
textureSet = set() textureSet = set()
textureList = [] textureList = []
textureCount = 0 textureCount = 0
# todo: texture filter have duplicated name error. fix it later
for material in materialList: for material in materialList:
# write finfo first # write finfo first
write_string(finfo, material.name) write_string(finfo, material.name)
write_uint32(finfo, info_bm_type.MATERIAL) write_uint8(finfo, info_bm_type.MATERIAL)
write_uint64(finfo, fmaterial.tell()) write_uint64(finfo, fmaterial.tell())
# try get original written data # try get original written data
@ -491,13 +488,13 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
if mat_wrap: if mat_wrap:
use_mirror = mat_wrap.metallic != 0.0 use_mirror = mat_wrap.metallic != 0.0
if use_mirror: if use_mirror:
set_value_when_none(material_colAmbient, (mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic)) material_colAmbient = set_value_when_none(material_colAmbient, (mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic))
else: else:
set_value_when_none(material_colAmbient, (1.0, 1.0, 1.0)) material_colAmbient = set_value_when_none(material_colAmbient, (1.0, 1.0, 1.0))
set_value_when_none(material_colDiffuse, (mat_wrap.base_color[0], mat_wrap.base_color[1], mat_wrap.base_color[2])) material_colDiffuse = set_value_when_none(material_colDiffuse, (mat_wrap.base_color[0], mat_wrap.base_color[1], mat_wrap.base_color[2]))
set_value_when_none(material_colSpecular, (mat_wrap.specular, mat_wrap.specular, mat_wrap.specular)) material_colSpecular = set_value_when_none(material_colSpecular, (mat_wrap.specular, mat_wrap.specular, mat_wrap.specular))
set_value_when_none(material_colEmissive, mat_wrap.emission_color[:3]) material_colEmissive = set_value_when_none(material_colEmissive, mat_wrap.emission_color[:3])
set_value_when_none(material_specularPower, 0.0) material_specularPower = set_value_when_none(material_specularPower, 0.0)
# confirm texture # confirm texture
tex_wrap = getattr(mat_wrap, "base_color_texture", None) tex_wrap = getattr(mat_wrap, "base_color_texture", None)
@ -526,11 +523,11 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
else: else:
# no Principled BSDF. write garbage # no Principled BSDF. write garbage
set_value_when_none(material_colAmbient, (0.8, 0.8, 0.8)) material_colAmbient = set_value_when_none(material_colAmbient, (0.8, 0.8, 0.8))
set_value_when_none(material_colDiffuse, (0.8, 0.8, 0.8)) material_colDiffuse = set_value_when_none(material_colDiffuse, (0.8, 0.8, 0.8))
set_value_when_none(material_colSpecular, (0.8, 0.8, 0.8)) material_colSpecular = set_value_when_none(material_colSpecular, (0.8, 0.8, 0.8))
set_value_when_none(material_colEmissive, (0.8, 0.8, 0.8)) material_colEmissive = set_value_when_none(material_colEmissive, (0.8, 0.8, 0.8))
set_value_when_none(material_specularPower, 0.0) material_specularPower = set_value_when_none(material_specularPower, 0.0)
material_useTexture = False material_useTexture = False
material_texture = 0 material_texture = 0
@ -553,7 +550,7 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
for texture in textureList: for texture in textureList:
# write finfo first # write finfo first
write_string(finfo, texture.name) write_string(finfo, texture.name)
write_uint32(finfo, info_bm_type.TEXTURE) write_uint8(finfo, info_bm_type.TEXTURE)
write_uint64(finfo, ftexture.tell()) write_uint64(finfo, ftexture.tell())
# confirm internal # confirm internal
@ -605,7 +602,68 @@ class info_block_helper():
self.blenderData = None self.blenderData = None
def load_component(component_id): def load_component(component_id):
return None # get file first
compName = config.component_list[component_id]
selectedFile = os.path.join(
os.path.dirname(__file__),
'meshes',
compName + '.bin'
)
# read file. please note this sector is sync with import_bm's mesh's code. when something change, please change each other.
fmesh = open(selectedFile, 'rb')
# create real mesh, we don't need to consider name. blender will solve duplicated name
mesh = bpy.data.meshes.new('mesh_' + compName)
vList = []
vnList = []
faceList = []
# in first read, store all data into list
listCount = read_uint32(fmesh)
for i in range(listCount):
cache = read_3vector(fmesh)
# switch yz
vList.append((cache[0], cache[2], cache[1]))
listCount = read_uint32(fmesh)
for i in range(listCount):
cache = read_3vector(fmesh)
# switch yz
vnList.append((cache[0], cache[2], cache[1]))
listCount = read_uint32(fmesh)
for i in range(listCount):
faceData = read_component_face(fmesh)
# we need invert triangle sort
faceList.append((
faceData[4], faceData[5],
faceData[2], faceData[3],
faceData[0], faceData[1]
))
# then, we need add correspond count for vertices
mesh.vertices.add(len(vList))
mesh.loops.add(len(faceList)*3) # triangle face confirm
mesh.polygons.add(len(faceList))
mesh.create_normals_split()
# add vertices data
mesh.vertices.foreach_set("co", unpack_list(vList))
mesh.loops.foreach_set("vertex_index", unpack_list(flat_component_vertices_index(faceList)))
mesh.loops.foreach_set("normal", unpack_list(flat_component_vertices_normal(faceList, vnList)))
for i in range(len(faceList)):
mesh.polygons[i].loop_start = i * 3
mesh.polygons[i].loop_total = 3
mesh.polygons[i].use_smooth = True
mesh.validate(clean_customdata=False)
mesh.update(calc_edges=False, calc_edges_loose=False)
fmesh.close()
return mesh
def flat_vertices_index(faceList): def flat_vertices_index(faceList):
for item in faceList: for item in faceList:
@ -625,13 +683,28 @@ def flat_vertices_uv(faceList, vtList):
yield vtList[item[4]] yield vtList[item[4]]
yield vtList[item[7]] yield vtList[item[7]]
def flat_component_vertices_index(faceList):
for item in faceList:
yield (item[0], )
yield (item[2], )
yield (item[4], )
def flat_component_vertices_normal(faceList, vnList):
for item in faceList:
yield vnList[item[1]]
yield vnList[item[3]]
yield vnList[item[5]]
# export # export
def is_component(name): def is_component(name):
return get_component_id(name) != -1 return get_component_id(name) != -1
def get_component_id(name): def get_component_id(name):
return -1 # todo: finish this, -1 mean not a component for ind, comp in enumerate(config.component_list):
if name.startswith(comp):
return ind
return -1
def is_external_texture(name): def is_external_texture(name):
if name in config.external_texture_list: if name in config.external_texture_list:
@ -648,13 +721,15 @@ def mesh_triangulate(me):
def try_get_custom_property(obj, field): def try_get_custom_property(obj, field):
try: try:
cache = obj[field] return obj[field]
except: except:
return None return None
def set_value_when_none(obj, newValue): def set_value_when_none(obj, newValue):
if obj == None: if obj is None:
obj = newValue return newValue
else:
return obj
# ======================================================================================= file io assistant # ======================================================================================= file io assistant
@ -702,6 +777,9 @@ def read_2vector(fs):
def read_face(fs): def read_face(fs):
return struct.unpack("IIIIIIIII", fs.read(4*9)) return struct.unpack("IIIIIIIII", fs.read(4*9))
def read_component_face(fs):
return struct.unpack("IIIIII", fs.read(4*6))
# export # export
def write_string(fs,str): def write_string(fs,str):

View File

@ -1,85 +1,113 @@
external_texture_list = set([ external_texture_list = set([
'Ball_LightningSphere1.bmp', "atari.avi",
'Ball_LightningSphere2.bmp', "atari.bmp",
'Ball_LightningSphere3.bmp', "Ball_LightningSphere1.bmp",
'Ball_Paper.bmp', "Ball_LightningSphere2.bmp",
'Ball_Stone.bmp', "Ball_LightningSphere3.bmp",
'Ball_Wood.bmp', "Ball_Paper.bmp",
'Brick.bmp', "Ball_Stone.bmp",
'Button01_deselect.tga', "Ball_Wood.bmp",
'Button01_select.tga', "Brick.bmp",
'Button01_special.tga', "Button01_deselect.tga",
'Column_beige.bmp', "Button01_select.tga",
'Column_beige_fade.tga', "Button01_special.tga",
'Column_blue.bmp', "Column_beige.bmp",
'Cursor.tga', "Column_beige_fade.tga",
'Dome.bmp', "Column_blue.bmp",
'DomeEnvironment.bmp', "Cursor.tga",
'DomeShadow.tga', "Dome.bmp",
'ExtraBall.bmp', "DomeEnvironment.bmp",
'ExtraParticle.bmp', "DomeShadow.tga",
'E_Holzbeschlag.bmp', "ExtraBall.bmp",
'FloorGlow.bmp', "ExtraParticle.bmp",
'Floor_Side.bmp', "E_Holzbeschlag.bmp",
'Floor_Top_Border.bmp', "FloorGlow.bmp",
'Floor_Top_Borderless.bmp', "Floor_Side.bmp",
'Floor_Top_Checkpoint.bmp', "Floor_Top_Border.bmp",
'Floor_Top_Flat.bmp', "Floor_Top_Borderless.bmp",
'Floor_Top_Profil.bmp', "Floor_Top_Checkpoint.bmp",
'Floor_Top_ProfilFlat.bmp', "Floor_Top_Flat.bmp",
'Font_1.tga', "Floor_Top_Profil.bmp",
'Gravitylogo_intro.bmp', "Floor_Top_ProfilFlat.bmp",
'HardShadow.bmp', "Font_1.tga",
'Laterne_Glas.bmp', "Gravitylogo_intro.bmp",
'Laterne_Schatten.tga', "HardShadow.bmp",
'Laterne_Verlauf.tga', "Laterne_Glas.bmp",
'Logo.bmp', "Laterne_Schatten.tga",
'Metal_stained.bmp', "Laterne_Verlauf.tga",
'Misc_Ufo.bmp', "Logo.bmp",
'Misc_UFO_Flash.bmp', "Metal_stained.bmp",
'Modul03_Floor.bmp', "Misc_Ufo.bmp",
'Modul03_Wall.bmp', "Misc_UFO_Flash.bmp",
'Modul11_13_Wood.bmp', "Modul03_Floor.bmp",
'Modul11_Wood.bmp', "Modul03_Wall.bmp",
'Modul15.bmp', "Modul11_13_Wood.bmp",
'Modul16.bmp', "Modul11_Wood.bmp",
'Modul18.bmp', "Modul15.bmp",
'Modul18_Gitter.tga', "Modul16.bmp",
'Modul30_d_Seiten.bmp', "Modul18.bmp",
'Particle_Flames.bmp', "Modul18_Gitter.tga",
'Particle_Smoke.bmp', "Modul30_d_Seiten.bmp",
'PE_Bal_balloons.bmp', "Particle_Flames.bmp",
'PE_Bal_platform.bmp', "Particle_Smoke.bmp",
'PE_Ufo_env.bmp', "PE_Bal_balloons.bmp",
'Pfeil.tga', "PE_Bal_platform.bmp",
'P_Extra_Life_Oil.bmp', "PE_Ufo_env.bmp",
'P_Extra_Life_Particle.bmp', "Pfeil.tga",
'P_Extra_Life_Shadow.bmp', "P_Extra_Life_Oil.bmp",
'Rail_Environment.bmp', "P_Extra_Life_Particle.bmp",
'sandsack.bmp', "P_Extra_Life_Shadow.bmp",
'SkyLayer.bmp', "Rail_Environment.bmp",
'Sky_Vortex.bmp', "sandsack.bmp",
'Stick_Bottom.tga', "SkyLayer.bmp",
'Stick_Stripes.bmp', "Sky_Vortex.bmp",
'Target.bmp', "Stick_Bottom.tga",
'Tower_Roof.bmp', "Stick_Stripes.bmp",
'Trafo_Environment.bmp', "Target.bmp",
'Trafo_FlashField.bmp', "Tower_Roof.bmp",
'Trafo_Shadow_Big.tga', "Trafo_Environment.bmp",
'Tut_Pfeil01.tga', "Trafo_FlashField.bmp",
'Tut_Pfeil_Hoch.tga', "Trafo_Shadow_Big.tga",
'Wolken_intro.tga', "Tut_Pfeil01.tga",
'Wood_Metal.bmp', "Tut_Pfeil_Hoch.tga",
'Wood_MetalStripes.bmp', "Wolken_intro.tga",
'Wood_Misc.bmp', "Wood_Metal.bmp",
'Wood_Nailed.bmp', "Wood_MetalStripes.bmp",
'Wood_Old.bmp', "Wood_Misc.bmp",
'Wood_Panel.bmp', "Wood_Nailed.bmp",
'Wood_Plain.bmp', "Wood_Old.bmp",
'Wood_Plain2.bmp', "Wood_Panel.bmp",
'Wood_Raft.bmp' "Wood_Plain.bmp",
"Wood_Plain2.bmp",
"Wood_Raft.bmp"
]) ])
component_list = [ component_list = [
"P_Extra_Life",
"P_Extra_Point",
"P_Trafo_Paper",
"P_Trafo_Stone",
"P_Trafo_Wood",
"P_Ball_Paper",
"P_Ball_Stone",
"P_Ball_Wood",
"P_Box",
"P_Dome",
"P_Modul_01",
"P_Modul_03",
"P_Modul_08",
"P_Modul_17",
"P_Modul_18",
"P_Modul_19",
"P_Modul_25",
"P_Modul_26",
"P_Modul_29",
"P_Modul_30",
"P_Modul_34",
"P_Modul_37",
"P_Modul_41",
"PC_TwoFlames",
"PE_Balloon",
"PR_Resetpoint",
"PS_FourFlames"
] ]

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.