diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_vertex_color_utils.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex_color_utils.c | 921 |
1 files changed, 468 insertions, 453 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c b/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c index 4a5c72e5199..6511c90f5e1 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c @@ -41,53 +41,50 @@ #include "ED_mesh.h" -#include "paint_intern.h" /* own include */ +#include "paint_intern.h" /* own include */ #define EPS_SATURATION 0.0005f /** * Apply callback to each vertex of the active vertex color layer. */ -bool ED_vpaint_color_transform( - struct Object *ob, - VPaintTransform_Callback vpaint_tx_fn, - const void *user_data) +bool ED_vpaint_color_transform(struct Object *ob, + VPaintTransform_Callback vpaint_tx_fn, + const void *user_data) { - Mesh *me; - const MPoly *mp; + Mesh *me; + const MPoly *mp; - if (((me = BKE_mesh_from_object(ob)) == NULL) || - (ED_mesh_color_ensure(me, NULL) == false)) - { - return false; - } + if (((me = BKE_mesh_from_object(ob)) == NULL) || (ED_mesh_color_ensure(me, NULL) == false)) { + return false; + } - const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; - mp = me->mpoly; + const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; + mp = me->mpoly; - for (int i = 0; i < me->totpoly; i++, mp++) { - MLoopCol *lcol = &me->mloopcol[mp->loopstart]; + for (int i = 0; i < me->totpoly; i++, mp++) { + MLoopCol *lcol = &me->mloopcol[mp->loopstart]; - if (use_face_sel && !(mp->flag & ME_FACE_SEL)) { - continue; - } + if (use_face_sel && !(mp->flag & ME_FACE_SEL)) { + continue; + } - for (int j = 0; j < mp->totloop; j++, lcol++) { - float col_mix[3]; - rgb_uchar_to_float(col_mix, &lcol->r); + for (int j = 0; j < mp->totloop; j++, lcol++) { + float col_mix[3]; + rgb_uchar_to_float(col_mix, &lcol->r); - vpaint_tx_fn(col_mix, user_data, col_mix); + vpaint_tx_fn(col_mix, user_data, col_mix); - rgb_float_to_uchar(&lcol->r, col_mix); - } - } + rgb_float_to_uchar(&lcol->r, col_mix); + } + } - /* remove stale me->mcol, will be added later */ - BKE_mesh_tessface_clear(me); + /* remove stale me->mcol, will be added later */ + BKE_mesh_tessface_clear(me); - DEG_id_tag_update(&me->id, 0); + DEG_id_tag_update(&me->id, 0); - return true; + return true; } /* -------------------------------------------------------------------- */ @@ -96,548 +93,566 @@ bool ED_vpaint_color_transform( BLI_INLINE uint mcol_blend(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac; + uint col_mix = 0; - if (fac == 0) { - return col_src; - } + if (fac == 0) { + return col_src; + } - if (fac >= 255) { - return col_dst; - } + if (fac >= 255) { + return col_dst; + } - mfac = 255 - fac; + mfac = 255 - fac; - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; - /* Updated to use the rgb squared color model which blends nicer. */ - int r1 = cp_src[0] * cp_src[0]; - int g1 = cp_src[1] * cp_src[1]; - int b1 = cp_src[2] * cp_src[2]; - int a1 = cp_src[3] * cp_src[3]; + /* Updated to use the rgb squared color model which blends nicer. */ + int r1 = cp_src[0] * cp_src[0]; + int g1 = cp_src[1] * cp_src[1]; + int b1 = cp_src[2] * cp_src[2]; + int a1 = cp_src[3] * cp_src[3]; - int r2 = cp_dst[0] * cp_dst[0]; - int g2 = cp_dst[1] * cp_dst[1]; - int b2 = cp_dst[2] * cp_dst[2]; - int a2 = cp_dst[3] * cp_dst[3]; + int r2 = cp_dst[0] * cp_dst[0]; + int g2 = cp_dst[1] * cp_dst[1]; + int b2 = cp_dst[2] * cp_dst[2]; + int a2 = cp_dst[3] * cp_dst[3]; - cp_mix[0] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * r1 + fac * r2), 255))); - cp_mix[1] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * g1 + fac * g2), 255))); - cp_mix[2] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * b1 + fac * b2), 255))); - cp_mix[3] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * a1 + fac * a2), 255))); + cp_mix[0] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * r1 + fac * r2), 255))); + cp_mix[1] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * g1 + fac * g2), 255))); + cp_mix[2] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * b1 + fac * b2), 255))); + cp_mix[3] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * a1 + fac * a2), 255))); - return col_mix; + return col_mix; } BLI_INLINE uint mcol_add(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - temp = cp_src[0] + divide_round_i((fac * cp_dst[0]), 255); - cp_mix[0] = (temp > 254) ? 255 : temp; - temp = cp_src[1] + divide_round_i((fac * cp_dst[1]), 255); - cp_mix[1] = (temp > 254) ? 255 : temp; - temp = cp_src[2] + divide_round_i((fac * cp_dst[2]), 255); - cp_mix[2] = (temp > 254) ? 255 : temp; - temp = cp_src[3] + divide_round_i((fac * cp_dst[3]), 255); - cp_mix[3] = (temp > 254) ? 255 : temp; - - return col_mix; + uchar *cp_src, *cp_dst, *cp_mix; + int temp; + uint col_mix = 0; + + if (fac == 0) { + return col_src; + } + + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; + + temp = cp_src[0] + divide_round_i((fac * cp_dst[0]), 255); + cp_mix[0] = (temp > 254) ? 255 : temp; + temp = cp_src[1] + divide_round_i((fac * cp_dst[1]), 255); + cp_mix[1] = (temp > 254) ? 255 : temp; + temp = cp_src[2] + divide_round_i((fac * cp_dst[2]), 255); + cp_mix[2] = (temp > 254) ? 255 : temp; + temp = cp_src[3] + divide_round_i((fac * cp_dst[3]), 255); + cp_mix[3] = (temp > 254) ? 255 : temp; + + return col_mix; } BLI_INLINE uint mcol_sub(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - temp = cp_src[0] - divide_round_i((fac * cp_dst[0]), 255); - cp_mix[0] = (temp < 0) ? 0 : temp; - temp = cp_src[1] - divide_round_i((fac * cp_dst[1]), 255); - cp_mix[1] = (temp < 0) ? 0 : temp; - temp = cp_src[2] - divide_round_i((fac * cp_dst[2]), 255); - cp_mix[2] = (temp < 0) ? 0 : temp; - temp = cp_src[3] - divide_round_i((fac * cp_dst[3]), 255); - cp_mix[3] = (temp < 0) ? 0 : temp; - - return col_mix; + uchar *cp_src, *cp_dst, *cp_mix; + int temp; + uint col_mix = 0; + + if (fac == 0) { + return col_src; + } + + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; + + temp = cp_src[0] - divide_round_i((fac * cp_dst[0]), 255); + cp_mix[0] = (temp < 0) ? 0 : temp; + temp = cp_src[1] - divide_round_i((fac * cp_dst[1]), 255); + cp_mix[1] = (temp < 0) ? 0 : temp; + temp = cp_src[2] - divide_round_i((fac * cp_dst[2]), 255); + cp_mix[2] = (temp < 0) ? 0 : temp; + temp = cp_src[3] - divide_round_i((fac * cp_dst[3]), 255); + cp_mix[3] = (temp < 0) ? 0 : temp; + + return col_mix; } BLI_INLINE uint mcol_mul(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac; + uint col_mix = 0; - if (fac == 0) { - return col_src; - } + if (fac == 0) { + return col_src; + } - mfac = 255 - fac; + mfac = 255 - fac; - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; - /* first mul, then blend the fac */ - cp_mix[0] = divide_round_i(mfac * cp_src[0] * 255 + fac * cp_dst[0] * cp_src[0], 255 * 255); - cp_mix[1] = divide_round_i(mfac * cp_src[1] * 255 + fac * cp_dst[1] * cp_src[1], 255 * 255); - cp_mix[2] = divide_round_i(mfac * cp_src[2] * 255 + fac * cp_dst[2] * cp_src[2], 255 * 255); - cp_mix[3] = divide_round_i(mfac * cp_src[3] * 255 + fac * cp_dst[3] * cp_src[3], 255 * 255); + /* first mul, then blend the fac */ + cp_mix[0] = divide_round_i(mfac * cp_src[0] * 255 + fac * cp_dst[0] * cp_src[0], 255 * 255); + cp_mix[1] = divide_round_i(mfac * cp_src[1] * 255 + fac * cp_dst[1] * cp_src[1], 255 * 255); + cp_mix[2] = divide_round_i(mfac * cp_src[2] * 255 + fac * cp_dst[2] * cp_src[2], 255 * 255); + cp_mix[3] = divide_round_i(mfac * cp_src[3] * 255 + fac * cp_dst[3] * cp_src[3], 255 * 255); - return col_mix; + return col_mix; } BLI_INLINE uint mcol_lighten(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - else if (fac >= 255) { - return col_dst; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - /* See if are lighter, if so mix, else don't do anything. - * if the paint color is darker then the original, then ignore */ - if (IMB_colormanagement_get_luminance_byte(cp_src) > IMB_colormanagement_get_luminance_byte(cp_dst)) { - return col_src; - } - - cp_mix[0] = divide_round_i(mfac * cp_src[0] + fac * cp_dst[0], 255); - cp_mix[1] = divide_round_i(mfac * cp_src[1] + fac * cp_dst[1], 255); - cp_mix[2] = divide_round_i(mfac * cp_src[2] + fac * cp_dst[2], 255); - cp_mix[3] = divide_round_i(mfac * cp_src[3] + fac * cp_dst[3], 255); - - return col_mix; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac; + uint col_mix = 0; + + if (fac == 0) { + return col_src; + } + else if (fac >= 255) { + return col_dst; + } + + mfac = 255 - fac; + + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; + + /* See if are lighter, if so mix, else don't do anything. + * if the paint color is darker then the original, then ignore */ + if (IMB_colormanagement_get_luminance_byte(cp_src) > + IMB_colormanagement_get_luminance_byte(cp_dst)) { + return col_src; + } + + cp_mix[0] = divide_round_i(mfac * cp_src[0] + fac * cp_dst[0], 255); + cp_mix[1] = divide_round_i(mfac * cp_src[1] + fac * cp_dst[1], 255); + cp_mix[2] = divide_round_i(mfac * cp_src[2] + fac * cp_dst[2], 255); + cp_mix[3] = divide_round_i(mfac * cp_src[3] + fac * cp_dst[3], 255); + + return col_mix; } BLI_INLINE uint mcol_darken(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - else if (fac >= 255) { - return col_dst; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - /* See if were darker, if so mix, else don't do anything. - * if the paint color is brighter then the original, then ignore */ - if (IMB_colormanagement_get_luminance_byte(cp_src) < IMB_colormanagement_get_luminance_byte(cp_dst)) { - return col_src; - } - - cp_mix[0] = divide_round_i((mfac * cp_src[0] + fac * cp_dst[0]), 255); - cp_mix[1] = divide_round_i((mfac * cp_src[1] + fac * cp_dst[1]), 255); - cp_mix[2] = divide_round_i((mfac * cp_src[2] + fac * cp_dst[2]), 255); - cp_mix[3] = divide_round_i((mfac * cp_src[3] + fac * cp_dst[3]), 255); - return col_mix; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac; + uint col_mix = 0; + + if (fac == 0) { + return col_src; + } + else if (fac >= 255) { + return col_dst; + } + + mfac = 255 - fac; + + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; + + /* See if were darker, if so mix, else don't do anything. + * if the paint color is brighter then the original, then ignore */ + if (IMB_colormanagement_get_luminance_byte(cp_src) < + IMB_colormanagement_get_luminance_byte(cp_dst)) { + return col_src; + } + + cp_mix[0] = divide_round_i((mfac * cp_src[0] + fac * cp_dst[0]), 255); + cp_mix[1] = divide_round_i((mfac * cp_src[1] + fac * cp_dst[1]), 255); + cp_mix[2] = divide_round_i((mfac * cp_src[2] + fac * cp_dst[2]), 255); + cp_mix[3] = divide_round_i((mfac * cp_src[3] + fac * cp_dst[3]), 255); + return col_mix; } BLI_INLINE uint mcol_colordodge(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - temp = (cp_dst[0] == 255) ? 255 : min_ii((cp_src[0] * 225) / (255 - cp_dst[0]), 255); - cp_mix[0] = (mfac * cp_src[0] + temp * fac) / 255; - temp = (cp_dst[1] == 255) ? 255 : min_ii((cp_src[1] * 225) / (255 - cp_dst[1]), 255); - cp_mix[1] = (mfac * cp_src[1] + temp * fac) / 255; - temp = (cp_dst[2] == 255) ? 255 : min_ii((cp_src[2] * 225) / (255 - cp_dst[2]), 255); - cp_mix[2] = (mfac * cp_src[2] + temp * fac) / 255; - temp = (cp_dst[3] == 255) ? 255 : min_ii((cp_src[3] * 225) / (255 - cp_dst[3]), 255); - cp_mix[3] = (mfac * cp_src[3] + temp * fac) / 255; - return col_mix; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac, temp; + uint col_mix = 0; + + if (fac == 0) { + return col_src; + } + + mfac = 255 - fac; + + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; + + temp = (cp_dst[0] == 255) ? 255 : min_ii((cp_src[0] * 225) / (255 - cp_dst[0]), 255); + cp_mix[0] = (mfac * cp_src[0] + temp * fac) / 255; + temp = (cp_dst[1] == 255) ? 255 : min_ii((cp_src[1] * 225) / (255 - cp_dst[1]), 255); + cp_mix[1] = (mfac * cp_src[1] + temp * fac) / 255; + temp = (cp_dst[2] == 255) ? 255 : min_ii((cp_src[2] * 225) / (255 - cp_dst[2]), 255); + cp_mix[2] = (mfac * cp_src[2] + temp * fac) / 255; + temp = (cp_dst[3] == 255) ? 255 : min_ii((cp_src[3] * 225) / (255 - cp_dst[3]), 255); + cp_mix[3] = (mfac * cp_src[3] + temp * fac) / 255; + return col_mix; } BLI_INLINE uint mcol_difference(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - temp = abs(cp_src[0] - cp_dst[0]); - cp_mix[0] = (mfac * cp_src[0] + temp * fac) / 255; - temp = abs(cp_src[1] - cp_dst[1]); - cp_mix[1] = (mfac * cp_src[1] + temp * fac) / 255; - temp = abs(cp_src[2] - cp_dst[2]); - cp_mix[2] = (mfac * cp_src[2] + temp * fac) / 255; - temp = abs(cp_src[3] - cp_dst[3]); - cp_mix[3] = (mfac * cp_src[3] + temp * fac) / 255; - return col_mix; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac, temp; + uint col_mix = 0; + + if (fac == 0) { + return col_src; + } + + mfac = 255 - fac; + + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; + + temp = abs(cp_src[0] - cp_dst[0]); + cp_mix[0] = (mfac * cp_src[0] + temp * fac) / 255; + temp = abs(cp_src[1] - cp_dst[1]); + cp_mix[1] = (mfac * cp_src[1] + temp * fac) / 255; + temp = abs(cp_src[2] - cp_dst[2]); + cp_mix[2] = (mfac * cp_src[2] + temp * fac) / 255; + temp = abs(cp_src[3] - cp_dst[3]); + cp_mix[3] = (mfac * cp_src[3] + temp * fac) / 255; + return col_mix; } BLI_INLINE uint mcol_screen(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - temp = max_ii(255 - (((255 - cp_src[0]) * (255 - cp_dst[0])) / 255), 0); - cp_mix[0] = (mfac * cp_src[0] + temp * fac) / 255; - temp = max_ii(255 - (((255 - cp_src[1]) * (255 - cp_dst[1])) / 255), 0); - cp_mix[1] = (mfac * cp_src[1] + temp * fac) / 255; - temp = max_ii(255 - (((255 - cp_src[2]) * (255 - cp_dst[2])) / 255), 0); - cp_mix[2] = (mfac * cp_src[2] + temp * fac) / 255; - temp = max_ii(255 - (((255 - cp_src[3]) * (255 - cp_dst[3])) / 255), 0); - cp_mix[3] = (mfac * cp_src[3] + temp * fac) / 255; - return col_mix; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac, temp; + uint col_mix = 0; + + if (fac == 0) { + return col_src; + } + + mfac = 255 - fac; + + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; + + temp = max_ii(255 - (((255 - cp_src[0]) * (255 - cp_dst[0])) / 255), 0); + cp_mix[0] = (mfac * cp_src[0] + temp * fac) / 255; + temp = max_ii(255 - (((255 - cp_src[1]) * (255 - cp_dst[1])) / 255), 0); + cp_mix[1] = (mfac * cp_src[1] + temp * fac) / 255; + temp = max_ii(255 - (((255 - cp_src[2]) * (255 - cp_dst[2])) / 255), 0); + cp_mix[2] = (mfac * cp_src[2] + temp * fac) / 255; + temp = max_ii(255 - (((255 - cp_src[3]) * (255 - cp_dst[3])) / 255), 0); + cp_mix[3] = (mfac * cp_src[3] + temp * fac) / 255; + return col_mix; } BLI_INLINE uint mcol_hardlight(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - int i = 0; - - for (i = 0; i < 4; i++) { - if (cp_dst[i] > 127) { - temp = 255 - ((255 - 2 * (cp_dst[i] - 127)) * (255 - cp_src[i]) / 255); - } - else { - temp = (2 * cp_dst[i] * cp_src[i]) >> 8; - } - cp_mix[i] = min_ii((mfac * cp_src[i] + temp * fac) / 255, 255); - } - return col_mix; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac, temp; + uint col_mix = 0; + + if (fac == 0) { + return col_src; + } + + mfac = 255 - fac; + + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; + + int i = 0; + + for (i = 0; i < 4; i++) { + if (cp_dst[i] > 127) { + temp = 255 - ((255 - 2 * (cp_dst[i] - 127)) * (255 - cp_src[i]) / 255); + } + else { + temp = (2 * cp_dst[i] * cp_src[i]) >> 8; + } + cp_mix[i] = min_ii((mfac * cp_src[i] + temp * fac) / 255, 255); + } + return col_mix; } BLI_INLINE uint mcol_overlay(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - int i = 0; - - for (i = 0; i < 4; i++) { - if (cp_src[i] > 127) { - temp = 255 - ((255 - 2 * (cp_src[i] - 127)) * (255 - cp_dst[i]) / 255); - } - else { - temp = (2 * cp_dst[i] * cp_src[i]) >> 8; - } - cp_mix[i] = min_ii((mfac * cp_src[i] + temp * fac) / 255, 255); - } - return col_mix; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac, temp; + uint col_mix = 0; + + if (fac == 0) { + return col_src; + } + + mfac = 255 - fac; + + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; + + int i = 0; + + for (i = 0; i < 4; i++) { + if (cp_src[i] > 127) { + temp = 255 - ((255 - 2 * (cp_src[i] - 127)) * (255 - cp_dst[i]) / 255); + } + else { + temp = (2 * cp_dst[i] * cp_src[i]) >> 8; + } + cp_mix[i] = min_ii((mfac * cp_src[i] + temp * fac) / 255, 255); + } + return col_mix; } BLI_INLINE uint mcol_softlight(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - int i = 0; - - for (i = 0; i < 4; i++) { - if (cp_src[i] < 127) { - temp = ((2 * ((cp_dst[i] / 2) + 64)) * cp_src[i]) / 255; - } - else { - temp = 255 - (2 * (255 - ((cp_dst[i] / 2) + 64)) * (255 - cp_src[i]) / 255); - } - cp_mix[i] = (temp * fac + cp_src[i] * mfac) / 255; - } - return col_mix; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac, temp; + uint col_mix = 0; + + if (fac == 0) { + return col_src; + } + + mfac = 255 - fac; + + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; + + int i = 0; + + for (i = 0; i < 4; i++) { + if (cp_src[i] < 127) { + temp = ((2 * ((cp_dst[i] / 2) + 64)) * cp_src[i]) / 255; + } + else { + temp = 255 - (2 * (255 - ((cp_dst[i] / 2) + 64)) * (255 - cp_src[i]) / 255); + } + cp_mix[i] = (temp * fac + cp_src[i] * mfac) / 255; + } + return col_mix; } BLI_INLINE uint mcol_exclusion(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac, temp; + uint col_mix = 0; - if (fac == 0) { - return col_src; - } + if (fac == 0) { + return col_src; + } - mfac = 255 - fac; + mfac = 255 - fac; - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; - int i = 0; + int i = 0; - for (i = 0; i < 4; i++) { - temp = 127 - ((2 * (cp_src[i] - 127) * (cp_dst[i] - 127)) / 255); - cp_mix[i] = (temp * fac + cp_src[i] * mfac) / 255; - } - return col_mix; + for (i = 0; i < 4; i++) { + temp = 127 - ((2 * (cp_src[i] - 127) * (cp_dst[i] - 127)) / 255); + cp_mix[i] = (temp * fac + cp_src[i] * mfac) / 255; + } + return col_mix; } BLI_INLINE uint mcol_luminosity(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac; + uint col_mix = 0; - if (fac == 0) { - return col_src; - } + if (fac == 0) { + return col_src; + } - mfac = 255 - fac; + mfac = 255 - fac; - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; - float h1, s1, v1; - float h2, s2, v2; - float r, g, b; - rgb_to_hsv(cp_src[0] / 255.0f, cp_src[1] / 255.0f, cp_src[2] / 255.0f, &h1, &s1, &v1); - rgb_to_hsv(cp_dst[0] / 255.0f, cp_dst[1] / 255.0f, cp_dst[2] / 255.0f, &h2, &s2, &v2); + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + rgb_to_hsv(cp_src[0] / 255.0f, cp_src[1] / 255.0f, cp_src[2] / 255.0f, &h1, &s1, &v1); + rgb_to_hsv(cp_dst[0] / 255.0f, cp_dst[1] / 255.0f, cp_dst[2] / 255.0f, &h2, &s2, &v2); - v1 = v2; + v1 = v2; - hsv_to_rgb(h1, s1, v1, &r, &g, &b); + hsv_to_rgb(h1, s1, v1, &r, &g, &b); - cp_mix[0] = ((int)(r * 255.0f) * fac + mfac * cp_src[0]) / 255; - cp_mix[1] = ((int)(g * 255.0f) * fac + mfac * cp_src[1]) / 255; - cp_mix[2] = ((int)(b * 255.0f) * fac + mfac * cp_src[2]) / 255; - cp_mix[3] = ((int)(cp_dst[3]) * fac + mfac * cp_src[3]) / 255; - return col_mix; + cp_mix[0] = ((int)(r * 255.0f) * fac + mfac * cp_src[0]) / 255; + cp_mix[1] = ((int)(g * 255.0f) * fac + mfac * cp_src[1]) / 255; + cp_mix[2] = ((int)(b * 255.0f) * fac + mfac * cp_src[2]) / 255; + cp_mix[3] = ((int)(cp_dst[3]) * fac + mfac * cp_src[3]) / 255; + return col_mix; } BLI_INLINE uint mcol_saturation(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac; + uint col_mix = 0; - if (fac == 0) { - return col_src; - } + if (fac == 0) { + return col_src; + } - mfac = 255 - fac; + mfac = 255 - fac; - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; - float h1, s1, v1; - float h2, s2, v2; - float r, g, b; - rgb_to_hsv(cp_src[0] / 255.0f, cp_src[1] / 255.0f, cp_src[2] / 255.0f, &h1, &s1, &v1); - rgb_to_hsv(cp_dst[0] / 255.0f, cp_dst[1] / 255.0f, cp_dst[2] / 255.0f, &h2, &s2, &v2); + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + rgb_to_hsv(cp_src[0] / 255.0f, cp_src[1] / 255.0f, cp_src[2] / 255.0f, &h1, &s1, &v1); + rgb_to_hsv(cp_dst[0] / 255.0f, cp_dst[1] / 255.0f, cp_dst[2] / 255.0f, &h2, &s2, &v2); - if (s1 > EPS_SATURATION) { - s1 = s2; - } + if (s1 > EPS_SATURATION) { + s1 = s2; + } - hsv_to_rgb(h1, s1, v1, &r, &g, &b); + hsv_to_rgb(h1, s1, v1, &r, &g, &b); - cp_mix[0] = ((int)(r * 255.0f) * fac + mfac * cp_src[0]) / 255; - cp_mix[1] = ((int)(g * 255.0f) * fac + mfac * cp_src[1]) / 255; - cp_mix[2] = ((int)(b * 255.0f) * fac + mfac * cp_src[2]) / 255; - return col_mix; + cp_mix[0] = ((int)(r * 255.0f) * fac + mfac * cp_src[0]) / 255; + cp_mix[1] = ((int)(g * 255.0f) * fac + mfac * cp_src[1]) / 255; + cp_mix[2] = ((int)(b * 255.0f) * fac + mfac * cp_src[2]) / 255; + return col_mix; } BLI_INLINE uint mcol_hue(uint col_src, uint col_dst, int fac) { - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; + uchar *cp_src, *cp_dst, *cp_mix; + int mfac; + uint col_mix = 0; - if (fac == 0) { - return col_src; - } + if (fac == 0) { + return col_src; + } - mfac = 255 - fac; + mfac = 255 - fac; - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; + cp_src = (uchar *)&col_src; + cp_dst = (uchar *)&col_dst; + cp_mix = (uchar *)&col_mix; - float h1, s1, v1; - float h2, s2, v2; - float r, g, b; - rgb_to_hsv(cp_src[0] / 255.0f, cp_src[1] / 255.0f, cp_src[2] / 255.0f, &h1, &s1, &v1); - rgb_to_hsv(cp_dst[0] / 255.0f, cp_dst[1] / 255.0f, cp_dst[2] / 255.0f, &h2, &s2, &v2); + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + rgb_to_hsv(cp_src[0] / 255.0f, cp_src[1] / 255.0f, cp_src[2] / 255.0f, &h1, &s1, &v1); + rgb_to_hsv(cp_dst[0] / 255.0f, cp_dst[1] / 255.0f, cp_dst[2] / 255.0f, &h2, &s2, &v2); - h1 = h2; + h1 = h2; - hsv_to_rgb(h1, s1, v1, &r, &g, &b); + hsv_to_rgb(h1, s1, v1, &r, &g, &b); - cp_mix[0] = ((int)(r * 255.0f) * fac + mfac * cp_src[0]) / 255; - cp_mix[1] = ((int)(g * 255.0f) * fac + mfac * cp_src[1]) / 255; - cp_mix[2] = ((int)(b * 255.0f) * fac + mfac * cp_src[2]) / 255; - cp_mix[3] = ((int)(cp_dst[3]) * fac + mfac * cp_src[3]) / 255; - return col_mix; + cp_mix[0] = ((int)(r * 255.0f) * fac + mfac * cp_src[0]) / 255; + cp_mix[1] = ((int)(g * 255.0f) * fac + mfac * cp_src[1]) / 255; + cp_mix[2] = ((int)(b * 255.0f) * fac + mfac * cp_src[2]) / 255; + cp_mix[3] = ((int)(cp_dst[3]) * fac + mfac * cp_src[3]) / 255; + return col_mix; } BLI_INLINE uint mcol_alpha_add(uint col_src, int fac) { - uchar *cp_src, *cp_mix; - int temp; - uint col_mix = col_src; + uchar *cp_src, *cp_mix; + int temp; + uint col_mix = col_src; - if (fac == 0) { - return col_src; - } + if (fac == 0) { + return col_src; + } - cp_src = (uchar *)&col_src; - cp_mix = (uchar *)&col_mix; + cp_src = (uchar *)&col_src; + cp_mix = (uchar *)&col_mix; - temp = cp_src[3] + fac; - cp_mix[3] = (temp > 254) ? 255 : temp; + temp = cp_src[3] + fac; + cp_mix[3] = (temp > 254) ? 255 : temp; - return col_mix; + return col_mix; } BLI_INLINE uint mcol_alpha_sub(uint col_src, int fac) { - uchar *cp_src, *cp_mix; - int temp; - uint col_mix = col_src; + uchar *cp_src, *cp_mix; + int temp; + uint col_mix = col_src; - if (fac == 0) { - return col_src; - } + if (fac == 0) { + return col_src; + } - cp_src = (uchar *)&col_src; - cp_mix = (uchar *)&col_mix; + cp_src = (uchar *)&col_src; + cp_mix = (uchar *)&col_mix; - temp = cp_src[3] - fac; - cp_mix[3] = temp < 0 ? 0 : temp; + temp = cp_src[3] - fac; + cp_mix[3] = temp < 0 ? 0 : temp; - return col_mix; + return col_mix; } /* wpaint has 'ED_wpaint_blend_tool' */ -uint ED_vpaint_blend_tool( - const int tool, const uint col, - const uint paintcol, const int alpha_i) +uint ED_vpaint_blend_tool(const int tool, const uint col, const uint paintcol, const int alpha_i) { - switch ((IMB_BlendMode)tool) { - case IMB_BLEND_MIX: return mcol_blend(col, paintcol, alpha_i); - case IMB_BLEND_ADD: return mcol_add(col, paintcol, alpha_i); - case IMB_BLEND_SUB: return mcol_sub(col, paintcol, alpha_i); - case IMB_BLEND_MUL: return mcol_mul(col, paintcol, alpha_i); - case IMB_BLEND_LIGHTEN: return mcol_lighten(col, paintcol, alpha_i); - case IMB_BLEND_DARKEN: return mcol_darken(col, paintcol, alpha_i); - case IMB_BLEND_COLORDODGE: return mcol_colordodge(col, paintcol, alpha_i); - case IMB_BLEND_DIFFERENCE: return mcol_difference(col, paintcol, alpha_i); - case IMB_BLEND_SCREEN: return mcol_screen(col, paintcol, alpha_i); - case IMB_BLEND_HARDLIGHT: return mcol_hardlight(col, paintcol, alpha_i); - case IMB_BLEND_OVERLAY: return mcol_overlay(col, paintcol, alpha_i); - case IMB_BLEND_SOFTLIGHT: return mcol_softlight(col, paintcol, alpha_i); - case IMB_BLEND_EXCLUSION: return mcol_exclusion(col, paintcol, alpha_i); - case IMB_BLEND_LUMINOSITY: return mcol_luminosity(col, paintcol, alpha_i); - case IMB_BLEND_SATURATION: return mcol_saturation(col, paintcol, alpha_i); - case IMB_BLEND_HUE: return mcol_hue(col, paintcol, alpha_i); - /* non-color */ - case IMB_BLEND_ERASE_ALPHA: return mcol_alpha_sub(col, alpha_i); - case IMB_BLEND_ADD_ALPHA: return mcol_alpha_add(col, alpha_i); - default: - BLI_assert(0); - return 0; - } + switch ((IMB_BlendMode)tool) { + case IMB_BLEND_MIX: + return mcol_blend(col, paintcol, alpha_i); + case IMB_BLEND_ADD: + return mcol_add(col, paintcol, alpha_i); + case IMB_BLEND_SUB: + return mcol_sub(col, paintcol, alpha_i); + case IMB_BLEND_MUL: + return mcol_mul(col, paintcol, alpha_i); + case IMB_BLEND_LIGHTEN: + return mcol_lighten(col, paintcol, alpha_i); + case IMB_BLEND_DARKEN: + return mcol_darken(col, paintcol, alpha_i); + case IMB_BLEND_COLORDODGE: + return mcol_colordodge(col, paintcol, alpha_i); + case IMB_BLEND_DIFFERENCE: + return mcol_difference(col, paintcol, alpha_i); + case IMB_BLEND_SCREEN: + return mcol_screen(col, paintcol, alpha_i); + case IMB_BLEND_HARDLIGHT: + return mcol_hardlight(col, paintcol, alpha_i); + case IMB_BLEND_OVERLAY: + return mcol_overlay(col, paintcol, alpha_i); + case IMB_BLEND_SOFTLIGHT: + return mcol_softlight(col, paintcol, alpha_i); + case IMB_BLEND_EXCLUSION: + return mcol_exclusion(col, paintcol, alpha_i); + case IMB_BLEND_LUMINOSITY: + return mcol_luminosity(col, paintcol, alpha_i); + case IMB_BLEND_SATURATION: + return mcol_saturation(col, paintcol, alpha_i); + case IMB_BLEND_HUE: + return mcol_hue(col, paintcol, alpha_i); + /* non-color */ + case IMB_BLEND_ERASE_ALPHA: + return mcol_alpha_sub(col, alpha_i); + case IMB_BLEND_ADD_ALPHA: + return mcol_alpha_add(col, alpha_i); + default: + BLI_assert(0); + return 0; + } } /** \} */ |