fix key range detection
1.0.0 - fix: broken algo for extreme keys range detectionmaster
parent
25b081e53a
commit
848bda410d
|
@ -1,5 +1,9 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
1.0.0
|
||||||
|
|
||||||
|
- fix: broken algo for extreme keys range detection
|
||||||
|
|
||||||
0.9.0
|
0.9.0
|
||||||
|
|
||||||
- fix problem with translation calculation when all keys are marked
|
- fix problem with translation calculation when all keys are marked
|
||||||
|
|
|
@ -42,9 +42,12 @@ def has_extremes(b, act=None):
|
||||||
|
|
||||||
def get_extreme_range(ob, act, b):
|
def get_extreme_range(ob, act, b):
|
||||||
b_fcurves = [fcu for fcu in act.fcurves if fcu.data_path.split('"')[1] == b.bone.name]
|
b_fcurves = [fcu for fcu in act.fcurves if fcu.data_path.split('"')[1] == b.bone.name]
|
||||||
start_frame = end_frame = None
|
# for f in b_fcurves:
|
||||||
|
# print('fc:', f.data_path, f.array_index)
|
||||||
|
curves = []
|
||||||
for fcu in b_fcurves:
|
for fcu in b_fcurves:
|
||||||
|
start_frame = end_frame = None
|
||||||
|
e_ct = 0
|
||||||
encountered_marks = False # flag to stop after last extreme of each fcu
|
encountered_marks = False # flag to stop after last extreme of each fcu
|
||||||
for k in fcu.keyframe_points:
|
for k in fcu.keyframe_points:
|
||||||
# if k.select_control_point: # based on selection ?
|
# if k.select_control_point: # based on selection ?
|
||||||
|
@ -61,15 +64,37 @@ def get_extreme_range(ob, act, b):
|
||||||
end_frame = f
|
end_frame = f
|
||||||
if end_frame < f:
|
if end_frame < f:
|
||||||
end_frame = f
|
end_frame = f
|
||||||
|
|
||||||
else:
|
e_ct += 1
|
||||||
if encountered_marks:
|
continue
|
||||||
## means back to other frame type after passed breakdown we stop
|
|
||||||
## (for this fcu)
|
# it's a normal keyframe
|
||||||
|
if encountered_marks:
|
||||||
|
if e_ct == 1:
|
||||||
|
# reset (continue scan to next frame range)
|
||||||
|
e_ct = 0
|
||||||
|
start_frame = end_frame = None
|
||||||
|
encountered_marks = False
|
||||||
|
|
||||||
|
else:
|
||||||
|
## means back to other frame type after passed sufficient key
|
||||||
|
## (stop for this fcu)
|
||||||
break
|
break
|
||||||
if start_frame is None or end_frame is None:
|
|
||||||
|
print(fcu.data_path, fcu.array_index, start_frame, end_frame)
|
||||||
|
if start_frame is None or end_frame is None:
|
||||||
|
continue
|
||||||
|
if end_frame - start_frame == 0: # same key
|
||||||
|
continue
|
||||||
|
|
||||||
|
print('ok')
|
||||||
|
curves.append(end_frame - start_frame)
|
||||||
|
|
||||||
|
if not curves:
|
||||||
return
|
return
|
||||||
return end_frame - start_frame
|
print('curves: ', curves)
|
||||||
|
curves.sort()
|
||||||
|
return curves[-1]
|
||||||
|
|
||||||
def find_best_foot(ob):
|
def find_best_foot(ob):
|
||||||
'''Get an armature object and do some wizardry to return best match for foot bone'''
|
'''Get an armature object and do some wizardry to return best match for foot bone'''
|
||||||
|
@ -120,17 +145,20 @@ def find_best_foot(ob):
|
||||||
return b
|
return b
|
||||||
|
|
||||||
flipped_contact_range = get_extreme_range(ob, act, flipped)
|
flipped_contact_range = get_extreme_range(ob, act, flipped)
|
||||||
if not flipped_contact_range:
|
print('flipped_contact_range: ', flipped_contact_range)
|
||||||
return b
|
|
||||||
|
|
||||||
bone_contact_range = get_extreme_range(ob, act, b)
|
bone_contact_range = get_extreme_range(ob, act, b)
|
||||||
if bone_contact_range:
|
print('bone_contact_range: ', bone_contact_range)
|
||||||
if bone_contact_range < flipped_contact_range:
|
|
||||||
return flipped
|
|
||||||
else:
|
|
||||||
return ('ERROR', f'No Extreme (red keys) on bone "{b.name}" for action "{act.name}"')
|
|
||||||
|
|
||||||
return b
|
if bone_contact_range:
|
||||||
|
if flipped_contact_range and (bone_contact_range < flipped_contact_range):
|
||||||
|
return flipped
|
||||||
|
else:
|
||||||
|
return b
|
||||||
|
elif flipped_contact_range:
|
||||||
|
return flipped
|
||||||
|
|
||||||
|
return ('ERROR', f'No Extreme (red keys) on bone "{b.name}" for action "{act.name}"')
|
||||||
|
|
||||||
|
|
||||||
def anim_path_from_translate():
|
def anim_path_from_translate():
|
||||||
|
@ -189,8 +217,10 @@ def anim_path_from_translate():
|
||||||
b_fcurves = [fcu for fcu in act.fcurves if fcu.data_path.split('"')[1] == b.bone.name]
|
b_fcurves = [fcu for fcu in act.fcurves if fcu.data_path.split('"')[1] == b.bone.name]
|
||||||
print('b_fcurves: ', len(b_fcurves))
|
print('b_fcurves: ', len(b_fcurves))
|
||||||
|
|
||||||
start_frame = end_frame = None
|
# find best fcurve
|
||||||
|
|
||||||
for fcu in b_fcurves:
|
for fcu in b_fcurves:
|
||||||
|
start_frame = end_frame = None
|
||||||
# skip problematic keys
|
# skip problematic keys
|
||||||
if not len(fcu.keyframe_points):
|
if not len(fcu.keyframe_points):
|
||||||
if debug: print(fcu.data_path, fcu.array_index, '>> no keys !')
|
if debug: print(fcu.data_path, fcu.array_index, '>> no keys !')
|
||||||
|
@ -202,8 +232,8 @@ def anim_path_from_translate():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
encountered_marks = False # flag to stop after last extreme of each fcu
|
encountered_marks = False # flag to stop after last extreme of each fcu
|
||||||
|
e_ct = 0
|
||||||
for k in fcu.keyframe_points:
|
for k in fcu.keyframe_points:
|
||||||
# if k.select_control_point: # based on selection ?
|
|
||||||
if k.type == 'EXTREME':
|
if k.type == 'EXTREME':
|
||||||
encountered_marks = True
|
encountered_marks = True
|
||||||
|
|
||||||
|
@ -217,15 +247,33 @@ def anim_path_from_translate():
|
||||||
end_frame = f
|
end_frame = f
|
||||||
if end_frame < f:
|
if end_frame < f:
|
||||||
end_frame = f
|
end_frame = f
|
||||||
|
|
||||||
else:
|
e_ct += 1
|
||||||
if encountered_marks:
|
continue
|
||||||
|
|
||||||
|
# this is a normal keyframe
|
||||||
|
if encountered_marks:
|
||||||
|
if e_ct == 1:
|
||||||
|
# mean only one extreme has been scanned
|
||||||
|
# reset and continue de keys scan
|
||||||
|
e_ct = 0
|
||||||
|
start_frame = end_frame = None
|
||||||
|
encountered_marks = False
|
||||||
|
else:
|
||||||
## means back to other frame type after passed breakdown we stop
|
## means back to other frame type after passed breakdown we stop
|
||||||
## (for this fcu)
|
## (for this fcu)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if start_frame is None or end_frame is None:
|
||||||
|
continue
|
||||||
|
if start_frame == end_frame:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# we have a range and were probably happy with this one.
|
||||||
|
break
|
||||||
|
|
||||||
if start_frame is None or end_frame is None:
|
if start_frame is None or end_frame is None:
|
||||||
return ('ERROR', f'No / All / not enough keyframe marked Extreme {ob.name} > {b.name}')
|
return ('ERROR', f'No / All or not enough keyframe marked Extreme {ob.name} > {b.name}')
|
||||||
if start_frame == end_frame:
|
if start_frame == end_frame:
|
||||||
return ('ERROR', f'Only one key detected as extreme (at frame {start_frame}) !\nNeed at least two chained marked keys')
|
return ('ERROR', f'Only one key detected as extreme (at frame {start_frame}) !\nNeed at least two chained marked keys')
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ bl_info = {
|
||||||
"name": "Unfold Anim Cycle",
|
"name": "Unfold Anim Cycle",
|
||||||
"description": "Anim tools to develop walk/run cycles along a curve",
|
"description": "Anim tools to develop walk/run cycles along a curve",
|
||||||
"author": "Samuel Bernou",
|
"author": "Samuel Bernou",
|
||||||
"version": (0, 9, 1),
|
"version": (1, 0, 0),
|
||||||
"blender": (3, 0, 0),
|
"blender": (3, 0, 0),
|
||||||
"location": "View3D",
|
"location": "View3D",
|
||||||
"warning": "",
|
"warning": "",
|
||||||
|
|
Loading…
Reference in New Issue