make Virtools material can be optional

This commit is contained in:
yyc12345 2022-11-20 12:02:15 +08:00
parent 02c11ffe5a
commit d5cb8eb1ec
7 changed files with 105 additions and 40 deletions

View File

@ -241,39 +241,19 @@ def export_bm(context, bmx_filepath, prefs_fncg, opts_exportMode, opts_exportTar
UTILS_file_io.write_uint64(finfo, fmaterial.tell()) UTILS_file_io.write_uint64(finfo, fmaterial.tell())
# try get original written data # 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_alphaTest, material_alphaBlend, material_zBuffer, material_twoSided,
material_texture) = UTILS_virtools_prop.get_virtools_material_data(material) 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 # only try get from Principled BSDF when we couldn't get from virtools_material props
if material_texture is None: if not material_enableVirtoolsMat:
# get node v = UTILS_functions.parse_material_nodes(material)
mat_wrap = node_shader_utils.PrincipledBSDFWrapper(material) if v is not None:
# check existence of Principled BSDF (material_enableVirtoolsMat,
if mat_wrap: material_colAmbient, material_colDiffuse, material_colSpecular, material_colEmissive, material_specularPower,
# we trying get texture data from Principled BSDF material_alphaTest, material_alphaBlend, material_zBuffer, material_twoSided,
# because bpy.types.Material.virtools_material now can provide material_texture) = v
# 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
# check texture index # check texture index
if material_texture is None: if material_texture is None:

View File

@ -173,7 +173,8 @@ def import_bm(context, bmx_filepath, prefs_fncg, prefs_externalTexture, prefs_te
# try create material nodes # try create material nodes
UTILS_functions.create_blender_material(material_target, 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, material_alphaTest, material_alphaBlend, material_zBuffer, material_twoSided,
textureList[material_texture].blender_data if material_useTexture else None) textureList[material_texture].blender_data if material_useTexture else None)
) )

View File

@ -216,7 +216,8 @@ def _create_or_get_material(material_name, prefs_externalTexture):
# set material data # set material data
# all floor do not have any transparency props, so we provide 4 False value. # all floor do not have any transparency props, so we provide 4 False value.
UTILS_functions.create_blender_material(mtl, 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']['specular'], try_item['data']['emissive'],
try_item['data']['power'], try_item['data']['power'],
False, False, False, False, False, False, False, False,

View File

@ -14,7 +14,32 @@ class BALLANCE_OT_apply_virtools_material(bpy.types.Operator):
def execute(self, context): def execute(self, context):
mtl = context.material mtl = context.material
mtl_data = UTILS_virtools_prop.get_virtools_material_data(mtl) mtl_data = UTILS_virtools_prop.get_virtools_material_data(mtl)
# check enable, [0] is enable_virtools_material
if mtl_data[0]:
UTILS_functions.create_material_nodes(mtl, mtl_data) 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'} return {'FINISHED'}
@ -30,21 +55,37 @@ class BALLANCE_PT_virtools_material(bpy.types.Panel):
def poll(cls, context): def poll(cls, context):
return context.material is not None 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): def draw(self, context):
# get layout and target
layout = self.layout layout = self.layout
#target = bpy.context.active_object.active_material
target = UTILS_virtools_prop.get_virtools_material(context.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, 'ambient')
layout.prop(target, 'diffuse') layout.prop(target, 'diffuse')
layout.prop(target, 'specular') layout.prop(target, 'specular')
layout.prop(target, 'emissive') layout.prop(target, 'emissive')
layout.prop(target, 'specular_power') 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_test')
layout.prop(target, 'alpha_blend') layout.prop(target, 'alpha_blend')
layout.prop(target, 'z_buffer') layout.prop(target, 'z_buffer')
layout.prop(target, 'two_sided') layout.prop(target, 'two_sided')
layout.separator()
layout.label(text="Operations")
layout.operator("ballance.apply_virtools_material", icon="NODETREE") layout.operator("ballance.apply_virtools_material", icon="NODETREE")
layout.operator("ballance.parse_virtools_material", icon="HIDE_OFF")

View File

@ -40,10 +40,9 @@ def get_component_id(name):
return -1 return -1
# ================================= # =================================
# create material # create / parse material
def create_blender_material(input_mtl, packed_data): def create_blender_material(input_mtl, packed_data):
# adding material nodes # adding material nodes
create_material_nodes(input_mtl, packed_data) 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) UTILS_virtools_prop.set_virtools_material_data(input_mtl, packed_data)
def create_material_nodes(input_mtl, packed_data): def create_material_nodes(input_mtl, packed_data):
(enable_virtools_material,
(ambient, diffuse, specular, emissive, specular_power, ambient, diffuse, specular, emissive, specular_power,
alpha_test, alpha_blend, z_buffer, two_sided, alpha_test, alpha_blend, z_buffer, two_sided,
texture) = packed_data texture) = packed_data
@ -78,6 +77,41 @@ def create_material_nodes(input_mtl, packed_data):
inode.image = texture inode.image = texture
input_mtl.node_tree.links.new(inode.outputs[0], bnode.inputs[0]) 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 # load component

View File

@ -2,6 +2,11 @@ import bpy
from . import UTILS_constants, UTILS_functions from . import UTILS_constants, UTILS_functions
class BALLANCE_PG_virtools_material(bpy.types.PropertyGroup): 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", ambient: bpy.props.FloatVectorProperty(name="Ambient",
subtype='COLOR', subtype='COLOR',
min=0.0, min=0.0,
@ -74,6 +79,7 @@ def get_virtools_material(mtl):
def get_virtools_material_data(mtl): def get_virtools_material_data(mtl):
data = get_virtools_material(mtl) data = get_virtools_material(mtl)
return ( return (
data.enable_virtools_material,
data.ambient, data.ambient,
data.diffuse, data.diffuse,
data.specular, data.specular,
@ -89,7 +95,8 @@ def get_virtools_material_data(mtl):
def set_virtools_material_data(mtl, packed_data): def set_virtools_material_data(mtl, packed_data):
data = get_virtools_material(mtl) data = get_virtools_material(mtl)
# packed_data have the same order with the return value of `get_virtools_material_data` # 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.alpha_test, data.alpha_blend, data.z_buffer, data.two_sided,
data.texture) = packed_data data.texture) = packed_data

View File

@ -151,6 +151,7 @@ classes = (
PROPS_virtools_group.BALLANCE_UL_virtools_group, PROPS_virtools_group.BALLANCE_UL_virtools_group,
PROPS_virtools_group.BALLANCE_PT_virtools_group, PROPS_virtools_group.BALLANCE_PT_virtools_group,
PROPS_virtools_material.BALLANCE_OT_apply_virtools_material, PROPS_virtools_material.BALLANCE_OT_apply_virtools_material,
PROPS_virtools_material.BALLANCE_OT_parse_virtools_material,
PROPS_virtools_material.BALLANCE_PT_virtools_material, PROPS_virtools_material.BALLANCE_PT_virtools_material,
OBJS_group_opers.BALLANCE_OT_select_virtools_group, OBJS_group_opers.BALLANCE_OT_select_virtools_group,