[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15878] trunk/blender/source/blender: == Grease Pencil - Eraser (First Draft) ==

Joshua Leung aligorith at gmail.com
Wed Jul 30 11:07:56 CEST 2008


Revision: 15878
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15878
Author:   aligorith
Date:     2008-07-30 11:07:56 +0200 (Wed, 30 Jul 2008)

Log Message:
-----------
== Grease Pencil - Eraser (First Draft) ==

This commit introduces the ability to erase strokes. Admittedly, the code for this is not totally stable yet, and doesn't always produce optimum results. I'm committing now for backup purposes.

It currently uses the lasso code to check whether segments of the strokes (a segment occurs between two recorded points) occur inside a region defined by the 'eraser' stroke, or any intersections it makes with the 'eraser' stroke.

There are multiple ways to erase strokes:
* With 'Draw Mode' on, use RMB-drag to erase
* With a tablet, use the 'eraser' end of the stylus
* Hold the Alt Key, and use the 'selection' mouse-button (i.e. LMB if mouse-button swapping is on, RMB otherwise) to erase. For this one, this is necessary to avoid overriding the view-rotation hotkey combo for 2-button mice!

Todo:
* 3d-strokes are not correctly mapped back to screen-space for sampling yet
* Drawing of eraser strokes is still not distinctive enough
* After running a few times, may cause stack corruption/segfaults, so be careful!


== Bugfixes ==
* Grease-Pencil Onion-Skinning works again. Onionskining was being supplied the wrong frames, and the alpha factor was still the old one used for 0-255 ranged colour values

Modified Paths:
--------------
    trunk/blender/source/blender/include/BDR_gpencil.h
    trunk/blender/source/blender/include/BIF_editview.h
    trunk/blender/source/blender/makesdna/DNA_gpencil_types.h
    trunk/blender/source/blender/src/drawgpencil.c
    trunk/blender/source/blender/src/editview.c
    trunk/blender/source/blender/src/gpencil.c

Modified: trunk/blender/source/blender/include/BDR_gpencil.h
===================================================================
--- trunk/blender/source/blender/include/BDR_gpencil.h	2008-07-30 01:51:40 UTC (rev 15877)
+++ trunk/blender/source/blender/include/BDR_gpencil.h	2008-07-30 09:07:56 UTC (rev 15878)
@@ -38,6 +38,15 @@
 struct bGPDlayer;
 struct bGPDframe;
 
+/* ------------- Grease-Pencil Helpers -------------- */
+
+/* Temporary 'Stroke Point' data */
+typedef struct tGPspoint {
+	short x, y;				/* x and y coordinates of cursor (in relative to area) */
+	float xf, yf;			/* same as x and y, but as floats */
+	float pressure;			/* pressure of tablet at this point */
+} tGPspoint;
+
 /* ------------ Grease-Pencil API ------------------ */
 
 void free_gpencil_strokes(struct bGPDframe *gpf);

Modified: trunk/blender/source/blender/include/BIF_editview.h
===================================================================
--- trunk/blender/source/blender/include/BIF_editview.h	2008-07-30 01:51:40 UTC (rev 15877)
+++ trunk/blender/source/blender/include/BIF_editview.h	2008-07-30 09:07:56 UTC (rev 15878)
@@ -37,6 +37,7 @@
 
 void	arrows_move_cursor(unsigned short event);
 int		lasso_inside(short mcords[][2], short moves, short sx, short sy);
+int 	lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1);
 void	borderselect(void);
 void	circle_select(void);
 void	deselectall(void);

Modified: trunk/blender/source/blender/makesdna/DNA_gpencil_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_gpencil_types.h	2008-07-30 01:51:40 UTC (rev 15877)
+++ trunk/blender/source/blender/makesdna/DNA_gpencil_types.h	2008-07-30 09:07:56 UTC (rev 15878)
@@ -125,7 +125,7 @@
 	 */
 	short sbuffer_size;			/* number of elements currently in cache */
 	short sbuffer_sflag;		/* flags for stroke that cache represents */
-	bGPDspoint *sbuffer;		/* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */
+	void *sbuffer;				/* stroke buffer (can hold GP_STROKE_BUFFER_MAX) */
 } bGPdata;
 
 /* bGPdata->flag */

Modified: trunk/blender/source/blender/src/drawgpencil.c
===================================================================
--- trunk/blender/source/blender/src/drawgpencil.c	2008-07-30 01:51:40 UTC (rev 15877)
+++ trunk/blender/source/blender/src/drawgpencil.c	2008-07-30 09:07:56 UTC (rev 15878)
@@ -280,11 +280,15 @@
 		
 		/* show override lmb-clicks button + painting lock */
 		uiBlockBeginAlign(block);
-			uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 130, 20, &gpd->flag, 0, 0, 0, 0, "Interpret LMB-click as new strokes (same as holding Shift-Key per stroke)");
-			
-			uiBlockSetCol(block, TH_BUT_SETTING);
-				uiDefIconButBitI(block, ICONTOG, GP_DATA_LMBPLOCK, B_REDR, ICON_UNLOCKED,	300, 225, 20, 20, &gpd->flag, 0.0, 0.0, 0, 0, "Painting cannot occur with Shift-LMB (when making selections)");
-			uiBlockSetCol(block, TH_AUTO);
+			if ((gpd->flag & GP_DATA_EDITPAINT)==0) {
+				uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 130, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes");
+				
+				uiBlockSetCol(block, TH_BUT_SETTING);
+					uiDefIconButBitI(block, ICONTOG, GP_DATA_LMBPLOCK, B_REDR, ICON_UNLOCKED,	300, 225, 20, 20, &gpd->flag, 0.0, 0.0, 0, 0, "Painting cannot occur with Shift-LMB (when making selections)");
+				uiBlockSetCol(block, TH_AUTO);
+			}
+			else
+				uiDefButBitI(block, TOG, GP_DATA_EDITPAINT, B_REDR, "Draw Mode", 170, 225, 150, 20, &gpd->flag, 0, 0, 0, 0, "Interpret click-drag as new strokes");
 		uiBlockEndAlign(block);
 		
 		/* 'view align' button (naming depends on context) */
@@ -313,6 +317,66 @@
 	GP_DRAWDATA_ONLYV2D		= (1<<2),	/* only draw 'canvas' strokes */
 };
 
+/* draw stroke in buffer */
+static void gp_draw_stroke_buffer (tGPspoint *points, int totpoints, short thickness, short dflag, short sflag)
+{
+	tGPspoint *pt;
+	int i;
+	
+	/* error checking */
+	if ((points == NULL) || (totpoints <= 0))
+		return;
+	
+	/* check if buffer can be drawn */
+	if (dflag & (GP_DRAWDATA_ONLY3D|GP_DRAWDATA_ONLYV2D))
+		return;
+	
+	/* if drawing a single point, draw it larger */	
+	if (totpoints == 1) {		
+		/* draw point */
+		glBegin(GL_POINTS);
+			glVertex2f(points->x, points->y);
+		glEnd();
+	}
+	else if (sflag & GP_STROKE_ERASER) {
+		/* draw stroke curve - just standard thickness */
+		setlinestyle(4);
+		glLineWidth(1.0f);
+		
+		glBegin(GL_LINE_STRIP);
+		for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
+			glVertex2f(pt->x, pt->y);
+		}
+		glEnd();
+		
+		setlinestyle(0);
+	}
+	else {
+		float oldpressure = 0.0f;
+		
+		/* draw stroke curve */
+		setlinestyle(2);
+		
+		glBegin(GL_LINE_STRIP);
+		for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
+			if (fabs(pt->pressure - oldpressure) > 0.2f) {
+				glEnd();
+				glLineWidth(pt->pressure * thickness);
+				glBegin(GL_LINE_STRIP);
+				
+				glVertex2f(pt->x, pt->y);
+				
+				oldpressure = pt->pressure;
+			}
+			else
+				glVertex2f(pt->x, pt->y);
+		}
+		glEnd();
+		
+		setlinestyle(0);
+	}
+}
+
 /* draw a given stroke */
 static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, short debug, int winx, int winy)
 {
@@ -489,8 +553,8 @@
 					/* check if frame is drawable */
 					if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
 						/* alpha decreases with distance from curframe index */
-						tcolor[3] = color[3] - (i * 0.7);
-						gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
+						tcolor[3] = color[3] - (i/gpl->gstep);
+						gp_draw_strokes(gf, winx, winy, dflag, debug, lthick, tcolor);
 					}
 					else 
 						break;
@@ -501,8 +565,8 @@
 					/* check if frame is drawable */
 					if ((gf->framenum - gpf->framenum) <= gpl->gstep) {
 						/* alpha decreases with distance from curframe index */
-						tcolor[3] = color[3] - (i * 0.7);
-						gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
+						tcolor[3] = color[3] - (i/gpl->gstep);
+						gp_draw_strokes(gf, winx, winy, dflag, debug, lthick, tcolor);
 					}
 					else 
 						break;
@@ -515,12 +579,12 @@
 				/* draw the strokes for the ghost frames (at half of the alpha set by user) */
 				if (gpf->prev) {
 					tcolor[3] = (color[3] / 7);
-					gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
+					gp_draw_strokes(gpf->prev, winx, winy, dflag, debug, lthick, tcolor);
 				}
 				
 				if (gpf->next) {
 					tcolor[3] = (color[3] / 4);
-					gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
+					gp_draw_strokes(gpf->next, winx, winy, dflag, debug, lthick, tcolor);
 				}
 				
 				/* restore alpha */
@@ -533,15 +597,13 @@
 		gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
 		
 		/* Check if may need to draw the active stroke cache, only if this layer is the active layer
-		 * that is being edited. (Stroke cache is currently stored in gp-data)
+		 * that is being edited. (Stroke buffer is currently stored in gp-data)
 		 */
 		if ((G.f & G_GREASEPENCIL) && (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. */
-			setlinestyle(2);
-			gp_draw_stroke(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag, debug, winx, winy);
-			setlinestyle(0);
+			gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag);
 		}
 	}
 	

Modified: trunk/blender/source/blender/src/editview.c
===================================================================
--- trunk/blender/source/blender/src/editview.c	2008-07-30 01:51:40 UTC (rev 15877)
+++ trunk/blender/source/blender/src/editview.c	2008-07-30 09:07:56 UTC (rev 15878)
@@ -298,7 +298,7 @@
 }
 
 /* edge version for lasso select. we assume boundbox check was done */
-static int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1)
+int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1)
 {
 	short v1[2], v2[2];
 	int a;

Modified: trunk/blender/source/blender/src/gpencil.c
===================================================================
--- trunk/blender/source/blender/src/gpencil.c	2008-07-30 01:51:40 UTC (rev 15877)
+++ trunk/blender/source/blender/src/gpencil.c	2008-07-30 09:07:56 UTC (rev 15878)
@@ -57,6 +57,7 @@
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
 #include "BIF_butspace.h"
+#include "BIF_editview.h"
 #include "BIF_graphics.h"
 #include "BIF_interface.h"
 #include "BIF_mywindow.h"
@@ -683,7 +684,7 @@
 	bGPDframe *gpf;		/* frame we're working on */
 	
 	short status;		/* current status of painting */
-	short paintmode;	/* mode for painting (L_MOUSE or R_MOUSE for now) */
+	short paintmode;	/* mode for painting */
 } tGPsdata;
 
 /* values for tGPsdata->status */
@@ -693,6 +694,12 @@
 	GP_STATUS_DONE			/* painting done */
 };
 
+/* values for tGPsdata->paintmode */
+enum {
+	GP_PAINTMODE_DRAW = 0,
+	GP_PAINTMODE_ERASER
+};
+
 /* Return flags for adding points to stroke buffer */
 enum {
 	GP_STROKEADD_INVALID	= -2,		/* error occurred - insufficient info to do so */
@@ -710,9 +717,9 @@
 	
 	/* clear memory of buffer (or allocate it if starting a new session) */
 	if (gpd->sbuffer)
-		memset(gpd->sbuffer, 0, sizeof(bGPDspoint)*GP_STROKE_BUFFER_MAX);
+		memset(gpd->sbuffer, 0, sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX);
 	else
-		gpd->sbuffer= MEM_callocN(sizeof(bGPDspoint)*GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
+		gpd->sbuffer= MEM_callocN(sizeof(tGPspoint)*GP_STROKE_BUFFER_MAX, "gp_session_strokebuffer");
 	
 	/* reset indices */
 	gpd->sbuffer_size = 0;
@@ -850,6 +857,25 @@
 	gpd->sbuffer_sflag= 0;
 }
 
+/* check if the current mouse position is suitable for adding a new point */
+static short gp_stroke_filtermval (tGPsdata *p, short mval[2], short pmval[2])
+{
+	short dx= abs(mval[0] - pmval[0]);
+	short dy= abs(mval[1] - pmval[1]);
+	
+	/* check if mouse moved at least certain distance on both axes (best case) */
+	if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX))
+		return 1;
+	
+	/* check if the distance since the last point is significant enough */
+	else if (sqrt(dx*dx + dy*dy) > MIN_EUCLIDEAN_PX)
+		return 1;
+	
+	/* mouse 'didn't move' */
+	else
+		return 0;
+}
+
 /* convert screen-coordinates to buffer-coordinates */

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list