diff options
author | Antonio Vazquez <blendergit@gmail.com> | 2020-03-09 18:27:24 +0300 |
---|---|---|
committer | Antonio Vazquez <blendergit@gmail.com> | 2020-03-09 18:27:24 +0300 |
commit | 29f3af95272590d26f610ae828b2eeee89c82a00 (patch) | |
tree | a696a58a2561c48f7ec6166e369e22081e0a64d8 /source/blender/blenkernel/intern/paint.c | |
parent | dcb93126876879d969a30a7865700abd072066f8 (diff) |
GPencil: Refactor of Draw Engine, Vertex Paint and all internal functions
This commit is a full refactor of the grease pencil modules including Draw Engine, Modifiers, VFX, depsgraph update, improvements in operators and conversion of Sculpt and Weight paint tools to real brushes.
Also, a huge code cleanup has been done at all levels.
Thanks to @fclem for his work and yo @pepeland and @mendio for the testing and help in the development.
Differential Revision: https://developer.blender.org/D6293
Diffstat (limited to 'source/blender/blenkernel/intern/paint.c')
-rw-r--r-- | source/blender/blenkernel/intern/paint.c | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 35683ca93f4..e6042b6ad4c 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -215,6 +215,15 @@ bool BKE_paint_ensure_from_paintmode(Scene *sce, ePaintMode mode) case PAINT_MODE_GPENCIL: paint_ptr = (Paint **)&ts->gp_paint; break; + case PAINT_MODE_VERTEX_GPENCIL: + paint_ptr = (Paint **)&ts->gp_vertexpaint; + break; + case PAINT_MODE_SCULPT_GPENCIL: + paint_ptr = (Paint **)&ts->gp_sculptpaint; + break; + case PAINT_MODE_WEIGHT_GPENCIL: + paint_ptr = (Paint **)&ts->gp_weightpaint; + break; case PAINT_MODE_INVALID: break; } @@ -244,6 +253,12 @@ Paint *BKE_paint_get_active_from_paintmode(Scene *sce, ePaintMode mode) return &ts->uvsculpt->paint; case PAINT_MODE_GPENCIL: return &ts->gp_paint->paint; + case PAINT_MODE_VERTEX_GPENCIL: + return &ts->gp_vertexpaint->paint; + case PAINT_MODE_SCULPT_GPENCIL: + return &ts->gp_sculptpaint->paint; + case PAINT_MODE_WEIGHT_GPENCIL: + return &ts->gp_weightpaint->paint; case PAINT_MODE_INVALID: return NULL; default: @@ -270,6 +285,12 @@ const EnumPropertyItem *BKE_paint_get_tool_enum_from_paintmode(ePaintMode mode) return rna_enum_brush_uv_sculpt_tool_items; case PAINT_MODE_GPENCIL: return rna_enum_brush_gpencil_types_items; + case PAINT_MODE_VERTEX_GPENCIL: + return rna_enum_brush_gpencil_vertex_types_items; + case PAINT_MODE_SCULPT_GPENCIL: + return rna_enum_brush_gpencil_sculpt_types_items; + case PAINT_MODE_WEIGHT_GPENCIL: + return rna_enum_brush_gpencil_weight_types_items; case PAINT_MODE_INVALID: break; } @@ -292,6 +313,12 @@ const char *BKE_paint_get_tool_prop_id_from_paintmode(ePaintMode mode) return "uv_sculpt_tool"; case PAINT_MODE_GPENCIL: return "gpencil_tool"; + case PAINT_MODE_VERTEX_GPENCIL: + return "gpencil_vertex_tool"; + case PAINT_MODE_SCULPT_GPENCIL: + return "gpencil_sculpt_tool"; + case PAINT_MODE_WEIGHT_GPENCIL: + return "gpencil_weight_tool"; default: /* invalid paint mode */ return NULL; @@ -315,6 +342,12 @@ Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer) return &ts->imapaint.paint; case OB_MODE_PAINT_GPENCIL: return &ts->gp_paint->paint; + case OB_MODE_VERTEX_GPENCIL: + return &ts->gp_vertexpaint->paint; + case OB_MODE_SCULPT_GPENCIL: + return &ts->gp_sculptpaint->paint; + case OB_MODE_WEIGHT_GPENCIL: + return &ts->gp_weightpaint->paint; case OB_MODE_EDIT: return &ts->uvsculpt->paint; default: @@ -429,6 +462,12 @@ ePaintMode BKE_paintmode_get_from_tool(const struct bToolRef *tref) return PAINT_MODE_GPENCIL; case CTX_MODE_PAINT_TEXTURE: return PAINT_MODE_TEXTURE_3D; + case CTX_MODE_VERTEX_GPENCIL: + return PAINT_MODE_VERTEX_GPENCIL; + case CTX_MODE_SCULPT_GPENCIL: + return PAINT_MODE_SCULPT_GPENCIL; + case CTX_MODE_WEIGHT_GPENCIL: + return PAINT_MODE_WEIGHT_GPENCIL; } } else if (tref->space_type == SPACE_IMAGE) { @@ -485,6 +524,18 @@ void BKE_paint_runtime_init(const ToolSettings *ts, Paint *paint) paint->runtime.tool_offset = offsetof(Brush, gpencil_tool); paint->runtime.ob_mode = OB_MODE_PAINT_GPENCIL; } + else if (paint == &ts->gp_vertexpaint->paint) { + paint->runtime.tool_offset = offsetof(Brush, gpencil_vertex_tool); + paint->runtime.ob_mode = OB_MODE_VERTEX_GPENCIL; + } + else if (paint == &ts->gp_sculptpaint->paint) { + paint->runtime.tool_offset = offsetof(Brush, gpencil_sculpt_tool); + paint->runtime.ob_mode = OB_MODE_SCULPT_GPENCIL; + } + else if (paint == &ts->gp_weightpaint->paint) { + paint->runtime.tool_offset = offsetof(Brush, gpencil_weight_tool); + paint->runtime.ob_mode = OB_MODE_WEIGHT_GPENCIL; + } else { BLI_assert(0); } @@ -506,6 +557,12 @@ uint BKE_paint_get_brush_tool_offset_from_paintmode(const ePaintMode mode) return offsetof(Brush, uv_sculpt_tool); case PAINT_MODE_GPENCIL: return offsetof(Brush, gpencil_tool); + case PAINT_MODE_VERTEX_GPENCIL: + return offsetof(Brush, gpencil_vertex_tool); + case PAINT_MODE_SCULPT_GPENCIL: + return offsetof(Brush, gpencil_sculpt_tool); + case PAINT_MODE_WEIGHT_GPENCIL: + return offsetof(Brush, gpencil_weight_tool); case PAINT_MODE_INVALID: break; /* We don't use these yet. */ } @@ -639,6 +696,204 @@ bool BKE_palette_is_empty(const struct Palette *palette) return BLI_listbase_is_empty(&palette->colors); } +/* helper function to sort using qsort */ +static int palettecolor_compare_hsv(const void *a1, const void *a2) +{ + const tPaletteColorHSV *ps1 = a1, *ps2 = a2; + + /* Hue */ + if (ps1->h > ps2->h) { + return 1; + } + else if (ps1->h < ps2->h) { + return -1; + } + + /* Saturation. */ + if (ps1->s > ps2->s) { + return 1; + } + else if (ps1->s < ps2->s) { + return -1; + } + + /* Value. */ + if (1.0f - ps1->v > 1.0f - ps2->v) { + return 1; + } + else if (1.0f - ps1->v < 1.0f - ps2->v) { + return -1; + } + + return 0; +} + +/* helper function to sort using qsort */ +static int palettecolor_compare_svh(const void *a1, const void *a2) +{ + const tPaletteColorHSV *ps1 = a1, *ps2 = a2; + + /* Saturation. */ + if (ps1->s > ps2->s) { + return 1; + } + else if (ps1->s < ps2->s) { + return -1; + } + + /* Value. */ + if (1.0f - ps1->v > 1.0f - ps2->v) { + return 1; + } + else if (1.0f - ps1->v < 1.0f - ps2->v) { + return -1; + } + + /* Hue */ + if (ps1->h > ps2->h) { + return 1; + } + else if (ps1->h < ps2->h) { + return -1; + } + + return 0; +} + +static int palettecolor_compare_vhs(const void *a1, const void *a2) +{ + const tPaletteColorHSV *ps1 = a1, *ps2 = a2; + + /* Value. */ + if (1.0f - ps1->v > 1.0f - ps2->v) { + return 1; + } + else if (1.0f - ps1->v < 1.0f - ps2->v) { + return -1; + } + + /* Hue */ + if (ps1->h > ps2->h) { + return 1; + } + else if (ps1->h < ps2->h) { + return -1; + } + + /* Saturation. */ + if (ps1->s > ps2->s) { + return 1; + } + else if (ps1->s < ps2->s) { + return -1; + } + + return 0; +} + +static int palettecolor_compare_luminance(const void *a1, const void *a2) +{ + const tPaletteColorHSV *ps1 = a1, *ps2 = a2; + + float lumi1 = (ps1->rgb[0] + ps1->rgb[1] + ps1->rgb[2]) / 3.0f; + float lumi2 = (ps2->rgb[0] + ps2->rgb[1] + ps2->rgb[2]) / 3.0f; + + if (lumi1 > lumi2) { + return -1; + } + else if (lumi1 < lumi2) { + return 1; + } + + return 0; +} + +void BKE_palette_sort_hsv(tPaletteColorHSV *color_array, const int totcol) +{ + /* Sort by Hue , Saturation and Value. */ + qsort(color_array, totcol, sizeof(tPaletteColorHSV), palettecolor_compare_hsv); +} + +void BKE_palette_sort_svh(tPaletteColorHSV *color_array, const int totcol) +{ + /* Sort by Saturation, Value and Hue. */ + qsort(color_array, totcol, sizeof(tPaletteColorHSV), palettecolor_compare_svh); +} + +void BKE_palette_sort_vhs(tPaletteColorHSV *color_array, const int totcol) +{ + /* Sort by Saturation, Value and Hue. */ + qsort(color_array, totcol, sizeof(tPaletteColorHSV), palettecolor_compare_vhs); +} + +void BKE_palette_sort_luminance(tPaletteColorHSV *color_array, const int totcol) +{ + /* Sort by Luminance (calculated with the average, enough for sorting). */ + qsort(color_array, totcol, sizeof(tPaletteColorHSV), palettecolor_compare_luminance); +} + +bool BKE_palette_from_hash(Main *bmain, GHash *color_table, const char *name, const bool linear) +{ + tPaletteColorHSV *color_array = NULL; + tPaletteColorHSV *col_elm = NULL; + bool done = false; + + const int totpal = BLI_ghash_len(color_table); + + if (totpal > 0) { + color_array = MEM_calloc_arrayN(totpal, sizeof(tPaletteColorHSV), __func__); + /* Put all colors in an array. */ + GHashIterator gh_iter; + int t = 0; + GHASH_ITER (gh_iter, color_table) { + const uint col = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter)); + float r, g, b; + float h, s, v; + cpack_to_rgb(col, &r, &g, &b); + rgb_to_hsv(r, g, b, &h, &s, &v); + + col_elm = &color_array[t]; + col_elm->rgb[0] = r; + col_elm->rgb[1] = g; + col_elm->rgb[2] = b; + col_elm->h = h; + col_elm->s = s; + col_elm->v = v; + t++; + } + } + + /* Create the Palette. */ + if (totpal > 0) { + /* Sort by Hue and saturation. */ + BKE_palette_sort_hsv(color_array, totpal); + + Palette *palette = BKE_palette_add(bmain, name); + if (palette) { + for (int i = 0; i < totpal; i++) { + col_elm = &color_array[i]; + PaletteColor *palcol = BKE_palette_color_add(palette); + if (palcol) { + copy_v3_v3(palcol->rgb, col_elm->rgb); + if (linear) { + linearrgb_to_srgb_v3_v3(palcol->rgb, palcol->rgb); + } + } + } + done = true; + } + } + else { + done = false; + } + + if (totpal > 0) { + MEM_SAFE_FREE(color_array); + } + + return done; +} + /* are we in vertex paint or weight paint face select mode? */ bool BKE_paint_select_face_test(Object *ob) { @@ -720,6 +975,9 @@ bool BKE_paint_ensure(ToolSettings *ts, struct Paint **r_paint) BLI_assert(ELEM(*r_paint, /* Cast is annoying, but prevent NULL-pointer access. */ (Paint *)ts->gp_paint, + (Paint *)ts->gp_vertexpaint, + (Paint *)ts->gp_sculptpaint, + (Paint *)ts->gp_weightpaint, (Paint *)ts->sculpt, (Paint *)ts->vpaint, (Paint *)ts->wpaint, @@ -755,6 +1013,18 @@ bool BKE_paint_ensure(ToolSettings *ts, struct Paint **r_paint) GpPaint *data = MEM_callocN(sizeof(*data), __func__); paint = &data->paint; } + else if ((GpVertexPaint **)r_paint == &ts->gp_vertexpaint) { + GpVertexPaint *data = MEM_callocN(sizeof(*data), __func__); + paint = &data->paint; + } + else if ((GpSculptPaint **)r_paint == &ts->gp_sculptpaint) { + GpSculptPaint *data = MEM_callocN(sizeof(*data), __func__); + paint = &data->paint; + } + else if ((GpWeightPaint **)r_paint == &ts->gp_weightpaint) { + GpWeightPaint *data = MEM_callocN(sizeof(*data), __func__); + paint = &data->paint; + } else if ((UvSculpt **)r_paint == &ts->uvsculpt) { UvSculpt *data = MEM_callocN(sizeof(*data), __func__); paint = &data->paint; |