Change conform behavior, now show individual items.

Add store/restore visibility  for items
This commit is contained in:
pullusb
2025-07-29 15:05:44 +02:00
parent adc35fac62
commit 0c6523049f
7 changed files with 741 additions and 349 deletions
+158 -6
View File
@@ -337,6 +337,19 @@ def get_view_layer_collection(col, vl_col=None, view_layer=None):
if c is not None:
return c
## Alternative implementation
# def get_view_layer_collection(collection, vl_col=None):
# """Find the view layer collection corresponding to a given collection"""
# if vl_col is None:
# vl_col = bpy.context.view_layer.layer_collection
# if vl_col.collection == collection:
# return vl_col
# for child in vl_col.children:
# found = get_view_layer_collection(collection, child)
# if found:
# return found
# return None
def get_parents_cols(col, root=None, scene=None, cols=None):
'''Return a list of parents collections of passed col
root : Pass a collection to search in (recursive)
@@ -544,7 +557,24 @@ def build_path_from_template(template: str,
# endregion
# region visibility states store
# region visibility states
## targets for conformation
def get_target_collection(target_name, context):
"""Get the target collection based on active or the target name, None if nothing"""
if target_name:
return next((c for c in context.scene.collection.children_recursive if c.name == target_name), None)
else:
return context.collection
def get_target_object(target_name, context):
"""Get the target object based on active or the target name, None if nothing"""
if target_name:
return bpy.context.scene.objects.get(target_name)
else:
return context.object
def store_visibility_states(collection=None):
"""Store visibility states of objects and collections
@@ -560,7 +590,7 @@ def store_visibility_states(collection=None):
'collections': {},
'view_layer_collections': {}
}
# Determine target viewlayer collection
if collection is None:
target_vl_collection = bpy.context.view_layer.layer_collection
@@ -569,7 +599,7 @@ def store_visibility_states(collection=None):
if target_vl_collection is None:
# Collection not found in current viewlayer
return visibility_states
# Store visibility states by iterating through viewlayer collections
def store_visibility_recursive(vl_col):
# Get the actual collection from viewlayer collection
@@ -581,14 +611,13 @@ def store_visibility_states(collection=None):
'hide_viewport': getattr(col, 'hide_viewport', False),
'hide_render': getattr(col, 'hide_render', False),
}
# Store viewlayer collection visibility states
visibility_states['view_layer_collections'][vl_col.name] = {
'exclude': getattr(vl_col, 'exclude', False),
'hide_viewport': getattr(vl_col, 'hide_viewport', False),
'indirect_only': getattr(vl_col, 'indirect_only', False),
'holdout': getattr(vl_col, 'indirect_only', False),
}
# Store objects in this collection
@@ -600,7 +629,7 @@ def store_visibility_states(collection=None):
'hide_select': obj.hide_select,
'hide_viewlayer': obj.hide_get(),
}
# Recursively process children
for child_vl_col in vl_col.children:
store_visibility_recursive(child_vl_col)
@@ -608,3 +637,126 @@ def store_visibility_states(collection=None):
store_visibility_recursive(target_vl_collection)
return visibility_states
def store_collection_states(collection, context=None):
'''Pass a colelction and store visibility state'''
context = context or bpy.context
scene = context.scene
outliner_state = scene.get('outliner_state', {})
## By name
# if collection is None:
# collection = next((c for c in context.scene.collection.children_recursive if c.name == target_name), None)
state = store_visibility_states(collection)
key = collection.name if collection else "ALL"
outliner_state[key] = state
scene['outliner_state'] = outliner_state
# return ({'INFO'}, f"Stored visibility states for '{key}'")
def apply_collection_states(collection, context=None):
context = context or bpy.context
scene = context.scene
outliner_state = scene.get('outliner_state', {})
if collection is None:
# If no collection is passed, apply to all collections
collection = context.scene.collection
key = "ALL"
else:
key = collection.name
state = outliner_state.get(key)
if not state:
return ({'WARNING'}, f"No stored state for '{key}'")
# return {'CANCELLED'}
for obj_name, obj_state in state['objects'].items():
# obj = context.scene.objects.get(obj_name)
obj = collection.all_objects.get(obj_name)
if obj:
obj.hide_viewport = obj_state.get('hide_viewport', False)
obj.hide_render = obj_state.get('hide_render', False)
obj.hide_select = obj_state.get('hide_select', False)
try:
obj.hide_set(obj_state.get('hide_viewlayer', False))
except Exception:
pass
for col_name, col_state in state['collections'].items():
col = next((c for c in context.scene.collection.children_recursive if c.name == col_name), None)
if col:
col.hide_select = col_state.get('hide_select', False)
col.hide_viewport = col_state.get('hide_viewport', False)
col.hide_render = col_state.get('hide_render', False)
for vlcol_name, vlcol_state in state['view_layer_collections'].items():
col = next((c for c in context.scene.collection.children_recursive if c.name == vlcol_name), None)
vlcol = get_view_layer_collection(col, context.view_layer.layer_collection)
if vlcol:
vlcol.exclude = vlcol_state.get('exclude', False)
vlcol.hide_viewport = vlcol_state.get('hide_viewport', False)
vlcol.indirect_only = vlcol_state.get('indirect_only', False)
vlcol.holdout = vlcol_state.get('holdout', False)
## ---
# # Restore object states
# for obj, obj_state in state.get('objects', {}).items():
# # obj = bpy.data.objects.get(obj_name)
# obj.hide_viewport = obj_state.get('hide_viewport', False)
# obj.hide_render = obj_state.get('hide_render', False)
# obj.hide_select = obj_state.get('hide_select', False)
# try:
# obj.hide_set(obj_state.get('hide_viewlayer', False))
# except Exception:
# pass
# # Restore collection states
# for col, col_state in state.get('collections', {}).items():
# # col = bpy.data.collections.get(col_name)
# col.hide_select = col_state.get('hide_select', False)
# col.hide_viewport = col_state.get('hide_viewport', False)
# col.hide_render = col_state.get('hide_render', False)
# for vlcol, vlcol_state in state.get('view_layer_collections', {}).items():
# vlcol.hide_select = vlcol_state.get('hide_select', False)
# vlcol.hide_viewport = vlcol_state.get('hide_viewport', False)
# vlcol.hide_render = vlcol_state.get('hide_render', False)
### ----
# Restore view layer collection states
# def apply_vl_states(vl_col):
# vl_state = state.get('view_layer_collections', {}).get(vl_col.name)
# if vl_state:
# vl_col.exclude = vl_state.get('exclude', False)
# vl_col.hide_viewport = vl_state.get('hide_viewport', False)
# vl_col.indirect_only = vl_state.get('indirect_only', False)
# vl_col.holdout = vl_state.get('holdout', False)
# for child in vl_col.children:
# apply_vl_states(child)
# if collection:
# vl_col = get_view_layer_collection(collection)
# if vl_col:
# apply_vl_states(vl_col)
# else:
# apply_vl_states(context.view_layer.layer_collection)
def delete_collection_states(collection_name, context=None):
"""Delete stored visibility states for a collection or all if None"""
context = context or bpy.context
scene = context.scene
outliner_state = scene.get('outliner_state', {})
key = collection_name if collection_name else "ALL"
if key in outliner_state:
del outliner_state[key]
scene['outliner_state'] = outliner_state
return ({'INFO'}, f"Deleted visibility states for '{key}'")
else:
return ({'WARNING'}, f"No stored state for '{key}'")