animation mode to create all keys at once
parent
a56a9ea537
commit
77e3049d5d
|
@ -1,7 +1,7 @@
|
|||
bl_info = {
|
||||
"name": "gp interpolate",
|
||||
"author": "Christophe Seux, Samuel Bernou",
|
||||
"version": (0, 1, 2),
|
||||
"version": (0, 2, 0),
|
||||
"blender": (3, 6, 0),
|
||||
"location": "Sidebar > Gpencil Tab > Interpolate",
|
||||
"description": "Interpolate Grease pencil strokes over 3D",
|
||||
|
|
|
@ -20,13 +20,26 @@ from mathutils.geometry import (barycentric_transform,
|
|||
tessellate_polygon)
|
||||
|
||||
|
||||
def following_key(forward=True):
|
||||
def following_keys(forward=True, all_keys=True) -> list:# -> list[int] | list | None:
|
||||
'''return a lsit of int or an empty list'''
|
||||
direction = 1 if forward else -1
|
||||
cur_frame = bpy.context.scene.frame_current
|
||||
settings = bpy.context.scene.gp_interpo_settings
|
||||
|
||||
if settings.mode == 'FRAME':
|
||||
return cur_frame + (settings.padding * direction)
|
||||
if all_keys:
|
||||
scn = bpy.context.scene
|
||||
if forward:
|
||||
limit = scn.frame_preview_end if scn.use_preview_range else scn.frame_end
|
||||
else:
|
||||
limit = scn.frame_preview_start if scn.use_preview_range else scn.frame_start
|
||||
|
||||
limit += direction # offset by one for limit to be in range
|
||||
|
||||
return list(range(cur_frame, limit, settings.padding * direction))
|
||||
|
||||
else:
|
||||
return [cur_frame + (settings.padding * direction)]
|
||||
|
||||
elif settings.mode == 'GPKEY':
|
||||
layers = bpy.context.object.data.layers
|
||||
|
@ -42,18 +55,26 @@ def following_key(forward=True):
|
|||
frames = [k.co.x for fc in arm.animation_data.action.fcurves for k in fc.keyframe_points]
|
||||
|
||||
if not frames:
|
||||
return
|
||||
return []
|
||||
|
||||
# Sort frames (invert if looking backward)
|
||||
frames.sort(reversed=not forward)
|
||||
|
||||
if all_keys:
|
||||
frames = list(set(frames))
|
||||
if forward:
|
||||
frame_list = [int(f) for f in frames if f > cur_frame]
|
||||
else:
|
||||
frame_list = [int(f) for f in frames if f < cur_frame]
|
||||
return frame_list
|
||||
|
||||
frames.sort()
|
||||
if forward:
|
||||
new = next((f for f in frames if f > cur_frame), None)
|
||||
else:
|
||||
below = [f for f in frames if f < cur_frame]
|
||||
if not below:
|
||||
return
|
||||
new = below[-1]
|
||||
|
||||
return int(new)
|
||||
new = next((f for f in frames if f < cur_frame), None)
|
||||
if new is None:
|
||||
return []
|
||||
return [int(new)]
|
||||
|
||||
|
||||
## TODO: add bake animation to empty for later GP layer parenting
|
||||
|
@ -88,9 +109,9 @@ class GP_OT_interpolate_stroke(bpy.types.Operator):
|
|||
# auto_key_status = context.tool_settings.use_keyframe_insert_auto
|
||||
# context.tool_settings.use_keyframe_insert_auto = True
|
||||
|
||||
## Determine on what key to jump
|
||||
frame_to_jump = following_key(forward=self.next)
|
||||
if frame_to_jump is None:
|
||||
## Determine on what key/keys to jump
|
||||
frames_to_jump = following_keys(forward=self.next, all_keys=settings.use_animation)
|
||||
if not len(frames_to_jump):
|
||||
self.report({'WARNING'}, 'No keyframe available in this direction')
|
||||
return {'CANCELLED'}
|
||||
|
||||
|
@ -214,7 +235,13 @@ class GP_OT_interpolate_stroke(bpy.types.Operator):
|
|||
# Copy stroke selection, jump frame and paste
|
||||
|
||||
bpy.ops.gpencil.copy()
|
||||
scn.frame_set(frame_to_jump)
|
||||
|
||||
wm = bpy.context.window_manager # Pgs
|
||||
|
||||
wm.progress_begin(frames_to_jump[0], frames_to_jump[-1]) # Pgs
|
||||
for f in frames_to_jump:
|
||||
wm.progress_update(f) # Pgs
|
||||
scn.frame_set(f)
|
||||
plan_co, plane_no = get_gp_draw_plane(gp)
|
||||
bpy.ops.gpencil.paste()
|
||||
|
||||
|
@ -246,6 +273,7 @@ class GP_OT_interpolate_stroke(bpy.types.Operator):
|
|||
new_stroke.points.foreach_set('co', new_local_co_3d.reshape(nb_points*3))
|
||||
new_stroke.points.update()
|
||||
|
||||
wm.progress_end() # Pgs
|
||||
## Reset autokey status
|
||||
# context.tool_settings.use_keyframe_insert_auto = auto_key_status # (Done in context manager)
|
||||
|
||||
|
@ -284,8 +312,8 @@ class GP_OT_interpolate_stroke(bpy.types.Operator):
|
|||
context.tool_settings.use_keyframe_insert_auto = True
|
||||
|
||||
## Determine on what key to jump
|
||||
frame_to_jump = following_key(forward=self.next)
|
||||
if frame_to_jump is None:
|
||||
frames_to_jump = following_keys(forward=self.next)
|
||||
if frames_to_jump is None:
|
||||
self.report({'WARNING'}, 'No keyframe available in this direction')
|
||||
return {'CANCELLED'}
|
||||
|
||||
|
@ -376,7 +404,7 @@ class GP_OT_interpolate_stroke(bpy.types.Operator):
|
|||
|
||||
bpy.ops.gpencil.copy()
|
||||
|
||||
scn.frame_set(frame_to_jump)
|
||||
scn.frame_set(frames_to_jump)
|
||||
|
||||
plan_co, plane_no = get_gp_draw_plane(gp)
|
||||
|
||||
|
|
|
@ -24,6 +24,11 @@ class GP_PG_interpolate_settings(PropertyGroup):
|
|||
description='Select method for interpolating strokes'
|
||||
)
|
||||
|
||||
use_animation : BoolProperty(
|
||||
name='Animatation',
|
||||
default=True,
|
||||
description='Apply the interpolation on the remaining range')
|
||||
|
||||
search_range : FloatProperty(
|
||||
name="Search Range",
|
||||
description="Search range size when points are out of mesh",
|
||||
|
|
Loading…
Reference in New Issue