From d5cb8eb1ecb5f8ede9310148dfd9e2dbeada4e82 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Sun, 20 Nov 2022 12:02:15 +0800 Subject: [PATCH] make Virtools material can be optional --- ballance_blender_plugin/BMFILE_export.py | 40 ++++------------ ballance_blender_plugin/BMFILE_import.py | 3 +- ballance_blender_plugin/OBJS_add_floors.py | 3 +- .../PROPS_virtools_material.py | 47 +++++++++++++++++-- ballance_blender_plugin/UTILS_functions.py | 42 +++++++++++++++-- .../UTILS_virtools_prop.py | 9 +++- ballance_blender_plugin/__init__.py | 1 + 7 files changed, 105 insertions(+), 40 deletions(-) diff --git a/ballance_blender_plugin/BMFILE_export.py b/ballance_blender_plugin/BMFILE_export.py index fb85134..f83c638 100644 --- a/ballance_blender_plugin/BMFILE_export.py +++ b/ballance_blender_plugin/BMFILE_export.py @@ -241,40 +241,20 @@ def export_bm(context, bmx_filepath, prefs_fncg, opts_exportMode, opts_exportTar UTILS_file_io.write_uint64(finfo, fmaterial.tell()) # try get original written data - (material_colAmbient, material_colDiffuse, material_colSpecular, material_colEmissive, material_specularPower, + (material_enableVirtoolsMat, + material_colAmbient, material_colDiffuse, material_colSpecular, material_colEmissive, material_specularPower, material_alphaTest, material_alphaBlend, material_zBuffer, material_twoSided, material_texture) = UTILS_virtools_prop.get_virtools_material_data(material) # only try get from Principled BSDF when we couldn't get from virtools_material props - if material_texture is None: - # get node - mat_wrap = node_shader_utils.PrincipledBSDFWrapper(material) - # check existence of Principled BSDF - if mat_wrap: - # we trying get texture data from Principled BSDF - # because bpy.types.Material.virtools_material now can provide - # Virtools material data stablely, so i annotate following code - # only keep texture data - ''' - use_mirror = mat_wrap.metallic != 0.0 - if use_mirror: - material_colAmbient = _set_value_when_none(material_colAmbient, (mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic)) - else: - material_colAmbient = _set_value_when_none(material_colAmbient, (1.0, 1.0, 1.0)) - material_colDiffuse = _set_value_when_none(material_colDiffuse, (mat_wrap.base_color[0], mat_wrap.base_color[1], mat_wrap.base_color[2])) - material_colSpecular = _set_value_when_none(material_colSpecular, (mat_wrap.specular, mat_wrap.specular, mat_wrap.specular)) - material_colEmissive = _set_value_when_none(material_colEmissive, mat_wrap.emission_color[:3]) - material_specularPower = _set_value_when_none(material_specularPower, 0.0) - ''' - - # confirm texture - tex_wrap = getattr(mat_wrap, "base_color_texture", None) - if tex_wrap: - image = tex_wrap.image - if image: - material_texture = image - - + if not material_enableVirtoolsMat: + v = UTILS_functions.parse_material_nodes(material) + if v is not None: + (material_enableVirtoolsMat, + material_colAmbient, material_colDiffuse, material_colSpecular, material_colEmissive, material_specularPower, + material_alphaTest, material_alphaBlend, material_zBuffer, material_twoSided, + material_texture) = v + # check texture index if material_texture is None: material_useTexture = False diff --git a/ballance_blender_plugin/BMFILE_import.py b/ballance_blender_plugin/BMFILE_import.py index a5e8da2..d683041 100644 --- a/ballance_blender_plugin/BMFILE_import.py +++ b/ballance_blender_plugin/BMFILE_import.py @@ -173,7 +173,8 @@ def import_bm(context, bmx_filepath, prefs_fncg, prefs_externalTexture, prefs_te # try create material nodes UTILS_functions.create_blender_material(material_target, - (material_colAmbient, material_colDiffuse, material_colSpecular, material_colEmissive, material_specularPower, + (True, + material_colAmbient, material_colDiffuse, material_colSpecular, material_colEmissive, material_specularPower, material_alphaTest, material_alphaBlend, material_zBuffer, material_twoSided, textureList[material_texture].blender_data if material_useTexture else None) ) diff --git a/ballance_blender_plugin/OBJS_add_floors.py b/ballance_blender_plugin/OBJS_add_floors.py index 7b3e308..2ff52fe 100644 --- a/ballance_blender_plugin/OBJS_add_floors.py +++ b/ballance_blender_plugin/OBJS_add_floors.py @@ -216,7 +216,8 @@ def _create_or_get_material(material_name, prefs_externalTexture): # set material data # all floor do not have any transparency props, so we provide 4 False value. UTILS_functions.create_blender_material(mtl, - (try_item['data']['ambient'], try_item['data']['diffuse'], + (True, + try_item['data']['ambient'], try_item['data']['diffuse'], try_item['data']['specular'], try_item['data']['emissive'], try_item['data']['power'], False, False, False, False, diff --git a/ballance_blender_plugin/PROPS_virtools_material.py b/ballance_blender_plugin/PROPS_virtools_material.py index 84d148d..0aca2b2 100644 --- a/ballance_blender_plugin/PROPS_virtools_material.py +++ b/ballance_blender_plugin/PROPS_virtools_material.py @@ -14,7 +14,32 @@ class BALLANCE_OT_apply_virtools_material(bpy.types.Operator): def execute(self, context): mtl = context.material mtl_data = UTILS_virtools_prop.get_virtools_material_data(mtl) - UTILS_functions.create_material_nodes(mtl, mtl_data) + + # check enable, [0] is enable_virtools_material + if mtl_data[0]: + UTILS_functions.create_material_nodes(mtl, mtl_data) + else: + UTILS_functions.show_message_box(("Virtools Material is not enabled.", ), "Apply Failed", 'ERROR') + + return {'FINISHED'} + +class BALLANCE_OT_parse_virtools_material(bpy.types.Operator): + """Apply Virtools Material to Blender Material.""" + bl_idname = "ballance.parse_virtools_material" + bl_label = "Parse from Blender Principled BSDF" + bl_options = {'UNDO'} + + @classmethod + def poll(cls, context): + return context.material is not None + + def execute(self, context): + mtl = context.material + mtl_data = UTILS_functions.parse_material_nodes(mtl) + if mtl_data is None: + UTILS_functions.show_message_box(("Fail to parse Principled BSDF.", ), "Parsing Failed", 'ERROR') + else: + UTILS_virtools_prop.set_virtools_material_data(mtl, mtl_data) return {'FINISHED'} @@ -30,21 +55,37 @@ class BALLANCE_PT_virtools_material(bpy.types.Panel): def poll(cls, context): return context.material is not None + def draw_header(self, context): + # draw a checkbox in header + target = UTILS_virtools_prop.get_virtools_material(context.material) + self.layout.prop(target, "enable_virtools_material", text="") + def draw(self, context): + # get layout and target layout = self.layout - #target = bpy.context.active_object.active_material target = UTILS_virtools_prop.get_virtools_material(context.material) - layout.prop(target, 'texture', emboss=True) + # decide visible + layout.enabled = target.enable_virtools_material + + # draw layout + layout.label(text="Basic Parameters") layout.prop(target, 'ambient') layout.prop(target, 'diffuse') layout.prop(target, 'specular') layout.prop(target, 'emissive') layout.prop(target, 'specular_power') + layout.prop(target, 'texture', emboss=True) + + layout.separator() + layout.label(text="Advanced Parameters") layout.prop(target, 'alpha_test') layout.prop(target, 'alpha_blend') layout.prop(target, 'z_buffer') layout.prop(target, 'two_sided') + layout.separator() + layout.label(text="Operations") layout.operator("ballance.apply_virtools_material", icon="NODETREE") + layout.operator("ballance.parse_virtools_material", icon="HIDE_OFF") diff --git a/ballance_blender_plugin/UTILS_functions.py b/ballance_blender_plugin/UTILS_functions.py index 4c277f7..cd29a99 100644 --- a/ballance_blender_plugin/UTILS_functions.py +++ b/ballance_blender_plugin/UTILS_functions.py @@ -40,10 +40,9 @@ def get_component_id(name): return -1 # ================================= -# create material +# create / parse material def create_blender_material(input_mtl, packed_data): - # adding material nodes create_material_nodes(input_mtl, packed_data) @@ -51,8 +50,8 @@ def create_blender_material(input_mtl, packed_data): UTILS_virtools_prop.set_virtools_material_data(input_mtl, packed_data) def create_material_nodes(input_mtl, packed_data): - - (ambient, diffuse, specular, emissive, specular_power, + (enable_virtools_material, + ambient, diffuse, specular, emissive, specular_power, alpha_test, alpha_blend, z_buffer, two_sided, texture) = packed_data @@ -78,6 +77,41 @@ def create_material_nodes(input_mtl, packed_data): inode.image = texture input_mtl.node_tree.links.new(inode.outputs[0], bnode.inputs[0]) +# return None if fail to parse +def parse_material_nodes(mtl): + # get node + mat_wrap = node_shader_utils.PrincipledBSDFWrapper(mtl) + # check existence of Principled BSDF + if mat_wrap: + # we trying get texture data from Principled BSDF + use_mirror = mat_wrap.metallic != 0.0 + if use_mirror: + mtl_ambient = (mat_wrap.metallic, mat_wrap.metallic, mat_wrap.metallic) + else: + mtl_ambient = (1.0, 1.0, 1.0) + mtl_diffuse = (mat_wrap.base_color[0], mat_wrap.base_color[1], mat_wrap.base_color[2]) + mtl_specular = (mat_wrap.specular, mat_wrap.specular, mat_wrap.specular) + mtl_emissive = mat_wrap.emission_color[:3] + mtl_specularPower = 0.0 + + # confirm texture + mtl_texture = None + tex_wrap = getattr(mat_wrap, "base_color_texture", None) + if tex_wrap: + image = tex_wrap.image + if image: + mtl_texture = image + + # return value + return (True, + mtl_ambient, mtl_diffuse, mtl_specular, mtl_emissive, mtl_specularPower, + False, False, False, False, + mtl_texture + ) + + else: + return None + # ================================= # load component diff --git a/ballance_blender_plugin/UTILS_virtools_prop.py b/ballance_blender_plugin/UTILS_virtools_prop.py index 21d31e6..02a062d 100644 --- a/ballance_blender_plugin/UTILS_virtools_prop.py +++ b/ballance_blender_plugin/UTILS_virtools_prop.py @@ -2,6 +2,11 @@ import bpy from . import UTILS_constants, UTILS_functions class BALLANCE_PG_virtools_material(bpy.types.PropertyGroup): + enable_virtools_material: bpy.props.BoolProperty( + name="Enable Virtools Material", + default=False, + ) + ambient: bpy.props.FloatVectorProperty(name="Ambient", subtype='COLOR', min=0.0, @@ -74,6 +79,7 @@ def get_virtools_material(mtl): def get_virtools_material_data(mtl): data = get_virtools_material(mtl) return ( + data.enable_virtools_material, data.ambient, data.diffuse, data.specular, @@ -89,7 +95,8 @@ def get_virtools_material_data(mtl): def set_virtools_material_data(mtl, packed_data): data = get_virtools_material(mtl) # packed_data have the same order with the return value of `get_virtools_material_data` - (data.ambient, data.diffuse, data.specular, data.emissive, data.specular_power, + (data.enable_virtools_material, + data.ambient, data.diffuse, data.specular, data.emissive, data.specular_power, data.alpha_test, data.alpha_blend, data.z_buffer, data.two_sided, data.texture) = packed_data diff --git a/ballance_blender_plugin/__init__.py b/ballance_blender_plugin/__init__.py index 9cd7ce1..271db16 100644 --- a/ballance_blender_plugin/__init__.py +++ b/ballance_blender_plugin/__init__.py @@ -151,6 +151,7 @@ classes = ( PROPS_virtools_group.BALLANCE_UL_virtools_group, PROPS_virtools_group.BALLANCE_PT_virtools_group, PROPS_virtools_material.BALLANCE_OT_apply_virtools_material, + PROPS_virtools_material.BALLANCE_OT_parse_virtools_material, PROPS_virtools_material.BALLANCE_PT_virtools_material, OBJS_group_opers.BALLANCE_OT_select_virtools_group,