How to structure data per object per material

I'm working on an addon where I need to be able to store a float that is not just specific to a just an object or just a material, but both. I want to display this property next to the material in a UIList that is similar to the Material Slots UI list but also has an additional float field next to the material name that can be edited. I've been following this documentation, which has been very helpful.

In the UI list, I can display the name of the materials in the list using layout.prop(ma, "name", text="", emboss=False, icon_value=icon). I realize that I could add an additional property that belongs to just an object by registering a property using code like:

bpy.types.Object.my_float = bpy.props.FloatProperty()


Similarly, I can register a float property with a material:

bpy.types.Material.my_float = bpy.props.FloatProperty()


I can then display these properties in the UI list with a line something like:

row.prop(context.active_object, "my_float", emboss=False, icon_value = 0)


or:

row.prop(ma, "my_float", emboss=False, icon_value=0)


But what would be the best way to go about structuring the data in my addon such that for each object, each material has a separate float even if that material is shared with other objects? (e.g., Cube has TestMaterial1 with a value of 0.5 for my_float, but Cube.001 has the same material (TestMaterial1) in its material slot, but instead stores 5.4 for my_float.)

I'm assuming I'll need to use some kind of Enum, but I want to make sure that the data updates properly as new materials are added to the materials slot and whatnot. Any suggestions?

Thanks!

If your property is bound to bpy.types.Material, each instance of Material will initialize its own property.

What you want to do sounds like a bpy.types.Object property. So, instead of:

bpy.types.Material.my_float = bpy.props.FloatProperty()


you should do:

bpy.types.Object.my_float = bpy.props.FloatProperty()


If that property is logically bound to a material, you can display it in the Material context.

In that case, context.active_object might not be available. Instead you may try to use the global bpy.context.

• Hey, thank you so much for the thoughtful answer and taking the time to respond! I really appreciate it. I realize now I should have structured my question better to explain more clearly what I was asking. I figured out what I needed to do more or less, and I can update this post when I get a chance. Thank you again so much for taking the time to respond! Apr 21 at 17:47