render_toolbox/operators/simplify_conflicts.py

356 lines
16 KiB
Python
Executable File

import bpy
from bpy.types import Operator
from bpy.props import (BoolProperty,
EnumProperty,
PointerProperty,
CollectionProperty,
StringProperty)
def list_simplify_affected_objects(context):
"""Return a list of object affected by simplify
return : [[obj, [{type: "SUBSURF", ..}, {..}], icon], ..]
"""
ob_list = []
# Get simplify settings
render = context.scene.render
simplify_viewport = render.simplify_subdivision
simplify_render = render.simplify_subdivision_render
max_child_particles = min(render.simplify_child_particles, render.simplify_child_particles_render)
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:
ob_list.append([obj, affected_data, "OUTLINER_OB_" + obj.type])
return ob_list
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 = []
self.ob_list = list_simplify_affected_objects(context)
# 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
layout.use_property_decorate = False
layout.use_property_split = True
render = context.scene.render
row = layout.row()
row.prop(render, "use_simplify", text="Use Simplify")
if not render.use_simplify:
row.label(text="Simplify is Disabled", icon='INFO')
# Get current simplify settings
simplify_viewport = render.simplify_subdivision
simplify_render = render.simplify_subdivision_render
max_child_particles = min(render.simplify_child_particles, render.simplify_child_particles_render)
volume_limit_resolution = render.simplify_volumes
## 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)
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):
# Show the specific affected feature
if data['type'] == 'SUBSURF':
mod = data['modifier']
# Check if currently affected by simplify
viewport_limited = mod.levels > simplify_viewport
render_limited = mod.render_levels > simplify_render
is_currently_affected = viewport_limited or render_limited
# Modifier name row
row = col.row()
row.active = is_currently_affected
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')
# Modifier name as operator + Viewport levels on same row
op = row.operator('rt.select_object_by_name', text=mod.name, icon='MOD_SUBSURF', emboss=False)
op.object_name = obj.name
op.modifier_name = mod.name
row.label(text="Viewport:")
# Create subrow for viewport setting
subrow = row.row()
subrow.active = viewport_limited
subrow.prop(mod, "levels", text="")
# Render levels row (indented)
row = col.row()
row.active = is_currently_affected
# Indent to match
row.label(text=' ', icon='BLANK1')
row.label(text=' ', icon='BLANK1')
row.label(text="Render:")
# Create subrow for render setting
subrow = row.row()
subrow.active = render_limited
subrow.prop(mod, "render_levels", text="")
elif data['type'] == 'MULTIRES':
mod = data['modifier']
# Check if currently affected by simplify
viewport_limited = mod.levels > simplify_viewport
render_limited = mod.render_levels > simplify_render
is_currently_affected = viewport_limited or render_limited
# Modifier name row
row = col.row()
row.active = is_currently_affected
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')
# Modifier name as operator + Viewport levels on same row
op = row.operator('rt.select_object_by_name', text=mod.name, icon='MOD_MULTIRES', emboss=False)
op.object_name = obj.name
op.modifier_name = mod.name
row.label(text="Viewport:")
# Create subrow for viewport setting
subrow = row.row()
subrow.active = viewport_limited
subrow.prop(mod, "levels", text="")
# Render levels row (indented)
row = col.row()
row.active = is_currently_affected
# Indent to match
row.label(text=' ', icon='BLANK1')
row.label(text=' ', icon='BLANK1')
row.label(text="Render:")
# Create subrow for render setting
subrow = row.row()
subrow.active = render_limited
subrow.prop(mod, "render_levels", text="")
elif data['type'] == 'PARTICLE':
# Check if currently affected by simplify
is_currently_affected = max_child_particles < 1.0
row = col.row()
row.active = is_currently_affected
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')
psys = data['particle_system']
# Create subrow for particle info
subrow = row.row()
subrow.label(text=f"Particles: {psys.name}", icon='PARTICLES')
subrow.label(text=f"Type: {data['particle_type']}")
subrow.label(text=f"Count: {data['count']}")
elif data['type'] == 'HAIR':
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')
mod = data['modifier']
# Create subrow for hair info
subrow = row.row()
subrow.label(text=f"Hair: {mod.name}", icon='HAIR')
subrow.label(text=f"Node Group: {data['node_group']}")
elif data['type'] == 'SUBSURFACE':
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')
mat = data['material']
# Create subrow for material info
subrow = row.row()
subrow.label(text=f"Material: {mat.name}", icon='MATERIAL')
subrow.label(text=f"Subsurface: {data['subsurface_value']:.3f}")
elif data['type'] == 'VOLUME_MAT':
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')
mat = data['material']
# Create subrow for volume material info
subrow = row.row()
subrow.label(text=f"Volume Material: {mat.name}", icon='MATERIAL')
elif data['type'] == 'VOLUME_OBJ':
# Check if currently affected by simplify
is_currently_affected = volume_limit_resolution < 1.0
row = col.row()
row.active = is_currently_affected
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')
# Create subrow for volume object info
subrow = row.row()
subrow.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)