[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