Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2016-04-28 18:12:53 +0300
committerJoshua Leung <aligorith@gmail.com>2016-05-08 15:53:48 +0300
commitf5ddcfeb031176becb40c2bd9ad226466c6ddff7 (patch)
tree909bd1aacd3a7d0d660b938cc2b2f24e1073a127
parent1d5c71bca74fe3bef40446259d424380f237c27f (diff)
Code Cleanups: A bunch of tweaks to tidy up things from the GPencil Fill patch
-rw-r--r--source/blender/blenloader/intern/readfile.c4
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c134
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h7
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c4
4 files changed, 84 insertions, 65 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 9c3091f186b..678fd84de94 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6159,9 +6159,11 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
for (gps = gpf->strokes.first; gps; gps = gps->next) {
gps->points = newdataadr(fd, gps->points);
+
/* the triangulation is not saved, so need to be recalculated */
- gps->triangles = NULL;
gps->flag |= GP_STROKE_RECALC_CACHES;
+ gps->triangles = NULL;
+ gps->tot_triangles = 0;
}
}
}
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index 3f7805fa2c4..c885842e756 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -328,128 +328,134 @@ static void gp_draw_stroke_volumetric_3d(bGPDspoint *points, int totpoints, shor
/* --------------- Stroke Fills ----------------- */
-/* get points of stroke always flat to view not affected by camera view or view position
- */
+
+/* Get points of stroke always flat to view not affected by camera view or view position */
static void gp_stroke_2d_flat(bGPDspoint *points, int totpoints, float(*points2d)[2], int *r_direction)
{
bGPDspoint *pt0 = &points[0];
bGPDspoint *pt1 = &points[1];
- bGPDspoint *pt3 = &points[(int) (totpoints * 0.75)];
- bGPDspoint *pt;
+ bGPDspoint *pt3 = &points[(int)(totpoints * 0.75)];
+
float locx[3];
float locy[3];
float loc3[3];
float normal[3];
-
+
/* local X axis (p0-p1) */
sub_v3_v3v3(locx, &pt1->x, &pt0->x);
-
+
/* point vector at 3/4 */
sub_v3_v3v3(loc3, &pt3->x, &pt0->x);
-
+
/* vector orthogonal to polygon plane */
cross_v3_v3v3(normal, locx, loc3);
-
+
/* local Y axis (cross to normal/x axis) */
cross_v3_v3v3(locy, normal, locx);
-
+
/* Normalize vectors */
normalize_v3(locx);
normalize_v3(locy);
-
+
/* Get all points in local space */
- for (int i = 0; i < totpoints; i++) {
-
+ for (int i = 0; i < totpoints; i++) {
+ bGPDspoint *pt = &points[i];
float loc[3];
+
/* Get local space using first point as origin */
- pt = &points[i];
sub_v3_v3v3(loc, &pt->x, &pt0->x);
-
- float co[2];
- co[0] = dot_v3v3(loc, locx);
- co[1] = dot_v3v3(loc, locy);
- points2d[i][0] = co[0];
- points2d[i][1] = co[1];
+
+ points2d[i][0] = dot_v3v3(loc, locx);
+ points2d[i][1] = dot_v3v3(loc, locy);
}
-
+
*r_direction = (int)locy[2];
}
-/* triangulate stroke for high quality fill (this is done only if cache is null or stroke was modified) */
+/* Triangulate stroke for high quality fill (this is done only if cache is null or stroke was modified) */
static void gp_triangulate_stroke_fill(bGPDstroke *gps)
{
BLI_assert(gps->totpoints >= 3);
-
- bGPDtriangle *stroke_triangle;
- int i;
-
+
/* allocate memory for temporary areas */
- unsigned int(*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->totpoints, "GP Stroke temp triangulation");
- float(*points2d)[2] = MEM_mallocN(sizeof(*points2d) * gps->totpoints, "GP Stroke temp 2d points");
-
+ unsigned int (*tmp_triangles)[3] = MEM_mallocN(sizeof(*tmp_triangles) * gps->totpoints, "GP Stroke temp triangulation");
+ float (*points2d)[2] = MEM_mallocN(sizeof(*points2d) * gps->totpoints, "GP Stroke temp 2d points");
+
int direction;
-
+
/* convert to 2d and triangulate */
gp_stroke_2d_flat(gps->points, gps->totpoints, points2d, &direction);
BLI_polyfill_calc((const float(*)[2])points2d, (unsigned int)gps->totpoints, direction, (unsigned int(*)[3])tmp_triangles);
-
+
/* count number of valid triangles */
gps->tot_triangles = 0;
- for (i = 0; i < gps->totpoints; i++) {
+ for (int i = 0; i < gps->totpoints; i++) {
if ((tmp_triangles[i][0] >= 0) && (tmp_triangles[i][0] < gps->totpoints) &&
(tmp_triangles[i][1] >= 0) && (tmp_triangles[i][1] < gps->totpoints) &&
(tmp_triangles[i][2] >= 0) && (tmp_triangles[i][2] < gps->totpoints))
{
- gps->tot_triangles += 1;
+ gps->tot_triangles++;
}
}
-
+
/* save triangulation data in stroke cache */
- if (gps->triangles == NULL) {
- gps->triangles = MEM_callocN(sizeof(bGPDtriangle) * gps->tot_triangles, "GP Stroke triangulation");
+ if (gps->tot_triangles > 0) {
+ if (gps->triangles == NULL) {
+ gps->triangles = MEM_callocN(sizeof(bGPDtriangle) * gps->tot_triangles, "GP Stroke triangulation");
+ }
+ else {
+ gps->triangles = MEM_recallocN(gps->triangles, sizeof(bGPDtriangle) * gps->tot_triangles);
+ }
+
+ for (int i = 0; i < gps->tot_triangles; i++) {
+ if ((tmp_triangles[i][0] >= 0) && (tmp_triangles[i][0] < gps->totpoints) &&
+ (tmp_triangles[i][1] >= 0) && (tmp_triangles[i][1] < gps->totpoints) &&
+ (tmp_triangles[i][2] >= 0) && (tmp_triangles[i][2] < gps->totpoints))
+ {
+ bGPDtriangle *stroke_triangle = &gps->triangles[i];
+
+ stroke_triangle->v1 = tmp_triangles[i][0];
+ stroke_triangle->v2 = tmp_triangles[i][1];
+ stroke_triangle->v3 = tmp_triangles[i][2];
+ }
+ }
}
else {
- gps->triangles = MEM_recallocN(gps->triangles, sizeof(*gps->triangles) * gps->tot_triangles);
- }
-
- for (i = 0; i < gps->tot_triangles; i++) {
- if ((tmp_triangles[i][0] >= 0) && (tmp_triangles[i][0] < gps->totpoints) &&
- (tmp_triangles[i][1] >= 0) && (tmp_triangles[i][1] < gps->totpoints) &&
- (tmp_triangles[i][2] >= 0) && (tmp_triangles[i][2] < gps->totpoints))
- {
- stroke_triangle = &gps->triangles[i];
- stroke_triangle->v1 = tmp_triangles[i][0];
- stroke_triangle->v2 = tmp_triangles[i][1];
- stroke_triangle->v3 = tmp_triangles[i][2];
- }
+ /* No triangles needed - Free anything allocated previously */
+ if (gps->triangles)
+ MEM_freeN(gps->triangles);
+
+ gps->triangles = NULL;
}
- /* disable recalculation flag (False)*/
+
+ /* disable recalculation flag */
if (gps->flag & GP_STROKE_RECALC_CACHES) {
- gps->flag ^= GP_STROKE_RECALC_CACHES;
+ gps->flag &= ~GP_STROKE_RECALC_CACHES;
}
+
/* clear memory */
if (tmp_triangles) MEM_freeN(tmp_triangles);
if (points2d) MEM_freeN(points2d);
-
}
/* draw fills for shapes */
static void gp_draw_stroke_fill(bGPDstroke *gps, short UNUSED(thickness), short dflag, int offsx, int offsy, int winx, int winy)
{
- int i;
-
BLI_assert(gps->totpoints >= 3);
+
/* Triangulation fill if high quality flag is enabled */
if (dflag & GP_DRAWDATA_HQ_FILL) {
bGPDtriangle *stroke_triangle;
bGPDspoint *pt;
-
+ int i;
+
/* Calculate triangles cache for filling area (must be done only after changes) */
if ((gps->flag & GP_STROKE_RECALC_CACHES) || (gps->tot_triangles == 0) || (gps->triangles == NULL)) {
gp_triangulate_stroke_fill(gps);
}
+
/* Draw all triangles for filling the polygon (cache must be calculated before) */
BLI_assert(gps->tot_triangles >= 1);
glBegin(GL_TRIANGLES);
@@ -458,23 +464,28 @@ static void gp_draw_stroke_fill(bGPDstroke *gps, short UNUSED(thickness), short
/* vertex 1 */
pt = &gps->points[stroke_triangle->v1];
glVertex3fv(&pt->x);
+
/* vertex 2 */
pt = &gps->points[stroke_triangle->v2];
glVertex3fv(&pt->x);
+
/* vertex 3 */
pt = &gps->points[stroke_triangle->v3];
glVertex3fv(&pt->x);
}
else {
float co[2];
+
/* vertex 1 */
pt = &gps->points[stroke_triangle->v1];
gp_calc_2d_stroke_xy(pt, gps->flag, offsx, offsy, winx, winy, co);
glVertex2fv(co);
+
/* vertex 2 */
pt = &gps->points[stroke_triangle->v2];
gp_calc_2d_stroke_xy(pt, gps->flag, offsx, offsy, winx, winy, co);
glVertex2fv(co);
+
/* vertex 3 */
pt = &gps->points[stroke_triangle->v3];
gp_calc_2d_stroke_xy(pt, gps->flag, offsx, offsy, winx, winy, co);
@@ -486,11 +497,17 @@ static void gp_draw_stroke_fill(bGPDstroke *gps, short UNUSED(thickness), short
else {
/* As an initial implementation, we use the OpenGL filled polygon drawing
* here since it's the easiest option to implement for this case. It does
- * come with limitations (notably for concave shapes), though it shouldn't
- * be much of an issue in most cases.
+ * come with limitations (notably for concave shapes), though it works well
+ * enough for many simple situations.
+ *
+ * We keep this legacy implementation around despite now having the high quality
+ * fills, as this is necessary for keeping everything working nicely for files
+ * created using old versions of Blender which may have depended on the artifacts
+ * the old fills created.
*/
bGPDspoint *pt;
-
+ int i;
+
glBegin(GL_POLYGON);
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if (gps->flag & GP_STROKE_3DSPACE) {
@@ -498,12 +515,11 @@ static void gp_draw_stroke_fill(bGPDstroke *gps, short UNUSED(thickness), short
}
else {
float co[2];
-
+
gp_calc_2d_stroke_xy(pt, gps->flag, offsx, offsy, winx, winy, co);
glVertex2fv(co);
}
}
-
glEnd();
}
}
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index e1f9a99c610..ab0fcb81379 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -59,7 +59,7 @@ typedef enum eGPDspoint_Flag {
/* Grease-Pencil Annotations - 'Triangle'
* -> A triangle contains the index of three vertices for filling the stroke
- * this is only used if high quality fill is enabled
+ * This is only used if high quality fill is enabled
*/
typedef struct bGPDtriangle {
int v1, v2, v3; /* indices for tesselated triangle used for GP Fill */
@@ -77,6 +77,7 @@ typedef struct bGPDstroke {
short thickness; /* thickness of stroke (currently not used) */
short flag; /* various settings about this stroke */
+
bGPDtriangle *triangles;/* tesselated triangles for GP Fill */
int tot_triangles; /* number of triangles in array */
short pad2[2]; /* avoid compiler align error */
@@ -94,7 +95,7 @@ typedef enum eGPDstroke_Flag {
GP_STROKE_2DIMAGE = (1 << 2),
/* stroke is selected */
GP_STROKE_SELECT = (1 << 3),
- /* Recalculate triangulation for high quality fill (true force a new recalc) */
+ /* Recalculate triangulation for high quality fill (when true, force a new recalc) */
GP_STROKE_RECALC_CACHES = (1 << 4),
/* only for use with stroke-buffer (while drawing eraser) */
GP_STROKE_ERASER = (1 << 15)
@@ -173,7 +174,7 @@ typedef enum eGPDlayer_Flag {
GP_LAYER_GHOST_NEXTCOL = (1 << 9),
/* "volumetric" strokes (i.e. GLU Quadric discs in 3D) */
GP_LAYER_VOLUMETRIC = (1 << 10),
- /* Use High quality fill using stencil */
+ /* Use high quality fill (instead of buggy legacy OpenGL Fill) */
GP_LAYER_HQ_FILL = (1 << 11)
} eGPDlayer_Flag;
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index 6f67a4c992f..10d7efe9374 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -721,10 +721,10 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Volumetric Strokes", "Draw strokes as a series of circular blobs, resulting in a volumetric effect");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
- /* Use High quality fill */
+ /* Use High Quality Fill */
prop = RNA_def_property(srna, "use_hq_fill", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HQ_FILL);
- RNA_def_property_ui_text(prop, "High Quality Fill", "Fill strokes using high quality to avoid glitches (slower fps during animation play)");
+ RNA_def_property_ui_text(prop, "High Quality Fill", "Fill strokes using high quality method to avoid glitches (slower fps during animation playback)");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
/* Stroke Drawing Color */