import bpy
from bpy.props import PointerProperty, BoolProperty
from bpy.types import PropertyGroup
class SaunaCloudPanel:
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_category = "Sauna"
@classmethod
def poll(cls, context):
ao = context.active_object
return ao and ao.type == 'MESH'
class SAUNA_PT_Wall(SaunaCloudPanel, bpy.types.Panel):
bl_idname = "SAUNA_PT_Wall"
bl_label = "Wall"
def draw(self, context):
layout = self.layout
sc = context.scene.saunacloud
ob = context.active_object
mat = ob.active_material
layout.context_pointer_set("material", mat)
layout.context_pointer_set("sauna_cloud_material", sc.material)
box = layout.box()
box.prop(ob, "name")
col = box.column()
col.template_list("MATERIAL_UL_matslots", "", ob, "material_slots", ob, "active_material_index", rows=5)
col.operator("object.material_slot_add")
if mat:
col.prop(mat, "is_sauna_cloud")
#col.prop(sc, 'material', text=getattr(sc.material, "name", "None"))
col.template_ID(sc, "material")
class SAUNA_Global_Props(PropertyGroup):
def poll_material(self, material):
print("poll", material.name, material.is_sauna_cloud)
return material.is_sauna_cloud
def update_material(self, context):
scene = self.id_data
sc = self
ob = context.object
mat = self.material
# debug print
print(f"Update object: {ob.name} with material: {mat.name}")
ob.active_material = mat
material : PointerProperty(
type=bpy.types.Material,
poll=poll_material,
update=update_material,
)
classes = (
SAUNA_Global_Props,
SAUNA_PT_Wall,
)
def draw_sc_material_checkbox(self, context):
mat = getattr(context, "material", None)
self.layout.label(text=mat.name if mat else "None")
if mat:
self.layout.prop(mat, "is_sauna_cloud")
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.Scene.saunacloud = bpy.props.PointerProperty(type=SAUNA_Global_Props)
bpy.types.Material.is_sauna_cloud = BoolProperty()
bpy.types.MATERIAL_PT_preview.prepend(draw_sc_material_checkbox)
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
bpy.types.MATERIAL_PT_preview.remove(draw_sc_material_checkbox)
if __name__ == "__main__":
register()
To answer the question, in an update or items method self
is the propertygroup and self.id_data
the ID object down the chain it belongs to. Scene in this case.
To get the enum value in either
self.matlist
Consider defining an enum and using same on material and object to poll instead of relying on naming convention.
enum = EnumProperty(... our types ...)
bpy.types.Material.sauna_type = enum
bpy.types.Object.sauna_type = enum
You can't set properties of ID objects in a draw method.
In the update method, to do same as above
ob.active_material = bpy.data.materials.get(sc.matname)
however IMO far better to poll a pointer. Import from bpy import context
into the poll method to get context object. eg using matching enums,
def material_poll(self, material):
from bpy import context
ob = context.object
return material.sauna_type == getattr(ob, "sauna_type", None)
or via name slicing method used in question