GPv3: Add operator to insert blank frames

This adds a new operator to insert blank keyframes for the new
grease pencil data type.

This uses the newly added `insert_frame` API.
This commit is contained in:
Falk David 2023-07-04 18:04:00 +02:00
parent 39b3a95efb
commit 44ee5b38ac
7 changed files with 121 additions and 1 deletions

@ -221,6 +221,7 @@ class Layer : public ::GreasePencilLayer {
bool is_visible() const;
bool is_locked() const;
bool is_editable() const;
/**
* Inserts the frame into the layer frames map. Will not overwrite existing frames at \a

@ -498,6 +498,11 @@ bool Layer::is_locked() const
return this->parent_group().is_locked() || (this->base.flag & GP_LAYER_TREE_NODE_LOCKED) != 0;
}
bool Layer::is_editable() const
{
return !this->is_locked() && this->is_visible();
}
bool Layer::insert_frame(const int frame_number, const GreasePencilFrame &frame)
{
BLI_assert(!frame.is_null());
@ -1168,6 +1173,20 @@ void GreasePencil::add_empty_drawings(const int add_num)
/* TODO: Update drawing user counts. */
}
bool GreasePencil::insert_blank_frame(blender::bke::greasepencil::Layer &layer,
int frame_number,
int duration,
eBezTriple_KeyframeType keytype)
{
using namespace blender;
GreasePencilFrame frame{static_cast<int>(this->drawings().size()), 0, keytype};
if (!layer.insert_frame(frame_number, duration, frame)) {
return false;
}
this->add_empty_drawings(1);
return true;
}
void GreasePencil::remove_drawing(const int index_to_remove)
{
using namespace blender::bke::greasepencil;
@ -1256,7 +1275,7 @@ static void foreach_drawing_ex(
break;
}
case EDITABLE: {
if (!layer->is_visible() || layer->is_locked()) {
if (!layer->is_editable()) {
continue;
}
break;

@ -24,6 +24,7 @@ set(INC_SYS
set(SRC
intern/grease_pencil_add.cc
intern/grease_pencil_edit.cc
intern/grease_pencil_frames.cc
intern/grease_pencil_layers.cc
intern/grease_pencil_ops.cc
intern/grease_pencil_select.cc

@ -0,0 +1,91 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup edgreasepencil
*/
#include "BKE_context.h"
#include "BKE_grease_pencil.hh"
#include "DEG_depsgraph.h"
#include "DNA_scene_types.h"
#include "ED_grease_pencil.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "WM_api.h"
namespace blender::ed::greasepencil {
static int insert_blank_frame_exec(bContext *C, wmOperator *op)
{
using namespace blender::bke::greasepencil;
Scene *scene = CTX_data_scene(C);
Object *object = CTX_data_active_object(C);
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
const int current_frame = scene->r.cfra;
const bool all_layers = RNA_boolean_get(op->ptr, "all_layers");
const int duration = RNA_int_get(op->ptr, "duration");
bool changed = false;
if (all_layers) {
for (Layer *layer : grease_pencil.layers_for_write()) {
if (!layer->is_editable()) {
continue;
}
changed = grease_pencil.insert_blank_frame(
*layer, current_frame, duration, BEZT_KEYTYPE_KEYFRAME);
}
}
else {
if (!grease_pencil.has_active_layer()) {
return OPERATOR_CANCELLED;
}
changed = grease_pencil.insert_blank_frame(*grease_pencil.get_active_layer_for_write(),
current_frame,
duration,
BEZT_KEYTYPE_KEYFRAME);
}
if (changed) {
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
}
return OPERATOR_FINISHED;
}
static void GREASE_PENCIL_OT_insert_blank_frame(wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name = "Insert Blank Frame";
ot->idname = "GREASE_PENCIL_OT_insert_blank_frame";
ot->description = "Insert a blank frame on the current scene frame";
/* callbacks */
ot->exec = insert_blank_frame_exec;
ot->poll = active_grease_pencil_poll;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
prop = RNA_def_boolean(
ot->srna, "all_layers", false, "All Layers", "Insert a blank frame in all editable layers");
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
RNA_def_int(ot->srna, "duration", 1, 1, MAXFRAME, "Duration", "", 1, 100);
}
} // namespace blender::ed::greasepencil
void ED_operatortypes_grease_pencil_frames()
{
using namespace blender::ed::greasepencil;
WM_operatortype_append(GREASE_PENCIL_OT_insert_blank_frame);
}

@ -11,6 +11,7 @@
void ED_operatortypes_grease_pencil()
{
ED_operatortypes_grease_pencil_draw();
ED_operatortypes_grease_pencil_frames();
ED_operatortypes_grease_pencil_layers();
ED_operatortypes_grease_pencil_select();
}

@ -32,6 +32,7 @@ enum {
void ED_operatortypes_grease_pencil(void);
void ED_operatortypes_grease_pencil_draw(void);
void ED_operatortypes_grease_pencil_frames(void);
void ED_operatortypes_grease_pencil_layers(void);
void ED_operatortypes_grease_pencil_select(void);
void ED_keymap_grease_pencil(struct wmKeyConfig *keyconf);

@ -9,6 +9,7 @@
#pragma once
#include "DNA_ID.h"
#include "DNA_curve_types.h"
#include "DNA_curves_types.h"
#include "DNA_listBase.h"
@ -479,6 +480,11 @@ typedef struct GreasePencil {
void remove_layer(blender::bke::greasepencil::Layer &layer);
void add_empty_drawings(int add_num);
bool insert_blank_frame(blender::bke::greasepencil::Layer &layer,
int frame_number,
int duration,
eBezTriple_KeyframeType keytype);
void remove_drawing(int index);
void foreach_visible_drawing(