[Bf-blender-cvs] [575ade22d4d] master: Commit D14179: Revamp Vertex Paint With C++

Joseph Eagar noreply at git.blender.org
Thu Apr 21 07:21:00 CEST 2022


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. @@



More information about the Bf-blender-cvs mailing list