0
$\begingroup$

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

$\endgroup$
3
  • 1
    $\begingroup$ Have you tried something like ´´´ bpy.ops.wm.bake_diffuse() bpy.ops.wm.bake_height() ... ´´´ In a simple operator, without using Macros ? $\endgroup$
    – B.Pader
    Commented Oct 31, 2022 at 10:37
  • $\begingroup$ Well, that seems to work. I tried that first, and it didn't do anything at all. Where were you when I was trying that, lol. But thank you for telling me this one. I'm still going to keep the bounty open for the Macro function because I am genuinely curious how that's supposed to work. If nobody has anything for the macro by day 5 you should write up a formulated answer with this solution and I'll give you the bounty for solving my problem. $\endgroup$ Commented Oct 31, 2022 at 14:09
  • $\begingroup$ I've just been debugging a similar issue, and I ended up finding that defining the macro steps via the Blender operator syntax (with the class name named correctly) fixed it, rather than using the python syntax. i.e. instead of using .define("wm.bake_diffuse") use .define("WM_OT_Bake_Diffuse") $\endgroup$ Commented Jul 19 at 14:15

0

You must log in to answer this question.

Browse other questions tagged .