[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [39960] trunk/blender/source/blender: Grease pencil: non-blocking sketch sessions

Sergey Sharybin g.ulairi at gmail.com
Tue Sep 6 09:59:20 CEST 2011


Revision: 39960
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=39960
Author:   nazgul
Date:     2011-09-06 07:59:18 +0000 (Tue, 06 Sep 2011)
Log Message:
-----------
Grease pencil: non-blocking sketch sessions

- Implement own undo stack for grease pencil, so now there'll be no keymaps conflicts.
- Supported redo's during sketch session.
- Get rid of flag stored in Globals -- use undo stack to check if grease pencil session is active.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_global.h
    trunk/blender/source/blender/editors/gpencil/CMakeLists.txt
    trunk/blender/source/blender/editors/gpencil/drawgpencil.c
    trunk/blender/source/blender/editors/gpencil/gpencil_intern.h
    trunk/blender/source/blender/editors/gpencil/gpencil_paint.c
    trunk/blender/source/blender/editors/include/ED_gpencil.h
    trunk/blender/source/blender/editors/util/undo.c

Added Paths:
-----------
    trunk/blender/source/blender/editors/gpencil/gpencil_undo.c

Modified: trunk/blender/source/blender/blenkernel/BKE_global.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_global.h	2011-09-06 07:08:20 UTC (rev 39959)
+++ trunk/blender/source/blender/blenkernel/BKE_global.h	2011-09-06 07:59:18 UTC (rev 39960)
@@ -111,7 +111,7 @@
 #define G_SCRIPT_OVERRIDE_PREF (1 << 14) /* when this flag is set ignore the userprefs */
 
 /* #define G_NOFROZEN	(1 << 17) also removed */
-#define G_GREASEPENCIL 	(1 << 17)
+/* #define G_GREASEPENCIL 	(1 << 17)   also removed */
 
 /* #define G_AUTOMATKEYS	(1 << 30)   also removed */
 

Modified: trunk/blender/source/blender/editors/gpencil/CMakeLists.txt
===================================================================
--- trunk/blender/source/blender/editors/gpencil/CMakeLists.txt	2011-09-06 07:08:20 UTC (rev 39959)
+++ trunk/blender/source/blender/editors/gpencil/CMakeLists.txt	2011-09-06 07:59:18 UTC (rev 39960)
@@ -42,6 +42,7 @@
 	gpencil_edit.c
 	gpencil_ops.c
 	gpencil_paint.c
+	gpencil_undo.c
 
 	gpencil_intern.h
 )

Modified: trunk/blender/source/blender/editors/gpencil/drawgpencil.c
===================================================================
--- trunk/blender/source/blender/editors/gpencil/drawgpencil.c	2011-09-06 07:08:20 UTC (rev 39959)
+++ trunk/blender/source/blender/editors/gpencil/drawgpencil.c	2011-09-06 07:59:18 UTC (rev 39960)
@@ -644,7 +644,7 @@
 		/* Check if may need to draw the active stroke cache, only if this layer is the active layer
 		 * that is being edited. (Stroke buffer is currently stored in gp-data)
 		 */
-		if ((G.f & G_GREASEPENCIL) && (gpl->flag & GP_LAYER_ACTIVE) &&
+		if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) &&
 			(gpf->flag & GP_FRAME_PAINT)) 
 		{
 			/* Buffer stroke needs to be drawn with a different linestyle to help differentiate them from normal strokes. */

Modified: trunk/blender/source/blender/editors/gpencil/gpencil_intern.h
===================================================================
--- trunk/blender/source/blender/editors/gpencil/gpencil_intern.h	2011-09-06 07:08:20 UTC (rev 39959)
+++ trunk/blender/source/blender/editors/gpencil/gpencil_intern.h	2011-09-06 07:59:18 UTC (rev 39960)
@@ -37,6 +37,7 @@
 /* ***************************************************** */
 /* Operator Defines */
 
+struct bGPdata;
 struct wmOperatorType;
 
 /* drawing ---------- */
@@ -61,7 +62,12 @@
 
 void GPENCIL_OT_convert(struct wmOperatorType *ot);
 
+/* undo stack ---------- */
 
+void gpencil_undo_init(struct bGPdata *gpd);
+void gpencil_undo_push(struct bGPdata *gpd);
+void gpencil_undo_finish(void);
+
 /******************************************************* */
 /* FILTERED ACTION DATA - TYPES  ---> XXX DEPRECEATED OLD ANIM SYSTEM CODE! */
 

Modified: trunk/blender/source/blender/editors/gpencil/gpencil_paint.c
===================================================================
--- trunk/blender/source/blender/editors/gpencil/gpencil_paint.c	2011-09-06 07:08:20 UTC (rev 39959)
+++ trunk/blender/source/blender/editors/gpencil/gpencil_paint.c	2011-09-06 07:59:18 UTC (rev 39960)
@@ -152,7 +152,7 @@
 		/* check if current context can support GPencil data */
 		if (gpencil_data_get_pointers(C, NULL) != NULL) {
 			/* check if Grease Pencil isn't already running */
-			if ((G.f & G_GREASEPENCIL) == 0)
+			if (ED_gpencil_session_active() == 0)
 				return 1;
 			else
 				CTX_wm_operator_poll_msg_set(C, "Grease Pencil operator is already active");
@@ -893,8 +893,10 @@
 	/* clear memory of buffer (or allocate it if starting a new session) */
 	if (gpd->sbuffer)
 		memset(gpd->sbuffer, 0, sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX);
-	else
+	else {
+		//printf("\t\tGP - allocate sbuffer\n");
 		gpd->sbuffer= MEM_callocN(sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
+	}
 	
 	/* reset indices */
 	gpd->sbuffer_size = 0;
@@ -1051,8 +1053,11 @@
 		p->gpd= *gpd_ptr;
 	}
 	
-	/* set edit flags - so that buffer will get drawn */
-	G.f |= G_GREASEPENCIL;
+	if(ED_gpencil_session_active()==0) {
+		/* initialize undo stack,
+		   also, existing undo stack would make buffer drawn */
+		gpencil_undo_init(p->gpd);
+	}
 	
 	/* clear out buffer (stored in gp-data), in case something contaminated it */
 	gp_session_validatebuffer(p);
@@ -1078,6 +1083,7 @@
 	
 	/* free stroke buffer */
 	if (gpd->sbuffer) {
+		//printf("\t\tGP - free sbuffer\n");
 		MEM_freeN(gpd->sbuffer);
 		gpd->sbuffer= NULL;
 	}
@@ -1247,7 +1253,8 @@
 static void gp_paint_cleanup (tGPsdata *p)
 {
 	/* finish off a stroke */
-	gp_paint_strokeend(p);
+	if(p->gpd)
+		gp_paint_strokeend(p);
 	
 	/* "unlock" frame */
 	if (p->gpf)
@@ -1260,8 +1267,8 @@
 {
 	tGPsdata *p= op->customdata;
 	
-	/* clear edit flags */
-	G.f &= ~G_GREASEPENCIL;
+	/* clear undo stack */
+	gpencil_undo_finish();
 	
 	/* restore cursor to indicate end of drawing */
 	WM_cursor_restore(CTX_wm_window(C));
@@ -1592,6 +1599,7 @@
 		//printf("\tGP - hotkey invoked... waiting for click-drag\n");
 	}
 	
+	WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL, NULL);
 	/* add a modal handler for this operator, so that we can then draw continuous strokes */
 	WM_event_add_modal_handler(C, op);
 	return OPERATOR_RUNNING_MODAL;
@@ -1609,16 +1617,60 @@
 	return 0;
 }
 
+static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
+{
+	tGPsdata *p= op->customdata;
+
+	/* we must check that we're still within the area that we're set up to work from
+	 * otherwise we could crash (see bug #20586)
+	 */
+	if (CTX_wm_area(C) != p->sa) {
+		printf("\t\t\tGP - wrong area execution abort! \n");
+		p->status= GP_STATUS_ERROR;
+	}
+
+	/* free pointer used by previous stroke */
+	if(p)
+		MEM_freeN(p);
+
+	//printf("\t\tGP - start stroke \n");
+
+	/* we may need to set up paint env again if we're resuming */
+	// XXX: watch it with the paintmode! in future, it'd be nice to allow changing paint-mode when in sketching-sessions
+	// XXX: with tablet events, we may event want to check for eraser here, for nicer tablet support
+
+	gpencil_draw_init(C, op);
+
+	p= op->customdata;
+
+	if(p->status != GP_STATUS_ERROR)
+		p->status= GP_STATUS_PAINTING;
+
+	return op->customdata;
+}
+
+static void gpencil_stroke_end(wmOperator *op)
+{
+	tGPsdata *p= op->customdata;
+
+	gp_paint_cleanup(p);
+
+	gpencil_undo_push(p->gpd);
+
+	gp_session_cleanup(p);
+
+	p->status= GP_STATUS_IDLING;
+
+	p->gpd= NULL;
+	p->gpl= NULL;
+	p->gpf= NULL;
+}
+
 /* events handling during interactive drawing part of operator */
 static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event)
 {
 	tGPsdata *p= op->customdata;
-	//int estate = OPERATOR_PASS_THROUGH; /* default exit state - not handled, so let others have a share of the pie */
-	/* currently, grease pencil conflicts with such operators as undo and set object mode
-	   which makes behavior of operator totally unpredictable and crash for some cases.
-	   the only way to solve this proper is to ger rid of pointers to data which can
-	   chage stored in operator custom data (sergey) */
-	int estate = OPERATOR_RUNNING_MODAL;
+	int estate = OPERATOR_PASS_THROUGH; /* default exit state - not handled, so let others have a share of the pie */
 	
 	// if (event->type == NDOF_MOTION)
 	//	return OPERATOR_PASS_THROUGH;
@@ -1652,11 +1704,13 @@
 			if (GPENCIL_SKETCH_SESSIONS_ON(p->scene)) {
 				/* end stroke only, and then wait to resume painting soon */
 				//printf("\t\tGP - end stroke only\n");
-				gp_paint_cleanup(p);
-				p->status= GP_STATUS_IDLING;
+				gpencil_stroke_end(op);
 				
 				/* we've just entered idling state, so this event was processed (but no others yet) */
 				estate = OPERATOR_RUNNING_MODAL;
+
+				/* stroke could be smoothed, send notifier to refresh screen */
+				ED_region_tag_redraw(p->ar);
 			}
 			else {
 				//printf("\t\tGP - end of stroke + op\n");
@@ -1664,35 +1718,19 @@
 				estate = OPERATOR_FINISHED;
 			}
 		}
-		else {
+		else if (event->val == KM_PRESS) {
 			/* not painting, so start stroke (this should be mouse-button down) */
 			
-			/* we must check that we're still within the area that we're set up to work from
-			 * otherwise we could crash (see bug #20586)
-			 */
-			if (CTX_wm_area(C) != p->sa) {
-				//printf("\t\t\tGP - wrong area execution abort! \n");
-				p->status= GP_STATUS_ERROR;
+			p= gpencil_stroke_begin(C, op);
+
+			if (p->status == GP_STATUS_ERROR) {
 				estate = OPERATOR_CANCELLED;
 			}
-			else {
-				//printf("\t\tGP - start stroke \n");
-				p->status= GP_STATUS_PAINTING;
-				
-				/* we may need to set up paint env again if we're resuming */
-				// XXX: watch it with the paintmode! in future, it'd be nice to allow changing paint-mode when in sketching-sessions
-				// XXX: with tablet events, we may event want to check for eraser here, for nicer tablet support
-				gp_paint_initstroke(p, p->paintmode);
-				
-				if (p->status == GP_STATUS_ERROR) {
-					estate = OPERATOR_CANCELLED;
-				}
-			}
+		} else {
+			p->status = GP_STATUS_IDLING;
 		}
 	}
 	
-	
-	
 	/* handle mode-specific events */
 	if (p->status == GP_STATUS_PAINTING) {
 		/* handle painting mouse-movements? */
@@ -1704,7 +1742,7 @@
 			
 			/* finish painting operation if anything went wrong just now */
 			if (p->status == GP_STATUS_ERROR) {
-				//printf("\t\t\t\tGP - add error done! \n");
+				printf("\t\t\t\tGP - add error done! \n");
 				estate = OPERATOR_CANCELLED;
 			}
 			else {
@@ -1721,28 +1759,6 @@
 			estate = OPERATOR_RUNNING_MODAL;
 		}
 	}
-	else if (p->status == GP_STATUS_IDLING) {
-		/* standard undo/redo shouldn't be allowed to execute or else it causes crashes, so catch it here */
-		// FIXME: this is a hardcoded hotkey that can't be changed
-		// TODO: catch redo as well, but how?
-		if (event->type == ZKEY && event->val == KM_RELEASE) {
-			/* oskey = cmd key on macs as they seem to use cmd-z for undo as well? */
-			if ((event->ctrl) || (event->oskey)) {
-				/* just delete last stroke, which will look like undo to the end user */
-				//printf("caught attempted undo event... deleting last stroke \n");
-				gpencil_frame_delete_laststroke(p->gpl, p->gpf);
-				/* undoing the last line can free p->gpf
-				 * note, could do this in a bit more of an elegant way then a search but it at least prevents a crash */
-				if(BLI_findindex(&p->gpl->frames, p->gpf) == -1) {
-					p->gpf= NULL;
-				}
-
-				/* event handled, so force refresh */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list