diff options
author | Joshua Leung <aligorith@gmail.com> | 2008-10-09 03:42:00 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2008-10-09 03:42:00 +0400 |
commit | 2e9d07b33b7189d4716cbc8504e029483d6bac5b (patch) | |
tree | 744b22e9357ce3c96c36d8c666f7b77052880433 | |
parent | 890b9f26f717dd5f58533673873f9f663f4a9ee3 (diff) |
Grease Pencil:
Added comments a few + stroke simplification code (hidden behind rt and userpref, adapted from theeth's etch-a-ton code). This shouldn't have any other adverse effects.
-rw-r--r-- | source/blender/makesdna/DNA_userdef_types.h | 3 | ||||
-rw-r--r-- | source/blender/src/gpencil.c | 89 | ||||
-rw-r--r-- | source/blender/src/space.c | 18 |
3 files changed, 101 insertions, 9 deletions
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index fdf08c73798..fbd962f9372 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -327,7 +327,8 @@ extern UserDef U; /* from usiblender.c !!!! */ /* tw_flag (transform widget) */ /* gp_settings (Grease Pencil Settings) */ -#define GP_PAINT_DOSMOOTH (1<<0) +#define GP_PAINT_DOSMOOTH (1<<0) +#define GP_PAINT_DOSIMPLIFY (1<<1) #endif diff --git a/source/blender/src/gpencil.c b/source/blender/src/gpencil.c index 1c16e833d78..6d6430aa76b 100644 --- a/source/blender/src/gpencil.c +++ b/source/blender/src/gpencil.c @@ -1186,6 +1186,16 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[]) float *fp= give_cursor(); float dvec[3]; + /* Current method just converts each point in screen-coordinates to + * 3D-coordinates using the 3D-cursor as reference. In general, this + * works OK, but it could of course be improved. + * + * TODO: + * - investigate using nearest point(s) on a previous stroke as + * reference point instead or as offset, for easier stroke matching + * - investigate projection onto geometry (ala retopo) + */ + /* method taken from editview.c - mouse_cursor() */ project_short_noclip(fp, mval); window_to_3d(dvec, mval[0]-mx, mval[1]-my); @@ -1203,8 +1213,7 @@ static void gp_stroke_convertcoords (tGPsdata *p, short mval[], float out[]) } /* 2d - on image 'canvas' (assume that p->v2d is set) */ - else if ( (gpd->sbuffer_sflag & GP_STROKE_2DIMAGE) && (p->v2d) ) - { + else if ((gpd->sbuffer_sflag & GP_STROKE_2DIMAGE) && (p->v2d)) { /* for now - space specific */ switch (p->sa->spacetype) { case SPACE_SEQ: /* sequencer */ @@ -1285,7 +1294,7 @@ static void gp_stroke_smooth (tGPsdata *p) int i=0, cmx=gpd->sbuffer_size; /* only smooth if smoothing is enabled, and we're not doing a straight line */ - if ( !(U.gp_settings & GP_PAINT_DOSMOOTH) || GP_BUFFER2STROKE_ENDPOINTS) + if (!(U.gp_settings & GP_PAINT_DOSMOOTH) || GP_BUFFER2STROKE_ENDPOINTS) return; /* don't try if less than 2 points in buffer */ @@ -1305,6 +1314,77 @@ static void gp_stroke_smooth (tGPsdata *p) } } +/* simplify a stroke (in buffer) before storing it + * - applies a reverse Chaikin filter + * - code adapted from etch-a-ton branch (editarmature_sketch.c) + */ +static void gp_stroke_simplify (tGPsdata *p) +{ + bGPdata *gpd= p->gpd; + tGPspoint *old_points= (tGPspoint *)gpd->sbuffer; + short num_points= gpd->sbuffer_size; + short flag= gpd->sbuffer_sflag; + short i, j; + + /* only simplify if simlification is enabled, and we're not doing a straight line */ + if (!(U.gp_settings & GP_PAINT_DOSIMPLIFY) || GP_BUFFER2STROKE_ENDPOINTS) + return; + + /* don't simplify if less than 4 points in buffer */ + if ((num_points <= 2) || (old_points == NULL)) + return; + + /* clear buffer (but don't free mem yet) so that we can write to it + * - firstly set sbuffer to NULL, so a new one is allocated + * - secondly, reset flag after, as it gets cleared auto + */ + gpd->sbuffer= NULL; + gp_session_validatebuffer(p); + gpd->sbuffer_sflag = flag; + +/* macro used in loop to get position of new point + * - used due to the mixture of datatypes in use here + */ +#define GP_SIMPLIFY_AVPOINT(offs, sfac) \ + { \ + co[0] += (float)(old_points[offs].x * sfac); \ + co[1] += (float)(old_points[offs].y * sfac); \ + pressure += old_points[offs].pressure * sfac; \ + } + + for (i = 0, j = 0; i < num_points; i++) + { + if (i - j == 3) + { + float co[2], pressure; + short mco[2]; + + /* initialise values */ + co[0]= 0; + co[1]= 0; + pressure = 0; + + /* using macro, calculate new point */ + GP_SIMPLIFY_AVPOINT(j, -0.25); + GP_SIMPLIFY_AVPOINT(j+1, 0.75); + GP_SIMPLIFY_AVPOINT(j+2, 0.75); + GP_SIMPLIFY_AVPOINT(j+3, -0.25); + + /* set values for adding */ + mco[0]= (short)co[0]; + mco[1]= (short)co[1]; + + /* ignore return values on this... assume to be ok for now */ + gp_stroke_addpoint(p, mco, pressure); + + j += 2; + } + } + + /* free old buffer */ + MEM_freeN(old_points); +} + /* make a new stroke from the buffer data */ static void gp_stroke_newfrombuffer (tGPsdata *p) @@ -1804,6 +1884,9 @@ static void gp_paint_strokeend (tGPsdata *p) /* smooth stroke before transferring? */ gp_stroke_smooth(p); + /* simplify stroke before transferring? */ + gp_stroke_simplify(p); + /* transfer stroke to frame */ gp_stroke_newfrombuffer(p); } diff --git a/source/blender/src/space.c b/source/blender/src/space.c index f0c9d763579..52a646a2c64 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -4120,14 +4120,22 @@ void drawinfospace(ScrArea *sa, void *spacedata) (xpos+(5*midsp)+(3*mpref)+(spref*2.5)),y5,(spref*1.5),buth, &(U.gp_euclideandist), 0, 100, 0, 0, "Distance moved by mouse when drawing stroke (in pixels) to include"); - - uiDefButS(block, NUM, 0, "Eraser Radius:", - (xpos+(7*midsp)+(3*mpref)+(3.75*spref)),y5,spref*1.5,buth, - &(U.gp_eraser), 0, 100, 0, 0, "Radius of eraser 'brush'"); uiDefButBitS(block, TOG, GP_PAINT_DOSMOOTH, 0,"Smooth Stroke", - (xpos+(8*midsp)+(3*mpref)+(5*spref)),y5,spref,buth, + (xpos+(4*midsp)+(3*mpref)+spref),y4,(spref*1.5),buth, &(U.gp_settings), 0, 100, 0, 0, "Smooth the final stroke"); + + // currently hidden behind G.rt, as it is not that useful yet + if (G.rt) { + uiDefButBitS(block, TOG, GP_PAINT_DOSIMPLIFY, 0,"Simplify Stroke", + (xpos+(5*midsp)+(3*mpref)+(spref*2.5)),y4,(spref*1.5),buth, + &(U.gp_settings), 0, 100, 0, 0, "Simplify the final stroke"); + } uiBlockEndAlign(block); + + uiDefButS(block, NUM, 0, "Eraser Radius:", + (xpos+(7*midsp)+(3*mpref)+(4*spref)),y5,mpref,buth, + &(U.gp_eraser), 0, 100, 0, 0, "Radius of eraser 'brush'"); + } else if(U.userpref == 2) { /* language & colors */ |