Commit: 575ade22d4de472ccf9e7d2dc1ffca37416c58f6 Author: Joseph Eagar Date: Wed Apr 20 22:03:45 2022 -0700 Branches: master https://developer.blender.org/rB575ade22d4de472ccf9e7d2dc1ffca37416c58f6
Commit D14179: Revamp Vertex Paint With C++ - Verrtex paint mode has been refactored into C++ templates. It now works with both byte and float colors and point & corner attribute domains. - There is a new API for mixing colors (also based on C++ templates). Unlike the existing APIs byte and float colors are interpolated identically. Interpolation does happen in a squared rgb space, this may be changed in the future. - Vertex paint now uses the sculpt undo system. Reviewed By: Brecht Van Lommel. Differential Revision: https://developer.blender.org/D14179 Ref D14179 =================================================================== M release/datafiles/locale M release/scripts/addons M source/blender/blenkernel/BKE_paint.h M source/blender/blenkernel/intern/paint.c M source/blender/blenlib/BLI_color.hh A source/blender/blenlib/BLI_color_mix.hh M source/blender/blenlib/CMakeLists.txt M source/blender/blenloader/intern/versioning_300.c M source/blender/draw/engines/workbench/workbench_engine.c M source/blender/editors/mesh/mesh_data.c M source/blender/editors/sculpt_paint/CMakeLists.txt M source/blender/editors/sculpt_paint/paint_intern.h R064 source/blender/editors/sculpt_paint/paint_vertex.c source/blender/editors/sculpt_paint/paint_vertex.cc M source/blender/editors/sculpt_paint/paint_vertex_color_ops.c M source/blender/editors/sculpt_paint/paint_vertex_color_utils.c M source/blender/editors/sculpt_paint/sculpt.c M source/blender/editors/sculpt_paint/sculpt_intern.h M source/tools =================================================================== diff --git a/release/datafiles/locale b/release/datafiles/locale index 63699f96834..716dc02ec30 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 63699f968344db7dc853d2c5972325beea44900c +Subproject commit 716dc02ec30c0810513f7b4adc4ae865ae50c4e6 diff --git a/release/scripts/addons b/release/scripts/addons index baa581415c7..787ea78f7fa 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit baa581415c7ed23d7c45ef873631748135672683 +Subproject commit 787ea78f7fa6f0373d80ba1247768402df93f8ad diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 4ae37095411..10043941948 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -615,9 +615,6 @@ typedef struct SculptSession { union { struct { struct SculptVertexPaintGeomMap gmap; - - /* For non-airbrush painting to re-apply from the original (MLoop aligned). */ - unsigned int *previous_color; } vpaint; struct { diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index fe8b002302c..472e2c7ada8 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -1341,8 +1341,6 @@ void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss) struct SculptVertexPaintGeomMap *gmap = NULL; if (ss->mode_type == OB_MODE_VERTEX_PAINT) { gmap = &ss->mode.vpaint.gmap; - - MEM_SAFE_FREE(ss->mode.vpaint.previous_color); } else if (ss->mode_type == OB_MODE_WEIGHT_PAINT) { gmap = &ss->mode.wpaint.gmap; diff --git a/source/blender/blenlib/BLI_color.hh b/source/blender/blenlib/BLI_color.hh index 0754221eb65..98fd7d0f15d 100644 --- a/source/blender/blenlib/BLI_color.hh +++ b/source/blender/blenlib/BLI_color.hh @@ -345,5 +345,7 @@ BLI_color_convert_to_theme4b(const ColorSceneLinear4f<eAlpha::Straight> &scene_l using ColorGeometry4f = ColorSceneLinear4f<eAlpha::Premultiplied>; using ColorGeometry4b = ColorSceneLinearByteEncoded4b<eAlpha::Premultiplied>; +using ColorPaint4f = ColorSceneLinear4f<eAlpha::Straight>; +using ColorPaint4b = ColorSceneLinearByteEncoded4b<eAlpha::Straight>; } // namespace blender diff --git a/source/blender/blenlib/BLI_color_mix.hh b/source/blender/blenlib/BLI_color_mix.hh new file mode 100644 index 00000000000..8398f2c3326 --- /dev/null +++ b/source/blender/blenlib/BLI_color_mix.hh @@ -0,0 +1,1053 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2001-2002 NaN Holding BV. All rights reserved. */ + +/** \file + * \ingroup blenlib + * + * Contains color mixing utilities. + * + */ + +#include "BLI_color.hh" +#include "BLI_math_base.h" +#include "BLI_math_color.h" +#include "BLI_sys_types.h" + +#include "IMB_colormanagement.h" +#include "IMB_imbuf.h" + +#include <type_traits> + +namespace blender::color { + +struct ByteTraits { + using ValueType = uchar; + using BlendType = int; + + inline static const uchar range = 255; /* Zero-based maximum value. */ + inline static const float frange = 255.0f; /* Convienent floating-point version of range. */ + inline static const int cmpRange = 254; + inline static const int expandedRange = 256; /* One-based maxium value. */ + + inline static const int bytes = 1; + inline static const float unit = 255.0f; + + static inline BlendType divide_round(BlendType a, BlendType b) + { + return divide_round_i(a, b); + } + + static inline BlendType min(BlendType a, BlendType b) + { + return min_ii(a, b); + } + + static inline BlendType max(BlendType a, BlendType b) + { + return max_ii(a, b); + } + /* Discretizes in steps of 1.0 / range */ + static inline ValueType round(float f) + { + return round_fl_to_uchar(f); + } +}; + +struct FloatTraits { + using ValueType = float; + using BlendType = float; + + inline const static float range = 1.0f; + inline const static float frange = 1.0f; + inline const static float cmpRange = 0.9999f; + inline static const int expandedRange = 1.0f; + + inline const static float unit = 1.0f; + inline const static int bytes = 4; + + static inline BlendType divide_round(BlendType a, BlendType b) + { + return a / b; + } + + static inline BlendType min(BlendType a, BlendType b) + { + return min_ff(a, b); + } + + static inline BlendType max(BlendType a, BlendType b) + { + return min_ff(a, b); + } + + /* Discretizes in steps of 1.0 / range */ + static inline ValueType round(float f) + { + return f; + } +}; + +static float get_luminance(ColorPaint4f c) +{ + return IMB_colormanagement_get_luminance(&c.r); +} + +static int get_luminance(ColorPaint4b c) +{ + return IMB_colormanagement_get_luminance_byte(&c.r); +} + +#define EPS_SATURATION 0.0005f + +/* -------------------------------------------------------------------- */ +/** \name Color Blending Modes + * \{ */ + +template<typename Color, typename Traits> +static Color mix_blend(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Color col_mix(0, 0, 0, 0); + Blend mfac; + + if (fac == 0) { + return col_src; + } + + if (fac >= Traits::range) { + return col_dst; + } + + mfac = Traits::range - fac; + + cp_src = &col_src.r; + cp_dst = &col_dst.r; + cp_mix = &col_mix.r; + + /* Updated to use the rgb squared color model which blends nicer. */ + Blend r1 = cp_src[0] * cp_src[0]; + Blend g1 = cp_src[1] * cp_src[1]; + Blend b1 = cp_src[2] * cp_src[2]; + Blend a1 = cp_src[3] * cp_src[3]; + + Blend r2 = cp_dst[0] * cp_dst[0]; + Blend g2 = cp_dst[1] * cp_dst[1]; + Blend b2 = cp_dst[2] * cp_dst[2]; + Blend a2 = cp_dst[3] * cp_dst[3]; + + cp_mix[0] = Traits::round(sqrtf(Traits::divide_round((mfac * r1 + fac * r2), Traits::range))); + cp_mix[1] = Traits::round(sqrtf(Traits::divide_round((mfac * g1 + fac * g2), Traits::range))); + cp_mix[2] = Traits::round(sqrtf(Traits::divide_round((mfac * b1 + fac * b2), Traits::range))); + cp_mix[3] = Traits::round(sqrtf(Traits::divide_round((mfac * a1 + fac * a2), Traits::range))); + return Color(col_mix[0], col_mix[1], col_mix[2], col_mix[3]); + + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_add(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend temp; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + cp_src = (Value *)&col_src.r; + cp_dst = (Value *)&col_dst.r; + cp_mix = (Value *)&col_mix.r; + + temp = cp_src[0] + Traits::divide_round((fac * cp_dst[0]), Traits::range); + cp_mix[0] = (temp > Traits::cmpRange) ? Traits::range : temp; + temp = cp_src[1] + Traits::divide_round((fac * cp_dst[1]), Traits::range); + cp_mix[1] = (temp > Traits::cmpRange) ? Traits::range : temp; + temp = cp_src[2] + Traits::divide_round((fac * cp_dst[2]), Traits::range); + cp_mix[2] = (temp > Traits::cmpRange) ? Traits::range : temp; + temp = cp_src[3] + Traits::divide_round((fac * cp_dst[3]), Traits::range); + cp_mix[3] = (temp > Traits::cmpRange) ? Traits::range : temp; + + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_sub(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend temp; + Color col_mix(0, 0, 0, 0); + + cp_src = (Value *)&col_src.r; + cp_dst = (Value *)&col_dst.r; + cp_mix = (Value *)&col_mix.r; + + temp = cp_src[0] - Traits::divide_round((fac * cp_dst[0]), Traits::range); + cp_mix[0] = (temp < 0) ? 0 : temp; + temp = cp_src[1] - Traits::divide_round((fac * cp_dst[1]), Traits::range); + cp_mix[1] = (temp < 0) ? 0 : temp; + temp = cp_src[2] - Traits::divide_round((fac * cp_dst[2]), Traits::range); + cp_mix[2] = (temp < 0) ? 0 : temp; + temp = cp_src[3] - Traits::divide_round((fac * cp_dst[3]), Traits::range); + cp_mix[3] = (temp < 0) ? 0 : temp; + + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_mul(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + /* first mul, then blend the fac */ + cp_mix[0] = Traits::divide_round(mfac * cp_src[0] * Traits::range + fac * cp_dst[0] * cp_src[0], + Traits::range * Traits::range); + cp_mix[1] = Traits::divide_round(mfac * cp_src[1] * Traits::range + fac * cp_dst[1] * cp_src[1], + Traits::range * Traits::range); + cp_mix[2] = Traits::divide_round(mfac * cp_src[2] * Traits::range + fac * cp_dst[2] * cp_src[2], + Traits::range * Traits::range); + cp_mix[3] = Traits::divide_round(mfac * cp_src[3] * Traits::range + fac * cp_dst[3] * cp_src[3], + Traits::range * Traits::range); + + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_lighten(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + if (fac >= Traits::range) { + return col_dst; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + /* See if we're lighter, if so mix, else don't do anything. + * if the paint color is darker then the original, then ignore */ + if (get_luminance(cp_src) > get_luminance(cp_dst)) { + return col @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs