GPv3: Snap selected grease pencil frames #111507

Closed
Amélie Fondevilla wants to merge 2 commits from amelief:gpv3-snap-selection into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
3 changed files with 61 additions and 1 deletions

View File

@ -19,6 +19,7 @@
#include "ED_grease_pencil.hh"
#include "ED_keyframes_edit.hh"
#include "ED_markers.hh"
#include "RNA_access.hh"
#include "RNA_define.hh"
@ -27,6 +28,52 @@
namespace blender::ed::greasepencil {
static float get_snapped_frame_number(const float frame_number,
Scene &scene,
const eEditKeyframes_Snap mode)
{
switch (mode) {
case SNAP_KEYS_CURFRAME: /* Snap to current frame. */
return scene.r.cfra;
case SNAP_KEYS_NEARSEC: /* Snap to nearest second. */
{
float secf = (scene.r.frs_sec / scene.r.frs_sec_base);
return floorf(frame_number / secf + 0.5f) * secf;
}
case SNAP_KEYS_NEARMARKER: /* Snap to nearest marker. */
return ED_markers_find_nearest_marker_time(&scene.markers, frame_number);
default:
break;
}
return frame_number;
}
bool snap_layer_frames(GreasePencil &grease_pencil,
bke::greasepencil::Layer &layer,
Scene &scene,
const eEditKeyframes_Snap mode)
{
bool changed = false;
blender::Map<int, int> frame_number_destinations;
for (auto [frame_number, frame] : layer.frames().items()) {
if (!frame.is_selected()) {
continue;
}
const int snapped = round_fl_to_int(
get_snapped_frame_number(float(frame_number), scene, mode));
if (snapped != frame_number) {
frame_number_destinations.add(frame_number, snapped);
changed = true;
}
}
if (changed) {
grease_pencil.move_frames(layer, frame_number_destinations);
}
return changed;
}
bool remove_all_selected_frames(GreasePencil &grease_pencil, bke::greasepencil::Layer &layer)
{
Vector<int> frames_to_remove;

View File

@ -47,6 +47,11 @@ eAttrDomain ED_grease_pencil_selection_domain_get(bContext *C);
namespace blender::ed::greasepencil {
bool snap_layer_frames(GreasePencil &grease_pencil,
bke::greasepencil::Layer &layer,
Scene &scene,
const eEditKeyframes_Snap mode);
bool remove_all_selected_frames(GreasePencil &grease_pencil, bke::greasepencil::Layer &layer);
void select_layer_channel(GreasePencil &grease_pencil, bke::greasepencil::Layer *layer);

View File

@ -1898,7 +1898,15 @@ static void snap_action_keys(bAnimContext *ac, short mode)
ED_gpencil_layer_snap_frames(static_cast<bGPDlayer *>(ale->data), ac->scene, mode);
}
else if (ale->type == ANIMTYPE_GREASE_PENCIL_LAYER) {
/* GPv3: To be implemented. */
GreasePencil *grease_pencil = reinterpret_cast<GreasePencil *>(ale->id);
GreasePencilLayer *layer = static_cast<GreasePencilLayer *>(ale->data);
const bool changed = blender::ed::greasepencil::snap_layer_frames(
*grease_pencil, layer->wrap(), *(ac->scene), static_cast<eEditKeyframes_Snap>(mode));
if (changed) {
DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY);
}
}
else if (ale->type == ANIMTYPE_MASKLAYER) {
ED_masklayer_snap_frames(static_cast<MaskLayer *>(ale->data), ac->scene, mode);