[Bf-blender-cvs] [2c17844] GPencil_Editing_Stage3: GP Sculpt: Sculpting on a frame without an existing key will create a new one
Joshua Leung
noreply at git.blender.org
Fri Jul 24 17:10:58 CEST 2015
Commit: 2c178440e3f9a8953af047a83732a25fbb210c7d
Author: Joshua Leung
Date: Sat Jul 25 02:00:22 2015 +1200
Branches: GPencil_Editing_Stage3
https://developer.blender.org/rB2c178440e3f9a8953af047a83732a25fbb210c7d
GP Sculpt: Sculpting on a frame without an existing key will create a new one
Just like with the transform tools, if you start trying to sculpt strokes on a frame
where no gpframe/drawings exist, a new gpframe will now be created. This makes it
easier to use the sculpt tools for animating, as all you need to do is to start
animating a sketch is to jump to a frame and start sculpting.
The grab tool in particular works quite well for this sort of workflow. It appears
to be particularly handy when doing breakdowns and/or straight-ahead animation, as
well as for doing smaller tweaks.
===================================================================
M source/blender/editors/gpencil/gpencil_brush.c
===================================================================
diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c
index f8060b0..b097006 100644
--- a/source/blender/editors/gpencil/gpencil_brush.c
+++ b/source/blender/editors/gpencil/gpencil_brush.c
@@ -90,6 +90,9 @@ typedef struct tGP_BrushEditData {
ScrArea *sa;
ARegion *ar;
+ /* Current GPencil datablock */
+ bGPdata *gpd;
+
/* Brush Settings */
GP_BrushEdit_Settings *settings;
GP_EditBrush_Data *brush;
@@ -107,6 +110,9 @@ typedef struct tGP_BrushEditData {
/* Start of new sculpt stroke */
bool first;
+ /* Current frame */
+ int cfra;
+
/* Brush Runtime Data: */
/* - position and pressure
@@ -705,9 +711,13 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
gso->brush_type = gso->settings->brushtype;
+
gso->is_painting = false;
gso->first = true;
+ gso->gpd = ED_gpencil_data_get_active(C);
+ gso->cfra = INT_MAX; /* NOTE: So that first stroke will get handled in init_stroke() */
+
gso->scene = scene;
gso->sa = CTX_wm_area(C);
@@ -773,6 +783,81 @@ static int gpsculpt_brush_poll(bContext *C)
return CTX_DATA_COUNT(C, editable_gpencil_strokes) != 0;
}
+/* Init Sculpt Stroke ---------------------------------- */
+
+static void gpsculpt_brush_init_stroke(tGP_BrushEditData *gso)
+{
+ Scene *scene = gso->scene;
+ bGPdata *gpd = gso->gpd;
+ bGPDlayer *gpl;
+ int cfra = CFRA;
+
+ /* only try to add a new frame if this is the first stroke, or the frame has changed */
+ if ((gpd == NULL) || (cfra == gso->cfra))
+ return;
+
+ /* go through each layer, and ensure that */
+ for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ /* only editable and visible layers are considered */
+ if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0 &&
+ (gpl->actframe != NULL))
+ {
+ bGPDframe *gpf = gpl->actframe;
+
+ /* Make a new frame to work on if the layer's frame and the current scene frame don't match up
+ * - 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...
+ */
+ // XXX: should this be allowed when framelock is enabled?
+ // XXX: the logic below should be deduplicated, as the transform conversion code also does it
+ if (gpf->framenum != cfra) {
+ bGPDframe *new_frame = gpencil_frame_duplicate(gpf);
+ bGPDframe *gf;
+ bool found = false;
+
+ /* Find frame to insert it before */
+ for (gf = gpf->next; gf; gf = gf->next) {
+ if (gf->framenum > cfra) {
+ /* Add it here */
+ BLI_insertlinkbefore(&gpl->frames, gf, new_frame);
+
+ found = true;
+ break;
+ }
+ else if (gf->framenum == cfra) {
+ /* This only happens when we're editing with framelock on...
+ * - Delete the new frame and don't do anything else here...
+ */
+ //printf("GP Sculpt init stroke - Copy aborted for frame %d -> %d\n", gpf->framenum, gf->framenum);
+ free_gpencil_strokes(new_frame);
+ MEM_freeN(new_frame);
+ new_frame = NULL;
+
+ found = true;
+ break;
+ }
+ }
+
+ if (found == false) {
+ /* Add new frame to the end */
+ BLI_addtail(&gpl->frames, new_frame);
+ }
+
+ /* Edit the new frame instead, if it did get created + added */
+ if (new_frame) {
+ // TODO: tag this one as being "newly created" so that we can remove it if the edit is cancelled
+ new_frame->framenum = cfra;
+
+ gpl->actframe = gpf = new_frame;
+ }
+ }
+ }
+ }
+
+ /* save off new current frame, so that next update works fine */
+ gso->cfra = cfra;
+}
+
/* Apply ----------------------------------------------- */
/* Apply brush operation to points in this stroke */
@@ -1147,6 +1232,7 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
gso->is_painting = true;
gso->first = true;
+ gpsculpt_brush_init_stroke(gso);
gpsculpt_brush_apply_event(C, op, event);
break;
@@ -1197,6 +1283,13 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
redraw_region = true;
break;
+ /* Change Frame - Allowed */
+ case LEFTARROWKEY:
+ case RIGHTARROWKEY:
+ case UPARROWKEY:
+ case DOWNARROWKEY:
+ return OPERATOR_PASS_THROUGH;
+
/* Unhandled event */
default:
break;
More information about the Bf-blender-cvs
mailing list