Now I've got this operator working, and in multiple versions for similar functions, I would like a way to have them all fire off in sequence with one button press.
My first instinct was to just make a simple operator with the layout stack, but it didn't seem to do anything.
Now I'm on to trying a Macro for this, as discussed here, but this isn't doing anything either for some reason. The button shows up, but it just doesn't do anything. It's possible the macro function has been altered since 2016 and I just can't find any details of how it works now.
Here's the active code, including the macro and one of the modules I need it to run, the rest are all structurally the same.
class WM_OT_Bake_All(Macro):
bl_idname = "bake_all.trigger_macro"
bl_label = "Bake All Maps"
bl_options = {'REGISTER', 'INTERNAL', 'MACRO'}
@classmethod
def poll(cls, context):
return {'FINISHED'}
# Texture Bake Module
class WM_OT_Bake_Diffuse(Operator):
bl_label = "Bake Diffuse"
bl_idname = "wm.bake_diffuse"
bl_options = {'REGISTER', 'INTERNAL'}
@classmethod
def poll(cls, context):
return True
def execute(self, context):
size = bpy.data.scenes["Scene"].bake_tool.bake_int, bpy.data.scenes["Scene"].bake_tool.bake_int
obj = bpy.context.active_object
diffuse = bpy.data.materials["Skin"].node_tree.nodes["DiffuseBake"]
imgbake = bpy.data.images.new("DiffuseBake", width=size[0], height=size[1])
BSDF = bpy.data.materials["Skin"].node_tree.nodes["Baked_BSDF"]
# set bake type and parameters
for mat in obj.data.materials:
mat.use_nodes = True #Here it is assumed that the materials have been created with nodes, otherwise it would not be possible to assign a node for the Bake, so this step is a bit useless
bake_one.is_active_output = True
mat.node_tree.links.new(skin_comp.outputs[0], bake_one.inputs[0])
if BSDF.inputs[0].links: # Checks if the connection in question exists, skips the step if it doesn't.
linkToDelete = BSDF.inputs[0].links[0]
mat.node_tree.links.remove(linkToDelete)
bump_main.mute = True
texture_node = diffuse
texture_node.select = True
nodes.active = texture_node
texture_node.image = imgbake #Assign the image to the node
bpy.context.view_layer.objects.active = obj
bpy.ops.object.bake(type='DIFFUSE', save_mode='EXTERNAL')
imgbake.filepath_raw = "//bakes/DiffuseBake.png"
imgbake.file_format = 'PNG'
imgbake.save()
# find node and assign the texture to it
img = bpy.data.images.load("//bakes/DiffuseBake.png", check_existing=True)
bpy.data.materials["Skin"].node_tree.nodes["DiffuseBake"].image = img
bpy.data.images["DiffuseBake"].colorspace_settings.name = 'sRGB'
mat.node_tree.links.new(diffuse.outputs[0], baked_BSDF.inputs[0])
bump_main.mute = False
return {'FINISHED'}
# Panel section, this all displays, including the macro button, the modules all work, just the macro button doesn't do anything.
class NODE_PT_Bake(Panel):
bl_label = "DIPSS Bake"
bl_idname = "NODE_PT_bake"
bl_space_type = "NODE_EDITOR"
bl_region_type = "UI"
bl_category = "DIPSS Bake"
bl_context = "material"
@classmethod
def poll(self,context):
return context.object is not None
def draw(self, context):
layout = self.layout
scene = context.scene
baketool = scene.bake_tool
layout.label(text="Bake Properties", icon='MATERIAL')
layout.prop(baketool, "samp_int")
layout.operator("wm.set_samp", text = 'Confirm Samples')
layout.prop(baketool, "bake_int")
layout.separator()
layout.label(text="Full Array Bake", icon='MATERIAL')
layout.operator("bake_all.trigger_macro", text="Bake All Textures")
layout.separator()
layout.label(text="Individual Bakes", icon='MATERIAL')
layout.operator("wm.bake_diffuse")
layout.operator("wm.bake_normal")
layout.operator("wm.bake_rough")
layout.operator("wm.bake_spec")
layout.operator("wm.bake_weight")
layout.operator("wm.bake_height")
classes = (
BakeProperties,
WM_OT_Samp,
WM_OT_Bake_All,
WM_OT_Bake_Diffuse,
WM_OT_Bake_Normal,
WM_OT_Bake_Rough,
WM_OT_Bake_Spec,
WM_OT_Bake_Weight,
WM_OT_Bake_Height,
NODE_PT_Bake
)
def register():
from bpy.utils import register_class
for cls in classes:
register_class(cls)
WM_OT_Bake_All.define("wm.bake_diffuse")
WM_OT_Bake_All.define("wm.bake_normal")
WM_OT_Bake_All.define("wm.bake_rough")
WM_OT_Bake_All.define("wm.bake_spec")
WM_OT_Bake_All.define("wm.bake_weight")
WM_OT_Bake_All.define("wm.bake_height")
#I've tried this pointer property above and below the macro list, no change.
bpy.types.Scene.bake_tool = PointerProperty(type=BakeProperties)
def unregister():
from bpy.utils import unregister_class
for cls in reversed(classes):
unregister_class(cls)
del bpy.types.Scene.my_tool
if __name__ == "__main__":
register()
I've added a {'REGISTER'}
option to the macro to see what it was actually doing and the Info window gives me this:
bpy.ops.bake_all.trigger_macro(WM_OT_bake_diffuse={}, WM_OT_bake_normal={}, WM_OT_bake_rough={}, WM_OT_bake_spec={}, WM_OT_bake_weight={}, WM_OT_bake_height={})
Which tells me that it is interacting with my modules, but it's not actually running them. It's also not spitting any errors at me, so Blender thinks it's doing what it's supposed to.
I can't even find any meaningful articles about the bpy macro system, so for the first time, I'm setting a bounty on this.
At this point I'm torn between doubling the length of my script just to have the Bake All button work, and making the macro function work just out of spite...
.define("wm.bake_diffuse")
use.define("WM_OT_Bake_Diffuse")
$\endgroup$