forked from bartvdbraak/blender
== 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
This commit is contained in:
parent
5e13055849
commit
1ed408e8c6
@ -40,6 +40,7 @@ void arrows_move_cursor(unsigned short event);
|
|||||||
void lasso_select_boundbox(struct rcti *rect, short mcords[][2], short moves);
|
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(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 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 borderselect(void);
|
||||||
void circle_select(void);
|
void circle_select(void);
|
||||||
void deselectall(void);
|
void deselectall(void);
|
||||||
|
@ -61,7 +61,7 @@ typedef struct bGPDstroke {
|
|||||||
#define GP_STROKE_2DSPACE (1<<1)
|
#define GP_STROKE_2DSPACE (1<<1)
|
||||||
/* stroke is in 2d-space (but with special 'image' scaling) */
|
/* stroke is in 2d-space (but with special 'image' scaling) */
|
||||||
#define GP_STROKE_2DIMAGE (1<<2)
|
#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)
|
#define GP_STROKE_ERASER (1<<15)
|
||||||
|
|
||||||
|
|
||||||
|
@ -323,6 +323,9 @@ enum {
|
|||||||
GP_DRAWDATA_ONLYI2D = (1<<3), /* only draw 'image' strokes */
|
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 ------ */
|
/* ----- Tool Buffer Drawing ------ */
|
||||||
|
|
||||||
/* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */
|
/* draw stroke defined in buffer (simple ogl lines/points for now, as dotted lines) */
|
||||||
@ -347,23 +350,13 @@ static void gp_draw_stroke_buffer (tGPspoint *points, int totpoints, short thick
|
|||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
else if (sflag & GP_STROKE_ERASER) {
|
else if (sflag & GP_STROKE_ERASER) {
|
||||||
/* draw stroke curve - just standard thickness */
|
/* don't draw stroke at all! */
|
||||||
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 {
|
else {
|
||||||
float oldpressure = 0.0f;
|
float oldpressure = 0.0f;
|
||||||
|
|
||||||
/* draw stroke curve */
|
/* draw stroke curve */
|
||||||
setlinestyle(2);
|
if (G.f & G_DEBUG) setlinestyle(2);
|
||||||
|
|
||||||
glBegin(GL_LINE_STRIP);
|
glBegin(GL_LINE_STRIP);
|
||||||
for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
|
for (i=0, pt=points; i < totpoints && pt; i++, pt++) {
|
||||||
@ -381,14 +374,14 @@ static void gp_draw_stroke_buffer (tGPspoint *points, int totpoints, short thick
|
|||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
setlinestyle(0);
|
if (G.f & G_DEBUG) setlinestyle(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----- Existing Strokes Drawing (3D and Point) ------ */
|
/* ----- Existing Strokes Drawing (3D and Point) ------ */
|
||||||
|
|
||||||
/* draw a given stroke - just a single dot (only one 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 */
|
/* draw point */
|
||||||
if (sflag & GP_STROKE_3DSPACE) {
|
if (sflag & GP_STROKE_3DSPACE) {
|
||||||
@ -396,18 +389,38 @@ static void gp_draw_stroke_point (bGPDspoint *points, short sflag, int winx, int
|
|||||||
glVertex3f(points->x, points->y, points->z);
|
glVertex3f(points->x, points->y, points->z);
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
else if (sflag & GP_STROKE_2DSPACE) {
|
|
||||||
glBegin(GL_POINTS);
|
|
||||||
glVertex2f(points->x, points->y);
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
const float x= (points->x / 1000 * winx);
|
float co[2];
|
||||||
const float y= (points->y / 1000 * winy);
|
|
||||||
|
|
||||||
glBegin(GL_POINTS);
|
/* get coordinates of point */
|
||||||
glVertex2f(x, y);
|
if (sflag & GP_STROKE_2DSPACE) {
|
||||||
glEnd();
|
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 @@ static void gp_draw_stroke_3d (bGPDspoint *points, int totpoints, short thicknes
|
|||||||
/* draw a given stroke in 2d */
|
/* 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)
|
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 is less than GP_DRAWTHICKNESS_SPECIAL, 'smooth' opengl lines look better */
|
||||||
if (thickness < 3) {
|
if (thickness < GP_DRAWTHICKNESS_SPECIAL) {
|
||||||
bGPDspoint *pt;
|
bGPDspoint *pt;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -671,7 +684,7 @@ static void gp_draw_strokes (bGPDframe *gpf, int winx, int winy, int dflag, shor
|
|||||||
|
|
||||||
/* check which stroke-drawer to use */
|
/* check which stroke-drawer to use */
|
||||||
if (gps->totpoints == 1)
|
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)
|
else if (dflag & GP_DRAWDATA_ONLY3D)
|
||||||
gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
|
gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
|
||||||
else if (gps->totpoints > 1)
|
else if (gps->totpoints > 1)
|
||||||
|
@ -1631,7 +1631,7 @@ void mouse_select(void)
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
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;
|
int radsq= rad*rad;
|
||||||
float v1[2], v2[2], v3[2];
|
float v1[2], v2[2], v3[2];
|
||||||
|
@ -707,6 +707,10 @@ typedef struct tGPsdata {
|
|||||||
|
|
||||||
short status; /* current status of painting */
|
short status; /* current status of painting */
|
||||||
short paintmode; /* mode for 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;
|
} tGPsdata;
|
||||||
|
|
||||||
/* values for tGPsdata->status */
|
/* values for tGPsdata->status */
|
||||||
@ -1037,30 +1041,6 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* --- 'Eraser' for 'Paint' Tool ------ */
|
/* --- '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) */
|
/* eraser tool - remove segment from stroke/split stroke (after lasso inside) */
|
||||||
static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i)
|
static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i)
|
||||||
@ -1130,8 +1110,20 @@ static short gp_stroke_eraser_splitdel (bGPDframe *gpf, bGPDstroke *gps, int i)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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 */
|
/* 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;
|
bGPDspoint *pt1, *pt2;
|
||||||
short x0=0, y0=0, x1=0, y1=0;
|
short x0=0, y0=0, x1=0, y1=0;
|
||||||
@ -1147,10 +1139,9 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo
|
|||||||
else if (gps->totpoints == 1) {
|
else if (gps->totpoints == 1) {
|
||||||
/* get coordinates */
|
/* get coordinates */
|
||||||
if (gps->flag & GP_STROKE_3DSPACE) {
|
if (gps->flag & GP_STROKE_3DSPACE) {
|
||||||
// FIXME: this may not be the correct correction
|
|
||||||
project_short(&gps->points->x, xyval);
|
project_short(&gps->points->x, xyval);
|
||||||
x0= xyval[0];
|
x0= xyval[0];
|
||||||
x1= xyval[1];
|
y0= xyval[1];
|
||||||
}
|
}
|
||||||
else if (gps->flag & GP_STROKE_2DSPACE) {
|
else if (gps->flag & GP_STROKE_2DSPACE) {
|
||||||
ipoco_to_areaco_noclip(p->v2d, &gps->points->x, xyval);
|
ipoco_to_areaco_noclip(p->v2d, &gps->points->x, xyval);
|
||||||
@ -1165,7 +1156,7 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo
|
|||||||
/* do boundbox check first */
|
/* do boundbox check first */
|
||||||
if (BLI_in_rcti(rect, x0, y0)) {
|
if (BLI_in_rcti(rect, x0, y0)) {
|
||||||
/* only check if point is inside */
|
/* 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 */
|
/* free stroke */
|
||||||
MEM_freeN(gps->points);
|
MEM_freeN(gps->points);
|
||||||
BLI_freelinkN(&gpf->strokes, gps);
|
BLI_freelinkN(&gpf->strokes, gps);
|
||||||
@ -1183,10 +1174,9 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo
|
|||||||
|
|
||||||
/* get coordinates */
|
/* get coordinates */
|
||||||
if (gps->flag & GP_STROKE_3DSPACE) {
|
if (gps->flag & GP_STROKE_3DSPACE) {
|
||||||
// FIXME: may not be correct correction
|
|
||||||
project_short(&gps->points->x, xyval);
|
project_short(&gps->points->x, xyval);
|
||||||
x0= xyval[0];
|
x0= xyval[0];
|
||||||
x1= xyval[1];
|
y0= xyval[1];
|
||||||
}
|
}
|
||||||
else if (gps->flag & GP_STROKE_2DSPACE) {
|
else if (gps->flag & GP_STROKE_2DSPACE) {
|
||||||
ipoco_to_areaco_noclip(p->v2d, &pt1->x, xyval);
|
ipoco_to_areaco_noclip(p->v2d, &pt1->x, xyval);
|
||||||
@ -1211,7 +1201,7 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo
|
|||||||
* - this assumes that linewidth is irrelevant
|
* - this assumes that linewidth is irrelevant
|
||||||
* - handled using the lasso-select checking code
|
* - 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 function returns true, break this loop (as no more point to check) */
|
||||||
if (gp_stroke_eraser_splitdel(gpf, gps, i))
|
if (gp_stroke_eraser_splitdel(gpf, gps, i))
|
||||||
break;
|
break;
|
||||||
@ -1226,24 +1216,21 @@ static void gp_stroke_eraser_dostroke (tGPsdata *p, short mcoords[][2], short mo
|
|||||||
/* erase strokes which fall under the eraser strokes */
|
/* erase strokes which fall under the eraser strokes */
|
||||||
static void gp_stroke_doeraser (tGPsdata *p)
|
static void gp_stroke_doeraser (tGPsdata *p)
|
||||||
{
|
{
|
||||||
bGPdata *gpd= p->gpd;
|
|
||||||
bGPDframe *gpf= p->gpf;
|
bGPDframe *gpf= p->gpf;
|
||||||
bGPDstroke *gps, *gpn;
|
bGPDstroke *gps, *gpn;
|
||||||
short (*mcoords)[2];
|
|
||||||
rcti rect;
|
rcti rect;
|
||||||
|
|
||||||
/* get buffer-stroke coordinates as shorts array, and then get bounding box */
|
/* rect is rectangle of eraser */
|
||||||
mcoords= gp_stroke_eraser_2mco(gpd);
|
rect.xmin= p->mval[0] - p->radius;
|
||||||
lasso_select_boundbox(&rect, mcoords, gpd->sbuffer_size);
|
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 */
|
/* loop over strokes, checking segments for intersections */
|
||||||
for (gps= gpf->strokes.first; gps; gps= gpn) {
|
for (gps= gpf->strokes.first; gps; gps= gpn) {
|
||||||
gpn= gps->next;
|
gpn= gps->next;
|
||||||
gp_stroke_eraser_dostroke(p, mcoords, gpd->sbuffer_size, &rect, gpf, gps);
|
gp_stroke_eraser_dostroke(p, p->mval, p->mvalo, p->radius, &rect, gpf, gps);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free mcoords array */
|
|
||||||
MEM_freeN(mcoords);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- 'Paint' Tool ------------ */
|
/* ---------- 'Paint' Tool ------------ */
|
||||||
@ -1308,8 +1295,7 @@ static void gp_paint_strokeend (tGPsdata *p)
|
|||||||
{
|
{
|
||||||
/* check if doing eraser or not */
|
/* check if doing eraser or not */
|
||||||
if (p->gpd->sbuffer_sflag & GP_STROKE_ERASER) {
|
if (p->gpd->sbuffer_sflag & GP_STROKE_ERASER) {
|
||||||
/* get rid of relevant sections of strokes */
|
/* don't do anything */
|
||||||
gp_stroke_doeraser(p);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* transfer stroke to frame */
|
/* transfer stroke to frame */
|
||||||
@ -1345,7 +1331,6 @@ static void gp_paint_cleanup (tGPsdata *p)
|
|||||||
short gpencil_paint (short mousebutton, short paintmode)
|
short gpencil_paint (short mousebutton, short paintmode)
|
||||||
{
|
{
|
||||||
tGPsdata p;
|
tGPsdata p;
|
||||||
short prevmval[2], mval[2];
|
|
||||||
float opressure, pressure;
|
float opressure, pressure;
|
||||||
short ok = GP_STROKEADD_NORMAL;
|
short ok = GP_STROKEADD_NORMAL;
|
||||||
|
|
||||||
@ -1365,31 +1350,51 @@ short gpencil_paint (short mousebutton, short paintmode)
|
|||||||
setcursor_space(p.sa->spacetype, CURSOR_VPAINT);
|
setcursor_space(p.sa->spacetype, CURSOR_VPAINT);
|
||||||
|
|
||||||
/* init drawing-device settings */
|
/* init drawing-device settings */
|
||||||
getmouseco_areawin(mval);
|
getmouseco_areawin(p.mval);
|
||||||
pressure = get_pressure();
|
pressure = get_pressure();
|
||||||
|
|
||||||
prevmval[0]= mval[0];
|
p.mvalo[0]= p.mval[0];
|
||||||
prevmval[1]= mval[1];
|
p.mvalo[1]= p.mval[1];
|
||||||
opressure= pressure;
|
opressure= pressure;
|
||||||
|
|
||||||
|
/* radius for eraser circle is thickness^2 */
|
||||||
|
p.radius= p.gpl->thickness * p.gpl->thickness;
|
||||||
|
|
||||||
|
/* start drawing eraser-circle (if applicable) */
|
||||||
|
if (paintmode == GP_PAINTMODE_ERASER)
|
||||||
|
draw_sel_circle(p.mval, NULL, p.radius, p.radius, 0); // draws frontbuffer, but sets backbuf again
|
||||||
|
|
||||||
/* only allow painting of single 'dots' if:
|
/* only allow painting of single 'dots' if:
|
||||||
* - pressure is not excessive (as it can be on some windows tablets)
|
* - pressure is not excessive (as it can be on some windows tablets)
|
||||||
* - draw-mode for active datablock is turned on
|
* - draw-mode for active datablock is turned on
|
||||||
|
* - not erasing
|
||||||
*/
|
*/
|
||||||
if (!(pressure >= 0.99f) || (p.gpd->flag & GP_DATA_EDITPAINT)) {
|
if (paintmode != GP_PAINTMODE_ERASER) {
|
||||||
gp_stroke_addpoint(&p, mval, pressure);
|
if (!(pressure >= 0.99f) || (p.gpd->flag & GP_DATA_EDITPAINT)) {
|
||||||
|
gp_stroke_addpoint(&p, p.mval, pressure);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* paint loop */
|
/* paint loop */
|
||||||
do {
|
do {
|
||||||
/* get current user input */
|
/* get current user input */
|
||||||
getmouseco_areawin(mval);
|
getmouseco_areawin(p.mval);
|
||||||
pressure = get_pressure();
|
pressure = get_pressure();
|
||||||
|
|
||||||
/* only add current point to buffer if mouse moved (otherwise wait until it does) */
|
/* only add current point to buffer if mouse moved (otherwise wait until it does) */
|
||||||
if (gp_stroke_filtermval(&p, mval, prevmval)) {
|
if (paintmode == GP_PAINTMODE_ERASER) {
|
||||||
|
/* do 'live' erasing now */
|
||||||
|
gp_stroke_doeraser(&p);
|
||||||
|
|
||||||
|
draw_sel_circle(p.mval, p.mvalo, p.radius, p.radius, 0);
|
||||||
|
force_draw(0);
|
||||||
|
|
||||||
|
p.mvalo[0]= p.mval[0];
|
||||||
|
p.mvalo[1]= p.mval[1];
|
||||||
|
}
|
||||||
|
else if (gp_stroke_filtermval(&p, p.mval, p.mvalo)) {
|
||||||
/* try to add point */
|
/* try to add point */
|
||||||
ok= gp_stroke_addpoint(&p, mval, pressure);
|
ok= gp_stroke_addpoint(&p, p.mval, pressure);
|
||||||
|
|
||||||
/* handle errors while adding point */
|
/* handle errors while adding point */
|
||||||
if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) {
|
if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) {
|
||||||
@ -1397,8 +1402,8 @@ short gpencil_paint (short mousebutton, short paintmode)
|
|||||||
gp_paint_strokeend(&p);
|
gp_paint_strokeend(&p);
|
||||||
|
|
||||||
/* start a new stroke, starting from previous point */
|
/* start a new stroke, starting from previous point */
|
||||||
gp_stroke_addpoint(&p, prevmval, opressure);
|
gp_stroke_addpoint(&p, p.mvalo, opressure);
|
||||||
ok= gp_stroke_addpoint(&p, mval, pressure);
|
ok= gp_stroke_addpoint(&p, p.mval, pressure);
|
||||||
}
|
}
|
||||||
else if (ok == GP_STROKEADD_INVALID) {
|
else if (ok == GP_STROKEADD_INVALID) {
|
||||||
/* the painting operation cannot continue... */
|
/* the painting operation cannot continue... */
|
||||||
@ -1411,8 +1416,8 @@ short gpencil_paint (short mousebutton, short paintmode)
|
|||||||
}
|
}
|
||||||
force_draw(0);
|
force_draw(0);
|
||||||
|
|
||||||
prevmval[0]= mval[0];
|
p.mvalo[0]= p.mval[0];
|
||||||
prevmval[1]= mval[1];
|
p.mvalo[1]= p.mval[1];
|
||||||
opressure= pressure;
|
opressure= pressure;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1430,8 +1435,10 @@ short gpencil_paint (short mousebutton, short paintmode)
|
|||||||
setcursor_space(p.sa->spacetype, CURSOR_STD);
|
setcursor_space(p.sa->spacetype, CURSOR_STD);
|
||||||
|
|
||||||
/* check size of buffer before cleanup, to determine if anything happened here */
|
/* check size of buffer before cleanup, to determine if anything happened here */
|
||||||
if (paintmode == GP_PAINTMODE_ERASER)
|
if (paintmode == GP_PAINTMODE_ERASER) {
|
||||||
ok= (p.gpd->sbuffer_size > 1);
|
ok= 1; // fixme
|
||||||
|
draw_sel_circle(NULL, p.mvalo, 0, p.radius, 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ok= p.gpd->sbuffer_size;
|
ok= p.gpd->sbuffer_size;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user