Fix #4 paste layers skipping empty frames
1.8.1 - fix: Gp clipboard paste `Paste layers` don't skip empty frames anymoregpv2
parent
6c19fa54af
commit
3c7477c442
|
@ -1,5 +1,8 @@
|
|||
# Changelog
|
||||
|
||||
1.8.1
|
||||
|
||||
- fix: Gp clipboard paste `Paste layers` don't skip empty frames anymore
|
||||
|
||||
1.8.0
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
132
UI_tools.py
132
UI_tools.py
|
@ -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
|
||||
"""
|
||||
|
|
|
@ -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": "",
|
||||
|
|
Loading…
Reference in New Issue