When you select couple of objects in the viewport and click on New Selection Set the uilist gets populated and clicking on the Hide from Render icon, the objects get hidden from render but the icon in the uilist stays the same and there is my roadblock.
I have been reading about how to do it, but sadly the lack of tutorials or guides or examples on how to do in on a uilist is almost non-existant. I was checking the topic How to create a custom UI? but there is no a section related to uilist matters, maybe that section could be updated with that as well?
import bpy
import bpy_extras
import os
import collections
import json
import random
import copy
from bpy.types import (Operator,
Panel,
PropertyGroup,
IntProperty,
CollectionProperty,
BoolProperty,
UIList)
from bpy.props import (StringProperty,
BoolProperty,
IntProperty,
FloatProperty,
FloatVectorProperty,
EnumProperty,
PointerProperty,
CollectionProperty,
BoolVectorProperty,
)
def select_current_selset(self, context):
r"""Selection"""
if len(context.scene.sj_sel_set_items) is 0:
return None
index = int(self.selection_set_dplist)
obj_list = json.loads(
context.scene.sj_sel_set_items[self.index].object_list,
object_pairs_hook=collections.OrderedDict)
if len(obj_list) is 0:
return None
bpy.ops.object.select_all(action='DESELECT')
for obj in obj_list:
if bpy.context.scene.objects.get(obj):
bpy.data.objects[obj].select_set(True)
if bpy.context.scene.objects.get(obj_list[0]):
context.view_layer.objects.active = bpy.data.objects[obj_list[0]]
return None
def get_selection_list_items(scene, context):
r"""Get a list of selection sets"""
items = []
for i, item in enumerate(context.scene.sj_sel_set_items, 0):
items.append((str(i), item.set_name, ''))
if len(items) is 0:
items.append(('0', 'Selection Set Empty.', ''))
return items
def get_sel_set_item_name(self):
return self["set_name"]
def set_sel_set_item_name(self, value):
self["set_name"] = value
current_names = [i.set_name for i in bpy.context.scene.sj_sel_set_items]
current_names.remove(value)
new_name = value
cnt = 1
while new_name in current_names:
new_name = '{}.{:03d}'.format(new_name.split('.')[0], cnt)
cnt = cnt + 1
self["set_name"] = new_name
return None
class SJSelectionSetAddItem(bpy.types.Operator):
r"""Add new selection set"""
bl_idname = "sj_selection_set.add_selset"
bl_label = ""
bl_description = "Add new Selection Set from selected objects"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
r""""""
return True
def execute(self, context):
r""""""
if len(bpy.context.selected_objects) is 0:
msg = 'Please Select any object.'
def draw(self, context):
self.layout.label(text=msg)
bpy.context.window_manager.popup_menu(draw, title="Info", icon="INFO")
self.report({'INFO'}, msg)
return {'FINISHED'}
new_item = context.scene.sj_sel_set_items.add()
current_names = [i.set_name for i in context.scene.sj_sel_set_items]
new_name = 'SelectionSet'
cnt = 1
while new_name in current_names:
new_name = 'SelectionSet.{:03d}'.format(cnt)
cnt = cnt + 1
new_item.set_name = new_name
index = len(context.scene.sj_sel_set_items) - 1
context.scene.sj_sel_set_item_index = index
context.scene.sj_sel_set_props.selection_set_dplist = str(index)
obj_list = [obj.name for obj in bpy.context.selected_objects]
new_item.object_list = json.dumps(obj_list)
get_selection_list_items(self, context)
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
return {'FINISHED'}
class SJSelectionSetRender(bpy.types.Operator):
r"""Select objects in selected set"""
bl_idname = "sj_selection_set.render"
bl_label = ""
bl_description = "Select objects in selected set"
index: bpy.props.IntProperty(name="Objects in set", default=0)
@classmethod
def poll(cls, context):
return context.scene.sj_sel_set_items
def execute(self, context):
r""""""
index = context.scene.sj_sel_set_item_index
obj_list = json.loads(
context.scene.sj_sel_set_items[self.index].object_list,
object_pairs_hook=collections.OrderedDict)
if len(obj_list) is 0:
return {'FINISHED'}
bpy.ops.object.select_all(action='DESELECT')
for obj in obj_list:
if bpy.context.scene.objects.get(obj):
bpy.data.objects[obj].select_set(True)
if context.scene.objects.get(obj_list[0]):
context.view_layer.objects.active = bpy.data.objects[obj_list[0]]
for objs in bpy.context.selected_objects:
if objs.hide_render == True:
objs.hide_render = False
else:
objs.hide_render = True
return {'FINISHED'}
class SJSelectionSetEditList(bpy.types.UIList):
r""""""
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
custom_icon = 'OBJECT_HIDDEN'
ob = context.object
if self.layout_type in {'DEFAULT', 'COMPACT'}:
c = layout.column()
row = c.row()
split = row.split(factor=0.01)
c = split.column()
split = split.split()
c = split.column()
c.prop(item, "set_name", text="", emboss=False, icon=custom_icon)
show = layout.row(align=True)
show.scale_x = 1
show.operator(SJSelectionSetRender.bl_idname, icon = "RESTRICT_RENDER_OFF").index = index
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label(text="", icon=custom_icon)
class SJSelectionSetListPanel(bpy.types.Panel):
r"""UI"""
bl_label = "Selection Set List"
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_context = "objectmode"
bl_category = "Selection Set"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
sjss = context.scene.sj_sel_set_props
scn = context.scene
ob = context.object
row = layout.row()
sub_row = row.row(align=True)
sub_row.operator("sj_selection_set.add_selset", text="New Selection Set")
layout.separator(factor=0.5)
row = layout.row()
row.template_list("SJSelectionSetEditList", "Sel Set List", context.scene, "sj_sel_set_items", context.scene, "sj_sel_set_item_index", rows=1)
if len(context.scene.sj_sel_set_items) is 0:
return None
classes = (
SJSelectionSetEditList,
SJSelectionSetAddItem,
SJSelectionSetListPanel,
SJSelectionSetRender,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.Scene.sj_sel_set_item_index = bpy.props.IntProperty(name="Objects in set")
def unregister():
for cls in classes:
bpy.utils.unregister_class(cls)
del bpy.types.Scene.sj_sel_set_props
del bpy.types.Object.action_list_index
del bpy.types.Scene.my_test
bpy.types.VIEW3D_HT_tool_header.remove(SJSelectionSetPanel.draw)
if name == "main":
register()

show.operator(SJSelectionSetRender.bl_idname, icon = "RESTRICT_RENDER_OFF").index = indexsince it's an operator and not a direct reference to an item's attribute you may want for instance to change the icon depending on theshow_renderstate of the first object in the set.icon="RESTRICT_RENDER_ON" if context.scene.sj_sel_set_items[0].hide_render else "RESTRICT_RENDER_OFF"or something like that – Gorgious Nov 16 '21 at 08:19obj.hide_render = not obj.hide_renderinstead of your if/else lines – Gorgious Nov 16 '21 at 08:23context.scene.sj_sel_set_items[0].object_list[0]idk since it's a bit convoluted and you didn't include the contents ofsj_sel_set_itemsbtw instead of json serialization you should use CollectionProperty to store multiple objects references. or reference by name since it's as reliable and less complicated ^^ – Gorgious Nov 16 '21 at 08:38No matter what I try it refuses to work :(
– pekkuskär Nov 16 '21 at 08:50