Files
blender-portable-repo/scripts/addons/SimpleBake/object_preperation.py
T
2026-07-16 12:41:53 -06:00

658 lines
29 KiB
Python

import bpy
from bpy.types import Operator
from bpy.props import StringProperty, BoolProperty
from bpy.utils import register_class, unregister_class
from .utils import SBConstants
from .messages import print_message
from .aov import get_aov_name
class SimpleBake_OT_PrepareObjectMatsPbr(Operator):
"""Prepare an object for PBR baking"""
bl_idname = "simplebake.prepare_object_mats_pbr"
bl_description = "Prepare object for PBR bake"
bl_label = "Prepare"
target_name: StringProperty()
this_bake: StringProperty()
bake_operation_id: StringProperty()
no_bake_image_node: BoolProperty(default=False)
only_bake_image_node: BoolProperty(default=False)
def create_dummy_nodes(self, context, mat):
print_message(context, f"Creating dummy nodes for {self.target_name}")
node_tree = mat.node_tree
nodes = node_tree.nodes
p_nodes = [n for n in nodes if n.bl_idname == "ShaderNodeBsdfPrincipled"]
#Special case for bump
if self.this_bake == SBConstants.PBR_BUMP:
for p_node in p_nodes:
#Nothing connected
if len(p_node.inputs["Normal"].links) == 0:
p_node["SB_Ignore_Normal"]= True
continue
#Connected but not a bump node
bump_node = p_node.inputs["Normal"].links[0].from_node
if bump_node.bl_idname != "ShaderNodeBump":
p_node["SB_Ignore_Normal"]= True
continue
#Nothing connected to bump node height input
if len(bump_node.inputs['Height'].links) == 0:
p_node["SB_Ignore_Normal"]= True
continue
#Must be OK to be treated normally
#p_node.inputs["Normal"]["SB_Ignore"] = False
#if len(bump_node.inputs[2].links) == 0:
#val = bump_node.inputs[2].default_value
#vnode = nodes.new("ShaderNodeValue")
#vnode.outputs[0].default_value = val
#vnode.label = "SimpleBake"
#node_tree.links.new(vnode.outputs[0], bump_node.inputs[2])
#Normal case, not bump
else:
socket_name = SBConstants.get_socket_names()[self.this_bake]
for p_node in p_nodes:
#Get the sockets we care about (correct name + empty)
sockets = [s for s in p_node.inputs if s.name == socket_name and len(s.links)==0]
for socket in sockets:
#If not, get value of the unconnected socket
val = socket.default_value
socket_type = socket.bl_idname
#if socket_type == "NodeSocketColor":
#Not needed, but future proofing
if socket_type.startswith("NodeSocketColor"):
rgb = nodes.new("ShaderNodeRGB")
rgb.outputs[0].default_value = val
rgb.label = "SimpleBake" #????????????????????????????
node_tree.links.new(rgb.outputs[0], socket)
#if socket_type in ["NodeSocketFloat", "NodeSocketFloatFactor", "NodeSocketFloatDistance"]:
if socket_type.startswith("NodeSocketFloat"):
vnode = nodes.new("ShaderNodeValue")
vnode.outputs[0].default_value = val
vnode.label = "SimpleBake" #?????????????????????????????????????????
node_tree.links.new(vnode.outputs[0], socket)
def bypass_muted_mix_shaders(self, mat):
#Let's bypass all the muted mix shader nodes
node_tree = mat.node_tree
nodes = node_tree.nodes
for n in nodes:
if n.bl_idname == "ShaderNodeMixShader" and n.mute:
if len(n.inputs[1].links) > 0:
fs = n.inputs[1].links[0].from_socket
else: fs = False
if len(n.outputs[0].links) > 0:
ts = n.outputs[0].links[0].to_socket
else: ts = False
if fs and ts:
node_tree.links.new(fs, ts)
nodes.remove(n)
def swap_e_for_p(self,mat):
node_tree = mat.node_tree
nodes = node_tree.nodes
enodes = [n for n in nodes if n.bl_idname == "ShaderNodeEmission"]
for e in enodes:
cval = e.inputs[0].default_value
sval = e.inputs[1].default_value
pos = e.location
if len(e.inputs[0].links) > 0:
cfs = e.inputs[0].links[0].from_socket
else:
cfs = False
if len(e.inputs[1].links) > 0:
sfs = e.inputs[1].links[0].from_socket
else:
sfs = False
os = e.outputs[0].links[0].to_socket
#Create principled BSDF
p = nodes.new("ShaderNodeBsdfPrincipled")
if cfs:
node_tree.links.new(cfs, p.inputs["Emission Color"])
else:
p.inputs["Emission Color"].default_value = cval
if sfs:
node_tree.links.new(sfs, p.inputs["Emission Strength"])
else:
p.inputs["Emission Strength"].default_value = sval
p.inputs["Base Color"].default_value = (0.0,0.0,0.0,1.0)
node_tree.links.new(p.outputs[0], os)
p.location = pos
#Last action, remove all the e nodes
[nodes.remove(n) for n in enodes]
def remove_disconnected(self, context, mat):
print_message(context, f"Removing disconnected nodes from {mat.name}")
nodes = mat.node_tree.nodes
#Start with the material output node
#Remove any not in use. So not to confuse matters.
[nodes.remove(n) for n in nodes if n.bl_idname == "ShaderNodeOutputMaterial" and len(n.inputs[0].links)==0]
#Find the active material output
mos = [n for n in nodes if n.bl_idname == "ShaderNodeOutputMaterial" and n.is_active_output == True]
assert(len(mos) == 1)
active_mo = mos[0]
#Is it Cycles?
if active_mo.target in ["CYCLES", "ALL"]:
#Yes. So we are good. Just remove the others
mos = [nodes.remove(n) for n in nodes if n.bl_idname == "ShaderNodeOutputMaterial" and n.is_active_output == False]
else:
#Active not Cycles. Can we find a pre-existing Cycles one somewhere?
mos = [n for n in nodes if n.bl_idname == "ShaderNodeOutputMaterial" and n.target in ["CYCLES","ALL"]]
if len(mos)>0:
#Found existing Cycles one, make it active and remove the others
mos[0].is_active_output = True
#Set to All, just for the viewport candy
mos[0].target = "ALL"
[nodes.remove(n) for n in nodes if n.bl_idname == "ShaderNodeOutputMaterial" and n.is_active_output == False]
else:
#Active isn't Cycles, and no Cycles in the material. Pick one at random. Force to Cycles
mos = [n for n in nodes if n.bl_idname == "ShaderNodeOutputMaterial"]
mos[0].is_active_output = True
mos[0].target = "ALL"
[nodes.remove(n) for n in nodes if n.bl_idname == "ShaderNodeOutputMaterial" and n.is_active_output == False]
#Loop through nodes to remove disconnected nodes that we care about
repeat = False
r = [nodes.remove(n) for n in nodes if n.bl_idname == "ShaderNodeBsdfPrincipled" and len(n.outputs[0].links) == 0 ]
if len(r) >0: repeat = True #We removed something
r = [nodes.remove(n) for n in nodes if n.bl_idname == "ShaderNodeEmission" and len(n.outputs[0].links) == 0 ]
if len(r) >0: repeat = True #We removed something
r = [nodes.remove(n) for n in nodes if n.bl_idname == "ShaderNodeMixShader" and len(n.outputs[0].links) == 0 ]
if len(r) >0: repeat = True #We removed something
#Special case for Shader to RGB node
r = [nodes.remove(n) for n in nodes if n.bl_idname == "ShaderNodeShaderToRGB" and len(n.outputs[0].links) == 0 ]
if len(r) >0: repeat = True #We removed something
#If we removed any nodes, we need to do this again
if repeat: self.remove_disconnected(context, mat)
def get_active_output_node(self, mat):
nodes = mat.node_tree.nodes
output_nodes = [n for n in nodes if n.bl_idname == "ShaderNodeOutputMaterial"]
assert(len(output_nodes)==1)
return output_nodes[0]
def get_surface_shader_node(self, mat):
output_node = self.get_active_output_node(mat)
surface = output_node.inputs.get("Surface")
if surface == None or len(surface.links) == 0:
return None
return surface.links[0].from_node
def setup_pure_p_mat(self, context, mat):
print_message(context, f"Setup for pure P material for {self.target_name}")
node_tree = mat.node_tree
nodes = node_tree.nodes
output_node = self.get_active_output_node(mat)
p_node = self.get_surface_shader_node(mat)
if p_node == None or p_node.bl_idname != "ShaderNodeBsdfPrincipled":
print_message(context, f"Material {mat.name} is not a pure Principled material")
return False
#Create an emission shader and connect to output
emissnode = nodes.new("ShaderNodeEmission")
emissnode.label = "SimpleBake" #??????????????????????????????????
emissnode.location = (output_node.location.x, output_node.location.y+200)
node_tree.links.new(emissnode.outputs[0], output_node.inputs[0])
#Connect whatever is in Principled Shader for this bakemode to the emission
if self.this_bake == SBConstants.PBR_BUMP:
normal_socket = p_node.inputs["Normal"]
if "SB_Ignore_Normal" in p_node:
emissnode.inputs[0].default_value = (0.5,0.5,0.5,1)
else:
bump_node = p_node.inputs["Normal"].links[0].from_node
bump_input = bump_node.inputs['Height'].links[0].from_socket
node_tree.links.new(bump_input, emissnode.inputs[0])
else:
socket_name = SBConstants.get_socket_names()[self.this_bake]
socket = p_node.inputs[socket_name]
node_tree.links.new(socket.links[0].from_socket, emissnode.inputs[0])
return True
def setup_mix_mat(self, context, mat):
print_message(context, f"Setup for mix material for {self.target_name}")
node_tree = mat.node_tree
nodes = node_tree.nodes
output_node = self.get_active_output_node(mat)
surface_node = self.get_surface_shader_node(mat)
if surface_node == None or surface_node.bl_idname != "ShaderNodeMixShader":
print_message(context, f"Material {mat.name} is not a Mix Shader material")
return False
#For every mix shader, create a mixrgb above it
mix_nodes = [n for n in nodes if n.bl_idname == "ShaderNodeMixShader"]
for mix_node in mix_nodes:
#Create RGB mix for every mix shader node
rgbmix = nodes.new("ShaderNodeMixRGB")
rgbmix.location = (mix_node.location.x, mix_node.location.y+200)
rgbmix.label="SimpleBake" #????????????????????????????????????????
rgbmix["SB_rgb_proxy_for"] = mix_node.name
#If there is one, plug the factor from the original mix node into our new mix node
if len(mix_node.inputs[0].links) > 0:
node_tree.links.new(mix_node.inputs[0].links[0].from_socket, rgbmix.inputs[0])
#Else, copy the default value
else:
rgbmix.inputs[0].default_value = mix_node.inputs[0].default_value
#Loop over the new RGBmix nodes
rgbmix_nodes = [n for n in nodes if "SB_rgb_proxy_for" in n]
assert(len(rgbmix_nodes)>0)
for rgbmix_node in rgbmix_nodes:
#Get the original mix node
mix_node = nodes[rgbmix_node["SB_rgb_proxy_for"]]
#Socket 1 (back to p_node)
if len(mix_node.inputs[1].links)>0 and mix_node.inputs[1].links[0].from_node.bl_idname == "ShaderNodeBsdfPrincipled":
origin_p_node = mix_node.inputs[1].links[0].from_node
if self.this_bake == SBConstants.PBR_BUMP:
normal_socket = origin_p_node.inputs["Normal"]
if "SB_Ignore_Normal" in origin_p_node:
rgbmix_node.inputs[1].default_value = (0.5,0.5,0.5,1)
else:
bump_node = origin_p_node.inputs["Normal"].links[0].from_node
bump_input = bump_node.inputs['Height'].links[0].from_socket
node_tree.links.new(bump_input, rgbmix_node.inputs[1])
else:
socket_name = SBConstants.get_socket_names()[self.this_bake]
origin_socket = origin_p_node.inputs[socket_name].links[0].from_socket
node_tree.links.new(origin_socket, rgbmix_node.inputs[1])
#Socket 2 (back to p_node)
if len(mix_node.inputs[2].links)>0 and mix_node.inputs[2].links[0].from_node.bl_idname == "ShaderNodeBsdfPrincipled":
origin_p_node = mix_node.inputs[2].links[0].from_node
if self.this_bake == SBConstants.PBR_BUMP:
normal_socket = origin_p_node.inputs["Normal"]
if "SB_Ignore_Normal" in origin_p_node:
rgbmix_node.inputs[2].default_value = (0.5,0.5,0.5,1)
else:
bump_node = origin_p_node.inputs["Normal"].links[0].from_node
bump_input = bump_node.inputs['Height'].links[0].from_socket
node_tree.links.new(bump_input, rgbmix_node.inputs[2])
else:
socket_name = SBConstants.get_socket_names()[self.this_bake]
origin_socket = origin_p_node.inputs[socket_name].links[0].from_socket
node_tree.links.new(origin_socket, rgbmix_node.inputs[2])
#Socket 1 (back to mix node)
if len(mix_node.inputs[1].links)>0 and mix_node.inputs[1].links[0].from_node.bl_idname == "ShaderNodeMixShader":
origin_mix_node = mix_node.inputs[1].links[0].from_node
#Get the RGB mix for that origin mix node
origin_rgbmix = [n for n in nodes if "SB_rgb_proxy_for" in n and n["SB_rgb_proxy_for"] == origin_mix_node.name]
assert(len(origin_rgbmix) == 1)
origin_rgbmix = origin_rgbmix[0]
node_tree.links.new(origin_rgbmix.outputs[0], rgbmix_node.inputs[1])
#Socket 2 (back to mix node)
if len(mix_node.inputs[2].links)>0 and mix_node.inputs[2].links[0].from_node.bl_idname == "ShaderNodeMixShader":
origin_mix_node = mix_node.inputs[2].links[0].from_node
#Get the RGB mix for that origin mix node
origin_rgbmix = [n for n in nodes if "SB_rgb_proxy_for" in n and n["SB_rgb_proxy_for"] == origin_mix_node.name]
assert(len(origin_rgbmix) == 1)
origin_rgbmix = origin_rgbmix[0]
node_tree.links.new(origin_rgbmix.outputs[0], rgbmix_node.inputs[2])
#Back to nowhere
if len(mix_node.inputs[1].links) == 0:
rgbmix_node.inputs[1].default_value = (0,0,0,1)
if len(mix_node.inputs[2].links) == 0:
rgbmix_node.inputs[2].default_value = (0,0,0,1)
#Finally connect to the output
final_mix = output_node.inputs[0].links[0].from_node
final_rgbmix = [n for n in nodes if "SB_rgb_proxy_for" in n and n["SB_rgb_proxy_for"] == final_mix.name]
assert(len(final_rgbmix)>0)
final_rgbmix = final_rgbmix[0]
node_tree.links.new(final_rgbmix.outputs[0], output_node.inputs[0])
return True
def setup_displacement(self, context, mat):
print_message(context, f"Setup for displacement bake on {self.target_name}")
node_tree = mat.node_tree
nodes = node_tree.nodes
#Find the active MO node
mo_node = None
for n in nodes:
if n.bl_idname == "ShaderNodeOutputMaterial" and n.is_active_output:
mo_node = n
if mo_node == None:
print(f"Error - no active Material Output in material {mat.name}")
return False
#See if anything is plugged into the Displacement Socket
mo_disp_socket = mo_node.inputs["Displacement"]
if len(mo_disp_socket.links) <1:
print_message(context, f"Skipping. Nothing plugged into displacement socket for material {mat.name}")
return True
#Find the from node. Check it's either Displacement or Displacement Vector
disp_node = mo_disp_socket.links[0].from_node
if disp_node.bl_idname not in ["ShaderNodeDisplacement", "ShaderNodeVectorDisplacement"]:
return False
#Found disp node
source_socket = None
socket_name = "Height" if disp_node.bl_idname == "ShaderNodeDisplacement" else "Vector"
#Is something plugged into Height/Vector??
if len(disp_node.inputs[socket_name].links)>0:
source_socket = disp_node.inputs[socket_name].links[0].from_socket
else:
#NOTHING PLUGGED IN
if disp_node.inputs[socket_name].bl_idname == "NodeSocketColor":
#No dummy node possible
return False
else:
value_node = nodes.new(type='ShaderNodeValue')
value_node.outputs[0].default_value = disp_node.inputs[socket_name].default_value
source_socket = value_node.outputs[0]
if source_socket == None:
return False
#Create emission node and hook it up
emission_node = nodes.new(type='ShaderNodeEmission')
emission_node.location = (mo_node.location.x, mo_node.location.y+150)
node_tree.links.new(source_socket, emission_node.inputs["Color"])
node_tree.links.new(emission_node.outputs[0], mo_node.inputs["Surface"])
def setup_aov(self, context, mat, aovname):
print_message(context, f"Setup for AOV bake for {aovname}")
node_tree = mat.node_tree
nodes = node_tree.nodes
aov_node = None
#Find the AOV node that we want
for n in nodes:
if n.bl_idname == "ShaderNodeOutputAOV":
if n.aov_name == aovname:
#Found it
aov_node = n
#Give up if we can't find the AOV node we want (for whatver reason)
if aov_node == None:
return False
#Find the active MO node
mo_node = None
for n in nodes:
if n.bl_idname == "ShaderNodeOutputMaterial" and n.is_active_output:
mo_node = n
assert(mo_node!=None)
#Col is prioritised to fit with how vanilla Blender does it
if len(aov_node.inputs['Color'].links)>0:
source_socket = aov_node.inputs['Color'].links[0].from_socket
elif len(aov_node.inputs['Value'].links)>0:
source_socket = aov_node.inputs['Value'].links[0].from_socket
else:
print_message(context, "ERROR - Couldn't find source of AOV node")
return False
#Create emission node and hook it up
emission_node = nodes.new(type='ShaderNodeEmission')
emission_node.location = (mo_node.location.x, mo_node.location.y+150)
node_tree.links.new(source_socket, emission_node.inputs["Color"])
node_tree.links.new(emission_node.outputs[0], mo_node.inputs["Surface"])
def create_bake_image_node(self, mat, mat_name=""):
node_tree = mat.node_tree
nodes = node_tree.nodes
existing_bake_nodes = [n for n in nodes if "SB_bake_image_node" in n]
if len(existing_bake_nodes) !=0:
#Just quit if there is already a node in this material
#e.g. Specials are used more than once. Also object may have same PBR material multiple times
return True
image_node = nodes.new("ShaderNodeTexImage")
#Where is the image we want? This is different for a merged bake or per-mat bake
if not self.merged_bake:
if mat_name:
# tex_per_mat: find the image specific to this material
image_name = ([i.name for i in bpy.data.images if
i.get("SB_bake_object") == self.target_name and
i.get("SB_bake_operation_id") == self.bake_operation_id and
i.get("SB_this_bake") == self.this_bake and
i.get("SB_bake_material") == mat_name
])
else:
image_name = ([i.name for i in bpy.data.images if
"SB_bake_object" in i and i["SB_bake_object"] == self.target_name and
"SB_bake_operation_id" in i and i["SB_bake_operation_id"] == self.bake_operation_id and
"SB_this_bake" in i and i["SB_this_bake"] == self.this_bake
])
else:
image_name = ([i.name for i in bpy.data.images if
"SB_bake_operation_id" in i and i["SB_bake_operation_id"] == self.bake_operation_id and
"SB_this_bake" in i and i["SB_this_bake"] == self.this_bake
])
assert len(image_name)==1, f"Found {len(image_name)} images looking for {self.this_bake}"
image_name = image_name[0]
image_node.image = bpy.data.images[image_name]
#Leave it the only node selected
for n in nodes:
n.select = False
image_node.select = True
nodes.active = image_node
image_node["SB_bake_image_node"] = True
return True
def create_dummy_bake_image_node(self, mat):
"""Create a throwaway 1x1 image node for excluded materials so Blender has
somewhere to write their pixels (output is discarded)."""
node_tree = mat.node_tree
nodes = node_tree.nodes
existing_bake_nodes = [n for n in nodes if "SB_bake_image_node" in n]
if existing_bake_nodes:
return
dummy_name = "SB_excluded_mat_dummy"
if dummy_name not in bpy.data.images:
dummy = bpy.data.images.new(dummy_name, 1, 1, alpha=False)
dummy["SB_dummy"] = True
else:
dummy = bpy.data.images[dummy_name]
image_node = nodes.new("ShaderNodeTexImage")
image_node.image = dummy
for n in nodes:
n.select = False
image_node.select = True
nodes.active = image_node
image_node["SB_bake_image_node"] = True
def execute(self, context):
sbp = context.scene.SimpleBake_Props
self.merged_bake = sbp.merged_bake
mats=[]
if not (o:= context.scene.objects.get(self.target_name)):
print_message(context, f"ERROR: Preparing object. Couldn't find {self.target_name}!")
return {'CANCELLED'}
else:
#Get list of materials for target object
mats = [slot.material for slot in o.material_slots if slot.material!=None]
# Build per-material enabled/disabled sets from mat_bake_list (empty = no restrictions)
# Working backup materials have an SBW_ prefix — strip it to get the original name
mat_entries = [e for e in sbp.mat_bake_list if e.obj_name == self.target_name]
enabled_mat_names = {e.mat_name for e in mat_entries if e.enabled}
disabled_mat_names = {e.mat_name for e in mat_entries if not e.enabled}
has_restrictions = bool(mat_entries) # any mat_bake_list entries for this object
def orig_name(mat):
"""Return the original material name, stripping SBW_ (working) and SBM_ (master) backup prefixes."""
name = mat.name
if name.startswith("SBW_"):
name = name[4:]
if name.startswith("SBM_"):
name = name[4:]
return name
#No prep needed for normal or any specials. Just create bake image node (if that)
if (self.this_bake == SBConstants.PBR_NORMAL) or (self.this_bake in SBConstants.ALL_SPECIALS):
print_message(context, "No object prep needed - specials or normal map")
if not self.no_bake_image_node:
for mat in mats:
oname = orig_name(mat)
if self.this_bake in SBConstants.ALL_SPECIALS and "SB_original_mat_name" in mat:
oname = mat["SB_original_mat_name"]
if has_restrictions and oname in disabled_mat_names:
self.create_dummy_bake_image_node(mat)
else:
use_per_mat = sbp.tex_per_mat and not self.merged_bake and has_restrictions
bake_mat_name = oname if use_per_mat else ""
self.create_bake_image_node(mat, mat_name=bake_mat_name)
mat["SB_bake_config"] = self.this_bake
return {'FINISHED'}
#Otherwise, prepare each material for this bake type
for mat in mats:
oname = orig_name(mat)
# Handle excluded materials
if has_restrictions and oname in disabled_mat_names:
print_message(context, f"Material {mat.name} is excluded - creating dummy node")
self.create_dummy_bake_image_node(mat)
continue
if "SB_bake_config" in mat and mat["SB_bake_config"] == self.this_bake:
print_message(context, f"Material {mat.name} is already in correct config for {self.this_bake}")
continue
# mat_name to use when looking up per-material image (use original name, not working backup name)
# Only use per-mat lookup if this object has mat_bake_list entries (i.e. it's a source object,
# not an S2A target object which won't have any entries)
bake_mat_name = oname if (sbp.tex_per_mat and not self.merged_bake and has_restrictions) else ""
if self.only_bake_image_node:
print_message(context, f"Just creating bake image node in mat {mat}")
self.create_bake_image_node(mat, mat_name=bake_mat_name)
continue
#Special case for displacement. Don't need to mess with outher nodes
if self.this_bake == SBConstants.PBR_DISPLACEMENT:
self.setup_displacement(context, mat)
if not self.no_bake_image_node:
self.create_bake_image_node(mat, mat_name=bake_mat_name)
mat["SB_bake_config"] = self.this_bake #TODO-----------------CHECK FOR ISSUES
continue
#Special case for AOVs. Don't need to mess with outher nodes
print(f"--------------- {self.this_bake}")
if SBConstants.PBRAOVS in self.this_bake:
aovname = get_aov_name(context, self.this_bake)
self.setup_aov(context, mat, aovname)
if not self.no_bake_image_node:
self.create_bake_image_node(mat, mat_name=bake_mat_name)
mat["SB_bake_config"] = self.this_bake
continue
#Bypass muted mix shaders
self.bypass_muted_mix_shaders(mat)
#Remove disconnected nodes
self.remove_disconnected(context, mat)
#Swap all e for p
self.swap_e_for_p(mat)
#What kind of material is this?
node_tree = mat.node_tree
nodes = node_tree.nodes
surface_node = self.get_surface_shader_node(mat)
if surface_node != None and surface_node.bl_idname == "ShaderNodeMixShader":
print_message(context, "This is a Mix Material")
self.create_dummy_nodes(context, mat)
if self.setup_mix_mat(context, mat):
mat["SB_bake_config"] = self.this_bake #TODO-----------------CHECK FOR ISSUES
elif(surface_node != None and surface_node.bl_idname == "ShaderNodeBsdfPrincipled"):
#print_message(context, "This is a Pure P material")
self.create_dummy_nodes(context, mat)
if self.setup_pure_p_mat(context, mat):
mat["SB_bake_config"] = self.this_bake #TODO-----------------CHECK FOR ISSUES
else:
print_message(context, "Non-PBR material type - will still create bake image node")
if not self.no_bake_image_node:
self.create_bake_image_node(mat, mat_name=bake_mat_name)
return {'FINISHED'}
classes = ([
SimpleBake_OT_PrepareObjectMatsPbr
])
def register():
global classes
for cls in classes:
register_class(cls)
def unregister():
global classes
for cls in classes:
unregister_class(cls)