Grease Pencil - Backend work:
Just preparation work for an eraser tool (as well as the code of a failed attempt at an implementation).
This commit is contained in:
@@ -69,6 +69,6 @@ void gpencil_delete_operation(short mode);
|
||||
void gpencil_delete_menu(void);
|
||||
|
||||
//short gpencil_paint(short mousebutton);
|
||||
short gpencil_do_paint(struct ScrArea *sa);
|
||||
short gpencil_do_paint(struct ScrArea *sa, short mousebutton);
|
||||
|
||||
#endif /* BDR_GPENCIL_H */
|
||||
|
||||
@@ -59,6 +59,8 @@ typedef struct bGPDstroke {
|
||||
#define GP_STROKE_3DSPACE (1<<0)
|
||||
/* stroke is in 2d-space */
|
||||
#define GP_STROKE_2DSPACE (1<<1)
|
||||
/* stroke is an "eraser" stroke */
|
||||
#define GP_STROKE_ERASER (1<<2)
|
||||
|
||||
|
||||
/* Grease-Pencil Annotations - 'Frame'
|
||||
|
||||
@@ -415,6 +415,45 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness,
|
||||
}
|
||||
}
|
||||
|
||||
/* draw a set of strokes */
|
||||
static void gp_draw_strokes (bGPDframe *gpf, int winx, int winy, int dflag, short debug,
|
||||
short lthick, float color[4])
|
||||
{
|
||||
bGPDstroke *gps;
|
||||
|
||||
/* set color first (may need to reset it again later too) */
|
||||
glColor4f(color[0], color[1], color[2], color[3]);
|
||||
|
||||
for (gps= gpf->strokes.first; gps; gps= gps->next) {
|
||||
/* handle 'eraser' strokes differently */
|
||||
if (gps->flag & GP_STROKE_ERASER) {
|
||||
// FIXME: this method is a failed experiment
|
||||
#if 0
|
||||
/* draw stroke twice, first time with 'white' to set a mask to invert
|
||||
* contents of framebuffer, then second-time the same again but to restore
|
||||
* the contents
|
||||
*/
|
||||
glEnable(GL_COLOR_LOGIC_OP);
|
||||
glLogicOp(GL_XOR);
|
||||
|
||||
glColor4f(1, 1, 1, 1); /* white */
|
||||
|
||||
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, 0, winx, winy);
|
||||
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, 0, winx, winy);
|
||||
|
||||
glDisable(GL_COLOR_LOGIC_OP);
|
||||
|
||||
/* reset color for drawing next stroke */
|
||||
glColor4f(color[0], color[1], color[2], color[3]);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* just draw the stroke once */
|
||||
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* draw grease-pencil datablock */
|
||||
static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
|
||||
{
|
||||
@@ -430,11 +469,10 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
|
||||
/* loop over layers, drawing them */
|
||||
for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
|
||||
bGPDframe *gpf;
|
||||
bGPDstroke *gps;
|
||||
|
||||
short debug = (gpl->flag & GP_LAYER_DRAWDEBUG) ? 1 : 0;
|
||||
short lthick= gpl->thickness;
|
||||
float color[4];
|
||||
float color[4], tcolor[4];
|
||||
|
||||
/* don't draw layer if hidden */
|
||||
if (gpl->flag & GP_LAYER_HIDE)
|
||||
@@ -452,6 +490,7 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
|
||||
/* set color, stroke thickness, and point size */
|
||||
glLineWidth(lthick);
|
||||
QUATCOPY(color, gpl->color); // just for copying 4 array elements
|
||||
QUATCOPY(tcolor, gpl->color); // additional copy of color (for ghosting)
|
||||
glColor4f(color[0], color[1], color[2], color[3]);
|
||||
glPointSize(gpl->thickness + 2);
|
||||
|
||||
@@ -467,11 +506,8 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
|
||||
/* check if frame is drawable */
|
||||
if ((gpf->framenum - gf->framenum) <= gpl->gstep) {
|
||||
/* alpha decreases with distance from curframe index */
|
||||
glColor4f(color[0], color[1], color[2], (color[3]-(i*0.7)));
|
||||
|
||||
for (gps= gf->strokes.first; gps; gps= gps->next) {
|
||||
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
|
||||
}
|
||||
tcolor[3] = color[3] - (i * 0.7);
|
||||
gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
|
||||
}
|
||||
else
|
||||
break;
|
||||
@@ -482,11 +518,8 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
|
||||
/* check if frame is drawable */
|
||||
if ((gf->framenum - gpf->framenum) <= gpl->gstep) {
|
||||
/* alpha decreases with distance from curframe index */
|
||||
glColor4f(color[0], color[1], color[2], (color[3]-(i*0.7)));
|
||||
|
||||
for (gps= gf->strokes.first; gps; gps= gps->next) {
|
||||
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
|
||||
}
|
||||
tcolor[3] = color[3] - (i * 0.7);
|
||||
gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
|
||||
}
|
||||
else
|
||||
break;
|
||||
@@ -497,19 +530,14 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
|
||||
}
|
||||
else {
|
||||
/* draw the strokes for the ghost frames (at half of the alpha set by user) */
|
||||
glColor4f(color[0], color[1], color[2], (color[3] / 7));
|
||||
|
||||
if (gpf->prev) {
|
||||
for (gps= gpf->prev->strokes.first; gps; gps= gps->next) {
|
||||
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
|
||||
}
|
||||
tcolor[3] = (color[3] / 7);
|
||||
gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
|
||||
}
|
||||
|
||||
glColor4f(color[0], color[1], color[2], (color[3] / 4));
|
||||
if (gpf->next) {
|
||||
for (gps= gpf->next->strokes.first; gps; gps= gps->next) {
|
||||
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
|
||||
}
|
||||
tcolor[3] = (color[3] / 4);
|
||||
gp_draw_strokes(gpf, winx, winy, dflag, debug, lthick, tcolor);
|
||||
}
|
||||
|
||||
/* restore alpha */
|
||||
@@ -518,9 +546,8 @@ static void gp_draw_data (bGPdata *gpd, int winx, int winy, int dflag)
|
||||
}
|
||||
|
||||
/* draw the strokes already in active frame */
|
||||
for (gps= gpf->strokes.first; gps; gps= gps->next) {
|
||||
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
|
||||
}
|
||||
tcolor[3]= color[3];
|
||||
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)
|
||||
|
||||
@@ -2400,7 +2400,7 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
|
||||
switch(event) {
|
||||
case LEFTMOUSE:
|
||||
if(gpencil_do_paint(sa)) {
|
||||
if(gpencil_do_paint(sa, L_MOUSE)) {
|
||||
return;
|
||||
}
|
||||
else if(fromlib) {
|
||||
@@ -2421,7 +2421,10 @@ void winqreadnodespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
break;
|
||||
|
||||
case RIGHTMOUSE:
|
||||
if(find_indicated_socket(snode, &actnode, &actsock, SOCK_IN)) {
|
||||
if(gpencil_do_paint(sa, R_MOUSE)) {
|
||||
return;
|
||||
}
|
||||
else if(find_indicated_socket(snode, &actnode, &actsock, SOCK_IN)) {
|
||||
if(actsock->flag & SOCK_SEL) {
|
||||
snode->edittree->selin= NULL;
|
||||
actsock->flag&= ~SOCK_SEL;
|
||||
|
||||
@@ -972,7 +972,7 @@ static void gp_stroke_newfrombuffer (tGPsdata *p)
|
||||
/* ---------- 'Paint' Tool ------------ */
|
||||
|
||||
/* init new stroke */
|
||||
static void gp_paint_initstroke (tGPsdata *p)
|
||||
static void gp_paint_initstroke (tGPsdata *p, short mousebutton)
|
||||
{
|
||||
/* get active layer (or add a new one if non-existent) */
|
||||
p->gpl= gpencil_layer_getactive(p->gpd);
|
||||
@@ -995,8 +995,17 @@ static void gp_paint_initstroke (tGPsdata *p)
|
||||
}
|
||||
else
|
||||
p->gpf->flag |= GP_FRAME_PAINT;
|
||||
|
||||
/* set 'eraser' for this stroke if using eraser or right-mouse in action */
|
||||
if ( get_activedevice() == 2 || (mousebutton & R_MOUSE) ) {
|
||||
p->gpd->sbuffer_sflag |= GP_STROKE_ERASER;
|
||||
|
||||
/* check if points will need to be made in 3d-space */
|
||||
// for now: eraser isn't ready for prime-time yet, so no painting available here yet
|
||||
p->status= GP_STATUS_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
/* check if points will need to be made in view-aligned space */
|
||||
if (p->gpd->flag & GP_DATA_VIEWALIGN) {
|
||||
switch (p->sa->spacetype) {
|
||||
case SPACE_VIEW3D:
|
||||
@@ -1069,7 +1078,7 @@ short gpencil_paint (short mousebutton)
|
||||
gp_session_cleanup(&p);
|
||||
return 0;
|
||||
}
|
||||
gp_paint_initstroke(&p);
|
||||
gp_paint_initstroke(&p, mousebutton);
|
||||
if (p.status == GP_STATUS_ERROR) {
|
||||
gp_session_cleanup(&p);
|
||||
return 0;
|
||||
@@ -1158,10 +1167,9 @@ short gpencil_paint (short mousebutton)
|
||||
/* All event (loops) handling checking if stroke drawing should be initiated
|
||||
* should call this function.
|
||||
*/
|
||||
short gpencil_do_paint (ScrArea *sa)
|
||||
short gpencil_do_paint (ScrArea *sa, short mousebutton)
|
||||
{
|
||||
bGPdata *gpd = gpencil_data_getactive(sa);
|
||||
short mousebutton = L_MOUSE; /* for now, this is always on L_MOUSE*/
|
||||
short retval= 0;
|
||||
|
||||
/* check if possible to do painting */
|
||||
|
||||
@@ -1205,9 +1205,12 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
return; /* return if event was processed (swallowed) by handler(s) */
|
||||
}
|
||||
|
||||
if(gpencil_do_paint(sa)) return;
|
||||
if(gpencil_do_paint(sa, L_MOUSE)) return;
|
||||
if(BIF_do_manipulator(sa)) return;
|
||||
}
|
||||
else if(event==RIGHTMOUSE) {
|
||||
if(gpencil_do_paint(sa, R_MOUSE)) return;
|
||||
}
|
||||
|
||||
/* swap mouse buttons based on user preference */
|
||||
if (U.flag & USER_LMOUSESELECT) {
|
||||
@@ -4825,8 +4828,11 @@ static void winqreadseqspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
if( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
|
||||
|
||||
/* grease-pencil defaults to leftmouse */
|
||||
if(event==LEFTMOUSE) {
|
||||
if(gpencil_do_paint(sa)) return;
|
||||
if (event == LEFTMOUSE) {
|
||||
if(gpencil_do_paint(sa, L_MOUSE)) return;
|
||||
}
|
||||
else if (event == RIGHTMOUSE) {
|
||||
if(gpencil_do_paint(sa, R_MOUSE)) return;
|
||||
}
|
||||
|
||||
/* swap mouse buttons based on user preference */
|
||||
|
||||
Reference in New Issue
Block a user