[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