Add operator to list collection visibility conflicts
4.1.0
This commit is contained in:
		
							parent
							
								
									cf3f39b730
								
							
						
					
					
						commit
						aecef47d2f
					
				| @ -1,5 +1,9 @@ | |||||||
| # Changelog | # Changelog | ||||||
| 
 | 
 | ||||||
|  | 4.1.0 | ||||||
|  | 
 | ||||||
|  | added: operator `list collection visibility conflicts` (not exposed, called from search menu with dev extras enabled in prefs) | ||||||
|  | 
 | ||||||
| 4.0.3 | 4.0.3 | ||||||
| 
 | 
 | ||||||
| changed: File checker doest not fix directly when clicked (also removed choice in preference): | changed: File checker doest not fix directly when clicked (also removed choice in preference): | ||||||
|  | |||||||
| @ -650,6 +650,98 @@ class GPTB_OT_list_object_visibility_conflicts(bpy.types.Operator): | |||||||
|     def execute(self, context): |     def execute(self, context): | ||||||
|         return {'FINISHED'} |         return {'FINISHED'} | ||||||
| 
 | 
 | ||||||
|  | ## -- List collection visibility conflicts | ||||||
|  | 
 | ||||||
|  | # class GPTB_PG_collection_visibility(bpy.types.PropertyGroup): | ||||||
|  | #     """Property group to handle collection visibility""" | ||||||
|  | #     is_hidden: BoolProperty( | ||||||
|  | #         name="Hide in Viewport", | ||||||
|  | #         description="Toggle collection visibility in viewport", | ||||||
|  | #         get=lambda self: self.get("is_hidden", False), | ||||||
|  | #         set=lambda self, value: self.set_visibility(value) | ||||||
|  | #     ) | ||||||
|  | 
 | ||||||
|  | #     collection_name: StringProperty(name="Collection Name") | ||||||
|  | 
 | ||||||
|  | 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) | ## 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): | class GPTB_OT_list_modifier_visibility(bpy.types.Operator): | ||||||
|     bl_idname = "gp.list_modifier_visibility" |     bl_idname = "gp.list_modifier_visibility" | ||||||
| @ -697,6 +789,7 @@ GPTB_OT_sync_visibility_from_render, | |||||||
| GPTB_OT_sync_visibible_to_render, | GPTB_OT_sync_visibible_to_render, | ||||||
| GPTB_PG_object_visibility, | GPTB_PG_object_visibility, | ||||||
| GPTB_OT_list_object_visibility_conflicts, | GPTB_OT_list_object_visibility_conflicts, | ||||||
|  | GPTB_OT_list_collection_visibility_conflicts, | ||||||
| GPTB_OT_list_modifier_visibility, | GPTB_OT_list_modifier_visibility, | ||||||
| GPTB_OT_copy_string_to_clipboard, | GPTB_OT_copy_string_to_clipboard, | ||||||
| GPTB_OT_copy_multipath_clipboard, | GPTB_OT_copy_multipath_clipboard, | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ bl_info = { | |||||||
| "name": "GP toolbox", | "name": "GP toolbox", | ||||||
| "description": "Tool set for Grease Pencil in animation production", | "description": "Tool set for Grease Pencil in animation production", | ||||||
| "author": "Samuel Bernou, Christophe Seux", | "author": "Samuel Bernou, Christophe Seux", | ||||||
| "version": (4, 0, 4), | "version": (4, 1, 0), | ||||||
| "blender": (4, 3, 0), | "blender": (4, 3, 0), | ||||||
| "location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties", | "location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties", | ||||||
| "warning": "", | "warning": "", | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user