From f40d4d7a587b144b05d408c312317d54b06b05c2 Mon Sep 17 00:00:00 2001 From: pullusb Date: Tue, 4 Mar 2025 14:11:51 +0100 Subject: [PATCH] backport collection visibility conflict check from gpv3 version 3.3.3 --- OP_file_checker.py | 79 ++++++++++++++++++++++++++++++++++++++++++++++ __init__.py | 2 +- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/OP_file_checker.py b/OP_file_checker.py index e5318f1..a3a036e 100755 --- a/OP_file_checker.py +++ b/OP_file_checker.py @@ -665,6 +665,84 @@ class GPTB_OT_list_object_visibility_conflicts(bpy.types.Operator): def execute(self, context): return {'FINISHED'} +def get_collection_children_recursive(col, cols=None) -> list: + '''return a list of all the child collections + and their subcollections in the passed collection''' + + cols = cols or [] + for sub in col.children: + if sub not in cols: + cols.append(sub) + if len(sub.children): + cols = get_collection_children_recursive(sub, cols) + return cols + +class GPTB_OT_list_collection_visibility_conflicts(bpy.types.Operator): + bl_idname = "gp.list_collection_visibility_conflicts" + bl_label = "List Collection Visibility Conflicts" + bl_description = "List collection visibility conflicts, when viewport and render have different values" + bl_options = {"REGISTER"} + + # visibility_items: CollectionProperty(type=GPTB_PG_collection_visibility) + show_filter : bpy.props.EnumProperty( + name="View Filter", + description="Filter collections based on their exclusion status", + items=( + ('ALL', "All", "Show all collections", 0), + ('NOT_EXCLUDED', "Not Excluded", "Show collections that are not excluded", 1), + ('EXCLUDED', "Excluded", "Show collections that are excluded", 2) + ), + default='NOT_EXCLUDED') + + def invoke(self, context, event): + ## get all viewlayer collections + vcols = get_collection_children_recursive(context.view_layer.layer_collection) + vcols = list(set(vcols)) # ensure no duplicates + + ## 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.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] + + return context.window_manager.invoke_props_dialog(self, width=250) + + def draw(self, context): + layout = self.layout + layout.prop(self, 'show_filter', expand=True) + + # Add sync buttons at the top + row = layout.row(align=False) + # TODO: Add "set all from" ops on collection (optionnal) + # row.label(text="Sync All Visibility From:") + # row.operator("gp.sync_visibility_from_viewlayer", text="", icon='HIDE_OFF') + # row.operator("gp.sync_visibility_from_viewport", text="", icon='RESTRICT_VIEW_OFF') + # row.operator("gp.sync_visibility_from_render", text="", icon='RESTRICT_RENDER_OFF') + layout.separator() + + if self.show_filter == 'ALL': + vl_collections = self.conflict_collections + elif self.show_filter == 'EXCLUDED': + vl_collections = self.excluded_collection + elif self.show_filter == 'NOT_EXCLUDED': + vl_collections = self.included_collection + + col = layout.column() + for vlcol in vl_collections: + row = col.row(align=False) + row.label(text=vlcol.name) + + # Viewlayer collection settings + row.prop(vlcol, "exclude", text="", emboss=False) + row.prop(vlcol, "hide_viewport", text="", emboss=False) + + # Direct collection properties + row.prop(vlcol.collection, 'hide_viewport', text='', emboss=False) + row.prop(vlcol.collection, 'hide_render', text='', emboss=False) + + def execute(self, context): + return {'FINISHED'} ## not exposed in UI, Check is performed in Check file (can be called in popped menu) class GPTB_OT_list_modifier_visibility(bpy.types.Operator): @@ -723,6 +801,7 @@ GPTB_OT_sync_visibility_from_render, GPTB_OT_sync_visibible_to_render, GPTB_PG_object_visibility, GPTB_OT_list_object_visibility_conflicts, +GPTB_OT_list_collection_visibility_conflicts, GPTB_OT_list_modifier_visibility, GPTB_OT_copy_string_to_clipboard, GPTB_OT_copy_multipath_clipboard, diff --git a/__init__.py b/__init__.py index 59d806c..cd242af 100755 --- a/__init__.py +++ b/__init__.py @@ -4,7 +4,7 @@ bl_info = { "name": "GP toolbox", "description": "Tool set for Grease Pencil in animation production", "author": "Samuel Bernou, Christophe Seux", -"version": (3, 3, 2), +"version": (3, 3, 3), "blender": (4, 0, 0), "location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties", "warning": "",