Anim manager alert when anim off and affect groups
2.3.0 - added: Animation manager buttons are colored red when objects have disabled animation - fixed: Animation manager not enabling/disabling Action Groups - fixed: Animation manager `List Disabled Anims` list groups as wellgpv2
parent
9a49175859
commit
7e92ae182e
|
@ -1,5 +1,11 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
2.3.0
|
||||||
|
|
||||||
|
- added: Animation manager buttons are colored red when objects have disabled animation
|
||||||
|
- fixed: Animation manager not enabling/disabling Action Groups
|
||||||
|
- fixed: Animation manager `List Disabled Anims` list groups as well
|
||||||
|
|
||||||
2.2.3
|
2.2.3
|
||||||
|
|
||||||
- fixed: Type error on realign ops
|
- fixed: Type error on realign ops
|
||||||
|
|
|
@ -415,6 +415,8 @@ class GPTB_OT_toggle_mute_animation(bpy.types.Operator):
|
||||||
print(i, fcu.data_path, fcu.array_index)
|
print(i, fcu.data_path, fcu.array_index)
|
||||||
# fcu.group don't have mute attribute in api.
|
# fcu.group don't have mute attribute in api.
|
||||||
fcu.mute = self.mute
|
fcu.mute = self.mute
|
||||||
|
for g in act.groups:
|
||||||
|
g.mute = self.mute
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
if self.selection:
|
if self.selection:
|
||||||
|
@ -452,7 +454,9 @@ class GPTB_OT_toggle_mute_animation(bpy.types.Operator):
|
||||||
class GPTB_OT_toggle_hide_gp_modifier(bpy.types.Operator):
|
class GPTB_OT_toggle_hide_gp_modifier(bpy.types.Operator):
|
||||||
bl_idname = "gp.toggle_hide_gp_modifier"
|
bl_idname = "gp.toggle_hide_gp_modifier"
|
||||||
bl_label = "Toggle Modifier Hide"
|
bl_label = "Toggle Modifier Hide"
|
||||||
bl_description = "Show/Hide gp objects modifier (only touch modifier that are showed in render)\n(shift+clic to affect selection only)"
|
bl_description = "Show/Hide viewport on GP objects modifier\
|
||||||
|
\nOnly touch modifier that are showed in render\
|
||||||
|
\nShift + click to affect selection only"
|
||||||
bl_options = {"REGISTER"}
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
show : bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'})
|
show : bpy.props.BoolProperty(default=True, options={'SKIP_SAVE'})
|
||||||
|
@ -521,6 +525,11 @@ class GPTB_OT_list_disabled_anims(bpy.types.Operator):
|
||||||
act = o.animation_data.action
|
act = o.animation_data.action
|
||||||
if not act:
|
if not act:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
for g in act.groups:
|
||||||
|
if g.mute:
|
||||||
|
li.append(f'{o.name} - group: {g.name}')
|
||||||
|
|
||||||
for i, fcu in enumerate(act.fcurves):
|
for i, fcu in enumerate(act.fcurves):
|
||||||
# print(i, fcu.data_path, fcu.array_index)
|
# print(i, fcu.data_path, fcu.array_index)
|
||||||
if fcu.mute:
|
if fcu.mute:
|
||||||
|
|
55
UI_tools.py
55
UI_tools.py
|
@ -1,9 +1,10 @@
|
||||||
# from . import addon_updater_ops
|
# from . import addon_updater_ops
|
||||||
from .utils import get_addon_prefs
|
from .utils import get_addon_prefs, all_anim_enabled, all_object_modifier_enabled
|
||||||
import bpy
|
import bpy
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from bpy.types import Panel
|
from bpy.types import Panel
|
||||||
|
|
||||||
|
|
||||||
## UI in properties
|
## UI in properties
|
||||||
|
|
||||||
### dataprop_panel not used --> transferred to sidebar
|
### dataprop_panel not used --> transferred to sidebar
|
||||||
|
@ -184,48 +185,40 @@ class GPTB_PT_anim_manager(Panel):
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
## Animation enable disable anim (shift click to select) OP_helpers.GPTB_OT_toggle_mute_animation
|
## Animation enable disable anim (shift click to select) OP_helpers.GPTB_OT_toggle_mute_animation
|
||||||
|
|
||||||
|
# import time
|
||||||
|
# t0 = time.time()
|
||||||
|
|
||||||
|
scn = context.scene
|
||||||
|
objs = [o for o in scn.objects if o.type not in ('GPENCIL', 'CAMERA')] # show_alert
|
||||||
|
gps = [o for o in scn.objects if o.type == 'GPENCIL'] # show_alert
|
||||||
|
cams = [o for o in scn.objects if o.type == 'CAMERA'] # show_alert
|
||||||
|
|
||||||
col.operator('gp.list_disabled_anims')
|
col.operator('gp.list_disabled_anims')
|
||||||
## Objs
|
|
||||||
row = col.row(align=True)
|
## Show Enable / Disable
|
||||||
row.label(text='Obj anims:')
|
for cat, cat_type, tgt in [('Obj anims:', 'OBJECT', objs), ('Cam anims:', 'CAMERA', cams), ('Gp anims:', 'GPENCIL', gps)]:
|
||||||
|
subcol = col.column()
|
||||||
|
subcol.alert = not all_anim_enabled(tgt) # show_alert
|
||||||
|
row = subcol.row(align=True)
|
||||||
|
row.label(text=cat)
|
||||||
ops = row.operator('gp.toggle_mute_animation', text = 'ON')
|
ops = row.operator('gp.toggle_mute_animation', text = 'ON')
|
||||||
ops.mode = 'OBJECT'
|
ops.mode = cat_type
|
||||||
ops.mute = False
|
ops.mute = False
|
||||||
|
|
||||||
ops = row.operator('gp.toggle_mute_animation', text = 'OFF')
|
ops = row.operator('gp.toggle_mute_animation', text = 'OFF')
|
||||||
ops.mode = 'OBJECT'
|
ops.mode = cat_type
|
||||||
ops.mute = True
|
ops.mute = True
|
||||||
|
|
||||||
## Cams
|
|
||||||
row = col.row(align=True)
|
|
||||||
row.label(text='Cam anims:')
|
|
||||||
ops = row.operator('gp.toggle_mute_animation', text = 'ON')
|
|
||||||
ops.mode = 'CAMERA'
|
|
||||||
ops.mute = False
|
|
||||||
|
|
||||||
ops = row.operator('gp.toggle_mute_animation', text = 'OFF')
|
|
||||||
ops.mode = 'CAMERA'
|
|
||||||
ops.mute = True
|
|
||||||
|
|
||||||
## GPs
|
|
||||||
row = col.row(align=True)
|
|
||||||
row.label(text='Gp anims:')
|
|
||||||
ops = row.operator('gp.toggle_mute_animation', text = 'ON')
|
|
||||||
ops.mode = 'GPENCIL'
|
|
||||||
ops.mute = False
|
|
||||||
|
|
||||||
ops = row.operator('gp.toggle_mute_animation', text = 'OFF')
|
|
||||||
ops.mode = 'GPENCIL'
|
|
||||||
ops.mute = True
|
|
||||||
|
|
||||||
|
|
||||||
## GP modifiers
|
## GP modifiers
|
||||||
row = col.row(align=True)
|
subcol = col.column()
|
||||||
|
subcol.alert = not all_object_modifier_enabled(gps) # show_alert
|
||||||
|
row = subcol.row(align=True)
|
||||||
row.label(text='Gp modifiers:')
|
row.label(text='Gp modifiers:')
|
||||||
row.operator('gp.toggle_hide_gp_modifier', text = 'ON').show = True
|
row.operator('gp.toggle_hide_gp_modifier', text = 'ON').show = True
|
||||||
row.operator('gp.toggle_hide_gp_modifier', text = 'OFF').show = False
|
row.operator('gp.toggle_hide_gp_modifier', text = 'OFF').show = False
|
||||||
|
|
||||||
## Follow curve path
|
## Follow curve path
|
||||||
|
col = col.column()
|
||||||
row = col.row(align=True)
|
row = col.row(align=True)
|
||||||
# row.operator('object.create_follow_path_curve', text='Create Curve', icon='CURVE_BEZCURVE')
|
# row.operator('object.create_follow_path_curve', text='Create Curve', icon='CURVE_BEZCURVE')
|
||||||
|
|
||||||
|
@ -255,6 +248,8 @@ class GPTB_PT_anim_manager(Panel):
|
||||||
text, icon = ('Cursor Follow On', 'PIVOT_CURSOR') if context.scene.gptoolprops.cursor_follow else ('Cursor Follow Off', 'CURSOR')
|
text, icon = ('Cursor Follow On', 'PIVOT_CURSOR') if context.scene.gptoolprops.cursor_follow else ('Cursor Follow Off', 'CURSOR')
|
||||||
col.prop(context.scene.gptoolprops, 'cursor_follow', text=text, icon=icon)
|
col.prop(context.scene.gptoolprops, 'cursor_follow', text=text, icon=icon)
|
||||||
|
|
||||||
|
# print(f'{time.time() - t0:.6f}s')
|
||||||
|
|
||||||
class GPTB_PT_toolbox_playblast(Panel):
|
class GPTB_PT_toolbox_playblast(Panel):
|
||||||
bl_label = "Playblast"
|
bl_label = "Playblast"
|
||||||
bl_space_type = "VIEW_3D"
|
bl_space_type = "VIEW_3D"
|
||||||
|
|
|
@ -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": (2, 2, 3),
|
"version": (2, 3, 0),
|
||||||
"blender": (3, 0, 0),
|
"blender": (3, 0, 0),
|
||||||
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
|
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
|
47
utils.py
47
utils.py
|
@ -1104,6 +1104,11 @@ def create_follow_path_constraint(ob, curve, follow_curve=False, use_fixed_locat
|
||||||
# const.use_curve_follow = True
|
# const.use_curve_follow = True
|
||||||
# return curve, const
|
# return curve, const
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------
|
||||||
|
### Object
|
||||||
|
# -----------------
|
||||||
|
|
||||||
def go_edit_mode(ob, context=None):
|
def go_edit_mode(ob, context=None):
|
||||||
'''set mode to object, set passed obhject as active and go Edit'''
|
'''set mode to object, set passed obhject as active and go Edit'''
|
||||||
|
|
||||||
|
@ -1113,3 +1118,45 @@ def go_edit_mode(ob, context=None):
|
||||||
context.view_layer.objects.active = ob
|
context.view_layer.objects.active = ob
|
||||||
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||||
|
|
||||||
|
|
||||||
|
def all_anim_enabled(objects) -> bool:
|
||||||
|
'''return False if at least one fcurve/group has disabled animation in passed object anim'''
|
||||||
|
for o in objects:
|
||||||
|
if o.animation_data and o.animation_data.action:
|
||||||
|
## Skip hided object ?
|
||||||
|
# if o.hide_get():
|
||||||
|
# continue
|
||||||
|
|
||||||
|
## Check if groups are muted
|
||||||
|
for grp in o.animation_data.action.groups:
|
||||||
|
if grp.mute:
|
||||||
|
return False
|
||||||
|
|
||||||
|
## Check if fcurves are muted
|
||||||
|
for fcu in o.animation_data.action.fcurves:
|
||||||
|
if fcu.mute:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if o.type in ('GPENCIL', 'CAMERA'):
|
||||||
|
if o.data.animation_data and o.data.animation_data.action:
|
||||||
|
## Check if object data attributes fcurves are muted
|
||||||
|
for fcu in o.animation_data.action.fcurves:
|
||||||
|
if fcu.mute:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def all_object_modifier_enabled(objects) -> bool:
|
||||||
|
'''Return False if one modifier of one object has GP modifier disabled in viewport but enabled in render'''
|
||||||
|
for o in objects:
|
||||||
|
if o.type != 'GPENCIL':
|
||||||
|
continue
|
||||||
|
for m in o.grease_pencil_modifiers:
|
||||||
|
if m.show_render and not m.show_viewport:
|
||||||
|
return False
|
||||||
|
|
||||||
|
## return False when viewport but no render ?
|
||||||
|
# if not m.show_render and m.show_viewport:
|
||||||
|
# return False
|
||||||
|
|
||||||
|
return True
|
Loading…
Reference in New Issue