better UI, debug texts and support for object children
This commit is contained in:
parent
e98300ac44
commit
7d8535a7eb
@ -2,7 +2,7 @@ bl_info = {
|
|||||||
"name": "Render Toolbox",
|
"name": "Render Toolbox",
|
||||||
"description": "Perform checks and setup outputs",
|
"description": "Perform checks and setup outputs",
|
||||||
"author": "Samuel Bernou",
|
"author": "Samuel Bernou",
|
||||||
"version": (0, 6, 0),
|
"version": (0, 6, 1),
|
||||||
"blender": (4, 0, 0),
|
"blender": (4, 0, 0),
|
||||||
"location": "View3D",
|
"location": "View3D",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
@ -7,6 +7,9 @@ from bpy.props import (BoolProperty,
|
|||||||
StringProperty)
|
StringProperty)
|
||||||
from .. import fn
|
from .. import fn
|
||||||
|
|
||||||
|
## TODO : handle linked collection / object
|
||||||
|
## add properties to choose if linked/overidden object/collec should be used
|
||||||
|
|
||||||
def name_search_callback(self, context, edit_text):
|
def name_search_callback(self, context, edit_text):
|
||||||
"""Search callback for collection names"""
|
"""Search callback for collection names"""
|
||||||
## second arg is not displayed, can be and empty string...
|
## second arg is not displayed, can be and empty string...
|
||||||
@ -108,19 +111,19 @@ class RT_OT_conform_collection_hierarchy(Operator):
|
|||||||
conform_exclude: BoolProperty(
|
conform_exclude: BoolProperty(
|
||||||
name="Exclude View Layer State",
|
name="Exclude View Layer State",
|
||||||
description="Conform the exclude from view layer",
|
description="Conform the exclude from view layer",
|
||||||
default=True
|
default=False
|
||||||
)
|
)
|
||||||
|
|
||||||
conform_holdout: BoolProperty(
|
conform_holdout: BoolProperty(
|
||||||
name="Holdout State",
|
name="Holdout State",
|
||||||
description="Conform Collection Holdout State",
|
description="Conform Collection Holdout State",
|
||||||
default=True
|
default=False
|
||||||
)
|
)
|
||||||
|
|
||||||
conform_use_indirect: BoolProperty(
|
conform_use_indirect: BoolProperty(
|
||||||
name="Indirect Only State",
|
name="Indirect Only State",
|
||||||
description="Conform Collection Indirect Only",
|
description="Conform Collection Indirect Only",
|
||||||
default=True
|
default=False
|
||||||
)
|
)
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
@ -144,52 +147,60 @@ class RT_OT_conform_collection_hierarchy(Operator):
|
|||||||
layout = self.layout
|
layout = self.layout
|
||||||
# layout.use_property_split = True
|
# layout.use_property_split = True
|
||||||
|
|
||||||
# layout.prop(self, "hierarchy_type", text="Root Type", expand=True)
|
layout.prop(self, "hierarchy_type", text="Work On") # , expand=True
|
||||||
|
layout.separator()
|
||||||
|
tgt_row = layout.row()
|
||||||
layout.prop(self, "target_name", text="Search (Optional)")
|
layout.prop(self, "target_name", text="Search (Optional)")
|
||||||
|
|
||||||
|
|
||||||
if self.hierarchy_type == 'COLLECTION':
|
if self.hierarchy_type == 'COLLECTION':
|
||||||
root_collection = self.get_target_collection(context)
|
ref_collection = self.get_target_collection(context)
|
||||||
if not root_collection:
|
if not ref_collection or ref_collection == context.scene.collection:
|
||||||
layout.label(text="Select a collection or search by name", icon='INFO')
|
layout.label(text="Select a collection or search by name", icon='INFO')
|
||||||
|
if ref_collection == context.scene.collection:
|
||||||
|
layout.label(text="Cannot use the scene collection", icon='ERROR')
|
||||||
|
layout.label(text="An excluded collection collection cannot be active (use search)")
|
||||||
return
|
return
|
||||||
if not root_collection:
|
|
||||||
layout.label(text=f"Error: Collection '{root_collection}' not found", icon='ERROR')
|
if not ref_collection:
|
||||||
|
layout.label(text=f"Error: Collection '{ref_collection.name}' not found", icon='ERROR')
|
||||||
return
|
return
|
||||||
|
|
||||||
vlc_root = fn.get_view_layer_collection(root_collection)
|
ref_vlc = fn.get_view_layer_collection(ref_collection)
|
||||||
if not vlc_root:
|
if not ref_vlc:
|
||||||
layout.label(text=f"Error: Viewlayer Collection '{root_collection}' not found", icon='ERROR')
|
layout.label(text=f"Error: Viewlayer Collection '{ref_collection.name}' not found", icon='ERROR')
|
||||||
return
|
return
|
||||||
|
|
||||||
row = layout.row(align=True)
|
# tgt_row = layout.row(align=True)
|
||||||
row.label(text="", icon='TRIA_RIGHT')
|
tgt_row.label(text="", icon='TRIA_RIGHT')
|
||||||
row.label(text=root_collection.name, icon='OUTLINER_COLLECTION')
|
tgt_row.label(text=ref_collection.name, icon='OUTLINER_COLLECTION')
|
||||||
|
|
||||||
layout.prop(self, "affect_target", text="Target Items")
|
layout.prop(self, "affect_target", text="Target Items")
|
||||||
|
layout.separator()
|
||||||
row = layout.row(align=True)
|
## Show current collection state (behave badly when changed, should be tweaked before)
|
||||||
row.prop(vlc_root, "exclude", text="", emboss=False)
|
# col = layout.column(align=True)
|
||||||
row.prop(root_collection, "hide_select", text="", emboss=False)
|
# row = col.row(align=True)
|
||||||
row.prop(vlc_root, "hide_viewport", text="", emboss=False)
|
# row.label(text="Reference Collection State:")
|
||||||
row.prop(root_collection, "hide_viewport", text="", emboss=False)
|
# row.prop(ref_vlc, "exclude", text="", emboss=False)
|
||||||
row.prop(root_collection, "hide_render", text="", emboss=False)
|
# row.prop(ref_collection, "hide_select", text="", emboss=False)
|
||||||
row.prop(vlc_root, "holdout", text="", emboss=False)
|
# row.prop(ref_vlc, "hide_viewport", text="", emboss=False)
|
||||||
row.prop(vlc_root, "indirect_only", text="", emboss=False)
|
# row.prop(ref_collection, "hide_viewport", text="", emboss=False)
|
||||||
|
# row.prop(ref_collection, "hide_render", text="", emboss=False)
|
||||||
|
# row.prop(ref_vlc, "holdout", text="", emboss=False)
|
||||||
|
# row.prop(ref_vlc, "indirect_only", text="", emboss=False)
|
||||||
|
|
||||||
col = layout.column(align=True)
|
col = layout.column(align=True)
|
||||||
col.label(text="Parameter To Conform:")
|
|
||||||
row = col.row(align=True)
|
row = col.row(align=True)
|
||||||
|
row.label(text="Parameter To Conform:")
|
||||||
## Same order, greyout unused options
|
## Same order, greyout unused options
|
||||||
collec_row = row.row(align=True)
|
collec_row = row.row(align=True)
|
||||||
collec_row.prop(self, "conform_exclude", text="", icon='CHECKBOX_HLT') # Exclude from View Layer
|
collec_row.prop(self, "conform_exclude", text="", icon='CHECKBOX_DEHLT' if ref_vlc.exclude else 'CHECKBOX_HLT') # Exclude from View Layer
|
||||||
collec_row.active = self.affect_target != 'OBJECT'
|
collec_row.active = self.affect_target != 'OBJECT'
|
||||||
|
|
||||||
## Object and collections
|
## Object and collections
|
||||||
row.prop(self, "conform_selectability", text="", icon='RESTRICT_SELECT_OFF') # Hide Select
|
row.prop(self, "conform_selectability", text="", icon='RESTRICT_SELECT_ON' if ref_collection.hide_select else 'RESTRICT_SELECT_OFF') # Hide Select
|
||||||
row.prop(self, "conform_viewlayer", text="", icon='HIDE_OFF') # Hide in current viewlayer (eye)
|
row.prop(self, "conform_viewlayer", text="", icon='HIDE_ON' if ref_vlc.hide_viewport else 'HIDE_OFF') # Hide in current viewlayer (eye)
|
||||||
row.prop(self, "conform_viewport", text="", icon='RESTRICT_VIEW_OFF') # Disable in Viewports
|
row.prop(self, "conform_viewport", text="", icon='RESTRICT_VIEW_ON' if ref_collection.hide_viewport else 'RESTRICT_VIEW_OFF') # Disable in Viewports
|
||||||
row.prop(self, "conform_render", text="", icon='RESTRICT_RENDER_OFF') # Disable in Renders
|
row.prop(self, "conform_render", text="", icon='RESTRICT_RENDER_ON' if ref_collection.hide_render else 'RESTRICT_RENDER_OFF') # Disable in Renders
|
||||||
|
|
||||||
## Specific to collections
|
## Specific to collections
|
||||||
collec_row = row.row(align=True)
|
collec_row = row.row(align=True)
|
||||||
@ -198,31 +209,37 @@ class RT_OT_conform_collection_hierarchy(Operator):
|
|||||||
collec_row.active = self.affect_target != 'OBJECT'
|
collec_row.active = self.affect_target != 'OBJECT'
|
||||||
|
|
||||||
else:
|
else:
|
||||||
target_object = self.get_target_object(context)
|
ref_obj = self.get_target_object(context)
|
||||||
|
|
||||||
if not target_object:
|
if not ref_obj:
|
||||||
layout.label(text="Make object active or search by name", icon='INFO')
|
layout.label(text="Make object active or search by name", icon='INFO')
|
||||||
return
|
return
|
||||||
|
|
||||||
row = layout.row(align=True)
|
|
||||||
row.label(text="", icon='TRIA_RIGHT')
|
|
||||||
row.label(text=target_object.name, icon='OBJECT_DATA')
|
|
||||||
|
|
||||||
if not target_object.children_recursive:
|
# tgt_row = layout.row(align=True)
|
||||||
|
tgt_row.label(text="", icon='TRIA_RIGHT')
|
||||||
|
tgt_row.label(text=ref_obj.name, icon='OBJECT_DATA')
|
||||||
|
|
||||||
|
if not ref_obj.children_recursive:
|
||||||
layout.label(text="Object has no children", icon='ERROR')
|
layout.label(text="Object has no children", icon='ERROR')
|
||||||
return
|
return
|
||||||
|
|
||||||
col = layout.column(align=True)
|
layout.separator()
|
||||||
row.prop(target_object, "hide_select", text="", emboss=False)
|
## Show current collection state (can behave badly when changed, should be tweaked before)
|
||||||
row.prop(self, "active_object_viewlayer_hide", text="", icon='HIDE_ON' if target_object.hide_get() else 'HIDE_OFF', emboss=False) # hack
|
# col = layout.column(align=True)
|
||||||
row.prop(target_object, "hide_viewport", text="", emboss=False)
|
# row = col.row(align=True)
|
||||||
row.prop(target_object, "hide_render", text="", emboss=False)
|
# row.label(text="Reference Object State:")
|
||||||
|
# row.prop(ref_obj, "hide_select", text="", emboss=False)
|
||||||
|
# row.prop(self, "active_object_viewlayer_hide", text="", icon='HIDE_ON' if ref_obj.hide_get() else 'HIDE_OFF', emboss=False) # hack
|
||||||
|
# row.prop(ref_obj, "hide_viewport", text="", emboss=False)
|
||||||
|
# row.prop(ref_obj, "hide_render", text="", emboss=False)
|
||||||
|
|
||||||
col.label(text="Parameter To Conform:")
|
col = layout.column(align=True)
|
||||||
row.prop(self, "conform_selectability", text="", icon='RESTRICT_SELECT_OFF') # Hide Select
|
row = col.row(align=True)
|
||||||
row.prop(self, "conform_viewlayer", text="", icon='HIDE_OFF') # Hide in current viewlayer (eye)
|
row.label(text="Parameter To Conform:")
|
||||||
row.prop(self, "conform_viewport", text="", icon='RESTRICT_VIEW_OFF') # Disable in Viewports
|
row.prop(self, "conform_selectability", text="", icon='RESTRICT_SELECT_ON' if ref_obj.hide_select else 'RESTRICT_SELECT_OFF') # Hide Select
|
||||||
row.prop(self, "conform_render", text="", icon='RESTRICT_RENDER_OFF') # Disable in Renders
|
row.prop(self, "conform_viewlayer", text="", icon='HIDE_ON' if ref_obj.hide_get() else 'HIDE_OFF') # Hide in current viewlayer (eye)
|
||||||
|
row.prop(self, "conform_viewport", text="", icon='RESTRICT_VIEW_ON' if ref_obj.hide_viewport else 'RESTRICT_VIEW_OFF') # Disable in Viewports
|
||||||
|
row.prop(self, "conform_render", text="", icon='RESTRICT_RENDER_ON' if ref_obj.hide_render else 'RESTRICT_RENDER_OFF') # Disable in Renders
|
||||||
|
|
||||||
|
|
||||||
## Show dynamically wich object/collection are affected by the current confo.
|
## Show dynamically wich object/collection are affected by the current confo.
|
||||||
@ -235,25 +252,25 @@ class RT_OT_conform_collection_hierarchy(Operator):
|
|||||||
# collec_name_list = ['hide_select', 'hide_viewport', 'hide_render']
|
# collec_name_list = ['hide_select', 'hide_viewport', 'hide_render']
|
||||||
# ## VL props
|
# ## VL props
|
||||||
# if self.conform_exclude:
|
# if self.conform_exclude:
|
||||||
# to_conform_viewlayer['exclude'] = vlc_root.exclude
|
# to_conform_viewlayer['exclude'] = ref_vlc.exclude
|
||||||
# if self.conform_viewlayer:
|
# if self.conform_viewlayer:
|
||||||
# to_conform_viewlayer['hide_viewport'] = vlc_root.hide_viewport
|
# to_conform_viewlayer['hide_viewport'] = ref_vlc.hide_viewport
|
||||||
# if self.conform_holdout:
|
# if self.conform_holdout:
|
||||||
# to_conform_viewlayer['holdout'] = vlc_root.holdout
|
# to_conform_viewlayer['holdout'] = ref_vlc.holdout
|
||||||
# if self.conform_use_indirect:
|
# if self.conform_use_indirect:
|
||||||
# to_conform_viewlayer['indirect_only'] = vlc_root.indirect_only
|
# to_conform_viewlayer['indirect_only'] = ref_vlc.indirect_only
|
||||||
|
|
||||||
# ## collection props
|
# ## collection props
|
||||||
# if self.conform_selectability:
|
# if self.conform_selectability:
|
||||||
# to_conform_collection['hide_select'] = vlc_root.collection.hide_select
|
# to_conform_collection['hide_select'] = ref_vlc.collection.hide_select
|
||||||
# if self.conform_viewport:
|
# if self.conform_viewport:
|
||||||
# to_conform_collection['hide_viewport'] = vlc_root.collection.hide_viewport
|
# to_conform_collection['hide_viewport'] = ref_vlc.collection.hide_viewport
|
||||||
# if self.conform_render:
|
# if self.conform_render:
|
||||||
# to_conform_collection['hide_render'] = vlc_root.collection.hide_render
|
# to_conform_collection['hide_render'] = ref_vlc.collection.hide_render
|
||||||
|
|
||||||
|
|
||||||
# col = layout.column(align=True)
|
# col = layout.column(align=True)
|
||||||
# sub_vlc = fn.get_collection_children_recursive(vlc_root)
|
# sub_vlc = fn.get_collection_children_recursive(ref_vlc)
|
||||||
# for vlc in sub_vlc:
|
# for vlc in sub_vlc:
|
||||||
# viewlayer_conflicts = [attr for attr, value in to_conform_viewlayer.items() if value != getattr(vlc, attr, None)]
|
# viewlayer_conflicts = [attr for attr, value in to_conform_viewlayer.items() if value != getattr(vlc, attr, None)]
|
||||||
# collection_conflicts = [attr for attr, value in to_conform_collection.items() if value != getattr(vlc.collection, attr, None)]
|
# collection_conflicts = [attr for attr, value in to_conform_collection.items() if value != getattr(vlc.collection, attr, None)]
|
||||||
@ -277,35 +294,35 @@ class RT_OT_conform_collection_hierarchy(Operator):
|
|||||||
|
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
affected_items = [] # List to log affected items
|
||||||
if self.hierarchy_type == 'COLLECTION':
|
if self.hierarchy_type == 'COLLECTION':
|
||||||
ref_collection = self.get_target_collection(context)
|
ref_collection = self.get_target_collection(context)
|
||||||
vlc_root = fn.get_view_layer_collection(ref_collection)
|
ref_vlc = fn.get_view_layer_collection(ref_collection)
|
||||||
if not vlc_root:
|
if not ref_vlc:
|
||||||
self.report({'ERROR'}, f"View Layer Collection for '{ref_collection.name}' not found")
|
self.report({'ERROR'}, f"View Layer Collection for '{ref_collection.name}' not found")
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
print(f'Conform parameters on collection hierarchy from {ref_vlc.name}')
|
||||||
|
|
||||||
affected_items = [] # List to log affected items
|
|
||||||
if self.affect_target in {'ALL', 'COLLECTION'}:
|
if self.affect_target in {'ALL', 'COLLECTION'}:
|
||||||
## Apply on collection
|
## Apply on collection
|
||||||
sub_vlc = fn.get_collection_children_recursive(vlc_root)
|
sub_vlc = fn.get_collection_children_recursive(ref_vlc)
|
||||||
for vlc in sub_vlc:
|
for vlc in sub_vlc:
|
||||||
# Apply view layer collection properties
|
# Apply view layer collection properties
|
||||||
|
if self.conform_exclude and vlc.exclude != ref_vlc.exclude:
|
||||||
|
vlc.exclude = ref_vlc.exclude
|
||||||
|
affected_items.append((vlc.name, "exclude", ref_vlc.exclude))
|
||||||
|
|
||||||
if self.conform_exclude and vlc.exclude != vlc_root.exclude:
|
if self.conform_viewlayer and vlc.hide_viewport != ref_vlc.hide_viewport:
|
||||||
vlc.exclude = vlc_root.exclude
|
vlc.hide_viewport = ref_vlc.hide_viewport
|
||||||
affected_items.append((vlc.name, "exclude", vlc_root.exclude))
|
affected_items.append((vlc.name, "hide_viewport", ref_vlc.hide_viewport))
|
||||||
|
|
||||||
if self.conform_viewlayer and vlc.hide_viewport != vlc_root.hide_viewport:
|
if self.conform_holdout and vlc.holdout != ref_vlc.holdout:
|
||||||
vlc.hide_viewport = vlc_root.hide_viewport
|
vlc.holdout = ref_vlc.holdout
|
||||||
affected_items.append((vlc.name, "hide_viewport", vlc_root.hide_viewport))
|
affected_items.append((vlc.name, "holdout", ref_vlc.holdout))
|
||||||
|
|
||||||
if self.conform_holdout and vlc.holdout != vlc_root.holdout:
|
if self.conform_use_indirect and vlc.indirect_only != ref_vlc.indirect_only:
|
||||||
vlc.holdout = vlc_root.holdout
|
vlc.indirect_only = ref_vlc.indirect_only
|
||||||
affected_items.append((vlc.name, "holdout", vlc_root.holdout))
|
affected_items.append((vlc.name, "indirect_only", ref_vlc.indirect_only))
|
||||||
|
|
||||||
if self.conform_use_indirect and vlc.indirect_only != vlc_root.indirect_only:
|
|
||||||
vlc.indirect_only = vlc_root.indirect_only
|
|
||||||
affected_items.append((vlc.name, "indirect_only", vlc_root.indirect_only))
|
|
||||||
|
|
||||||
|
|
||||||
# Apply collection properties
|
# Apply collection properties
|
||||||
@ -330,9 +347,9 @@ class RT_OT_conform_collection_hierarchy(Operator):
|
|||||||
obj.hide_select = ref_collection.hide_select
|
obj.hide_select = ref_collection.hide_select
|
||||||
affected_items.append((obj.name, "hide_select", ref_collection.hide_select))
|
affected_items.append((obj.name, "hide_select", ref_collection.hide_select))
|
||||||
|
|
||||||
if self.conform_viewlayer and obj.hide_get() != vlc_root.hide_viewport:
|
if self.conform_viewlayer and obj.hide_get() != ref_vlc.hide_viewport:
|
||||||
obj.hide_set(vlc_root.hide_viewport)
|
obj.hide_set(ref_vlc.hide_viewport)
|
||||||
affected_items.append((obj.name, "hide_viewlayer", vlc_root.hide_viewport))
|
affected_items.append((obj.name, "hide_viewlayer", ref_vlc.hide_viewport))
|
||||||
|
|
||||||
if self.conform_viewport and obj.hide_viewport != ref_collection.hide_viewport:
|
if self.conform_viewport and obj.hide_viewport != ref_collection.hide_viewport:
|
||||||
obj.hide_viewport = ref_collection.hide_viewport
|
obj.hide_viewport = ref_collection.hide_viewport
|
||||||
@ -342,6 +359,29 @@ class RT_OT_conform_collection_hierarchy(Operator):
|
|||||||
obj.hide_render = ref_collection.hide_render
|
obj.hide_render = ref_collection.hide_render
|
||||||
affected_items.append((obj.name, "hide_render", ref_collection.hide_render))
|
affected_items.append((obj.name, "hide_render", ref_collection.hide_render))
|
||||||
|
|
||||||
|
else:
|
||||||
|
ref_object = self.get_target_object(context)
|
||||||
|
if not ref_object:
|
||||||
|
self.report({'ERROR'}, "No target object found")
|
||||||
|
return {'CANCELLED'}
|
||||||
|
print(f'Conform parameters on object childrens hierarchy from {ref_object.name}')
|
||||||
|
for obj in ref_object.children_recursive:
|
||||||
|
# Apply object properties
|
||||||
|
if self.conform_selectability and obj.hide_select != ref_object.hide_select:
|
||||||
|
obj.hide_select = ref_object.hide_select
|
||||||
|
affected_items.append((obj.name, "hide_select", ref_object.hide_select))
|
||||||
|
|
||||||
|
if self.conform_viewlayer and obj.hide_get() != ref_object.hide_get():
|
||||||
|
obj.hide_set(ref_object.hide_get())
|
||||||
|
affected_items.append((obj.name, "hide_viewlayer", ref_object.hide_get()))
|
||||||
|
|
||||||
|
if self.conform_viewport and obj.hide_viewport != ref_object.hide_viewport:
|
||||||
|
obj.hide_viewport = ref_object.hide_viewport
|
||||||
|
affected_items.append((obj.name, "hide_viewport", ref_object.hide_viewport))
|
||||||
|
|
||||||
|
if self.conform_render and obj.hide_render != ref_object.hide_render:
|
||||||
|
obj.hide_render = ref_object.hide_render
|
||||||
|
affected_items.append((obj.name, "hide_render", ref_object.hide_render))
|
||||||
|
|
||||||
# Log the affected items
|
# Log the affected items
|
||||||
message = []
|
message = []
|
||||||
@ -350,7 +390,6 @@ class RT_OT_conform_collection_hierarchy(Operator):
|
|||||||
print(line)
|
print(line)
|
||||||
message.append(line)
|
message.append(line)
|
||||||
|
|
||||||
# f" items in the hierarchy." + '\n'.join(message)
|
|
||||||
fn.show_message_box(
|
fn.show_message_box(
|
||||||
message=message,
|
message=message,
|
||||||
title=f"Conformed {len(affected_items)} in hierarchy",
|
title=f"Conformed {len(affected_items)} in hierarchy",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user