update export module into bm 1.1
This commit is contained in:
parent
da4f07f37a
commit
034f1e55aa
@ -42,7 +42,7 @@ class ExportBM(bpy.types.Operator, bpy_extras.io_utils.ExportHelper):
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
export_bm(context, self.filepath, self.export_mode, self.export_target, "") #todo: fix no_component_suffix
|
||||
export_bm(context, self.filepath, self.export_mode, self.export_target)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
@ -254,8 +254,20 @@ def import_bm(context,filepath,externalTexture,blenderTempFolder):
|
||||
|
||||
# object
|
||||
fobject = open(os.path.join(tempFolder, "object.bm"), "rb")
|
||||
|
||||
# we need get needed collection first
|
||||
view_layer = context.view_layer
|
||||
collection = view_layer.active_layer_collection.collection
|
||||
if prefs.no_component_collection == "":
|
||||
forcedCollection = None
|
||||
else:
|
||||
try:
|
||||
forcedCollection = bpy.data.collections[prefs.no_component_collection]
|
||||
except:
|
||||
forcedCollection = bpy.data.collections.new(prefs.no_component_collection)
|
||||
view_layer.active_layer_collection.collection.children.link(forcedCollection)
|
||||
|
||||
# start process it
|
||||
for item in objectList:
|
||||
fobject.seek(item.offset, os.SEEK_SET)
|
||||
|
||||
@ -276,9 +288,12 @@ def import_bm(context,filepath,externalTexture,blenderTempFolder):
|
||||
obj = bpy.data.objects.new(item.name, neededMesh)
|
||||
obj.matrix_world = object_worldMatrix
|
||||
obj.hide_viewport = object_isHidden
|
||||
# todo: finish forced collection grouping
|
||||
|
||||
collection.objects.link(obj)
|
||||
|
||||
if (not object_isComponent) and object_isForcedNoComponent and (forcedCollection != None):
|
||||
forcedCollection.objects.link(obj)
|
||||
else:
|
||||
collection.objects.link(obj)
|
||||
|
||||
fobject.close()
|
||||
view_layer.update()
|
||||
@ -293,27 +308,23 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
||||
# tempFolder = "G:\\ziptest"
|
||||
tempTextureFolder = os.path.join(tempFolder, "Texture")
|
||||
os.makedirs(tempTextureFolder)
|
||||
prefs = bpy.context.preferences.addons[__package__].preferences
|
||||
|
||||
# ============================================ find export target
|
||||
# ============================================ find export target. don't need judge them in there. just collect them
|
||||
if export_mode== "COLLECTION":
|
||||
objectList = bpy.data.collections[export_target].objects
|
||||
else:
|
||||
objectList = [bpy.data.objects[export_target]]
|
||||
|
||||
needSuffixChecker = no_component_suffix != ""
|
||||
componentObj = set()
|
||||
for obj in objectList:
|
||||
if needSuffixChecker and obj.name.endwith(no_component_suffix):
|
||||
pass # meshObjList.add(obj)
|
||||
else:
|
||||
if is_component(obj.name):
|
||||
componentObj.add(obj)
|
||||
else:
|
||||
pass # meshObjList.add(obj)
|
||||
# try get forcedCollection
|
||||
try:
|
||||
forcedCollection = bpy.data.collections[prefs.no_component_collection]
|
||||
except:
|
||||
forcedCollection = None
|
||||
|
||||
# ============================================ export
|
||||
finfo = open(os.path.join(tempFolder, "index.bm"), "wb")
|
||||
finfo.write(struct.pack("I", bm_current_version))
|
||||
write_uint32(finfo, bm_current_version)
|
||||
|
||||
# ====================== export object
|
||||
fobject = open(os.path.join(tempFolder, "object.bm"), "wb")
|
||||
@ -325,14 +336,21 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
||||
if obj.type != 'MESH':
|
||||
continue
|
||||
|
||||
varis_component = obj in componentObj
|
||||
|
||||
# clean no mesh object
|
||||
currentMesh = obj.data
|
||||
if currentMesh == None:
|
||||
continue
|
||||
|
||||
# judge component
|
||||
object_isComponent = is_component(obj.name)
|
||||
object_isForcedNoComponent = False
|
||||
if (forcedCollection != None) and (obj.name in forcedCollection.objects):
|
||||
# change it to forced no component
|
||||
object_isComponent = False
|
||||
object_isForcedNoComponent = True
|
||||
|
||||
# triangle first and then group
|
||||
if not varis_component:
|
||||
if not object_isComponent:
|
||||
if currentMesh not in meshSet:
|
||||
mesh_triangulate(currentMesh)
|
||||
meshSet.add(currentMesh)
|
||||
@ -341,19 +359,23 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
||||
meshCount += 1
|
||||
else:
|
||||
meshId = meshList.index(currentMesh)
|
||||
else:
|
||||
meshId = get_component_id(obj.name)
|
||||
|
||||
# get visibility
|
||||
object_isHidden = obj.hide_viewport
|
||||
|
||||
# write finfo first
|
||||
write_string(finfo, obj.name)
|
||||
write_int(finfo, info_bm_type.OBJECT)
|
||||
write_long(finfo, fobject.tell())
|
||||
write_uint32(finfo, info_bm_type.OBJECT)
|
||||
write_uint64(finfo, fobject.tell())
|
||||
|
||||
# write fobject
|
||||
write_int(fobject, 1 if varis_component else 0)
|
||||
write_bool(fobject, object_isComponent)
|
||||
write_bool(fobject, object_isForcedNoComponent)
|
||||
write_bool(fobject, object_isHidden)
|
||||
write_worldMatrix(fobject, obj.matrix_world)
|
||||
if varis_component:
|
||||
write_int(fobject, get_component_id(obj.name))
|
||||
else:
|
||||
write_int(fobject, meshId)
|
||||
write_uint32(fobject, meshId)
|
||||
|
||||
fobject.close()
|
||||
|
||||
@ -366,13 +388,13 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
||||
|
||||
# write finfo first
|
||||
write_string(finfo, mesh.name)
|
||||
write_int(finfo, info_bm_type.MESH)
|
||||
write_long(finfo, fmesh.tell())
|
||||
write_uint32(finfo, info_bm_type.MESH)
|
||||
write_uint64(finfo, fmesh.tell())
|
||||
|
||||
# write fmesh
|
||||
# vertices
|
||||
vecList = mesh.vertices[:]
|
||||
write_int(fmesh, len(vecList))
|
||||
write_uint32(fmesh, len(vecList))
|
||||
for vec in vecList:
|
||||
#swap yz
|
||||
write_3vector(fmesh,vec.co[0],vec.co[2],vec.co[1])
|
||||
@ -380,7 +402,7 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
||||
# uv
|
||||
face_index_pairs = [(face, index) for index, face in enumerate(mesh.polygons)]
|
||||
uv_layer = mesh.uv_layers.active.data[:]
|
||||
write_int(fmesh, len(face_index_pairs) * 3)
|
||||
write_uint32(fmesh, len(face_index_pairs) * 3)
|
||||
for f, f_index in face_index_pairs:
|
||||
# it should be triangle face, otherwise throw a error
|
||||
if (f.loop_total != 3):
|
||||
@ -392,7 +414,7 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
||||
write_2vector(fmesh, uv[0], -uv[1])
|
||||
|
||||
# normals
|
||||
write_int(fmesh, len(face_index_pairs) * 3)
|
||||
write_uint32(fmesh, len(face_index_pairs) * 3)
|
||||
for f, f_index in face_index_pairs:
|
||||
# no need to check triangle again
|
||||
for loop_index in range(f.loop_start, f.loop_start + f.loop_total):
|
||||
@ -409,7 +431,7 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
||||
materialSet.add(mat)
|
||||
materialList.append(mat)
|
||||
|
||||
write_int(fmesh, len(face_index_pairs))
|
||||
write_uint32(fmesh, len(face_index_pairs))
|
||||
vtIndex = []
|
||||
vnIndex = []
|
||||
vIndex = []
|
||||
@ -438,8 +460,8 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
||||
vIndex[0], vtIndex[0], vnIndex[0])
|
||||
|
||||
# set used material
|
||||
write_int(fmesh, 0 if noMaterial else 1)
|
||||
write_int(fmesh, usedMat)
|
||||
write_bool(fmesh, not noMaterial)
|
||||
write_uint32(fmesh, usedMat)
|
||||
|
||||
mesh.free_normals_split()
|
||||
|
||||
@ -454,19 +476,28 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
||||
for material in materialList:
|
||||
# write finfo first
|
||||
write_string(finfo, material.name)
|
||||
write_int(finfo, info_bm_type.MATERIAL)
|
||||
write_long(finfo, fmaterial.tell())
|
||||
write_uint32(finfo, info_bm_type.MATERIAL)
|
||||
write_uint64(finfo, fmaterial.tell())
|
||||
|
||||
# write basic color
|
||||
# try get original written data
|
||||
material_colAmbient = try_get_custom_property(material, 'virtools-ambient')
|
||||
material_colDiffuse = try_get_custom_property(material, 'virtools-diffuse')
|
||||
material_colSpecular = try_get_custom_property(material, 'virtools-specular')
|
||||
material_colEmissive = try_get_custom_property(material, 'virtools-emissive')
|
||||
material_specularPower = try_get_custom_property(material, 'virtools-power')
|
||||
|
||||
# get basic color
|
||||
mat_wrap = node_shader_utils.PrincipledBSDFWrapper(material)
|
||||
if mat_wrap:
|
||||
use_mirror = mat_wrap.metallic != 0.0
|
||||
if use_mirror:
|
||||
write_3vector(fmaterial, mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic)
|
||||
set_value_when_none(material_colAmbient, (mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic))
|
||||
else:
|
||||
write_3vector(fmaterial, 1, 1, 1)
|
||||
write_3vector(fmaterial, mat_wrap.base_color[0], mat_wrap.base_color[1], mat_wrap.base_color[2])
|
||||
write_3vector(fmaterial, mat_wrap.specular, mat_wrap.specular, mat_wrap.specular)
|
||||
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]))
|
||||
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])
|
||||
set_value_when_none(material_specularPower, 0.0)
|
||||
|
||||
# confirm texture
|
||||
tex_wrap = getattr(mat_wrap, "base_color_texture", None)
|
||||
@ -482,24 +513,35 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
||||
else:
|
||||
currentTexture = textureList.index(image)
|
||||
|
||||
write_int(fmaterial, 1)
|
||||
write_int(fmaterial, currentTexture)
|
||||
material_useTexture = True
|
||||
material_texture = currentTexture
|
||||
else:
|
||||
# no texture
|
||||
write_int(fmaterial, 0)
|
||||
write_int(fmaterial, 0)
|
||||
material_useTexture = False
|
||||
material_texture = 0
|
||||
else:
|
||||
# no texture
|
||||
write_int(fmaterial, 0)
|
||||
write_int(fmaterial, 0)
|
||||
material_useTexture = False
|
||||
material_texture = 0
|
||||
|
||||
else:
|
||||
# no Principled BSDF. write garbage
|
||||
write_3vector(fmaterial, 0.8, 0.8, 0.8)
|
||||
write_3vector(fmaterial, 0.8, 0.8, 0.8)
|
||||
write_3vector(fmaterial, 0.8, 0.8, 0.8)
|
||||
write_int(fmaterial, 0)
|
||||
write_int(fmaterial, 0)
|
||||
set_value_when_none(material_colAmbient, (0.8, 0.8, 0.8))
|
||||
set_value_when_none(material_colDiffuse, (0.8, 0.8, 0.8))
|
||||
set_value_when_none(material_colSpecular, (0.8, 0.8, 0.8))
|
||||
set_value_when_none(material_colEmissive, (0.8, 0.8, 0.8))
|
||||
set_value_when_none(material_specularPower, 0.0)
|
||||
|
||||
material_useTexture = False
|
||||
material_texture = 0
|
||||
|
||||
write_color(fmaterial, material_colAmbient)
|
||||
write_color(fmaterial, material_colDiffuse)
|
||||
write_color(fmaterial, material_colSpecular)
|
||||
write_color(fmaterial, material_colEmissive)
|
||||
write_float(fmaterial, material_specularPower)
|
||||
write_bool(fmaterial, material_useTexture)
|
||||
write_uint32(fmaterial, material_texture)
|
||||
|
||||
fmaterial.close()
|
||||
|
||||
@ -511,8 +553,8 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
||||
for texture in textureList:
|
||||
# write finfo first
|
||||
write_string(finfo, texture.name)
|
||||
write_int(finfo, info_bm_type.TEXTURE)
|
||||
write_long(finfo, ftexture.tell())
|
||||
write_uint32(finfo, info_bm_type.TEXTURE)
|
||||
write_uint64(finfo, ftexture.tell())
|
||||
|
||||
# confirm internal
|
||||
texture_filepath = io_utils.path_reference(texture.filepath, source_dir, tempTextureFolder,
|
||||
@ -520,10 +562,10 @@ def export_bm(context,filepath,export_mode, export_target, no_component_suffix):
|
||||
filename = os.path.basename(texture_filepath)
|
||||
write_string(ftexture, filename)
|
||||
if (is_external_texture(filename)):
|
||||
write_int(ftexture, 1)
|
||||
write_bool(ftexture, True)
|
||||
else:
|
||||
# copy internal texture, if this file is copied, do not copy it again
|
||||
write_int(ftexture, 0)
|
||||
write_bool(ftexture, False)
|
||||
if filename not in existed_texture:
|
||||
shutil.copy(texture_filepath, os.path.join(tempTextureFolder, filename))
|
||||
existed_texture.add(filename)
|
||||
@ -604,6 +646,16 @@ def mesh_triangulate(me):
|
||||
bm.to_mesh(me)
|
||||
bm.free()
|
||||
|
||||
def try_get_custom_property(obj, field):
|
||||
try:
|
||||
cache = obj[field]
|
||||
except:
|
||||
return None
|
||||
|
||||
def set_value_when_none(obj, newValue):
|
||||
if obj == None:
|
||||
obj = newValue
|
||||
|
||||
# ======================================================================================= file io assistant
|
||||
|
||||
# import
|
||||
@ -654,15 +706,27 @@ def read_face(fs):
|
||||
|
||||
def write_string(fs,str):
|
||||
count=len(str)
|
||||
write_int(fs,count)
|
||||
write_uint32(fs,count)
|
||||
fs.write(str.encode("utf_32_le"))
|
||||
|
||||
def write_int(fs,num):
|
||||
def write_uint8(fs,num):
|
||||
fs.write(struct.pack("B", num))
|
||||
|
||||
def write_uint32(fs,num):
|
||||
fs.write(struct.pack("I", num))
|
||||
|
||||
def write_long(fs,num):
|
||||
def write_uint64(fs,num):
|
||||
fs.write(struct.pack("Q", num))
|
||||
|
||||
def write_bool(fs,boolean):
|
||||
if boolean:
|
||||
write_uint8(fs, 1)
|
||||
else:
|
||||
write_uint8(fs, 0)
|
||||
|
||||
def write_float(fs,fl):
|
||||
fs.write(struct.pack("f", fl))
|
||||
|
||||
def write_worldMatrix(fs, matt):
|
||||
mat = matt.transposed()
|
||||
fs.write(struct.pack("ffffffffffffffff",
|
||||
@ -674,6 +738,9 @@ def write_worldMatrix(fs, matt):
|
||||
def write_3vector(fs, x, y ,z):
|
||||
fs.write(struct.pack("fff", x, y ,z))
|
||||
|
||||
def write_color(fs, colors):
|
||||
write_3vector(fs, colors[0], colors[1], colors[2])
|
||||
|
||||
def write_2vector(fs, u, v):
|
||||
fs.write(struct.pack("ff", u, v))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user