diff options
author | Joshua Leung <aligorith@gmail.com> | 2008-08-22 15:46:59 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2008-08-22 15:46:59 +0400 |
commit | c230bc4a820046953257984cc5a19bdf455940e7 (patch) | |
tree | 863a3f5541336f74591d18a9e5a14957e8647bc5 /source | |
parent | f88dabae8a611c4fd13f441abb51f0e11d6454c3 (diff) |
Grease Pencil - Drawing Improvements:
This commit finishes the work started in the previous commit.
1) Reduced the effects of 'shrinking' lines with acute angles (*)
2) Ends of strokes now get crude end-caps which look ok for most purposes (they are really just simple trapeziums not fancy semicircles)
* Note: some shrinking does still occur if the stroke was drawn quickly enough for few points to be recorded. Also, although there are still zones of overlapping when there are acute angles, this is reduced to steeper angles (and is not too bad considering real-life materials)
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/src/drawgpencil.c | 102 |
1 files changed, 75 insertions, 27 deletions
diff --git a/source/blender/src/drawgpencil.c b/source/blender/src/drawgpencil.c index 22f7fdc32f0..f60d53a9c5d 100644 --- a/source/blender/src/drawgpencil.c +++ b/source/blender/src/drawgpencil.c @@ -450,7 +450,7 @@ static void gp_draw_stroke_3d (bGPDspoint *points, int totpoints, short thicknes 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) || (G.rt==0)) { + if (thickness < 3) { bGPDspoint *pt; int i; @@ -472,19 +472,15 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, bGPDspoint *pt1, *pt2; float pm[2]; int i; - short n; glShadeModel(GL_FLAT); - - glPointSize(3.0f); // temp - - for (n= 0; n < 2; n++) { // temp - glBegin((n)?GL_POINTS:GL_QUADS); + glBegin(GL_QUADS); for (i=0, pt1=points, pt2=points+1; i < (totpoints-1); i++, pt1++, pt2++) { float s0[2], s1[2]; /* segment 'center' points */ float t0[2], t1[2]; /* tesselated coordinates */ float m1[2], m2[2]; /* gradient and normal */ + float mt[2], sc[2]; /* gradient for thickness, point for end-cap */ float pthick; /* thickness at segment point */ /* get x and y coordinates from points */ @@ -502,42 +498,75 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, /* calculate gradient and normal - 'angle'=(ny/nx) */ m1[1]= s1[1] - s0[1]; m1[0]= s1[0] - s0[0]; + Normalize2(m1); m2[1]= -m1[0]; m2[0]= m1[1]; - Normalize2(m2); /* always use pressure from first point here */ pthick= (pt1->pressure * thickness); /* if the first segment, start of segment is segment's normal */ if (i == 0) { - // TODO: also draw/do a round end-cap first + /* draw start cap first + * - make points slightly closer to center (about halfway across) + */ + mt[0]= m2[0] * pthick * 0.5; + mt[1]= m2[1] * pthick * 0.5; + sc[0]= s0[0] - (m1[0] * pthick * 0.75); + sc[1]= s0[1] - (m1[1] * pthick * 0.75); + + t0[0]= sc[0] - mt[0]; + t0[1]= sc[1] - mt[1]; + t1[0]= sc[0] + mt[0]; + t1[1]= sc[1] + mt[1]; + + glVertex2fv(t0); + glVertex2fv(t1); /* calculate points for start of segment */ - t0[0]= s0[0] - (pthick * m2[0]); - t0[1]= s0[1] - (pthick * m2[1]); - t1[0]= s0[0] + (pthick * m2[0]); - t1[1]= s0[1] + (pthick * m2[1]); + mt[0]= m2[0] * pthick; + mt[1]= m2[1] * pthick; + + t0[0]= s0[0] - mt[0]; + t0[1]= s0[1] - mt[1]; + t1[0]= s0[0] + mt[0]; + t1[1]= s0[1] + mt[1]; - /* draw this line only once */ + /* draw this line twice (first to finish off start cap, then for stroke) */ + glVertex2fv(t1); + glVertex2fv(t0); glVertex2fv(t0); glVertex2fv(t1); } /* if not the first segment, use bisector of angle between segments */ else { - float mb[2]; /* bisector normal */ + float mb[2]; /* bisector normal */ + float athick, dfac; /* actual thickness, difference between thicknesses */ /* calculate gradient of bisector (as average of normals) */ mb[0]= (pm[0] + m2[0]) / 2; mb[1]= (pm[1] + m2[1]) / 2; Normalize2(mb); + /* calculate gradient to apply + * - as basis, use just pthick * bisector gradient + * - if cross-section not as thick as it should be, add extra padding to fix it + */ + mt[0]= mb[0] * pthick; + mt[1]= mb[1] * pthick; + athick= Vec2Length(mt); + dfac= pthick - (athick * 2); + if ( ((athick * 2) < pthick) && (IS_EQ(athick, pthick)==0) ) + { + mt[0] += (mb[0] * dfac); + mt[1] += (mb[1] * dfac); + } + /* calculate points for start of segment */ - // FIXME: do we need extra padding for acute angles? - t0[0]= s0[0] - (pthick * mb[0]); - t0[1]= s0[1] - (pthick * mb[1]); - t1[0]= s0[0] + (pthick * mb[0]); - t1[1]= s0[1] + (pthick * mb[1]); + t0[0]= s0[0] - mt[0]; + t0[1]= s0[1] - mt[1]; + t1[0]= s0[0] + mt[0]; + t1[1]= s0[1] + mt[1]; /* draw this line twice (once for end of current segment, and once for start of next) */ glVertex2fv(t1); @@ -552,16 +581,36 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, pthick= (pt2->pressure * thickness); /* calculate points for end of segment */ - t0[0]= s1[0] - (pthick * m2[0]); - t0[1]= s1[1] - (pthick * m2[1]); - t1[0]= s1[0] + (pthick * m2[0]); - t1[1]= s1[1] + (pthick * m2[1]); + mt[0]= m2[0] * pthick; + mt[1]= m2[1] * pthick; + + t0[0]= s1[0] - mt[0]; + t0[1]= s1[1] - mt[1]; + t1[0]= s1[0] + mt[0]; + t1[1]= s1[1] + mt[1]; - /* draw this line only once */ + /* draw this line twice (once for end of stroke, and once for endcap)*/ glVertex2fv(t1); glVertex2fv(t0); + glVertex2fv(t0); + glVertex2fv(t1); + - // TODO: draw end cap as last step + /* draw end cap as last step + * - make points slightly closer to center (about halfway across) + */ + mt[0]= m2[0] * pthick * 0.5; + mt[1]= m2[1] * pthick * 0.5; + sc[0]= s1[0] + (m1[0] * pthick * 0.75); + sc[1]= s1[1] + (m1[1] * pthick * 0.75); + + t0[0]= sc[0] - mt[0]; + t0[1]= sc[1] - mt[1]; + t1[0]= sc[0] + mt[0]; + t1[1]= sc[1] + mt[1]; + + glVertex2fv(t1); + glVertex2fv(t0); } /* store stroke's 'natural' normal for next stroke to use */ @@ -569,7 +618,6 @@ static void gp_draw_stroke (bGPDspoint *points, int totpoints, short thickness, } glEnd(); - } } /* draw debug points of curve on top? (original stroke points) */ |