[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16244] trunk/blender/source/blender: == Grease Pencil - Drawing + Eraser Improvements ==

Joshua Leung aligorith at gmail.com
Mon Aug 25 08:22:25 CEST 2008


Revision: 16244
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16244
Author:   aligorith
Date:     2008-08-25 08:22:21 +0200 (Mon, 25 Aug 2008)

Log Message:
-----------
== Grease Pencil - Drawing + Eraser Improvements ==

Drawing Improvements:
* Single 'dots' now draw rounded
* Strokes being drawn are drawn 'solid' instead of as dotted lines

Eraser:
* Now operates interactively, so no more wait to see if stuff was erased
* An influence circle is now drawn - the radius of this is defined as the thickness^2

Modified Paths:
--------------
    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/BIF_editview.h
===================================================================
--- trunk/blender/source/blender/include/BIF_editview.h	2008-08-24 21:14:07 UTC (rev 16243)
+++ trunk/blender/source/blender/include/BIF_editview.h	2008-08-25 06:22:21 UTC (rev 16244)
@@ -40,6 +40,7 @@
 void 	lasso_select_boundbox(struct rcti *rect, short mcords[][2], short moves);
 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);
+int 	edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2);
 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-08-24 21:14:07 UTC (rev 16243)
+++ trunk/blender/source/blender/makesdna/DNA_gpencil_types.h	2008-08-25 06:22:21 UTC (rev 16244)
@@ -61,7 +61,7 @@
 #define GP_STROKE_2DSPACE		(1<<1)
 	/* stroke is in 2d-space (but with special 'image' scaling) */
 #define GP_STROKE_2DIMAGE		(1<<2)
-	/* stroke is an "eraser" stroke */
+	/* only for use with stroke-buffer (while drawing eraser) */
 #define GP_STROKE_ERASER		(1<<15)
 
 

Modified: trunk/blender/source/blender/src/drawgpencil.c
===================================================================
--- trunk/blender/source/blender/src/drawgpencil.c	2008-08-24 21:14:07 UTC (rev 16243)
+++ trunk/blender/source/blender/src/drawgpencil.c	2008-08-25 06:22:21 UTC (rev 16244)
@@ -323,6 +323,9 @@
 	GP_DRAWDATA_ONLYI2D		= (1<<3),	/* only draw 'image' strokes */
 };
 
+/* thickness above which we should use special drawing */
+#define GP_DRAWTHICKNESS_SPECIAL 	3
+
 /* ----- Tool Buffer Drawing ------ */
 
 /* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */
@@ -347,23 +350,13 @@
 		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);
+		/* don't draw stroke at all! */
 	}
 	else {
 		float oldpressure = 0.0f;
 		
 		/* draw stroke curve */
-		setlinestyle(2);
+		if (G.f & G_DEBUG) setlinestyle(2);
 		
 		glBegin(GL_LINE_STRIP);
 		for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
@@ -381,14 +374,14 @@
 		}
 		glEnd();
 		
-		setlinestyle(0);
+		if (G.f & G_DEBUG) setlinestyle(0);
 	}
 }
 
 /* ----- Existing Strokes Drawing (3D and Point) ------ */
 
 /* draw a given stroke - just a single dot (only one point) */
-static void gp_draw_stroke_point (bGPDspoint *points, short sflag, int winx, int winy)
+static void gp_draw_stroke_point (bGPDspoint *points, short thickness, short sflag, int winx, int winy)
 {
 	/* draw point */
 	if (sflag & GP_STROKE_3DSPACE) {
@@ -396,18 +389,38 @@
 			glVertex3f(points->x, points->y, points->z);
 		glEnd();
 	}
-	else if (sflag & GP_STROKE_2DSPACE) {
-		glBegin(GL_POINTS);
-			glVertex2f(points->x, points->y);
-		glEnd();
-	}
 	else {
-		const float x= (points->x / 1000 * winx);
-		const float y= (points->y / 1000 * winy);
+		float co[2];
 		
-		glBegin(GL_POINTS);
-			glVertex2f(x, y);
-		glEnd();
+		/* get coordinates of point */
+		if (sflag & GP_STROKE_2DSPACE) {
+			co[0]= points->x;
+			co[1]= points->y;
+		}
+		else {
+			co[0]= (points->x / 1000 * winx);
+			co[1]= (points->y / 1000 * winy);
+		}
+		
+		/* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, simple opengl point will do */
+		if (thickness < GP_DRAWTHICKNESS_SPECIAL) {
+			glBegin(GL_POINTS);
+				glVertex2fv(co);
+			glEnd();
+		}
+		else {
+			/* draw filled circle as is done in circf (but without the matrix push/pops which screwed things up) */
+			GLUquadricObj *qobj = gluNewQuadric(); 
+			
+			gluQuadricDrawStyle(qobj, GLU_FILL); 
+			
+			/* need to translate drawing position, but must reset after too! */
+			glTranslatef(co[0],  co[1], 0.); 
+			gluDisk( qobj, 0.0,  thickness, 32, 1); 
+			glTranslatef(-co[0],  -co[1], 0.);
+			
+			gluDeleteQuadric(qobj);
+		}
 	}
 }
 
@@ -449,8 +462,8 @@
 /* draw a given stroke in 2d */
 static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, short dflag, short sflag, short debug, int winx, int winy)
 {	
-	/* if thickness is less than 3, 'smooth' opengl lines look better */
-	if (thickness < 3) {
+	/* if thickness is less than GP_DRAWTHICKNESS_SPECIAL, 'smooth' opengl lines look better */
+	if (thickness < GP_DRAWTHICKNESS_SPECIAL) {
 		bGPDspoint *pt;
 		int i;
 		
@@ -671,7 +684,7 @@
 		
 		/* check which stroke-drawer to use */
 		if (gps->totpoints == 1)
-			gp_draw_stroke_point(gps->points, gps->flag, winx, winy);
+			gp_draw_stroke_point(gps->points, lthick, gps->flag, winx, winy);
 		else if (dflag & GP_DRAWDATA_ONLY3D)
 			gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
 		else if (gps->totpoints > 1)	

Modified: trunk/blender/source/blender/src/editview.c
===================================================================
--- trunk/blender/source/blender/src/editview.c	2008-08-24 21:14:07 UTC (rev 16243)
+++ trunk/blender/source/blender/src/editview.c	2008-08-25 06:22:21 UTC (rev 16244)
@@ -1631,7 +1631,7 @@
 
 /* ------------------------------------------------------------------------- */
 
-static int edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2)
+int edge_inside_circle(short centx, short centy, short rad, short x1, short y1, short x2, short y2)
 {
 	int radsq= rad*rad;
 	float v1[2], v2[2], v3[2];

Modified: trunk/blender/source/blender/src/gpencil.c
===================================================================
--- trunk/blender/source/blender/src/gpencil.c	2008-08-24 21:14:07 UTC (rev 16243)
+++ trunk/blender/source/blender/src/gpencil.c	2008-08-25 06:22:21 UTC (rev 16244)
@@ -707,6 +707,10 @@
 	
 	short status;		/* current status of painting */
 	short paintmode;	/* mode for painting */
+	
+	short mval[2];		/* current mouse-position */
+	short mvalo[2];		/* previous recorded mouse-position */
+	short radius;		/* radius of influence for eraser */
 } tGPsdata;
 
 /* values for tGPsdata->status */
@@ -1037,31 +1041,7 @@
 }
 
 /* --- 'Eraser' for 'Paint' Tool ------ */
-/* User should draw 'circles' around the parts of the sketches they wish to 
- * delete instead of drawing squiggles over existing lines. This should be 
- * easier to manage than if it was done otherwise.
- */
 
-/* convert gp-buffer stroke into mouse-coordinates array */
-static short (*gp_stroke_eraser_2mco (bGPdata *gpd))[2]
-{
-	tGPspoint *pt;
-	short (*mcoords)[2]; 
-	int i;
-	
-	/* allocate memory for coordinates array */
-	mcoords= MEM_mallocN(sizeof(*mcoords)*gpd->sbuffer_size,"gp_buf_mcords");
-	
-	/* copy coordinates */
-	for (pt=gpd->sbuffer, i=0; i < gpd->sbuffer_size; i++, pt++) {
-		mcoords[i][0]= pt->x;
-		mcoords[i][1]= pt->y;
-	}
-	
-	/* return */
-	return mcoords;
-}
-
 /* eraser tool - remove segment from stroke/split stroke (after lasso inside) */
 static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i)
 {
@@ -1130,8 +1110,20 @@
 	}
 }
 
+/* eraser tool - check if part of stroke occurs within last segment drawn by eraser */
+static short gp_stroke_eraser_strokeinside (short mval[], short mvalo[], short rad, short x0, short y0, short x1, short y1)
+{
+	/* step 1: check if within the radius for the new one */
+		/* simple within-radius check */
+	if (edge_inside_circle(mval[0], mval[1], rad, x0, y0, x1, y1))
+		return 1;
+	
+	/* step 2: check if within the quad formed between the two eraser coords */
+	return 0;
+} 
+
 /* eraser tool - evaluation per stroke */
-static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short moves, rcti *rect, bGPDframe *gpf, bGPDstroke *gps)
+static void gp_stroke_eraser_dostroke (tGPsdata *p, short mval[], short mvalo[], short rad, rcti *rect, bGPDframe *gpf, bGPDstroke *gps)
 {
 	bGPDspoint *pt1, *pt2;
 	short x0=0, y0=0, x1=0, y1=0;
@@ -1147,10 +1139,9 @@
 	else if (gps->totpoints == 1) {
 		/* get coordinates */
 		if (gps->flag & GP_STROKE_3DSPACE) {
-			// FIXME: this may not be the correct correction
 			project_short(&gps->points->x, xyval);
 			x0= xyval[0];
-			x1= xyval[1];
+			y0= xyval[1];
 		}
 		else if (gps->flag & GP_STROKE_2DSPACE) {			
 			ipoco_to_areaco_noclip(p->v2d, &gps->points->x, xyval);
@@ -1165,7 +1156,7 @@
 		/* do boundbox check first */
 		if (BLI_in_rcti(rect, x0, y0)) {
 			/* only check if point is inside */
-			if (lasso_inside(mcoords, moves, x0, y0)) {
+			if ( ((x0-mval[0])*(x0-mval[0]) + (y0-mval[1])*(y0-mval[1])) <= rad*rad ) {
 				/* free stroke */
 				MEM_freeN(gps->points);
 				BLI_freelinkN(&gpf->strokes, gps);
@@ -1183,10 +1174,9 @@
 			
 			/* get coordinates */
 			if (gps->flag & GP_STROKE_3DSPACE) {
-				// FIXME: may not be correct correction
 				project_short(&gps->points->x, xyval);
 				x0= xyval[0];
-				x1= xyval[1];
+				y0= xyval[1];
 			}
 			else if (gps->flag & GP_STROKE_2DSPACE) {
 				ipoco_to_areaco_noclip(p->v2d, &pt1->x, xyval);
@@ -1211,7 +1201,7 @@
 				 * 	- this assumes that linewidth is irrelevant
 				 *	- handled using the lasso-select checking code
 				 */
-				if (lasso_inside_edge(mcoords, moves, x0, y0, x1, x1)) {
+				if (gp_stroke_eraser_strokeinside(mval, mvalo, rad, x0, y0, x1, y1)) {
 					/* if function returns true, break this loop (as no more point to check) */
 					if (gp_stroke_eraser_splitdel(gpf, gps, i))
 						break;
@@ -1226,24 +1216,21 @@
 /* erase strokes which fall under the eraser strokes */
 static void gp_stroke_doeraser (tGPsdata *p)
 {
-	bGPdata *gpd= p->gpd;
 	bGPDframe *gpf= p->gpf;
 	bGPDstroke *gps, *gpn;
-	short (*mcoords)[2];
 	rcti rect;
 	
-	/* get buffer-stroke coordinates as shorts array, and then get bounding box */
-	mcoords= gp_stroke_eraser_2mco(gpd);
-	lasso_select_boundbox(&rect, mcoords, gpd->sbuffer_size);
+	/* rect is rectangle of eraser */
+	rect.xmin= p->mval[0] - p->radius;
+	rect.ymin= p->mval[1] - p->radius;
+	rect.xmax= p->mval[0] + p->radius;
+	rect.ymax= p->mval[1] + p->radius;
 	
 	/* loop over strokes, checking segments for intersections */
 	for (gps= gpf->strokes.first; gps; gps= gpn) {
 		gpn= gps->next;

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list