I’m programming an addon for Blender 3.2 in python.
With my addon I can load a file which creates an object. This object has a variable amount of materials which I only know at runtime.
I now want to include the feature to change the material color in my addon. I would like to implement something like this (this picture is edited, that’s not my actual state):
The main problem is that I only know at runtime how many materials there are which means that I only know at runtime how many properties I need.
Is it even possible to define a variable amount of properties?
And is there a smart way to update the material colors? I know that you can define an update function for a property as described here. But as I have a variable amount of properties I’d need to have a variable amount of update functions which is not possible as far as I know.
I’d be very thankful if anyone has an idea and could help me out with my problem!
Re the update part, you can define variable update functions at runtime although it’s a bit complicated (example), but you can also add extra parameters to let the update method know which property called it and use only one update function, eg
Perhaps I’m misunderstanding but it sounds as though
the object already has materials applied and you just don’t know how many prior to loading a specific object.
You shouldn’t need additional properties for this. Granted the below is specifically looking for a principled bsdf shader and adjusting the default base color; but the concept of accessing the active objects material properties remains the same.
import bpy
class TESTADDON_PT_Main(bpy.types.Panel):
bl_idname = "TESTADDON_PT_Main"
bl_label = "Test Addon"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "Test"
def draw(self, context):
layout = self.layout
col = layout.column(align=True)
if context.object and context.object.material_slots:
obj = context.object
obj_mats = [m.material for m in obj.material_slots]
for mat in obj_mats:
if mat and mat.use_nodes:
bsdf = mat.node_tree.nodes.get("Principled BSDF")
row = col.row(align=True)
row.prop(bsdf.inputs['Base Color'],
"default_value",
text=mat.name)
def register():
bpy.utils.register_class(TESTADDON_PT_Main)
def unregister():
bpy.utils.unregister_class(TESTADDON_PT_Main)
if __name__ == "__main__":
register()
I got it to work by doing that!
I didn’t know you could also insert existing panels like the base color panel of a bsdf shader directly into an addon. But that’s a lot smarter! So thank you a lot for your answer!
Yup most properties can be displayed if you have a handle on the holder and its attribute name with a simple layout.prop(obj, "prop_name") no need to reinvent the wheel