import bpy from bpy.types import Operator from bpy.props import (BoolProperty, EnumProperty, PointerProperty, CollectionProperty, StringProperty) class RT_OT_list_object_affected_by_simplify(Operator): bl_idname = "rt.list_object_affected_by_simplify" bl_label = "List Objects Affected By Simplify" bl_description = "List objects that are affected by the Simplify settings, either in viewport or render" bl_options = {"REGISTER"} def invoke(self, context, event): self.ob_list = [] # Get simplify settings render = context.scene.render simplify_viewport = render.simplify_subdivision simplify_render = render.simplify_subdivision_render max_child_particles = render.simplify_child_particles volume_limit_resolution = render.simplify_volumes for obj in context.scene.objects: affected_data = [] if hasattr(obj, 'modifiers'): # Check subdivision surface modifiers for modifier in obj.modifiers: if modifier.type == 'SUBSURF': viewport_limited = modifier.levels > simplify_viewport render_limited = modifier.render_levels > simplify_render if viewport_limited or render_limited: affected_data.append({ 'type': 'SUBSURF', 'modifier': modifier, 'viewport_current': modifier.levels, 'viewport_limited': min(modifier.levels, simplify_viewport), 'render_current': modifier.render_levels, 'render_limited': min(modifier.render_levels, simplify_render), 'is_limited': viewport_limited or render_limited }) # Check multires modifiers if modifier.type == 'MULTIRES': viewport_limited = modifier.levels > simplify_viewport render_limited = modifier.render_levels > simplify_render if viewport_limited or render_limited: affected_data.append({ 'type': 'MULTIRES', 'modifier': modifier, 'viewport_current': modifier.levels, 'viewport_limited': min(modifier.levels, simplify_viewport), 'render_current': modifier.render_levels, 'render_limited': min(modifier.render_levels, simplify_render), 'is_limited': viewport_limited or render_limited }) # # Check particle systems if hasattr(obj, 'particle_systems') and len(obj.particle_systems) > 0 and max_child_particles < 1.0: for psys in obj.particle_systems: if psys.settings.type in ['EMITTER', 'HAIR']: affected_data.append({ 'type': 'PARTICLE', 'particle_system': psys, 'particle_type': psys.settings.type, 'count': psys.settings.count }) # Check materials for subsurface scattering and volumes # material_affected = False # if obj.material_slots: # for slot in obj.material_slots: # if slot.material and slot.material.node_tree: # nodes = slot.material.node_tree.nodes # for node in nodes: # if node.type == 'BSDF_PRINCIPLED': # if hasattr(node.inputs['Subsurface'], 'default_value'): # if node.inputs['Subsurface'].default_value > 0: # affected_data.append({ # 'type': 'SUBSURFACE', # 'material': slot.material, # 'subsurface_value': node.inputs['Subsurface'].default_value # }) # material_affected = True # break # elif node.type == 'VOLUME_PRINCIPLED': # affected_data.append({ # 'type': 'VOLUME_MAT', # 'material': slot.material # }) # material_affected = True # break # if material_affected: # break # Check for volume objects if obj.type == 'VOLUME' and volume_limit_resolution < 1.0: affected_data.append({ 'type': 'VOLUME_OBJ' }) # If object has affected data, add it to the list if affected_data: self.ob_list.append([obj, affected_data, "OUTLINER_OB_" + obj.type]) # Sort by object type, then by name self.ob_list.sort(key=lambda x: (x[2], x[0].name)) return context.window_manager.invoke_props_dialog(self, width=450) def draw(self, context): layout = self.layout render = context.scene.render ## Show simplify settings # layout.label(text="Simplify Settings:") layout.label(text="Viewport:") bpy.types.RENDER_PT_simplify_viewport.draw(self, context) layout.label(text="Render:") bpy.types.RENDER_PT_simplify_render.draw(self, context) # row = box.row() # row.label(text="Current Simplify Settings:", icon='SETTINGS') # col = box.column(align=True) # row = col.row() # # row.label(text=f"Enabled: {render.use_simplify}") # row.prop(render, "use_simplify") # Enabled # row = col.row() # # row.label(text=f"Viewport Subdivision: {render.simplify_subdivision}") # row.prop(render, "simplify_subdivision") # Viewport # row = col.row() # # row.label(text=f"Render Subdivision: {render.simplify_subdivision_render}") # row.prop(render, "simplify_subdivision_render") # Render layout.separator() if not self.ob_list: layout.label(text='No objects affected by Simplify settings', icon='CHECKMARK') return col = layout.column(align=False) for ct, obj_data in enumerate(self.ob_list): if ct > 0: col.separator() obj, affected_data, icon = obj_data for i, data in enumerate(affected_data): row = col.row() if i == 0: # Show object name and icon for first item op = row.operator('rt.select_object_by_name', text=obj.name, icon=icon, emboss=False) op.object_name = obj.name else: # Subsequent rows, show empty space row.label(text=' ', icon='BLANK1') # Show the specific affected feature if data['type'] == 'SUBSURF': mod = data['modifier'] row.label(text=f"SubSurf: {mod.name}", icon='MOD_SUBSURF') # Show viewport levels sub_row = row.row(align=True) sub_row.label(text=f"V: {data['viewport_current']}→{data['viewport_limited']}") # Show render levels sub_row = row.row(align=True) sub_row.label(text=f"R: {data['render_current']}→{data['render_limited']}") elif data['type'] == 'MULTIRES': mod = data['modifier'] row.label(text=f"Multires: {mod.name}", icon='MOD_MULTIRES') # Show viewport levels sub_row = row.row(align=True) sub_row.label(text=f"V: {data['viewport_current']}→{data['viewport_limited']}") # Show render levels sub_row = row.row(align=True) sub_row.label(text=f"R: {data['render_current']}→{data['render_limited']}") elif data['type'] == 'PARTICLE': psys = data['particle_system'] row.label(text=f"Particles: {psys.name}", icon='PARTICLES') row.label(text=f"Type: {data['particle_type']}") row.label(text=f"Count: {data['count']}") elif data['type'] == 'HAIR': mod = data['modifier'] row.label(text=f"Hair: {mod.name}", icon='HAIR') row.label(text=f"Node Group: {data['node_group']}") elif data['type'] == 'SUBSURFACE': mat = data['material'] row.label(text=f"Material: {mat.name}", icon='MATERIAL') row.label(text=f"Subsurface: {data['subsurface_value']:.3f}") elif data['type'] == 'VOLUME_MAT': mat = data['material'] row.label(text=f"Volume Material: {mat.name}", icon='MATERIAL') elif data['type'] == 'VOLUME_OBJ': row.label(text="Volume Object", icon='VOLUME_DATA') def execute(self, context): return {'FINISHED'} def register(): bpy.utils.register_class(RT_OT_list_object_affected_by_simplify) def unregister(): bpy.utils.unregister_class(RT_OT_list_object_affected_by_simplify)