# SPDX-License-Identifier: GPL-2.0-or-later import bpy import math def redraw_areas_by_type(window, area_type, region_type='WINDOW'): """Redraw `window`'s areas matching the given `area_type` and optionnal `region_type`.""" for area in window.screen.areas: if area.type == area_type: for region in area.regions: if region.type == region_type: region.tag_redraw() def redraw_all_areas_by_type(context, area_type, region_type='WINDOW'): """Redraw areas in all windows matching the given `area_type` and optionnal `region_type`.""" for window in context.window_manager.windows: redraw_areas_by_type(window, area_type, region_type) def get_selected_keyframes(context): """Get list of selected keyframes for any object in the scene. """ keys = [] for ob in context.scene.objects: if ob.type == 'GPENCIL': for gpl in ob.data.layers: for gpf in gpl.frames: if gpf.select: keys.append(gpf.frame_number) elif ob.animation_data is not None and ob.animation_data.action is not None: action = ob.animation_data.action for fcu in action.fcurves: for kp in fcu.keyframe_points: if kp.select_control_point: keys.append(int(kp.co[0])) keys.sort() unique_keys = list(set(keys)) return unique_keys def find_collections_recursive(root, collections=None): # Initialize the result once if collections is None: collections = [] def recurse(parent, result): result.append(parent) # Look over children at next level for child in parent.children: recurse(child, result) recurse(root, collections) return collections def get_keyframe_list(scene, frame_start, frame_end): """Get list of frames for any gpencil object in the scene and meshes. """ keys = [] root = scene.view_layers[0].layer_collection collections = find_collections_recursive(root) for laycol in collections: if laycol.exclude is True or laycol.collection.hide_render is True: continue for ob in laycol.collection.objects: if ob.hide_render: continue if ob.type == 'GPENCIL': for gpl in ob.data.layers: if gpl.hide: continue for gpf in gpl.frames: if frame_start <= gpf.frame_number <= frame_end: keys.append(gpf.frame_number) # Animation at object level if ob.animation_data is not None and ob.animation_data.action is not None: action = ob.animation_data.action for fcu in action.fcurves: for kp in fcu.keyframe_points: if frame_start <= int(kp.co[0]) <= frame_end: keys.append(int(kp.co[0])) # Animation at datablock level if ob.type != 'GPENCIL': data = ob.data if data and data.animation_data is not None and data.animation_data.action is not None: action = data.animation_data.action for fcu in action.fcurves: for kp in fcu.keyframe_points: if frame_start <= int(kp.co[0]) <= frame_end: keys.append(int(kp.co[0])) # Scene Markers for m in scene.timeline_markers: if frame_start <= m.frame <= frame_end and m.camera is not None: keys.append(int(m.frame)) # If no animation or markers, must add first frame if len(keys) == 0: keys.append(int(frame_start)) unique_keys = list(set(keys)) unique_keys.sort() return unique_keys