From f25d2105a613e1bd41342289c47507a54ef8f62f Mon Sep 17 00:00:00 2001 From: aresdevo Date: Thu, 17 Feb 2022 01:47:03 -0800 Subject: [PATCH] -More fixes to the Key Manager --- __init__.py | 4 +- key_manager/support.py | 74 ++++++++++++++++++++++------------ utils/key.py | 91 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 141 insertions(+), 28 deletions(-) diff --git a/__init__.py b/__init__.py index ea36bea..437b86e 100755 --- a/__init__.py +++ b/__init__.py @@ -24,8 +24,8 @@ "name": "AnimAide", "description": "Helpful tools to manipulate keys on f-curves", "author": "Ares Deveaux", - "version": (1, 0, 38), - "blender": (2, 92, 0), + "version": (1, 0, 38_1), + "blender": (2, 93, 0), "location": "Graph Editor - Dope Sheet - Timeline - 3D View - sidebar and menu bar", "warning": "This addon is still in development.", "category": "Animation", diff --git a/key_manager/support.py b/key_manager/support.py index cc219ff..d1e5b41 100755 --- a/key_manager/support.py +++ b/key_manager/support.py @@ -95,10 +95,10 @@ def add_key_type(context, fcurve, key_type): def change_frame(context, amount, direction='RIGHT'): """move keys horizontally""" - def can_move(l_neighbor, r_neighbor, l_key, r_key): - if l_neighbor is not None and l_key.co.x + amount <= l_neighbor.co.x: + def can_move(l_limit, r_limit, most_l, most_r): + if l_limit is not None and most_l + amount <= l_limit: return False - elif r_neighbor is not None and r_key.co.x + amount >= r_neighbor.co.x: + elif r_limit is not None and most_r + amount >= r_limit: return False else: return True @@ -115,12 +115,20 @@ def can_move(l_neighbor, r_neighbor, l_key, r_key): frames = amount + some_selected_key = utils.key.some_selected_keys_in_objects(context, objects) + + bounding_box = utils.key.selected_bounding_box(context, objects, some_selected_key) + + most_left = bounding_box[0] + most_right = bounding_box[1] + left_limit = bounding_box[2] + right_limit = bounding_box[3] + lonely_cursor = bounding_box[4] + for obj in objects: if not utils.curve.valid_obj(context, obj): continue - some_selected_key = utils.key.some_selected_key(context, obj) - fcurves = obj.animation_data.action.fcurves for fcurve in fcurves: @@ -130,9 +138,7 @@ def can_move(l_neighbor, r_neighbor, l_key, r_key): selected_keys = utils.key.get_selected_index(fcurve) if selected_keys: - left_neighbor, right_neighbor = utils.key.get_selected_neigbors(fcurve, selected_keys) - left_key, right_key = utils.key.first_and_last_selected(fcurve, selected_keys) - if not can_move(left_neighbor, right_neighbor, left_key, right_key): + if not can_move(left_limit, right_limit, most_left, most_right): return for index in selected_keys: if not index: @@ -143,34 +149,50 @@ def can_move(l_neighbor, r_neighbor, l_key, r_key): frames = 0 elif not some_selected_key: - left_neighbor, right_neighbor = utils.key.get_frame_neighbors(fcurve) - current_index = utils.key.on_current_frame(fcurve) - if current_index: - key = fcurve.keyframe_points[current_index] - if not can_move(left_neighbor, right_neighbor, key, key): + index = utils.key.on_current_frame(fcurve) + if index: + if not can_move(left_limit, right_limit, most_left, most_right): return + key = fcurve.keyframe_points[index] key.co.x += amount - fcurve.update() - # context.scene.frame_current += amount frames = amount - # else: - # if direction == 'LEFT' and right_neighbor: - # right_neighbor.co.x = context.scene.frame_current - # elif direction == 'RIGHT' and left_neighbor: - # left_neighbor.co.x = context.scene.frame_current - # frames = 0 fcurve.update() - context.scene.frame_current += frames + if lonely_cursor and not some_selected_key: + if direction == 'LEFT' and left_limit: + context.scene.frame_current = left_limit + elif direction == 'RIGHT' and right_limit: + context.scene.frame_current = right_limit + else: + context.scene.frame_current += frames def insert_frames(context, amount): """insert frames between keys""" + def can_move(meta, margen): + if meta is not None and margen + amount <= meta: + return False + else: + return True + objects = context.selected_objects + if not objects: + return + current_frame = context.scene.frame_current + some_selected_key = utils.key.some_selected_keys_in_objects(context, objects) + + bounding_box = utils.key.selected_bounding_box(context, objects, some_selected_key) + + most_left = bounding_box[0] + most_right = bounding_box[1] + left_limit = bounding_box[2] + right_limit = bounding_box[3] + lonely_cursor = bounding_box[4] + def displace_keys(anchor_frame): for key in fcurve.keyframe_points: if key.co_ui.x <= anchor_frame: @@ -181,9 +203,6 @@ def displace_keys(anchor_frame): key.co_ui.x += amount - if not objects: - return - for obj in objects: if not utils.curve.valid_obj(context, obj): continue @@ -199,10 +218,15 @@ def displace_keys(anchor_frame): selected_keys = utils.key.get_selected_index(fcurve) if selected_keys: + if not can_move(most_right, right_limit): + return for selected_i in selected_keys: selected_k = fcurve.keyframe_points[selected_i] displace_keys(selected_k.co_ui.x) + # displace_keys(most_left) elif not some_selected_key: + if not can_move(current_frame, right_limit): + return displace_keys(current_frame) fcurve.update() diff --git a/utils/key.py b/utils/key.py index 751ba55..198a8cc 100755 --- a/utils/key.py +++ b/utils/key.py @@ -94,6 +94,18 @@ def some_selected_key(context, obj): return False +def some_selected_keys_in_objects(context, objects): + selected = False + for obj in objects: + if not utils.curve.valid_obj(context, obj): + continue + if some_selected_key(context, obj): + print('some selected Bone: ', some_selected_key(context, obj)) + return True + print('some selected Bone: ', False) + return False + + def add_key(keys, x, y, select=False, index=-1): keys.add(1) if index == -1: @@ -143,7 +155,8 @@ def first_and_last_selected(fcurve, keyframes): index = on_current_frame(fcurve) if index is None: return - keyframes = [index] + else: + keyframes = [index] first_index = keyframes[0] first_key = every_key[first_index] @@ -155,6 +168,82 @@ def first_and_last_selected(fcurve, keyframes): return first_key, last_key +def selected_bounding_box(context, objects, keys_selected=True): + + most_left = None + most_right = None + left_limit = None + right_limit = None + lonely_cursor = True + + for obj in objects: + if not utils.curve.valid_obj(context, obj): + continue + + fcurves = obj.animation_data.action.fcurves + + for fcurve in fcurves: + if not utils.curve.valid_fcurve(context, obj, fcurve): + continue + if keys_selected: + selected_keys_i = utils.key.get_selected_index(fcurve) + if selected_keys_i: + first, last = first_and_last_selected(fcurve, selected_keys_i) + left_neighbor, right_neighbor = get_selected_neigbors(fcurve, selected_keys_i) + first_frame = first.co.x + last_frame = last.co.x + left_neighbor_frame = left_neighbor.co.x + right_neighbor_frame = right_neighbor.co.x + else: + first_frame = most_left + last_frame = most_right + left_neighbor_frame = left_limit + right_neighbor_frame = right_limit + else: + key_i = utils.key.on_current_frame(fcurve) + if key_i: + lonely_cursor = False + first_frame = fcurve.keyframe_points[key_i].co.x + last_frame = fcurve.keyframe_points[key_i].co.x + left_neighbor, right_neighbor = get_index_neighbors(fcurve, key_i) + left_neighbor_frame = left_neighbor.co.x + right_neighbor_frame = right_neighbor.co.x + else: + first_frame = bpy.context.scene.frame_current + last_frame = bpy.context.scene.frame_current + left_neighbor, right_neighbor = get_frame_neighbors(fcurve) + left_neighbor_frame = left_neighbor.co.x + right_neighbor_frame = right_neighbor.co.x + + if most_left is None: + most_left = first_frame + elif first_frame < most_left: + most_left = first_frame + + if most_right is None: + most_right = last_frame + elif last_frame > most_right: + most_right = last_frame + + if left_limit is None: + left_limit = left_neighbor_frame + elif left_neighbor_frame > left_limit: + left_limit = left_neighbor_frame + + if right_limit is None: + right_limit = right_neighbor_frame + elif right_neighbor_frame < right_limit: + right_limit = right_neighbor_frame + + print('left limit: ', left_limit) + print('most left: ', most_left) + print('most right: ', most_right) + print('right limit: ', right_limit) + print('lonely cursor: ', lonely_cursor) + + return most_left, most_right, left_limit, right_limit, lonely_cursor + + def on_current_frame(fcurve): """returns the index of the key in the current frame"""