improved ui and poll handling

0.6.0

- World paste and `Jump next frame`
- more compact and improved ui for world paste
- fix errors in some operators
master
Pullusb 2022-04-11 11:41:56 +02:00
parent 3c5ccf422a
commit c6a75f25f8
9 changed files with 79 additions and 12 deletions

View File

@ -32,8 +32,6 @@ def anim_path_from_translate():
print(fn.helper())
ob = bpy.context.object
if ob.type != 'ARMATURE':
return ('ERROR', 'active is not an armature type')
# found curve through constraint
b = bpy.context.active_pose_bone
@ -216,6 +214,7 @@ class UAC_OT_animate_path(bpy.types.Operator):
def execute(self, context):
# TODO clear previous animation (keys) if there is any
err = anim_path_from_translate()
if err:
self.report({err[0]}, err[1])

View File

@ -159,12 +159,13 @@ class UAC_OT_create_curve_path(bpy.types.Operator):
class UAC_OT_create_follow_path(bpy.types.Operator):
bl_idname = "anim.create_follow_path"
bl_label = "Create Follow Path Constraint"
bl_description = "Create follow path targeting curve in field"
bl_description = "Create follow path targeting curve chosen in dedicated field"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return context.object and context.object.type == 'ARMATURE'
return context.object and context.object.type == 'ARMATURE' \
and context.scene.anim_cycle_settings.path_to_follow
def execute(self, context):
ob = context.object

View File

@ -248,6 +248,13 @@ class UAC_OT_contact_to_ground(bpy.types.Operator):
return context.object and context.object.type == 'ARMATURE'
def execute(self, context):
# TODO: check if possible to auto detect a ground when gnd is not specified
# (still instersteing to be able to get the ground user wants)
if not context.scene.anim_cycle_settings.gnd:
self.report({'ERROR'}, 'need to choose a target mesh for "Ground"')
return {"CANCELLED"}
# context.scene.anim_cycle_settings.expand_on_selected_bones
err = snap_feet()
if err:

View File

@ -85,11 +85,44 @@ class UAC_OT_world_space_paste_next(bpy.types.Operator):
context.scene.frame_current = new_frame
return {"FINISHED"}
class UAC_OT_world_space_paste_next_frame(bpy.types.Operator):
bl_idname = "anim.world_space_paste_next_frame"
bl_label = "World Paste Jump Frame"
bl_description = "Paste world space transforms and keyframe available chanels\nThen jump to prev/next frame"
bl_options = {"REGISTER", "UNDO"}
@classmethod
def poll(cls, context):
return context.object and context.mode == 'POSE' and context.active_pose_bone
prev: bpy.props.BoolProperty()
def execute(self, context):
# apply matrix
context.active_pose_bone.matrix = context.object.matrix_world.inverted() @ bpy.context.view_layer.world_space_store
# insert keyframe at value
# context.object.keyframe_insert(data_path, index=-1, frame=bpy.context.scene.frame_current, group="", options={'INSERTKEY_AVAILABLE'})
bpy.ops.anim.keyframe_insert_menu(type='Available')
# jump to next frame
act = fn.get_obj_action(context.object)
if not act:
self.report({'ERROR'}, 'No action on armature')
return {'CANCELLED'}
offset = -1 if self.prev else 1
new_frame = context.scene.frame_current + offset
context.scene.frame_current = new_frame
return {"FINISHED"}
classes=(
UAC_OT_world_space_copy,
UAC_OT_world_space_paste,
UAC_OT_world_space_paste_next,
UAC_OT_world_space_paste_next_frame,
)
def register():

View File

@ -56,6 +56,13 @@ Bonus:
## Changelog:
0.6.0
- World paste and `Jump next frame`
- more compact and improved ui for world paste
- fix errors in some operators
0.5.0
- pin feet working

View File

@ -2,7 +2,7 @@ bl_info = {
"name": "Unfold Anim Cycle",
"description": "Anim tools to develop walk/run cycles along a curve",
"author": "Samuel Bernou",
"version": (0, 5, 0),
"version": (0, 6, 0),
"blender": (3, 0, 0),
"location": "View3D",
"warning": "WIP",

1
fn.py
View File

@ -59,6 +59,7 @@ def get_follow_curve_from_armature(arm):
name = get_root_name()
parents = []
const = False
# root = b.id_data.pose.bones.get(name)
root = arm.pose.bones.get(name)
for c in root.constraints:

View File

@ -13,8 +13,12 @@ class UAC_PT_walk_cycle_anim_panel(bpy.types.Panel):
# need to know root orientation forward)
## know direction to evaluate feet moves
## Define Constraint axis (depend on root orientation)
layout.prop(settings, "forward_axis")
layout.operator("uac.autoset_axis", text='Auto-Set Axis')
# layout.prop(settings, "forward_axis") # plain prop
row = layout.row()
row.label(text='Forward Axis')
row.prop(settings, "forward_axis", text='')
layout.operator("uac.autoset_axis", text='Auto-Set Axis')
box = layout.box()
if not settings.path_to_follow:
@ -81,10 +85,25 @@ class UAC_PT_anim_tools_panel(bpy.types.Panel):
layout.operator('anim.contact_to_ground', text='Ground selected feet', icon='SNAP_OFF')
row = layout.row()
row.operator('anim.world_space_copy', text='Copy Pose', icon='COPYDOWN')
row.operator('anim.world_space_paste', text='Paste', icon='PASTEDOWN')
row = layout.row()
row.operator('anim.world_space_paste_next', text='Paste Prev', icon='PASTEDOWN').prev = True
row.operator('anim.world_space_paste_next', text='Paste Next', icon='PASTEDOWN').prev = False
# row.operator('anim.world_space_paste', text='Paste', icon='PASTEDOWN')
# row = layout.row(align=False)
## multi buttons
# row.label(text='Paste and jump:')
# row = layout.row(align=True)
# row.operator('anim.world_space_paste_next', text='Prev key', icon='PREV_KEYFRAME').prev = True # Paste Prev key
# row.operator('anim.world_space_paste_next', text='Next key', icon='NEXT_KEYFRAME').prev = False # Paste Next key
# row = layout.row(align=True)
# row.operator('anim.world_space_paste_next_frame', text='Prev frame', icon='FRAME_PREV').prev = True # Paste Prev frame
# row.operator('anim.world_space_paste_next_frame', text='Next frame', icon='FRAME_NEXT').prev = False # Paste Next frame
row = layout.row(align=True)
row.operator('anim.world_space_paste_next_frame', text='', icon='FRAME_PREV').prev = True
row.operator('anim.world_space_paste_next', text='', icon='PREV_KEYFRAME').prev = True
row.operator('anim.world_space_paste', text='', icon='PASTEDOWN')
row.operator('anim.world_space_paste_next', text='', icon='NEXT_KEYFRAME').prev = False
row.operator('anim.world_space_paste_next_frame', text='', icon='FRAME_NEXT').prev = False
row.scale_x = 2

View File

@ -31,7 +31,7 @@ class UAC_PG_settings(bpy.types.PropertyGroup) :
forward_axis : bpy.props.EnumProperty(
name='Forward Axis',
default='TRACK_NEGATIVE_Y', # Modifier default is FORWARD_X
default='FORWARD_Z', # Modifier default is FORWARD_X (should be TRACK_NEGATIVE_Y for a good rig)
description='Local axis of the "root" bone that point forward',
items=(
('FORWARD_X', 'X', ''),