diff --git a/core/properties.py b/core/properties.py index 2773ca4..abe3e17 100644 --- a/core/properties.py +++ b/core/properties.py @@ -1,12 +1,50 @@ import bpy -from bpy.types import Scene, PropertyGroup, Object, Material, TextureNode, Context +from bpy.types import Scene, PropertyGroup, Object, Material, TextureNode, Context, SceneObjects from bpy.props import BoolProperty, EnumProperty, FloatProperty, IntProperty, CollectionProperty, StringProperty, FloatVectorProperty, PointerProperty from bpy.utils import register_class +class material_list_bool: + old_list: list[Material] = [] + bool_material_list_expand: bool = False + + def set_bool(self, value: bool) -> None: + material_list_bool.bool_material_list_expand = value + if value == False: + material_list_bool.old_list = [] + + def get_bool(self) -> bool: + newlist: list[Material] = [] + for obj in bpy.context.scene.objects: + if len(obj.material_slots)>0: + for mat_slot in obj.material_slots: + if mat_slot.material: + if mat_slot.material not in newlist: + newlist.append(mat_slot.material) + + still_the_same: bool = True + for item in newlist: + if item not in material_list_bool.old_list: + still_the_same = False + break + for item in material_list_bool.old_list: + if item not in newlist: + still_the_same = False + break + + material_list_bool.bool_material_list_expand = still_the_same + + return material_list_bool.bool_material_list_expand + +class SceneMatClass(PropertyGroup): + mat: PointerProperty(type=Material) + + def register_properties(): + register_class(SceneMatClass) + #happy with how compressed this get_texture_node_list method is - @989onan def get_texture_node_list(self: Material, context: Context) -> list[set[3]]: if self.use_nodes: @@ -25,11 +63,14 @@ def register_properties(): Material.texture_atlas_ambient_occlusion = EnumProperty(name="Ambient Occlusion", description="The texture that will be used for the ambient occlusion map atlas", default=0, items=get_texture_node_list) Material.texture_atlas_height = EnumProperty(name="Height", description="The texture that will be used for the height map atlas", default=0, items=get_texture_node_list) - Scene.texture_atlas_material_index = IntProperty()#default=-1, get=(lambda self : -1), set=(lambda self,context : None) + Scene.texture_atlas_material_index = IntProperty(default=-1, get=(lambda self : -1), set=(lambda self,context : None)) - #class Texture_Atlas_PropertyGroup(PropertyGroup): - # materials: CollectionProperty(type=Material) - #register_class(Texture_Atlas_PropertyGroup) + + + + Scene.materials = CollectionProperty(type=SceneMatClass) + + Scene.texture_atlas_Has_Mat_List_Shown = BoolProperty(default=False, get=material_list_bool.get_bool, set=material_list_bool.set_bool) #Scene.texture_atlas_properties = PointerProperty(type=Texture_Atlas_PropertyGroup) diff --git a/ui/atlas_materials.py b/ui/atlas_materials.py index 78735a5..f0c8018 100644 --- a/ui/atlas_materials.py +++ b/ui/atlas_materials.py @@ -1,7 +1,38 @@ -from bpy.types import UIList, Panel, UILayout, Object,Context,MaterialSlot +from bpy.types import UIList, Panel, UILayout, Object, Context,Material, Operator import bpy from ..core.register import register_wrap from .panel import AvatarToolkitPanel +from ..core.properties import SceneMatClass, material_list_bool + + +@register_wrap +class ExpandSection_Materials(Operator): + bl_idname = 'avatar_toolkit.expand_section_materials' + bl_label = "" + bl_description = "" + + @classmethod + def poll(cls, context: Context) -> bool: + return True + + + def execute(self, context: Context) -> set: + + if not context.scene.texture_atlas_Has_Mat_List_Shown: + context.scene.materials.clear() + newlist: list[Material] = [] + for obj in bpy.context.scene.objects: + if len(obj.material_slots)>0: + for mat_slot in obj.material_slots: + if mat_slot.material: + if mat_slot.material not in newlist: + newlist.append(mat_slot.material) + newitem: SceneMatClass = context.scene.materials.add() + newitem.mat = mat_slot.material + material_list_bool.old_list = newlist + else: + context.scene.texture_atlas_Has_Mat_List_Shown = False + return {'FINISHED'} @register_wrap class MaterialTextureAtlasProperties(UIList): @@ -11,46 +42,25 @@ class MaterialTextureAtlasProperties(UIList): bl_region_type = 'UI' - def draw_item(self, context: Context, layout: UILayout, data: bpy.types.Object, item:MaterialSlot, icon, active_data, active_propname, index): + def draw_item(self , context: Context, layout: UILayout, data: bpy.types.Object, item:SceneMatClass, icon, active_data, active_propname, index): - if item.material: + if context.scene.texture_atlas_Has_Mat_List_Shown: box = layout.box() - col = box.row() - col.label(text="Material: \""+item.material.name+"\"") - if data.active_material_index == index: - col = box.row() - col.prop(item.material, "texture_atlas_albedo") - col = box.row() - col.prop(item.material, "texture_atlas_normal") - col = box.row() - col.prop(item.material, "texture_atlas_emission") - col = box.row() - col.prop(item.material, "texture_atlas_ambient_occlusion") - col = box.row() - col.prop(item.material, "texture_atlas_height") - else: - box = layout.box() - col = box.row() - col.label(text="Empty Material Slot.") - -@register_wrap -class MaterialListPanel(UIList): - bl_label = "Texture Atlas Material List" - bl_idname = "Material_UL_avatar_toolkit_texture_atlas_mat_list" - bl_space_type = 'VIEW_3D' - bl_region_type = 'UI' - - def draw_item(self, context: Context, layout: UILayout, data, item:Object, icon, active_data, active_propname, index): - custom_icon = "OBJECT_DATAMODE" - box = layout.box() - row = box.row() - row.label(text=item.name, icon = custom_icon) - if context.scene.texture_atlas_material_index == index: row = box.row() - box = row.box() + row.label(text=item.mat.name, icon = "MATERIAL") + col = box.row() + col.prop(item.mat, "texture_atlas_albedo") + col = box.row() + col.prop(item.mat, "texture_atlas_normal") + col = box.row() + col.prop(item.mat, "texture_atlas_emission") + col = box.row() + col.prop(item.mat, "texture_atlas_ambient_occlusion") + col = box.row() + col.prop(item.mat, "texture_atlas_height") - box.template_list("Material_UL_avatar_toolkit_texture_atlas_mat_list_mat", "The_Texture_Atlas_List_mat_"+item.name, item, "material_slots", item, "active_material_index") - + + @register_wrap class TextureAtlasPanel(Panel): @@ -65,7 +75,14 @@ class TextureAtlasPanel(Panel): layout = self.layout row = layout.row() boxoutter = row.box() + direction_icon = 'RIGHTARROW' if not context.scene.texture_atlas_Has_Mat_List_Shown else 'DOWNARROW_HLT' row = boxoutter.row() - row.label(text=MaterialListPanel.bl_label) - row = boxoutter.row() - row.template_list("Material_UL_avatar_toolkit_texture_atlas_mat_list", "The_Texture_Atlas_List", context.scene, "objects", context.scene, "texture_atlas_material_index") + row.operator(ExpandSection_Materials.bl_idname, text=("Reload Texture Atlas Material List" if not context.scene.texture_atlas_Has_Mat_List_Shown else "Loaded Texture Atlas Material List"), icon=direction_icon) + if context.scene.texture_atlas_Has_Mat_List_Shown: + + #get_texture_node_list(bpy.context) + + row = boxoutter.row() + row.template_list(MaterialTextureAtlasProperties.bl_idname, 'material_list', context.scene, 'materials', + context.scene, 'texture_atlas_material_index', rows=12, type='DEFAULT') + \ No newline at end of file