[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22855] branches/blender2.5/blender/source /blender/editors: Grease Pencil: Toolbar Compatability Fixes

Joshua Leung aligorith at gmail.com
Sat Aug 29 03:54:13 CEST 2009


Revision: 22855
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22855
Author:   aligorith
Date:     2009-08-29 03:54:10 +0200 (Sat, 29 Aug 2009)

Log Message:
-----------
Grease Pencil: Toolbar Compatability Fixes

* When starting Grease Pencil from the toolbar, strokes are now started only when a click-drag begins. 

* Made the 'straight-lines' option an RNA property for the operator

* Added an exec() callback and relevant stroke-collection stuff so that interactive redo/changing settings can work. 
WARNING: this is highly unstable here - keeps crashing though I cannot determine the cause yet.

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/editors/gpencil/gpencil_paint.c
    branches/blender2.5/blender/source/blender/editors/space_view3d/view3d_ops.c

Modified: branches/blender2.5/blender/source/blender/editors/gpencil/gpencil_paint.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/gpencil/gpencil_paint.c	2009-08-29 00:41:14 UTC (rev 22854)
+++ branches/blender2.5/blender/source/blender/editors/gpencil/gpencil_paint.c	2009-08-29 01:54:10 UTC (rev 22855)
@@ -115,7 +115,8 @@
 
 /* values for tGPsdata->status */
 enum {
-	GP_STATUS_NORMAL = 0,	/* running normally */
+	GP_STATUS_IDLING = 0,	/* stroke isn't in progress yet */
+	GP_STATUS_PAINTING,		/* a stroke is in progress */
 	GP_STATUS_ERROR,		/* something wasn't correctly set up */
 	GP_STATUS_DONE			/* painting done */
 };
@@ -196,7 +197,7 @@
 	if (gpd->sbuffer_sflag & GP_STROKE_3DSPACE) {
 		View3D *v3d= p->sa->spacedata.first;
 		const short mx=mval[0], my=mval[1];
-		float *fp= give_cursor(p->scene, v3d); // XXX NULL could be v3d
+		float *fp= give_cursor(p->scene, v3d);
 		float dvec[3];
 		
 		/* Current method just converts each point in screen-coordinates to 
@@ -727,10 +728,19 @@
 		{
 			//View3D *v3d= curarea->spacedata.first;
 			
-			/* set current area */
+			/* set current area 
+			 *	- must verify that region data is 3D-view (and not something else)
+			 */
 			p->sa= curarea;
 			p->ar= ar;
 			
+			if (ar->regiondata == NULL) {
+				p->status= GP_STATUS_ERROR;
+				if (G.f & G_DEBUG)
+					printf("Error: 3D-View active region doesn't have any region data, so cannot be drawable \n");
+				return p;
+			}
+			
 #if 0 // XXX will this sort of antiquated stuff be restored?
 			/* check that gpencil data is allowed to be drawn */
 			if ((v3d->flag2 & V3D_DISPGP)==0) {
@@ -1002,8 +1012,8 @@
 static int gpencil_draw_init (bContext *C, wmOperator *op)
 {
 	tGPsdata *p;
-	wmWindow *win= CTX_wm_window(C);
 	int paintmode= RNA_enum_get(op->ptr, "mode");
+	int straightLines= RNA_boolean_get(op->ptr, "straight_lines");
 	
 	/* check context */
 	p= op->customdata= gp_session_initpaint(C);
@@ -1023,11 +1033,9 @@
 	/* radius for eraser circle is defined in userprefs now */
 	p->radius= U.gp_eraser;
 	
-	/* set cursor */
-	if (p->paintmode == GP_PAINTMODE_ERASER)
-		WM_cursor_modal(win, BC_CROSSCURSOR); // XXX need a better cursor
-	else
-		WM_cursor_modal(win, BC_PAINTBRUSHCURSOR);
+	/* set line-drawing settings (straight or freehand lines) */
+	if (straightLines)
+		p->flags |= GP_PAINTFLAG_STRAIGHTLINES;
 	
 	/* everything is now setup ok */
 	return 1;
@@ -1069,10 +1077,57 @@
 
 /* ------------------------------- */
 
+/* create a new stroke point at the point indicated by the painting context */
+static void gpencil_draw_apply (bContext *C, wmOperator *op, tGPsdata *p)
+{
+	/* handle drawing/erasing -> test for erasing first */
+	if (p->paintmode == GP_PAINTMODE_ERASER) {
+		/* do 'live' erasing now */
+		gp_stroke_doeraser(p);
+		
+		/* store used values */
+		p->mvalo[0]= p->mval[0];
+		p->mvalo[1]= p->mval[1];
+		p->opressure= p->pressure;
+	}
+	/* only add current point to buffer if mouse moved (even though we got an event, it might be just noise) */
+	else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) {
+		/* try to add point */
+		short ok= gp_stroke_addpoint(p, p->mval, p->pressure);
+		
+		/* handle errors while adding point */
+		if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) {
+			/* finish off old stroke */
+			gp_paint_strokeend(p);
+			
+			/* start a new stroke, starting from previous point */
+			gp_stroke_addpoint(p, p->mvalo, p->opressure);
+			ok= gp_stroke_addpoint(p, p->mval, p->pressure);
+		}
+		else if (ok == GP_STROKEADD_INVALID) {
+			/* the painting operation cannot continue... */
+			BKE_report(op->reports, RPT_ERROR, "Cannot paint stroke");
+			p->status = GP_STATUS_ERROR;
+			
+			if (G.f & G_DEBUG) 
+				printf("Error: Grease-Pencil Paint - Add Point Invalid \n");
+			// XXX break!
+		}
+		
+		/* store used values */
+		p->mvalo[0]= p->mval[0];
+		p->mvalo[1]= p->mval[1];
+		p->opressure= p->pressure;
+	}
+}
+
+/* handle draw event */
 static void gpencil_draw_apply_event (bContext *C, wmOperator *op, wmEvent *event)
 {
 	tGPsdata *p= op->customdata;
 	ARegion *ar= p->ar;
+	PointerRNA itemptr;
+	float mousef[2];
 	int tablet=0;
 
 	/* convert from window-space to area-space mouse coordintes */
@@ -1107,56 +1162,86 @@
 			return;
 	}
 	
+	/* fill in stroke data (not actually used directly by gpencil_draw_apply) */
+	RNA_collection_add(op->ptr, "stroke", &itemptr);
+
+	mousef[0]= p->mval[0];
+	mousef[1]= p->mval[1];
+	RNA_float_set_array(&itemptr, "mouse", mousef);
+	RNA_float_set(&itemptr, "pressure", p->pressure);
 	
-	/* handle drawing/erasing -> test for erasing first */
-	if (p->paintmode == GP_PAINTMODE_ERASER) {
-		/* do 'live' erasing now */
-		gp_stroke_doeraser(p);
-		
-		/* store used values */
-		p->mvalo[0]= p->mval[0];
-		p->mvalo[1]= p->mval[1];
-		p->opressure= p->pressure;
+	/* apply the current latest drawing point */
+	gpencil_draw_apply(C, op, p);
+	
+	/* force refresh */
+	WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work!
+}
+
+/* ------------------------------- */
+
+/* operator 'redo' (i.e. after changing some properties) */
+static int gpencil_draw_exec (bContext *C, wmOperator *op)
+{
+	tGPsdata *p = NULL;
+	
+	printf("GPencil - Starting Re-Drawing \n");
+	
+	/* try to initialise context data needed while drawing */
+	if (!gpencil_draw_init(C, op)) {
+		if (op->customdata) MEM_freeN(op->customdata);
+		printf("\tGP - no valid data \n");
+		return OPERATOR_CANCELLED;
 	}
-	/* only add current point to buffer if mouse moved (even though we got an event, it might be just noise) */
-	else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) {
-		/* try to add point */
-		short ok= gp_stroke_addpoint(p, p->mval, p->pressure);
+	else
+		p= op->customdata;
+	
+	printf("\tGP - Start redrawing stroke \n");
+	
+	/* loop over the stroke RNA elements recorded (i.e. progress of mouse movement),
+	 * setting the relevant values in context at each step, then applying
+	 */
+	RNA_BEGIN(op->ptr, itemptr, "stroke") 
+	{
+		float mousef[2];
 		
-		/* handle errors while adding point */
-		if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) {
-			/* finish off old stroke */
-			gp_paint_strokeend(p);
+		printf("\t\tGP - stroke elem \n");
+		
+		/* get relevant data for this point from stroke */
+		RNA_float_get_array(&itemptr, "mouse", mousef);
+		p->mval[0] = (short)mousef[0];
+		p->mval[1] = (short)mousef[1];
+		p->pressure= RNA_float_get(&itemptr, "pressure");
+		
+		/* if first run, set previous data too */
+		if (p->flags & GP_PAINTFLAG_FIRSTRUN) {
+			p->flags &= ~GP_PAINTFLAG_FIRSTRUN;
 			
-			/* start a new stroke, starting from previous point */
-			gp_stroke_addpoint(p, p->mvalo, p->opressure);
-			ok= gp_stroke_addpoint(p, p->mval, p->pressure);
+			p->mvalo[0]= p->mval[0];
+			p->mvalo[1]= p->mval[1];
+			p->opressure= p->pressure;
 		}
-		else if (ok == GP_STROKEADD_INVALID) {
-			/* the painting operation cannot continue... */
-			BKE_report(op->reports, RPT_ERROR, "Cannot paint stroke");
-			p->status = GP_STATUS_ERROR;
-			
-			if (G.f & G_DEBUG) 
-				printf("Error: Grease-Pencil Paint - Add Point Invalid \n");
-			// XXX break!
-		}
 		
-		/* store used values */
-		p->mvalo[0]= p->mval[0];
-		p->mvalo[1]= p->mval[1];
-		p->opressure= p->pressure;
+		/* apply this data as necessary now (as per usual) */
+		gpencil_draw_apply(C, op, p);
 	}
+	RNA_END;
 	
-	/* force refresh */
-	WM_event_add_notifier(C, NC_SCREEN|ND_GPENCIL|NA_EDITED, NULL); // XXX please work!
+	printf("\tGP - done \n");
+	
+	/* cleanup */
+	gpencil_draw_exit(C, op);
+	
+	/* done */
+	return OPERATOR_FINISHED;
 }
 
 /* ------------------------------- */
 
+/* start of interactive drawing part of operator */
 static int gpencil_draw_invoke (bContext *C, wmOperator *op, wmEvent *event)
 {
 	tGPsdata *p = NULL;
+	wmWindow *win= CTX_wm_window(C);
 	
 	printf("GPencil - Starting Drawing \n");
 	
@@ -1177,16 +1262,35 @@
 		// TODO: this involves mucking around with radial control, so we leave this for now..
 	}
 	
-	printf("\tGP - set first spot\n");
+	/* set cursor */
+	if (p->paintmode == GP_PAINTMODE_ERASER)
+		WM_cursor_modal(win, BC_CROSSCURSOR); // XXX need a better cursor
+	else
+		WM_cursor_modal(win, BC_PAINTBRUSHCURSOR);
 	
-	/* handle the initial drawing - i.e. for just doing a simple dot */
-	gpencil_draw_apply_event(C, op, event);
+	/* special hack: if there was an initial event, then we were invoked via a hotkey, and 
+	 * painting should start immediately. Otherwise, this was called from a toolbar, in which
+	 * case we should wait for the mouse to be clicked.
+	 */
+	if (event->type) {
+		/* hotkey invoked - start drawing */
+		printf("\tGP - set first spot\n");
+		p->status= GP_STATUS_PAINTING;
+		
+		/* handle the initial drawing - i.e. for just doing a simple dot */
+		gpencil_draw_apply_event(C, op, event);
+	}
+	else {
+		/* toolbar invoked - don't start drawing yet... */
+		printf("\tGP - hotkey invoked... waiting for click-drag\n");
+	}
 	
 	/* add a modal handler for this operator, so that we can then draw continuous strokes */
 	WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
 	return OPERATOR_RUNNING_MODAL;
 }
 
+/* events handling during interactive drawing part of operator */
 static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event)
 {
 	tGPsdata *p= op->customdata;
@@ -1198,25 +1302,35 @@
 		 * otherwise, carry on to mouse-move...
 		 */
 		case LEFTMOUSE:
-		case MIDDLEMOUSE:
 		case RIGHTMOUSE: 
-			if (event->val != KM_PRESS) {
+			/* if painting, end stroke */
+			if (p->status == GP_STATUS_PAINTING) {
+				/* basically, this should be mouse-button up */
 				printf("\t\tGP - end of stroke \n");
 				gpencil_draw_exit(C, op);
 				return OPERATOR_FINISHED;
 			}
+			else {
+				/* not painting, so start stroke (this should be mouse-button down) */
+				printf("\t\tGP - start stroke \n");
+				p->status= GP_STATUS_PAINTING;
+				/* no break now, since we should immediately start painting */
+			}
 		
-		/* moving mouse - assumed that mouse button is down */
+		/* moving mouse - assumed that mouse button is down if in painting status */
 		case MOUSEMOVE:
-			/* handle drawing event */
-			printf("\t\tGP - add point\n");
-			gpencil_draw_apply_event(C, op, event);
-			
-			/* finish painting operation if anything went wrong just now */
-			if (p->status == GP_STATUS_ERROR) {
-				printf("\t\t\tGP - error done! \n");

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list