Fix #116343: Drawing on frame with auto-keying off gives error

When drawing on a frame that didn't have a keyframe, but did have a drawing,
Blender would report that there was no drawing to draw on.
The issue was some faulty logic on the invoke of the drawing code.

Now, this properly checks if a new frame needs to be inserted and
only reports an error in case auto-key is off and there is no drawing.

Pull Request: https://projects.blender.org/blender/blender/pulls/116417
This commit is contained in:
Falk David
2023-12-21 11:30:16 +01:00
committed by Gitea
parent 89947aac1c
commit da78dd47e3
3 changed files with 24 additions and 9 deletions

View File

@@ -394,6 +394,11 @@ class Layer : public ::GreasePencilLayer {
* drawing. */
int drawing_index_at(const int frame_number) const;
/**
* \returns true if there is a drawing on this layer at \a frame_number.
*/
bool has_drawing_at(const int frame_number) const;
/**
* \returns the key of the active frame at \a frame_number or -1 if there is no frame.
*/

View File

@@ -808,6 +808,11 @@ int Layer::drawing_index_at(const int frame_number) const
return (frame != nullptr) ? frame->drawing_index : -1;
}
bool Layer::has_drawing_at(const int frame_number) const
{
return frame_at(frame_number) != nullptr;
}
int Layer::get_frame_duration_at(const int frame_number) const
{
const FramesMapKey frame_key = this->frame_key_at(frame_number);

View File

@@ -141,16 +141,19 @@ static int grease_pencil_stroke_invoke(bContext *C, wmOperator *op, const wmEven
}
const int current_frame = scene->r.cfra;
// bke::greasepencil::Layer &active_layer = *grease_pencil.get_active_layer();
// grease_pencil.get_editable_drawing_at()
bke::greasepencil::Layer &active_layer = *grease_pencil.get_active_layer();
/* If there is no drawing at the current frame and auto-key is off, then */
if (!active_layer.has_drawing_at(current_frame) && !blender::animrig::is_autokey_on(scene)) {
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil frame to draw on");
return OPERATOR_CANCELLED;
}
if (!grease_pencil.get_active_layer()->frames().contains(current_frame)) {
if (!blender::animrig::is_autokey_on(scene)) {
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil frame to draw on");
return OPERATOR_CANCELLED;
}
/* If auto-key is on and the drawing at the current frame starts before the current frame a new
* keyframe needs to be inserted. */
if (blender::animrig::is_autokey_on(scene) &&
active_layer.frame_key_at(current_frame) < current_frame)
{
const ToolSettings *ts = CTX_data_tool_settings(C);
bke::greasepencil::Layer &active_layer = *grease_pencil.get_active_layer();
if ((ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) != 0) {
/* For additive drawing, we duplicate the frame that's currently visible and insert it at the
* current frame. */
@@ -158,10 +161,12 @@ static int grease_pencil_stroke_invoke(bContext *C, wmOperator *op, const wmEven
active_layer, active_layer.frame_key_at(current_frame), current_frame, false);
}
else {
/* Otherwise we just insert a blank keyframe. */
/* Otherwise we just insert a blank keyframe at the current frame. */
grease_pencil.insert_blank_frame(active_layer, current_frame, 0, BEZT_KEYTYPE_KEYFRAME);
}
}
/* There should now always be a drawing at the current frame. */
BLI_assert(active_layer.has_drawing_at(current_frame));
op->customdata = paint_stroke_new(C,
op,