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:
Diffstat (limited to 'source/blender/blenkernel/intern/paint.c')
-rw-r--r--source/blender/blenkernel/intern/paint.c270
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;