== Grease Pencil - Drawing (User Action not Display) Accuracy ==

This commit attempts to fix some of the problems with the accuracy of strokes recorded.

I've disabled the post-draw smoothing of strokes as it deviated from the source stroke too much. This was introduced to try to eliminate the effects of fine 'jitter' (which is especially noticable when using optical mice + fast computer). 

Now, I've introduced two thresholds which determine the 'minimum' distances that the mouse needs to have moved from the previous mouse-coordinates recorded, to be recorded. These are currently hardcoded, but may be exposed in the UI if there is significant need to do so.
- The first is for the distance that the mouse must have moved on both axes to be considered.
- The second is for the 'pythagorean' distance that needs to have been travelled by the mouse.
This commit is contained in:
Joshua Leung
2008-07-26 12:54:03 +00:00
parent c4116a7f8d
commit 70ce017777
2 changed files with 46 additions and 34 deletions

View File

@@ -228,6 +228,10 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
/* stroke thickness */
uiDefButS(block, NUMSLI, B_REDR, "Thickness:", *xco, *yco-75, 150, 20, &gpl->thickness, 1, 10, 0, 0, "Thickness of strokes (in pixels)");
/* debugging options */
if (G.f & G_DEBUG) {
uiDefButBitI(block, TOG, GP_LAYER_DRAWDEBUG, B_REDR, "Show Points", *xco, *yco-95, 150, 20, &gpl->flag, 0, 0, 0, 0, "Show points which form the strokes");
}
/* onion-skinning */
uiBlockBeginAlign(block);
@@ -243,8 +247,6 @@ static void gp_drawui_layer (uiBlock *block, bGPdata *gpd, bGPDlayer *gpl, short
but= uiDefBut(block, BUT, B_REDR, "Del Last Stroke", *xco+160, *yco-95, 140, 20, NULL, 0, 0, 0, 0, "Erases the last stroke from the active frame (Hotkey = Alt-XKEY/DEL)");
uiButSetFunc(but, gp_ui_delstroke_cb, gpd, gpl);
uiBlockEndAlign(block);
//uiDefButBitI(block, TOG, GP_LAYER_DRAWDEBUG, B_REDR, "Show Points", *xco+160, *yco-75, 130, 20, &gpl->flag, 0, 0, 0, 0, "Show points which form the strokes");
}
}
@@ -425,32 +427,8 @@ static void gp_draw_strokes (bGPDframe *gpf, int winx, int winy, int dflag, shor
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);
}
/* just draw the stroke once */
gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, winx, winy);
}
}

View File

@@ -662,7 +662,13 @@ void gpencil_delete_menu (void)
/* ---------- 'Globals' and Defines ----------------- */
/* maximum sizes of gp-session buffer */
#define GP_STROKE_BUFFER_MAX 5000
#define GP_STROKE_BUFFER_MAX 5000
/* 'Hardcoded' sensitivity thresholds... */
/* minimum number of pixels mouse should move before new point created */
#define MIN_MMOVE_PX 3
/* minimum length of new segment before new point can be added */
#define MIN_MDIST_PX 20
/* ------ */
@@ -877,8 +883,27 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[])
}
}
/* check if the current mouse position is suitable for adding a new point */
static short gp_stroke_filtermval (tGPsdata *p, short mval[2], short pmval[2])
{
short dx= abs(mval[0] - pmval[0]);
short dy= abs(mval[1] - pmval[1]);
/* check if mouse moved at least certain distance on both axes (best case) */
if ((dx > MIN_MMOVE_PX) && (dy > MIN_MMOVE_PX))
return 1;
/* check if the distance since the last point is significant enough */
else if (sqrt(dx*dx + dy*dy) > MIN_MDIST_PX)
return 1;
/* mouse 'didn't move' */
else
return 0;
}
/* add current stroke-point to buffer (returns whether point was successfully added) */
static short gp_stroke_addpoint (tGPsdata *p, short mval[], float pressure)
static short gp_stroke_addpoint (tGPsdata *p, short mval[2], float pressure)
{
bGPdata *gpd= p->gpd;
bGPDspoint *pt;
@@ -913,6 +938,9 @@ static void gp_stroke_smooth (tGPsdata *p)
bGPdata *gpd= p->gpd;
int i=0, cmx=gpd->sbuffer_size;
// fixme: currently disabled as it damages too much sometimes
return;
/* don't try if less than 2 points in buffer */
if ((cmx <= 2) || (gpd->sbuffer == NULL))
return;
@@ -1033,11 +1061,17 @@ static void gp_paint_initstroke (tGPsdata *p, short mousebutton)
/* finish off a stroke (clears buffer, but doesn't finish the paint operation) */
static void gp_paint_strokeend (tGPsdata *p)
{
/* sanitize stroke-points in buffer */
/* sanitize stroke-points in buffer (remove jitter) */
gp_stroke_smooth(p);
/* transfer stroke to frame */
gp_stroke_newfrombuffer(p);
/* check if doing eraser or not */
if (p->gpd->sbuffer_sflag & GP_STROKE_ERASER) {
/* get rid of relevant sections of strokes */
}
else {
/* transfer stroke to frame */
gp_stroke_newfrombuffer(p);
}
/* clean up buffer now */
gp_session_validatebuffer(p);
@@ -1110,7 +1144,7 @@ short gpencil_paint (short mousebutton)
pressure = get_pressure();
/* only add current point to buffer if mouse moved (otherwise wait until it does) */
if ((mval[0] != prevmval[0]) || (mval[1] != prevmval[1])) {
if (gp_stroke_filtermval(&p, mval, prevmval)) {
/* try to add point */
ok= gp_stroke_addpoint(&p, mval, pressure);