Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
laycol = layer_collections[self.name]
# 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"].collection.hide_viewport = disable_history[x]
# reset disable history
del rto_history["disable"][view_layer]
cls.isolated = False
else:
# isolate nested disable
rto_history["disable"][view_layer]["target"] = self.name
# reset disable history
disable_history.clear()
# save state
for item in layer_collections.values():
disable_history.append(item["ptr"].collection.hide_viewport)
# 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.collection.hide_viewport
if len(layer_collection.children) > 0:
new_laycol_iter_list.append(layer_collection.children)
laycol_iter_list = new_laycol_iter_list
# disable all collections in viewport
for laycol in layer_collections.values():
laycol["ptr"].collection.hide_viewport = True
# enable active collection plus parents in viewport
laycol_ptr.collection.hide_viewport = False
laycol = layer_collections[self.name]
while laycol["id"] != 0:
laycol["ptr"].collection.hide_viewport = False
laycol = laycol["parent"]
# 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.collection.hide_viewport = 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
# toggle disable
# reset disable history
del rto_history["disable"][view_layer]
# toggle disable of collection in viewport
laycol_ptr.collection.hide_viewport = not laycol_ptr.collection.hide_viewport
cls.isolated = False
# reset disable all history
if view_layer in rto_history["disable_all"]:
del rto_history["disable_all"][view_layer]
return {'FINISHED'}
class CMUnDisableViewportAllOperator(Operator):
''' * Click to toggle between current viewport display and all enabled.\n * Shift-Click to invert viewport display of all collections'''
bl_label = "Toggle Viewport Display of All Collections"
bl_idname = "view3d.un_disable_viewport_all_collections"
bl_options = {'REGISTER', 'UNDO'}
def invoke(self, context, event):
global rto_history
view_layer = context.view_layer.name
if not view_layer in rto_history["disable_all"]:
rto_history["disable_all"][view_layer] = []
disable_all_history = rto_history["disable_all"][view_layer]
if len(disable_all_history) == 0:
disable_all_history.clear()
keep_history = False
for item in layer_collections.values():
collection = item["ptr"].collection
if event.shift:
keep_history = True
disable_all_history.append(collection.hide_viewport)
collection.hide_viewport = not collection.hide_viewport
if collection.hide_viewport:
disable_all_history.append(collection.hide_viewport)
collection.hide_viewport = False
if not keep_history:
del rto_history["disable_all"][view_layer]
else:
for x, item in enumerate(layer_collections.values()):
item["ptr"].collection.hide_viewport = disable_all_history[x]
del rto_history["disable_all"][view_layer]
return {'FINISHED'}
class CMDisableRenderOperator(Operator):
''' * Shift-Click to isolate/restore previous state\n * Ctrl-Click to toggle children\n * Shift-Ctrl-Click to toggle nested isolation'''
bl_label = "Disable Collection in Render"
bl_idname = "view3d.disable_render_collection"
bl_options = {'REGISTER', 'UNDO'}
# static class var
isolated = False
def invoke(self, context, event):
global rto_history
cls = CMDisableRenderOperator
modifiers = get_modifiers(event)
view_layer = context.view_layer.name
laycol_ptr = layer_collections[self.name]["ptr"]
if not view_layer in rto_history["render"]:
rto_history["render"][view_layer] = {"target": "", "history": []}
target = rto_history["render"][view_layer]["target"]
render_history = rto_history["render"][view_layer]["history"]
if modifiers == {"shift"}:
# isolate/de-isolate render of collections
laycol = layer_collections[self.name]
active_layer_collections = [x["ptr"] for x in layer_collections.values()
if x["ptr"].collection.hide_render == False]
# 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"].collection.hide_render = render_history[x]
# reset render history
del rto_history["render"][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):
# allow render of all collections
for laycol in layer_collections.values():
laycol["ptr"].collection.hide_render = False
# reset render history
del rto_history["render"][view_layer]
cls.isolated = False
# isolate renderability
rto_history["render"][view_layer]["target"] = self.name
# reset render history
render_history.clear()
# save state
for item in layer_collections.values():
render_history.append(item["ptr"].collection.hide_render)
# disallow render of all collections
for laycol in layer_collections.values():
laycol["ptr"].collection.hide_render = True
# allow render of active collection plus parents
laycol_ptr.collection.hide_render = False
laycol = layer_collections[self.name]
while laycol["id"] != 0:
laycol["ptr"].collection.hide_render = False
laycol = laycol["parent"]
cls.isolated = True
elif modifiers == {"ctrl"}:
# reset render history
del rto_history["render"][view_layer]
# toggle view of collection
state = not laycol_ptr.collection.hide_render
laycol_ptr.collection.hide_render = state
# pass state to children
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.collection.hide_render = state
if len(layer_collection.children) > 0:
new_laycol_iter_list.append(layer_collection.children)
laycol_iter_list = new_laycol_iter_list
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
cls.isolated = False
elif modifiers == {"ctrl", "shift"}:
# isolate nested collections
laycol = layer_collections[self.name]
# 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"].collection.hide_render = render_history[x]
# reset render history
del rto_history["render"][view_layer]
cls.isolated = False
else:
# isolate nested renderability
rto_history["render"][view_layer]["target"] = self.name
# reset render history
render_history.clear()
# save state
for item in layer_collections.values():
render_history.append(item["ptr"].collection.hide_render)
# 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.collection.hide_render
if len(layer_collection.children) > 0:
new_laycol_iter_list.append(layer_collection.children)
laycol_iter_list = new_laycol_iter_list
# disallow render of all collections
for laycol in layer_collections.values():
laycol["ptr"].collection.hide_render = True
# allow render of active collection plus parents
laycol_ptr.collection.hide_render = False
laycol = layer_collections[self.name]
while laycol["id"] != 0:
laycol["ptr"].collection.hide_render = False
laycol = laycol["parent"]
# 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.collection.hide_render = 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
# toggle renderable
# reset render history
del rto_history["render"][view_layer]
# toggle renderability of collection
laycol_ptr.collection.hide_render = not laycol_ptr.collection.hide_render
cls.isolated = False
# reset render all history
if view_layer in rto_history["render_all"]:
del rto_history["render_all"][view_layer]
return {'FINISHED'}
class CMUnDisableRenderAllOperator(Operator):
''' * Click to toggle between current render status and all rendered.\n * Shift-Click to invert render status of all collections'''
bl_label = "Toggle Render Status of All Collections"
bl_idname = "view3d.un_disable_render_all_collections"
bl_options = {'REGISTER', 'UNDO'}
def invoke(self, context, event):
global rto_history
view_layer = context.view_layer.name
if not view_layer in rto_history["render_all"]:
rto_history["render_all"][view_layer] = []
render_all_history = rto_history["render_all"][view_layer]
if len(render_all_history) == 0:
render_all_history.clear()
keep_history = False
for item in layer_collections.values():
collection = item["ptr"].collection
if event.shift:
keep_history = True
render_all_history.append(collection.hide_render)
collection.hide_render = not collection.hide_render
render_all_history.append(collection.hide_render)
collection.hide_render = False
if not keep_history:
del rto_history["render_all"][view_layer]
else:
for x, item in enumerate(layer_collections.values()):
item["ptr"].collection.hide_render = render_all_history[x]
del rto_history["render_all"][view_layer]
return {'FINISHED'}
class CMRemoveCollectionOperator(Operator):
'''Remove Collection'''
bl_label = "Remove Collection"
bl_idname = "view3d.remove_collection"
bl_options = {'UNDO'}
collection_name: StringProperty()
def execute(self, context):
global rto_history
cm = context.scene.collection_manager
laycol = layer_collections[self.collection_name]
collection = laycol["ptr"].collection
parent_collection = laycol["parent"]["ptr"].collection
# shift all objects in this collection to the parent collection
for obj in collection.objects:
if obj.name not in parent_collection.objects:
parent_collection.objects.link(obj)
# shift all child collections to the parent collection
if collection.children:
for subcollection in collection.children:
parent_collection.children.link(subcollection)
# remove collection and update tree view
bpy.data.collections.remove(collection)
update_property_group(context)
if len(cm.cm_list_collection) == cm.cm_list_index:
cm.cm_list_index = len(cm.cm_list_collection) - 1
update_property_group(context)
# reset history
for rto in rto_history.values():
rto.clear()
return {'FINISHED'}
rename = [False]
class CMNewCollectionOperator(Operator):
'''Add New Collection'''
bl_label = "Add New Collection"
bl_idname = "view3d.add_collection"
bl_options = {'UNDO'}
def execute(self, context):
global rto_history
new_collection = bpy.data.collections.new('Collection')
cm = context.scene.collection_manager
# if there are collections
if len(cm.cm_list_collection) > 0:
laycol = layer_collections[cm.cm_list_collection[cm.cm_list_index].name]
# add new collection
if self.child:
laycol["ptr"].collection.children.link(new_collection)
expanded.append(laycol["name"])
# update tree view property
update_property_group(context)
cm.cm_list_index = layer_collections[new_collection.name]["row_index"]
else:
laycol["parent"]["ptr"].collection.children.link(new_collection)
# update tree view property
update_property_group(context)
cm.cm_list_index = layer_collections[new_collection.name]["row_index"]
# if no collections add top level collection and select it
else:
context.scene.collection.children.link(new_collection)
# update tree view property
update_property_group(context)
global rename
rename[0] = True
# reset history
for rto in rto_history.values():
rto.clear()
phantom_history = {"view_layer": "",
"initial_state": {},
"exclude_history": {},
"select_history": {},
"hide_history": {},
"disable_history": {},
"render_history": {},
"exclude_all_history": [],
"select_all_history": [],
"hide_all_history": [],
"disable_all_history": [],
"render_all_history": []
}
class CMPhantomModeOperator(Operator):
'''Toggle Phantom Mode'''
bl_label = "Toggle Phantom Mode"
bl_idname = "view3d.toggle_phantom_mode"
def execute(self, context):
global phantom_history
global rto_history
cm = context.scene.collection_manager
view_layer = context.view_layer
# save current visibility state
phantom_history["view_layer"] = view_layer.name
laycol_iter_list = [view_layer.layer_collection.children]
while len(laycol_iter_list) > 0:
new_laycol_iter_list = []
for laycol_iter in laycol_iter_list:
for layer_collection in laycol_iter:
phantom_history["initial_state"][layer_collection.name] = {
"exclude": layer_collection.exclude,
"select": layer_collection.collection.hide_select,
"hide": layer_collection.hide_viewport,
"disable": layer_collection.collection.hide_viewport,
"render": layer_collection.collection.hide_render,
}
if len(layer_collection.children) > 0:
new_laycol_iter_list.append(layer_collection.children)
laycol_iter_list = new_laycol_iter_list
# save current rto history
for rto, history, in rto_history.items():
if history.get(view_layer.name, None):
phantom_history[rto+"_history"] = deepcopy(history[view_layer.name])
# return to normal mode
else:
laycol_iter_list = [view_layer.layer_collection.children]
while len(laycol_iter_list) > 0:
new_laycol_iter_list = []
for laycol_iter in laycol_iter_list:
for layer_collection in laycol_iter:
phantom_laycol = phantom_history["initial_state"][layer_collection.name]
layer_collection.exclude = \
phantom_laycol["exclude"]
layer_collection.collection.hide_select = \
phantom_laycol["select"]
layer_collection.hide_viewport = \
phantom_laycol["hide"]
layer_collection.collection.hide_viewport = \
phantom_laycol["disable"]
layer_collection.collection.hide_render = \
phantom_laycol["render"]
if len(layer_collection.children) > 0:
new_laycol_iter_list.append(layer_collection.children)
laycol_iter_list = new_laycol_iter_list
# restore previous rto history
for rto, history, in rto_history.items():
if view_layer.name in history:
del history[view_layer.name]
if phantom_history[rto+"_history"]:
history[view_layer.name] = deepcopy(phantom_history[rto+"_history"])
phantom_history[rto+"_history"].clear()