Added global checks to popup and then launch individual checks

0.5.1
This commit is contained in:
pullusb 2025-07-23 14:30:44 +02:00
parent c33eab6f32
commit 373ed201d3
5 changed files with 84 additions and 39 deletions

View File

@ -4,6 +4,7 @@ from . import (
outputs_search_and_replace, outputs_search_and_replace,
visibility_conflicts, visibility_conflicts,
simplify_conflicts, simplify_conflicts,
scene_checker,
) )
mods = ( mods = (
@ -12,6 +13,7 @@ mods = (
outputs_search_and_replace, outputs_search_and_replace,
visibility_conflicts, visibility_conflicts,
simplify_conflicts, simplify_conflicts,
scene_checker,
) )
def register(): def register():

View File

@ -1,7 +1,8 @@
import bpy import bpy
from bpy.types import Operator
from .. import fn from .. import fn
from .simplify_conflicts import list_simplify_affected_objects from .simplify_conflicts import list_simplify_affected_objects
from .visibility_conflicts import get_viewlayer_collections_with_visiblity_conflict
## WIP : checker operator to perform all check at once (sometimes a limited version of the check) to expose useful solving operators. ## WIP : checker operator to perform all check at once (sometimes a limited version of the check) to expose useful solving operators.
@ -9,20 +10,19 @@ from .simplify_conflicts import list_simplify_affected_objects
class RT_OT_scene_checker(Operator): class RT_OT_scene_checker(Operator):
bl_idname = "rt.scene_checker" bl_idname = "rt.scene_checker"
bl_label = "Check Scene " bl_label = "Check Scene For Render Issues"
bl_description = "Check / correct some aspect of the scene and objects, properties, etc. and report" bl_description = "Check / correct some aspect of the scene and objects, properties, etc. and report"
bl_options = {"REGISTER"} bl_options = {"REGISTER"}
## List of possible actions calls : ## checkes and possible actions calls :
# set scene res # list_object_visibility_conflicts
# set scene percentage at 100: # list_modifier_visibility
# Disabled animation # list_collection_visibility_conflicts
# Objects visibility conflict # list_object_affected_by_simplify
# Objects modifiers visibility conflict
apply_fixes : bpy.props.BoolProperty(name="Apply Fixes", default=False, # apply_fixes : bpy.props.BoolProperty(name="Apply Fixes", default=False,
description="Apply possible fixes instead of just listing (pop the list again in fix mode)", # description="Apply possible fixes instead of just listing (pop the list again in fix mode)",
options={'SKIP_SAVE'}) # options={'SKIP_SAVE'})
def invoke(self, context, event): def invoke(self, context, event):
self.ctrl = event.ctrl self.ctrl = event.ctrl
@ -30,7 +30,7 @@ class RT_OT_scene_checker(Operator):
def execute(self, context): def execute(self, context):
problems = [] problems = []
print('-- Scene Checks --')
## Old method : Apply fixes based on pref (inverted by ctrl key) ## Old method : Apply fixes based on pref (inverted by ctrl key)
# # If Ctrl is pressed, invert behavior (invert boolean) # # If Ctrl is pressed, invert behavior (invert boolean)
# apply ^= self.ctrl # apply ^= self.ctrl
@ -49,7 +49,7 @@ class RT_OT_scene_checker(Operator):
viz_ct += 1 viz_ct += 1
print(f'{o.name} : viewlayer {hv} - viewport {vp} - render {rd}') print(f'{o.name} : viewlayer {hv} - viewport {vp} - render {rd}')
if viz_ct: if viz_ct:
problems.append(['rt.list_object_visibility_conflicts', f'{viz_ct} objects visibility conflicts (details in console)', 'OBJECT_DATAMODE']) problems.append(['rt.list_object_visibility_conflicts', f'{viz_ct} objects visibility conflicts', 'OBJECT_DATAMODE'])
## GP modifiers visibility conflict ## GP modifiers visibility conflict
mod_viz_ct = 0 mod_viz_ct = 0
@ -61,33 +61,44 @@ class RT_OT_scene_checker(Operator):
mod_viz_ct += 1 mod_viz_ct += 1
print(f'{o.name} - modifier {m.name}: viewport {vp} != render {rd}') print(f'{o.name} - modifier {m.name}: viewport {vp} != render {rd}')
if mod_viz_ct: if mod_viz_ct:
problems.append(['rt.list_modifier_visibility', f'{mod_viz_ct} modifiers visibility conflicts (details in console)', 'MODIFIER_DATA']) problems.append(['rt.list_modifier_visibility', f'{mod_viz_ct} modifiers visibility conflicts', 'MODIFIER_DATA'])
## Collection ## Collection
# TODO: add check for collection visibility conflicts if conflicts := get_viewlayer_collections_with_visiblity_conflict(context):
print('\nCollection visibility conflicts:')
for vc in conflicts:
vl = 'Yes' if vc.hide_viewport else 'No'
vp = 'Yes' if vc.collection.hide_viewport else 'No'
rd = 'Yes' if vc.collection.hide_render else 'No'
print(f'{vc.name}: viewlayer {vl} - viewport {vp} - render {rd}')
problems.append(['rt.list_collection_visibility_conflicts', f'{len(conflicts)} collections visibility conflicts', 'GROUP'])
## Simplify affected object ## Simplify affected object
if context.scene.render.use_simplify and list_simplify_affected_objects(context): if context.scene.render.use_simplify and (conflicts := list_simplify_affected_objects(context)):
problems.append(['rt.list_object_affected_by_simplify', 'Some objects are affected by simplify (details in console)', 'MOD_SIMPLIFY']) print('\nSimplify affected objects:')
# Conflict list model : [[obj, [{type: "SUBSURF", ..}, {..}], icon], ..]
for item_l in conflicts:
print(f'{item_l[0].name} : {[m.get("type", "issue") for m in item_l[1]]}')
problems.append(['rt.list_object_affected_by_simplify', f'{len(conflicts)} objects affected by simplify', 'MOD_SIMPLIFY'])
#### --- print fix/problems report #### --- print fix/problems report
if problems: if problems:
print('===File check===') print('===File check===')
for p in problems: ## List checks
if isinstance(p, str): # for p in problems:
print(p) # if isinstance(p, str):
else: # print(p)
print(p[0]) # else:
# print(p[0])
if not self.apply_fixes: # if not self.apply_fixes:
## button to call the operator again with apply_fixes set to True # ## button to call the operator again with apply_fixes set to True
problems.append(['OPERATOR', 'gp.file_checker', 'Apply Fixes', 'FORWARD', {'apply_fixes': True}]) # problems.append(['OPERATOR', 'gp.file_checker', 'Apply Fixes', 'FORWARD', {'apply_fixes': True}])
# Show in viewport # Show in viewport
title = "Changed Settings" if apply else "Checked Settings (nothing changed)" # title = "Changed Settings" if apply else "Checked Settings (nothing changed)"
title = "Visibility checks report (details in console)"
fn.show_message_box(problems, _title = title, _icon = 'INFO') fn.show_message_box(problems, _title = title, _icon = 'INFO')
else: else:
self.report({'INFO'}, 'All good') self.report({'INFO'}, 'All good')
@ -97,4 +108,9 @@ class RT_OT_scene_checker(Operator):
# endregion # endregion
# RT_OT_scene_checker, def register():
bpy.utils.register_class(RT_OT_scene_checker)
def unregister():
bpy.utils.unregister_class(RT_OT_scene_checker)

View File

@ -8,6 +8,10 @@ from bpy.props import (BoolProperty,
StringProperty) StringProperty)
def list_simplify_affected_objects(context): def list_simplify_affected_objects(context):
"""Return a list of object affected by simplify
return : [[obj, [{type: "SUBSURF", ..}, {..}], icon], ..]
"""
ob_list = [] ob_list = []
# Get simplify settings # Get simplify settings
render = context.scene.render render = context.scene.render

View File

@ -345,6 +345,14 @@ def get_collection_children_recursive(col, cols=None) -> list:
cols = get_collection_children_recursive(sub, cols) cols = get_collection_children_recursive(sub, cols)
return cols return cols
def get_viewlayer_collections_with_visiblity_conflict(context):
'''return viewlayer collections with visibility conflicts between hide in viewlayer, hide viewport and hide render'''
vcols = get_collection_children_recursive(context.view_layer.layer_collection)
vcols = list(set(vcols)) # ensure no duplicates
## Store collection with conflicts
return [vc for vc in vcols if not (vc.hide_viewport == vc.collection.hide_viewport == vc.collection.hide_render)]
class RT_OT_list_collection_visibility_conflicts(Operator): class RT_OT_list_collection_visibility_conflicts(Operator):
bl_idname = "rt.list_collection_visibility_conflicts" bl_idname = "rt.list_collection_visibility_conflicts"
bl_label = "List Collection Visibility Conflicts" bl_label = "List Collection Visibility Conflicts"
@ -364,12 +372,12 @@ class RT_OT_list_collection_visibility_conflicts(Operator):
def invoke(self, context, event): def invoke(self, context, event):
## get all viewlayer collections ## get all viewlayer collections
self.conflict_collections = get_viewlayer_collections_with_visiblity_conflict(context)
vcols = get_collection_children_recursive(context.view_layer.layer_collection) vcols = get_collection_children_recursive(context.view_layer.layer_collection)
vcols = list(set(vcols)) # ensure no duplicates vcols = list(set(vcols)) # ensure no duplicates
## Store collection with conflicts ## Store collection with conflicts
# layer_collection.is_visible against render visibility ?
## Do not list currently excluded collections
self.conflict_collections = [vc for vc in vcols if not (vc.hide_viewport == vc.collection.hide_viewport == vc.collection.hide_render)] self.conflict_collections = [vc for vc in vcols if not (vc.hide_viewport == vc.collection.hide_viewport == vc.collection.hide_render)]
self.included_collection = [vc for vc in self.conflict_collections if not vc.exclude] self.included_collection = [vc for vc in self.conflict_collections if not vc.exclude]
self.excluded_collection = [vc for vc in self.conflict_collections if vc.exclude] self.excluded_collection = [vc for vc in self.conflict_collections if vc.exclude]

29
ui.py
View File

@ -14,13 +14,17 @@ class RT_PT_render_toolbox_ui(Panel):
layout.operator("rt.create_output_layers", icon="NODE") layout.operator("rt.create_output_layers", icon="NODE")
layout.operator("rt.outputs_search_and_replace", text='Search and replace outputs', icon="BORDERMOVE") layout.operator("rt.outputs_search_and_replace", text='Search and replace outputs', icon="BORDERMOVE")
class RT_PT_visibility_check(Panel): # Base panel for drawing
bl_space_type = "NODE_EDITOR" class RT_PT_visibility_check_ui_base(bpy.types.Panel):
bl_space_type = "VIEW_3D"
bl_region_type = "UI" bl_region_type = "UI"
bl_category = "Render" # Wrangler bl_category = "View"
bl_label = "Visibility Checks" bl_label = "Visibility Checks"
# bl_parent_id = "RT_PT_render_toolbox_ui" bl_options = {'DEFAULT_CLOSED'}
# bl_options = {'DEFAULT_CLOSED'}
def draw_header_preset(self, context):
layout = self.layout
layout.operator('rt.scene_checker', text="", icon='CHECKMARK') #, depress=True
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@ -35,10 +39,20 @@ class RT_PT_visibility_check(Panel):
layout.separator() layout.separator()
layout.operator("rt.list_object_affected_by_simplify", text="List Object Affected By Simplify", icon="MOD_SIMPLIFY") layout.operator("rt.list_object_affected_by_simplify", text="List Object Affected By Simplify", icon="MOD_SIMPLIFY")
class RT_PT_visibility_check_ui_viewport(RT_PT_visibility_check_ui_base):
bl_space_type = "VIEW_3D"
bl_region_type = "UI"
bl_category = "View"
class RT_PT_visibility_check_ui_node(RT_PT_visibility_check_ui_base):
bl_space_type = 'NODE_EDITOR'
# bl_parent_id = "RT_PT_render_toolbox_ui"
bl_region_type = 'UI'
bl_category = "Render" # Wrangler ?
## Unused, only exposed in Create output panel ## Unused, only exposed in Create output panel
class RT_PT_output_template(Panel): class RT_PT_output_template(Panel):
bl_space_type = "NODE_EDITOR" bl_space_type = "3D_VIEW"
bl_region_type = "UI" bl_region_type = "UI"
bl_category = "Render" # Wrangler bl_category = "Render" # Wrangler
bl_label = "File Output Templates" bl_label = "File Output Templates"
@ -65,8 +79,9 @@ class RT_PT_output_template(Panel):
classes = ( classes = (
RT_PT_render_toolbox_ui, RT_PT_render_toolbox_ui,
RT_PT_visibility_check_ui_viewport,
RT_PT_visibility_check_ui_node
# RT_PT_output_template, # RT_PT_output_template,
RT_PT_visibility_check,
) )
def register(): def register():