[Bf-extensions-cvs] [05994562] master: Collection Manager: Add nested isolation. Task: T69577

Ryan Inch noreply at git.blender.org
Sat Jan 25 07:01:00 CET 2020


Commit: 05994562fc71735601c043f8a699fc1304394bba
Author: Ryan Inch
Date:   Sat Jan 25 00:54:15 2020 -0500
Branches: master
https://developer.blender.org/rBA05994562fc71735601c043f8a699fc1304394bba

Collection Manager: Add nested isolation. Task: T69577

Adds nested isolation with accompanying infrastructure changes
to accommodate this.

Includes latest fixes from blender-v2.82-release branch:
* Fix local render RTO tooltip.
* Fix isolation when history has only one.

Small whitespace cleanup.

===================================================================

M	object_collection_manager/__init__.py
M	object_collection_manager/internals.py
M	object_collection_manager/operators.py

===================================================================

diff --git a/object_collection_manager/__init__.py b/object_collection_manager/__init__.py
index 15a488cf..5c751fce 100644
--- a/object_collection_manager/__init__.py
+++ b/object_collection_manager/__init__.py
@@ -22,7 +22,7 @@ bl_info = {
     "name": "Collection Manager",
     "description": "Manage collections and their objects",
     "author": "Ryan Inch",
-    "version": (1,8,9),
+    "version": (1,9,2),
     "blender": (2, 80, 0),
     "location": "View3D - Object Mode (Shortcut - M)",
     "warning": '',  # used for warning icon and text in addons panel
diff --git a/object_collection_manager/internals.py b/object_collection_manager/internals.py
index eeef8238..e2e6a64b 100644
--- a/object_collection_manager/internals.py
+++ b/object_collection_manager/internals.py
@@ -85,7 +85,7 @@ def update_collection_tree(context):
 def get_all_collections(context, collections, parent, tree, level=0, visible=False):
     global row_index
     global max_lvl
-    
+
     if level > max_lvl:
         max_lvl = level
 
@@ -135,6 +135,24 @@ def create_property_group(context, tree):
             create_property_group(context, laycol["children"])
 
 
+def get_modifiers(event):
+    modifiers = []
+
+    if event.alt:
+        modifiers.append("alt")
+
+    if event.ctrl:
+        modifiers.append("ctrl")
+
+    if event.oskey:
+        modifiers.append("oskey")
+
+    if event.shift:
+        modifiers.append("shift")
+
+    return set(modifiers)
+
+
 class CMSendReport(Operator):
     bl_label = "Send Report"
     bl_idname = "view3d.cm_send_report"
@@ -164,10 +182,10 @@ class CMSendReport(Operator):
             layout.row().label(text=string, icon='ERROR')
         else:
             layout.row().label(text=string, icon='BLANK1')
-    
+
     def invoke(self, context, event):
         wm = context.window_manager
-    
+
         max_len = 0
         length = 0
 
@@ -196,3 +214,4 @@ def send_report(message):
         bpy.ops.view3d.cm_send_report(ctx, 'INVOKE_DEFAULT', message=message)
 
     bpy.app.timers.register(report)
+
diff --git a/object_collection_manager/operators.py b/object_collection_manager/operators.py
index f69b4bf2..bd23f8a9 100644
--- a/object_collection_manager/operators.py
+++ b/object_collection_manager/operators.py
@@ -36,6 +36,7 @@ from .internals import (
     expanded,
     layer_collections,
     update_property_group,
+    get_modifiers,
     send_report,
 )
 
@@ -164,50 +165,62 @@ class CMSetCollectionOperator(Operator):
 
 
 class CMExcludeOperator(Operator):
-    '''  * Shift-Click to isolate/restore previous state\n  * Ctrl-Click to toggle children'''
+    '''  * Shift-Click to isolate/restore previous state\n  * Ctrl-Click to toggle children\n  * Shift-Ctrl-Click to toggle nested isolation'''
     bl_label = "Exclude Collection from View Layer"
     bl_idname = "view3d.exclude_collection"
     bl_options = {'REGISTER', 'UNDO'}
 
     name: StringProperty()
 
+    # static class var
+    isolated = False
+
     def invoke(self, context, event):
         global rto_history
+        cls = CMExcludeOperator
 
+        modifiers = get_modifiers(event)
         view_layer = context.view_layer.name
         laycol_ptr = layer_collections[self.name]["ptr"]
 
         if not view_layer in rto_history["exclude"]:
             rto_history["exclude"][view_layer] = {"target": "", "history": []}
 
-        rto_history["exclude"][view_layer]["target"] = self.name
+        target = rto_history["exclude"][view_layer]["target"]
         exclude_history = rto_history["exclude"][view_layer]["history"]
 
-        if event.shift:
+        if modifiers == {"shift"}:
             # isolate/de-isolate exclusion of collections
 
-            # get active layer collections
-            active_layer_collections = [x for x in layer_collections.values() \
-                                          if x["ptr"].exclude == False]
+            active_layer_collections = [x["ptr"] for x in layer_collections.values() if not x["ptr"].exclude]
 
-            # check if collection isolated
-            if len(active_layer_collections) == 1 and active_layer_collections[0]["name"] == self.name:
-                if len(exclude_history) > 0:
-                    # restore previous state
-                    for x, item in enumerate(layer_collections.values()):
-                        item["ptr"].exclude = exclude_history[x]
+            # check if previous state should be restored
+            if cls.isolated and self.name == target:
+                # restore previous state
+                for x, item in enumerate(layer_collections.values()):
+                    item["ptr"].exclude = exclude_history[x]
 
-                else:
-                    # enable all collections
-                    for item in layer_collections.values():
-                        item["ptr"].exclude = False
+                # reset exclude history
+                del rto_history["exclude"][view_layer]
+
+                cls.isolated = False
+
+            # check if all collections should be enabled
+            elif len(active_layer_collections) == 1 and active_layer_collections[0].name == self.name:
+                # enable all collections
+                for item in layer_collections.values():
+                    item["ptr"].exclude = False
 
                 # reset exclude history
                 del rto_history["exclude"][view_layer]
 
+                cls.isolated = False
+
             else:
                 # isolate collection
 
+                rto_history["exclude"][view_layer]["target"] = self.name
+
                 # reset exclude history
                 exclude_history.clear()
 
@@ -234,8 +247,10 @@ class CMExcludeOperator(Operator):
 
                     laycol_iter_list = new_laycol_iter_list
 
+                cls.isolated = True
+
 
-        elif event.ctrl:
+        elif modifiers == {"ctrl"}:
             # toggle children
 
             # reset exclude history
@@ -244,6 +259,67 @@ class CMExcludeOperator(Operator):
             # toggle exclusion of collection (this propagates to children)
             laycol_ptr.exclude = not laycol_ptr.exclude
 
+            cls.isolated = False
+
+        elif modifiers == {"ctrl", "shift"}:
+            # toggle nested isolation
+
+            rto_history["exclude"][view_layer]["target"] = self.name
+
+            if cls.isolated and self.name == target:
+                # restore previous state
+                for x, item in enumerate(layer_collections.values()):
+                    item["ptr"].exclude = exclude_history[x]
+
+                # reset exclude history
+                del rto_history["exclude"][view_layer]
+
+                cls.isolated = False
+
+            else:
+                # isolate nested collections
+
+                # reset exclude history
+                exclude_history.clear()
+
+                # save state
+                for item in layer_collections.values():
+                    exclude_history.append(item["ptr"].exclude)
+
+                # get child states
+                child_states = {}
+                laycol_iter_list = [laycol_ptr.children]
+                while len(laycol_iter_list) > 0:
+                    new_laycol_iter_list = []
+                    for laycol_iter in laycol_iter_list:
+                        for layer_collection in laycol_iter:
+                            child_states[layer_collection.name] = layer_collection.exclude
+                            if len(layer_collection.children) > 0:
+                                new_laycol_iter_list.append(layer_collection.children)
+
+                    laycol_iter_list = new_laycol_iter_list
+
+                # isolate collection
+                for item in layer_collections.values():
+                    if item["name"] != laycol_ptr.name:
+                        item["ptr"].exclude = True
+
+                laycol_ptr.exclude = False
+
+                # restore child states
+                laycol_iter_list = [laycol_ptr.children]
+                while len(laycol_iter_list) > 0:
+                    new_laycol_iter_list = []
+                    for laycol_iter in laycol_iter_list:
+                        for layer_collection in laycol_iter:
+                            layer_collection.exclude = child_states[layer_collection.name]
+                            if len(layer_collection.children) > 0:
+                                new_laycol_iter_list.append(layer_collection.children)
+
+                    laycol_iter_list = new_laycol_iter_list
+
+                cls.isolated = True
+
         else:
             # toggle exclusion
 
@@ -274,6 +350,7 @@ class CMExcludeOperator(Operator):
             for laycol in child_exclusion:
                 laycol[0].exclude = laycol[1]
 
+            cls.isolated = False
 
         # reset exclude all history
         if view_layer in rto_history["exclude_all"]:
@@ -334,56 +411,66 @@ class CMUnExcludeAllOperator(Operator):
 
 
 class CMRestrictSelectOperator(Operator):
-    '''  * Shift-Click to isolate/restore previous state\n  * Ctrl-Click to toggle children'''
+    '''  * Shift-Click to isolate/restore previous state\n  * Ctrl-Click to toggle children\n  * Shift-Ctrl-Click to toggle nested isolation'''
     bl_label = "Disable Selection of Collection"
     bl_idname = "view3d.restrict_select_collection"
     bl_options = {'REGISTER', 'UNDO'}
 
     name: StringProperty()
 
+    # static class var
+    isolated = False
+
     def invoke(self, context, event):
         global rto_history
+        cls = CMRestrictSelectOperator
 
+        modifiers = get_modifiers(event)
         view_layer = context.view_layer.name
         laycol_ptr = layer_collections[self.name]["ptr"]
 
         if not view_layer in rto_history["select"]:
             rto_history["select"][view_layer] = {"target": "", "history": []}
 
-        rto_history["select"][view_layer]["target"] = self.name
+        target = rto_history["select"][view_layer]["target"]
         select_history = rto_history["select"][view_layer]["history"]
 
-        if event.shift:
+        if modifiers == {"shift"}:
             # isolate/de-isolate selectability of collections
 
+            laycol = laye

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list