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())
# 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:

View File

@ -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)
)

View File

@ -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,

View File

@ -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)
# 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")

View File

@ -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

View File

@ -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

View File

@ -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,