[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15894] trunk/blender/source/blender: == Grease Pencil Eraser - Tweaks ==

Joshua Leung aligorith at gmail.com
Thu Jul 31 14:23:31 CEST 2008


Revision: 15894
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15894
Author:   aligorith
Date:     2008-07-31 14:23:29 +0200 (Thu, 31 Jul 2008)

Log Message:
-----------
== Grease Pencil Eraser - Tweaks ==

Improved accuracy of the eraser a bit. Now it does a boundbox test first before trying to erase strokes, which means that other (rather unrelated) strokes are less likely to be affected as well.

Modified Paths:
--------------
    trunk/blender/source/blender/include/BIF_editview.h
    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-07-31 12:23:09 UTC (rev 15893)
+++ trunk/blender/source/blender/include/BIF_editview.h	2008-07-31 12:23:29 UTC (rev 15894)
@@ -34,8 +34,10 @@
 struct Object;
 struct Camera;
 struct View3D;
+struct rcti;
 
 void	arrows_move_cursor(unsigned short event);
+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);
 void	borderselect(void);

Modified: trunk/blender/source/blender/src/editview.c
===================================================================
--- trunk/blender/source/blender/src/editview.c	2008-07-31 12:23:09 UTC (rev 15893)
+++ trunk/blender/source/blender/src/editview.c	2008-07-31 12:23:29 UTC (rev 15894)
@@ -371,7 +371,7 @@
 	}
 }
 
-static void lasso_select_boundbox(rcti *rect, short mcords[][2], short moves)
+void lasso_select_boundbox(rcti *rect, short mcords[][2], short moves)
 {
 	short a;
 	

Modified: trunk/blender/source/blender/src/gpencil.c
===================================================================
--- trunk/blender/source/blender/src/gpencil.c	2008-07-31 12:23:09 UTC (rev 15893)
+++ trunk/blender/source/blender/src/gpencil.c	2008-07-31 12:23:29 UTC (rev 15894)
@@ -48,6 +48,7 @@
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
 #include "DNA_userdef_types.h"
+#include "DNA_vec_types.h"
 #include "DNA_view3d_types.h"
 
 #include "BKE_global.h"
@@ -920,7 +921,6 @@
 	if (gpd->sbuffer_size >= GP_STROKE_BUFFER_MAX)
 		return GP_STROKEADD_OVERFLOW;
 	
-	
 	/* get pointer to destination point */
 	pt= ((tGPspoint *)(gpd->sbuffer) + gpd->sbuffer_size);
 	
@@ -1012,9 +1012,77 @@
 	return mcoords;
 }
 
-/* eraser tool evaluation per curve */
-static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short moves, bGPDframe *gpf, bGPDstroke *gps)
+/* eraser tool - remove segment from stroke/split stroke (after lasso inside) */
+static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i)
 {
+	bGPDspoint *pt_tmp= gps->points;
+	bGPDstroke *gsn = NULL;
+
+	/* if stroke only had two points, get rid of stroke */
+	if (gps->totpoints == 2) {
+		/* free stroke points, then stroke */
+		MEM_freeN(pt_tmp);
+		BLI_freelinkN(&gpf->strokes, gps);
+		
+		/* nothing left in stroke, so stop */
+		return 1;
+	}
+
+	/* if last segment, just remove segment from the stroke */
+	else if (i == gps->totpoints - 2) {
+		/* allocate new points array, and assign most of the old stroke there */
+		gps->totpoints--;
+		gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points");
+		memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*gps->totpoints);
+		
+		/* free temp buffer */
+		MEM_freeN(pt_tmp);
+		
+		/* nothing left in stroke, so stop */
+		return 1;
+	}
+
+	/* if first segment, just remove segment from the stroke */
+	else if (i == 0) {
+		/* allocate new points array, and assign most of the old stroke there */
+		gps->totpoints--;
+		gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points");
+		memcpy(gps->points, pt_tmp + 1, sizeof(bGPDspoint)*gps->totpoints);
+		
+		/* free temp buffer */
+		MEM_freeN(pt_tmp);
+		
+		/* no break here, as there might still be stuff to remove in this stroke */
+		return 0;
+	}
+
+	/* segment occurs in 'middle' of stroke, so split */
+	else {
+		/* duplicate stroke, and assign 'later' data to that stroke */
+		gsn= MEM_dupallocN(gps);
+		gsn->prev= gsn->next= NULL;
+		BLI_insertlinkafter(&gpf->strokes, gps, gsn);
+		
+		gsn->totpoints= gps->totpoints - i;
+		gsn->points= MEM_callocN(sizeof(bGPDspoint)*gsn->totpoints, "gp_stroke_points");
+		memcpy(gsn->points, pt_tmp + i, sizeof(bGPDspoint)*gsn->totpoints);
+		
+		/* adjust existing stroke  */
+		gps->totpoints= i;
+		gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points");
+		memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*i);
+		
+		/* free temp buffer */
+		MEM_freeN(pt_tmp);
+		
+		/* nothing left in stroke, so stop */
+		return 1;
+	}
+}
+
+/* eraser tool - evaluation per stroke */
+static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short moves, rcti *rect, bGPDframe *gpf, bGPDstroke *gps)
+{
 	bGPDspoint *pt1, *pt2;
 	short x0=0, y0=0, x1=0, y1=0;
 	short xyval[2];
@@ -1044,11 +1112,14 @@
 			y0= (gps->points->y / 1000 * p->sa->winy);
 		}
 		
-		/* only check if point is inside */
-		if (lasso_inside(mcoords, moves, x0, y0)) {
-			/* free stroke */
-			MEM_freeN(gps->points);
-			BLI_freelinkN(&gpf->strokes, gps);
+		/* do boundbox check first */
+		if (BLI_in_rcti(rect, x0, y0)) {
+			/* only check if point is inside */
+			if (lasso_inside(mcoords, moves, x0, y0)) {
+				/* free stroke */
+				MEM_freeN(gps->points);
+				BLI_freelinkN(&gpf->strokes, gps);
+			}
 		}
 	}
 	else {	
@@ -1083,74 +1154,18 @@
 				y1= (pt2->y / 1000 * p->sa->winy);
 			}
 			
-			/* check if point segment of stroke had anything to do with
-			 * eraser region  (either within stroke painted, or on its lines)
-			 * 	- this assumes that linewidth is irrelevant
-			 *	- handled using the lasso-select checking code
-			 */
-			if (lasso_inside_edge(mcoords, moves, x0, y0, x1, x1)) {
-				bGPDspoint *pt_tmp= gps->points;
-				bGPDstroke *gsn = NULL;
-				
-				/* if stroke only had two points, get rid of stroke */
-				if (gps->totpoints == 2) {
-					/* free stroke points, then stroke */
-					MEM_freeN(pt_tmp);
-					BLI_freelinkN(&gpf->strokes, gps);
-					
-					/* nothing left in stroke, so stop */
-					break;
+			/* check that point segment of the boundbox of the eraser stroke */
+			if (BLI_in_rcti(rect, x0, y0) || BLI_in_rcti(rect, x1, y1)) {
+				/* check if point segment of stroke had anything to do with
+				 * eraser region  (either within stroke painted, or on its lines)
+				 * 	- this assumes that linewidth is irrelevant
+				 *	- handled using the lasso-select checking code
+				 */
+				if (lasso_inside_edge(mcoords, moves, x0, y0, x1, x1)) {
+					/* if function returns true, break this loop (as no more point to check) */
+					if (gp_stroke_eraser_splitdel(gpf, gps, i))
+						break;
 				}
-				
-				/* if last segment, just remove segment from the stroke */
-				else if (i == gps->totpoints - 2) {
-					/* allocate new points array, and assign most of the old stroke there */
-					gps->totpoints--;
-					gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points");
-					memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*gps->totpoints);
-					
-					/* free temp buffer */
-					MEM_freeN(pt_tmp);
-					
-					/* nothing left in stroke, so stop */
-					break;
-				}
-				
-				/* if first segment, just remove segment from the stroke */
-				else if (i == 0) {
-					/* allocate new points array, and assign most of the old stroke there */
-					gps->totpoints--;
-					gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points");
-					memcpy(gps->points, pt_tmp + 1, sizeof(bGPDspoint)*gps->totpoints);
-					
-					/* free temp buffer */
-					MEM_freeN(pt_tmp);
-					
-					/* no break here, as there might still be stuff to remove in this stroke */
-				}
-				
-				/* segment occurs in 'middle' of stroke, so split */
-				else {
-					/* duplicate stroke, and assign 'later' data to that stroke */
-					gsn= MEM_dupallocN(gps);
-					gsn->prev= gsn->next= NULL;
-					BLI_insertlinkafter(&gpf->strokes, gps, gsn);
-					
-					gsn->totpoints= gps->totpoints - i;
-					gsn->points= MEM_callocN(sizeof(bGPDspoint)*gsn->totpoints, "gp_stroke_points");
-					memcpy(gsn->points, pt_tmp + i, sizeof(bGPDspoint)*gsn->totpoints);
-					
-					/* adjust existing stroke  */
-					gps->totpoints= i;
-					gps->points= MEM_callocN(sizeof(bGPDspoint)*gps->totpoints, "gp_stroke_points");
-					memcpy(gps->points, pt_tmp, sizeof(bGPDspoint)*i);
-					
-					/* free temp buffer */
-					MEM_freeN(pt_tmp);
-					
-					/* nothing left in stroke, so stop */
-					break;
-				}
 			}
 		}
 	}
@@ -1165,14 +1180,16 @@
 	bGPDframe *gpf= p->gpf;
 	bGPDstroke *gps, *gpn;
 	short (*mcoords)[2];
+	rcti rect;
 	
-	/* get buffer-stroke coordinates as shorts array */
+	/* 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);
 	
 	/* loop over strokes, checking segments for intersections */
 	for (gps= gpf->strokes.first; gps; gps= gpn) {
 		gpn= gps->next;
-		gp_stroke_eraser_dostroke(p, mcoords, gpd->sbuffer_size, gpf, gps);
+		gp_stroke_eraser_dostroke(p, mcoords, gpd->sbuffer_size, &rect, gpf, gps);
 	}
 	
 	/* free mcoords array */





More information about the Bf-blender-cvs mailing list