GPencil: Implement Autokey button for Draw/Edit and Sculpt mode
Now, if the Autokey is not enabled, a new frame is not created and it is used the last active one. If no active frame, a message is displayed and the operation is canceled. This is a common request for 2D artists. Also, grease pencil was not working as Blender does in other areas. Reviewed By: pepeland Differential Revision: https://developer.blender.org/D10557
This commit is contained in:
parent
1668f883fb
commit
6a662ffda8
|
@ -58,6 +58,7 @@ def load_handler(dummy):
|
|||
# Grease pencil object
|
||||
scene = bpy.data.scenes[0]
|
||||
if scene:
|
||||
scene.tool_settings.use_keyframe_insert_auto = True
|
||||
for ob in scene.objects:
|
||||
if ob.type == 'GPENCIL':
|
||||
gpd = ob.data
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "BKE_screen.h"
|
||||
|
||||
#include "ED_gpencil.h"
|
||||
#include "ED_keyframing.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_space_api.h"
|
||||
#include "ED_view3d.h"
|
||||
|
@ -542,12 +543,18 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
|
|||
if (gpl == tgpf->gpl) {
|
||||
if ((gpl->actframe == NULL) || (gpl->actframe->framenum != tgpf->active_cfra)) {
|
||||
short add_frame_mode;
|
||||
if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) {
|
||||
add_frame_mode = GP_GETFRAME_ADD_COPY;
|
||||
if (IS_AUTOKEY_ON(tgpf->scene)) {
|
||||
if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) {
|
||||
add_frame_mode = GP_GETFRAME_ADD_COPY;
|
||||
}
|
||||
else {
|
||||
add_frame_mode = GP_GETFRAME_ADD_NEW;
|
||||
}
|
||||
}
|
||||
else {
|
||||
add_frame_mode = GP_GETFRAME_ADD_NEW;
|
||||
add_frame_mode = GP_GETFRAME_USE_PREV;
|
||||
}
|
||||
|
||||
BKE_gpencil_layer_frame_get(gpl, tgpf->active_cfra, add_frame_mode);
|
||||
}
|
||||
}
|
||||
|
@ -1456,7 +1463,10 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
|
|||
tgpf->done = true;
|
||||
|
||||
/* Get frame or create a new one. */
|
||||
tgpf->gpf = BKE_gpencil_layer_frame_get(tgpf->gpl, tgpf->active_cfra, GP_GETFRAME_ADD_NEW);
|
||||
tgpf->gpf = BKE_gpencil_layer_frame_get(tgpf->gpl,
|
||||
tgpf->active_cfra,
|
||||
IS_AUTOKEY_ON(tgpf->scene) ? GP_GETFRAME_ADD_NEW :
|
||||
GP_GETFRAME_USE_PREV);
|
||||
|
||||
/* Set frame as selected. */
|
||||
tgpf->gpf->flag |= GP_FRAME_SELECT;
|
||||
|
@ -2064,6 +2074,12 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
estate = OPERATOR_CANCELLED;
|
||||
break;
|
||||
case LEFTMOUSE:
|
||||
if (!IS_AUTOKEY_ON(tgpf->scene) && (!is_multiedit) && (tgpf->gpl->actframe == NULL)) {
|
||||
BKE_report(op->reports, RPT_INFO, "No available frame for creating stroke");
|
||||
estate = OPERATOR_CANCELLED;
|
||||
break;
|
||||
}
|
||||
|
||||
/* first time the event is not enabled to show help lines. */
|
||||
if ((tgpf->oldkey != -1) || (!help_lines)) {
|
||||
ARegion *region = BKE_area_find_region_xy(
|
||||
|
@ -2088,17 +2104,24 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
gpencil_stroke_convertcoords_tpoint(
|
||||
tgpf->scene, tgpf->region, tgpf->ob, &point2D, NULL, &pt->x);
|
||||
|
||||
/* If not multiframe and there is no frame in CFRA for the active layer, create
|
||||
* a new frame before to make the hash function can find something. */
|
||||
if (!is_multiedit) {
|
||||
tgpf->gpf = BKE_gpencil_layer_frame_get(
|
||||
tgpf->gpl, tgpf->active_cfra, GP_GETFRAME_ADD_NEW);
|
||||
tgpf->gpf->flag |= GP_FRAME_SELECT;
|
||||
}
|
||||
|
||||
/* Hash of selected frames.*/
|
||||
GHash *frame_list = BLI_ghash_int_new_ex(__func__, 64);
|
||||
BKE_gpencil_frame_selected_hash(tgpf->gpd, frame_list);
|
||||
|
||||
/* If not multiframe and there is no frame in CFRA for the active layer, create
|
||||
* a new frame. */
|
||||
if (!is_multiedit) {
|
||||
tgpf->gpf = BKE_gpencil_layer_frame_get(
|
||||
tgpf->gpl,
|
||||
tgpf->active_cfra,
|
||||
IS_AUTOKEY_ON(tgpf->scene) ? GP_GETFRAME_ADD_NEW : GP_GETFRAME_USE_PREV);
|
||||
tgpf->gpf->flag |= GP_FRAME_SELECT;
|
||||
|
||||
BLI_ghash_insert(
|
||||
frame_list, POINTER_FROM_INT(tgpf->active_cfra), tgpf->gpl->actframe);
|
||||
}
|
||||
else {
|
||||
BKE_gpencil_frame_selected_hash(tgpf->gpd, frame_list);
|
||||
}
|
||||
|
||||
/* Loop all frames. */
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
|
||||
#include "ED_clip.h"
|
||||
#include "ED_gpencil.h"
|
||||
#include "ED_keyframing.h"
|
||||
#include "ED_object.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_view3d.h"
|
||||
|
@ -2155,6 +2156,10 @@ static void gpencil_paint_initstroke(tGPsdata *p,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!IS_AUTOKEY_ON(scene) && (gpl->actframe == NULL)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Add a new frame if needed (and based off the active frame,
|
||||
* as we need some existing strokes to erase)
|
||||
*
|
||||
|
@ -2164,7 +2169,8 @@ static void gpencil_paint_initstroke(tGPsdata *p,
|
|||
*/
|
||||
if (gpl->actframe && gpl->actframe->strokes.first) {
|
||||
if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) {
|
||||
gpl->actframe = BKE_gpencil_layer_frame_get(gpl, CFRA, GP_GETFRAME_ADD_COPY);
|
||||
short frame_mode = IS_AUTOKEY_ON(scene) ? GP_GETFRAME_ADD_COPY : GP_GETFRAME_USE_PREV;
|
||||
gpl->actframe = BKE_gpencil_layer_frame_get(gpl, CFRA, frame_mode);
|
||||
}
|
||||
has_layer_to_erase = true;
|
||||
break;
|
||||
|
@ -2187,11 +2193,16 @@ static void gpencil_paint_initstroke(tGPsdata *p,
|
|||
/* Drawing Modes - Add a new frame if needed on the active layer */
|
||||
short add_frame_mode;
|
||||
|
||||
if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) {
|
||||
add_frame_mode = GP_GETFRAME_ADD_COPY;
|
||||
if (IS_AUTOKEY_ON(scene)) {
|
||||
if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) {
|
||||
add_frame_mode = GP_GETFRAME_ADD_COPY;
|
||||
}
|
||||
else {
|
||||
add_frame_mode = GP_GETFRAME_ADD_NEW;
|
||||
}
|
||||
}
|
||||
else {
|
||||
add_frame_mode = GP_GETFRAME_ADD_NEW;
|
||||
add_frame_mode = GP_GETFRAME_USE_PREV;
|
||||
}
|
||||
|
||||
bool need_tag = p->gpl->actframe == NULL;
|
||||
|
@ -2206,6 +2217,10 @@ static void gpencil_paint_initstroke(tGPsdata *p,
|
|||
if (G.debug & G_DEBUG) {
|
||||
printf("Error: No frame created (gpencil_paint_init)\n");
|
||||
}
|
||||
if (!IS_AUTOKEY_ON(scene)) {
|
||||
BKE_report(p->reports, RPT_INFO, "No available frame for creating stroke");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
p->gpf->flag |= GP_FRAME_PAINT;
|
||||
|
@ -2469,6 +2484,8 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
return 0;
|
||||
}
|
||||
|
||||
p->reports = op->reports;
|
||||
|
||||
/* init painting data */
|
||||
gpencil_paint_initstroke(p, paintmode, CTX_data_ensure_evaluated_depsgraph(C));
|
||||
if (p->status == GP_STATUS_ERROR) {
|
||||
|
@ -2483,8 +2500,6 @@ static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
p->keymodifier = -1;
|
||||
}
|
||||
|
||||
p->reports = op->reports;
|
||||
|
||||
/* everything is now setup ok */
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
#include "RNA_enum_types.h"
|
||||
|
||||
#include "ED_gpencil.h"
|
||||
#include "ED_keyframing.h"
|
||||
#include "ED_object.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_space_api.h"
|
||||
|
@ -1253,9 +1254,18 @@ static void gpencil_primitive_init(bContext *C, wmOperator *op)
|
|||
static int gpencil_primitive_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
bGPdata *gpd = CTX_data_gpencil_data(C);
|
||||
tGPDprimitive *tgpi = NULL;
|
||||
|
||||
if (!IS_AUTOKEY_ON(scene)) {
|
||||
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
|
||||
if ((gpl == NULL) || (gpl->actframe == NULL)) {
|
||||
BKE_report(op->reports, RPT_INFO, "No available frame for creating stroke");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize operator runtime data */
|
||||
gpencil_primitive_init(C, op);
|
||||
tgpi = op->customdata;
|
||||
|
@ -1310,11 +1320,16 @@ static void gpencil_primitive_interaction_end(bContext *C,
|
|||
|
||||
/* insert keyframes as required... */
|
||||
short add_frame_mode;
|
||||
if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) {
|
||||
add_frame_mode = GP_GETFRAME_ADD_COPY;
|
||||
if (IS_AUTOKEY_ON(tgpi->scene)) {
|
||||
if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) {
|
||||
add_frame_mode = GP_GETFRAME_ADD_COPY;
|
||||
}
|
||||
else {
|
||||
add_frame_mode = GP_GETFRAME_ADD_NEW;
|
||||
}
|
||||
}
|
||||
else {
|
||||
add_frame_mode = GP_GETFRAME_ADD_NEW;
|
||||
add_frame_mode = GP_GETFRAME_USE_PREV;
|
||||
}
|
||||
|
||||
bool need_tag = tgpi->gpl->actframe == NULL;
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
#include "UI_view2d.h"
|
||||
|
||||
#include "ED_gpencil.h"
|
||||
#include "ED_keyframing.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
|
@ -1019,7 +1020,11 @@ static void gpencil_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
|
|||
if (gpl == NULL) {
|
||||
gpl = CTX_data_active_gpencil_layer(C);
|
||||
}
|
||||
bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, CFRA, GP_GETFRAME_ADD_NEW);
|
||||
bGPDframe *gpf = BKE_gpencil_layer_frame_get(
|
||||
gpl, CFRA, IS_AUTOKEY_ON(scene) ? GP_GETFRAME_ADD_NEW : GP_GETFRAME_USE_PREV);
|
||||
if (gpf == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Make a new stroke */
|
||||
new_stroke = BKE_gpencil_stroke_duplicate(gps, true, true);
|
||||
|
@ -1334,6 +1339,10 @@ static void gpencil_sculpt_brush_init_stroke(bContext *C, tGP_BrushEditData *gso
|
|||
|
||||
/* go through each layer, and ensure that we've got a valid frame to use */
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
if (!IS_AUTOKEY_ON(scene) && (gpl->actframe == NULL)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* only editable and visible layers are considered */
|
||||
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
|
||||
bGPDframe *gpf = gpl->actframe;
|
||||
|
@ -1343,7 +1352,7 @@ static void gpencil_sculpt_brush_init_stroke(bContext *C, tGP_BrushEditData *gso
|
|||
* - This is useful when animating as it saves that "uh-oh" moment when you realize you've
|
||||
* spent too much time editing the wrong frame.
|
||||
*/
|
||||
if (gpf->framenum != cfra) {
|
||||
if ((IS_AUTOKEY_ON(scene)) && (gpf->framenum != cfra)) {
|
||||
BKE_gpencil_frame_addcopy(gpl, cfra);
|
||||
/* Need tag to recalculate evaluated data to avoid crashes. */
|
||||
DEG_id_tag_update(&gso->gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "BKE_gpencil_geom.h"
|
||||
|
||||
#include "ED_gpencil.h"
|
||||
#include "ED_keyframing.h"
|
||||
|
||||
#include "transform.h"
|
||||
#include "transform_convert.h"
|
||||
|
@ -114,6 +115,7 @@ static void createTransGPencil_curves(bContext *C,
|
|||
#define SEL_F3 (1 << 2)
|
||||
|
||||
View3D *v3d = t->view;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
const bool handle_only_selected_visible = (v3d->overlay.handle_display == CURVE_HANDLE_SELECTED);
|
||||
const bool handle_all_visible = (v3d->overlay.handle_display == CURVE_HANDLE_ALL);
|
||||
|
||||
|
@ -230,7 +232,9 @@ static void createTransGPencil_curves(bContext *C,
|
|||
}
|
||||
|
||||
if ((gpf->framenum != cfra) && (!is_multiedit)) {
|
||||
gpf = BKE_gpencil_frame_addcopy(gpl, cfra);
|
||||
if (IS_AUTOKEY_ON(scene)) {
|
||||
gpf = BKE_gpencil_frame_addcopy(gpl, cfra);
|
||||
}
|
||||
/* in some weird situations (framelock enabled) return NULL */
|
||||
if (gpf == NULL) {
|
||||
continue;
|
||||
|
@ -405,6 +409,7 @@ static void createTransGPencil_strokes(bContext *C,
|
|||
const bool is_prop_edit_connected,
|
||||
const bool is_scale_thickness)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
TransData *td = NULL;
|
||||
float mtx[3][3], smtx[3][3];
|
||||
|
||||
|
@ -517,7 +522,9 @@ static void createTransGPencil_strokes(bContext *C,
|
|||
* spent too much time editing the wrong frame...
|
||||
*/
|
||||
if ((gpf->framenum != cfra) && (!is_multiedit)) {
|
||||
gpf = BKE_gpencil_frame_addcopy(gpl, cfra);
|
||||
if (IS_AUTOKEY_ON(scene)) {
|
||||
gpf = BKE_gpencil_frame_addcopy(gpl, cfra);
|
||||
}
|
||||
/* in some weird situations (framelock enabled) return NULL */
|
||||
if (gpf == NULL) {
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue