Fix #4 paste layers skipping empty frames

1.8.1

- fix: Gp clipboard paste `Paste layers` don't skip empty frames anymore
gpv2
Pullusb 2021-12-17 23:26:48 +01:00
parent 6c19fa54af
commit 3c7477c442
4 changed files with 108 additions and 90 deletions

View File

@ -1,5 +1,8 @@
# Changelog
1.8.1
- fix: Gp clipboard paste `Paste layers` don't skip empty frames anymore
1.8.0

View File

@ -17,7 +17,7 @@ bl_info = {
"name": "GP clipboard",
"description": "Copy/Cut/Paste Grease Pencil strokes to/from OS clipboard across layers and blends",
"author": "Samuel Bernou",
"version": (1, 3, 2),
"version": (1, 3, 3),
"blender": (2, 83, 0),
"location": "View3D > Toolbar > Gpencil > GP clipboard",
"warning": "",
@ -280,7 +280,6 @@ def copy_all_strokes_in_frame(frame=None, layers=None, obj=None):
'''
copy all stroke, not affected by selection on active frame
layers can be None, a single layer object or list of layer object as filter
if keep_empty is False the frame is deleted when all strokes are cutted
'''
t0 = time()
scene = bpy.context.scene
@ -312,8 +311,7 @@ def copy_all_strokes_in_frame(frame=None, layers=None, obj=None):
# send index of all points to get the whole stroke with "range"
stroke_list.append( dump_gp_stroke_range(s, [i for i in range(len(s.points))], l, obj) )
print(len(stroke_list), 'strokes copied in', time()-t0, 'seconds')
#print(stroke_list)
# print(len(stroke_list), 'strokes copied in', time()-t0, 'seconds')
return stroke_list
def add_stroke(s, frame, layer, obj, select=False):
@ -368,7 +366,8 @@ def add_multiple_strokes(stroke_list, layer=None, use_current_frame=True, select
add a list of strokes to active frame of given layer
if no layer specified, active layer is used
if use_current_frame is True, a new frame will be created only if needed
if select is True, newly added strokes are selected
if select is True, newly added strokes are set selected
if stroke list is empty create an empty frame at current frame
'''
scene = bpy.context.scene
obj = bpy.context.object
@ -382,24 +381,26 @@ def add_multiple_strokes(stroke_list, layer=None, use_current_frame=True, select
fnum = scene.frame_current
target_frame = False
act = layer.active_frame
## set frame if needed
if act:
if use_current_frame or act.frame_number == fnum:
#work on current frame if exists
# use current frame anyway if one key exist at this scene.frame
target_frame = act
if not target_frame:
#no active frame
#or active exists but not aligned scene.current with use_current_frame disabled
target_frame = layer.frames.new(fnum)
for s in stroke_list:
if act:
if use_current_frame or act.frame_number == fnum:
#work on current frame if exists
# use current frame anyway if one key exist at this scene.frame
target_frame = act
if not target_frame:
#no active frame
#or active exists but not aligned scene.current with use_current_frame disabled
target_frame = layer.frames.new(fnum)
add_stroke(s, target_frame, layer, obj, select=select)
'''
for s in stroke_data:
add_stroke(s, target_frame)
'''
print(len(stroke_list), 'strokes pasted')
# print(len(stroke_list), 'strokes pasted')
### OPERATORS
@ -493,8 +494,8 @@ class GPCLIP_OT_paste_strokes(bpy.types.Operator):
class GPCLIP_OT_copy_multi_strokes(bpy.types.Operator):
bl_idname = "gp.copy_multi_strokes"
bl_label = "GP Copy multi strokes"
bl_description = "Copy multiple layers>frames>strokes (unlocked and unhided ones) to str in paperclip"
bl_label = "GP Copy Multi Strokes"
bl_description = "Copy multiple layers>frames>strokes from selected layers to str in paperclip"
bl_options = {"REGISTER"}
#copy = bpy.props.BoolProperty(default=True)
@ -513,12 +514,12 @@ class GPCLIP_OT_copy_multi_strokes(bpy.types.Operator):
#ct = check_pressure()
layerdic = {}
layerpool = [l for l in gpl if not l.hide and l.select]# and not l.lock
layerpool = [l for l in gpl if not l.hide and l.select] # and not l.lock
if not layerpool:
self.report({'ERROR'}, 'No layers selected in GP dopesheet (needs to be visible and selected to be copied)\nHint: Changing active layer reset selection to active only')
return {"CANCELLED"}
if not bake_moves:# copy only drawed frames as is.
if not bake_moves: # copy only drawed frames as is.
for l in layerpool:
if not l.frames:
continue# skip empty layers
@ -579,8 +580,8 @@ class GPCLIP_OT_copy_multi_strokes(bpy.types.Operator):
class GPCLIP_OT_paste_multi_strokes(bpy.types.Operator):
bl_idname = "gp.paste_multi_strokes"
bl_label = "GP paste multi strokes"
bl_description = "Paste multiple layers>frames>strokes from paperclip"
bl_label = "GP Paste Multi Strokes"
bl_description = "Paste multiple layers>frames>strokes from paperclip on active layer"
bl_options = {"REGISTER"}
#copy = bpy.props.BoolProperty(default=True)
@ -614,8 +615,8 @@ class GPCLIP_OT_paste_multi_strokes(bpy.types.Operator):
if not layer:
layer = gpl.new(layname)
for fnum, fstrokes in allframes.items():
context.scene.frame_set(int(fnum))#use matrix of this frame for copying (maybe just evaluate depsgraph for object
add_multiple_strokes(fstrokes, use_current_frame=False)#create a new frame at each encoutered
context.scene.frame_set(int(fnum)) # use matrix of this frame for copying (maybe just evaluate depsgraph for object
add_multiple_strokes(fstrokes, use_current_frame=False) # create a new frame at each encoutered occurence
print('total_time', time() - t0)
@ -640,13 +641,13 @@ class GPCLIP_PT_clipboard_ui(bpy.types.Panel):
col = layout.column(align=True)
row = col.row(align=True)
row.operator('gp.copy_strokes', text='Copy strokes', icon='COPYDOWN')
row.operator('gp.cut_strokes', text='Cut strokes', icon='PASTEFLIPUP')
col.operator('gp.paste_strokes', text='Paste strokes', icon='PASTEDOWN')
row.operator('gp.copy_strokes', text='Copy Strokes', icon='COPYDOWN')
row.operator('gp.cut_strokes', text='Cut Strokes', icon='PASTEFLIPUP')
col.operator('gp.paste_strokes', text='Paste Strokes', icon='PASTEDOWN')
# layout.separator()
col = layout.column(align=True)
col.operator('gp.copy_multi_strokes', text='Copy layers', icon='COPYDOWN')
col.operator('gp.paste_multi_strokes', text='Paste layers', icon='PASTEDOWN')
col.operator('gp.copy_multi_strokes', text='Copy Layers', icon='COPYDOWN')
col.operator('gp.paste_multi_strokes', text='Paste Layers', icon='PASTEDOWN')
###---TEST zone

View File

@ -572,65 +572,8 @@ def asset_browser_ui(self, context):
classes = (
GPTB_PT_sidebar_panel,
GPTB_PT_checker,
GPTB_PT_anim_manager,
GPTB_PT_color,
GPTB_PT_tint_layers,
GPTB_PT_toolbox_playblast,
# palettes linker
GPTB_PT_palettes_linker_main_ui, # main panel
GPTB_PT_palettes_list_popup, # popup (dummy region)
GPTB_PT_palettes_path_ui, # subpanels
GPTB_PT_palettes_list_ui, # subpanels
# GPTB_PT_extra,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.GPENCIL_MT_material_context_menu.append(palette_manager_menu)
bpy.types.DOPESHEET_PT_gpencil_layer_display.append(expose_use_channel_color_pref)
# if bpy.app.version >= (3,0,0):
# bpy.types.ASSETBROWSER_PT_metadata.append(asset_browser_ui)
def unregister():
bpy.types.DOPESHEET_PT_gpencil_layer_display.remove(expose_use_channel_color_pref)
bpy.types.GPENCIL_MT_material_context_menu.remove(palette_manager_menu)
# if bpy.app.version >= (3,0,0):
# bpy.types.ASSETBROWSER_PT_metadata.remove(asset_browser_ui)
for cls in reversed(classes):
bpy.utils.unregister_class(cls)
"""
## direct panel def append (no submenu with arrow)
## need to use append and remove in register/unregister
# bpy.types.DATA_PT_gpencil_layers.append(UI_tools.GPdata_toolbox_panel)
# bpy.types.DATA_PT_gpencil_layers.remove(UI_tools.GPdata_toolbox_panel)
def GPdata_toolbox_panel(self, context):
layout = self.layout
layout.use_property_split = True
settings = context.scene.gptoolprops
col = layout.column(align = True)
col.prop(settings, 'autotint_offset')
col.operator("gp.auto_tint_gp_layers", icon = "COLOR").reset = False
col.operator("gp.auto_tint_gp_layers", text = "Reset tint", icon = "COLOR").reset = True
"""
"""
Put back UI for interpolate
# Grease Pencil stroke interpolation tools native pop hover panel from 2.92
class VIEW3D_PT_tools_grease_pencil_interpolate(Panel):
# Put back pop-over UI for Grease Pencil stroke interpolation tools native pop hover panel from 2.92
class GPTB_PT_tools_grease_pencil_interpolate(Panel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'HEADER'
bl_label = "Interpolate"
@ -680,4 +623,75 @@ class VIEW3D_PT_tools_grease_pencil_interpolate(Panel):
sub.prop(settings, "amplitude")
sub.prop(settings, "period")
def interpolate_header_ui(self, context):
layout = self.layout
obj = context.active_object
if obj and obj.type == 'GPENCIL' and context.gpencil_data:
gpd = context.gpencil_data
else:
return
if gpd.use_stroke_edit_mode or gpd.is_stroke_paint_mode:
row = layout.row(align=True)
row.popover(
panel="GPTB_PT_tools_grease_pencil_interpolate",
text="Interpolate",
)
classes = (
GPTB_PT_sidebar_panel,
GPTB_PT_checker,
GPTB_PT_anim_manager,
GPTB_PT_color,
GPTB_PT_tint_layers,
GPTB_PT_toolbox_playblast,
# GPTB_PT_tools_grease_pencil_interpolate, # WIP
# palettes linker
GPTB_PT_palettes_linker_main_ui, # main panel
GPTB_PT_palettes_list_popup, # popup (dummy region)
GPTB_PT_palettes_path_ui, # subpanels
GPTB_PT_palettes_list_ui, # subpanels
# GPTB_PT_extra,
)
def register():
for cls in classes:
bpy.utils.register_class(cls)
bpy.types.GPENCIL_MT_material_context_menu.append(palette_manager_menu)
bpy.types.DOPESHEET_PT_gpencil_layer_display.append(expose_use_channel_color_pref)
# bpy.types.VIEW3D_HT_header.append(interpolate_header_ui) # WIP
# if bpy.app.version >= (3,0,0):
# bpy.types.ASSETBROWSER_PT_metadata.append(asset_browser_ui)
def unregister():
# bpy.types.VIEW3D_HT_header.remove(interpolate_header_ui) # WIP
bpy.types.DOPESHEET_PT_gpencil_layer_display.remove(expose_use_channel_color_pref)
bpy.types.GPENCIL_MT_material_context_menu.remove(palette_manager_menu)
# if bpy.app.version >= (3,0,0):
# bpy.types.ASSETBROWSER_PT_metadata.remove(asset_browser_ui)
for cls in reversed(classes):
bpy.utils.unregister_class(cls)
"""
## direct panel def append (no submenu with arrow)
## need to use append and remove in register/unregister
# bpy.types.DATA_PT_gpencil_layers.append(UI_tools.GPdata_toolbox_panel)
# bpy.types.DATA_PT_gpencil_layers.remove(UI_tools.GPdata_toolbox_panel)
def GPdata_toolbox_panel(self, context):
layout = self.layout
layout.use_property_split = True
settings = context.scene.gptoolprops
col = layout.column(align = True)
col.prop(settings, 'autotint_offset')
col.operator("gp.auto_tint_gp_layers", icon = "COLOR").reset = False
col.operator("gp.auto_tint_gp_layers", text = "Reset tint", icon = "COLOR").reset = True
"""

View File

@ -15,7 +15,7 @@ bl_info = {
"name": "GP toolbox",
"description": "Tool set for Grease Pencil in animation production",
"author": "Samuel Bernou, Christophe Seux",
"version": (1, 8, 0),
"version": (1, 8, 1),
"blender": (2, 91, 0),
"location": "Sidebar (N menu) > Gpencil > Toolbox / Gpencil properties",
"warning": "",