[Bf-blender-cvs] [1acb608f526] sculpt-dev: Sculpt-dev: Start moving brush engine API to C++

Joseph Eagar noreply at git.blender.org
Sun Jan 23 21:56:57 CET 2022


Commit: 1acb608f5268a32cbfec0db807d806842e4830be
Author: Joseph Eagar
Date:   Sat Jan 22 10:59:35 2022 -0800
Branches: sculpt-dev
https://developer.blender.org/rB1acb608f5268a32cbfec0db807d806842e4830be

Sculpt-dev: Start moving brush engine API to C++

Meed to do a merge so the code is in an
incomplete state.  Anyway, I'm going to
move the brush engine code to C++, the
existing C code would never pass code
review.

I figure I can do this incrementally over
the next month or two and then submit a patch.

===================================================================

A	source/blender/blenkernel/BKE_brush_engine.hh
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/brush_channel_define.h
A	source/blender/blenkernel/intern/brush_channel_names.hh
A	source/blender/blenkernel/intern/brush_engine.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_brush_engine.hh b/source/blender/blenkernel/BKE_brush_engine.hh
new file mode 100644
index 00000000000..1d816960673
--- /dev/null
+++ b/source/blender/blenkernel/BKE_brush_engine.hh
@@ -0,0 +1,228 @@
+#include "DNA_brush_enums.h"
+#include "DNA_brush_types.h"
+#include "DNA_color_types.h"
+#include "DNA_curveprofile_types.h"
+#include "DNA_material_types.h"
+#include "DNA_node_types.h"
+#include "DNA_sculpt_brush_types.h"
+
+#include "BLI_compiler_attrs.h"
+#include "BLI_compiler_compat.h"
+#include "BLI_ghash.h"
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_rand.h"
+#include "BLI_rect.h"
+#include "BLI_smallhash.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_brush_engine.h"
+
+#include "BKE_brush.h"
+#include "BKE_brush_engine.h"
+#include "BKE_colorband.h"
+#include "BKE_colortools.h"
+#include "BKE_context.h"
+#include "BKE_curvemapping_cache.h"
+#include "BKE_curveprofile.h"
+#include "BKE_lib_override.h"
+#include "BKE_lib_query.h"
+#include "BKE_main.h"
+#include "BKE_node.h"
+#include "BKE_paint.h"
+
+#include <algorithm>
+#include <cmath>
+#include <type_traits>
+
+/* build compile time list of channel idnames */
+
+namespace blender {
+namespace brush {
+
+template<typename T> class BrushChannelIF {
+ public:
+  BrushChannelIF(BrushChannel *source) : _channel(source)
+  {
+  }
+
+  /* evaluation functions */
+
+  /** int evaluator */
+  std::enable_if_t<std::is_same<T, int>::value> evaluate(BrushMappingData *mapdata = nullptr)
+  {
+    double val = static_cast<double>(_channel->ivalue);
+
+    val = _evaluate(val, t, 0UL, mapdata);
+    return static_cast<int>(val);
+  }
+
+  /** float evaluator */
+  std::enable_if_t<std::is_same<T, float>::value> evaluate(BrushMappingData *mapdata = nullptr)
+  {
+    double val = static_cast<double>(_channel->fvalue);
+
+    val = _evaluate(val, t, 0UL, mapdata);
+    return static_cast<float>(val);
+  }
+
+  /** bool evaluator */
+  std::enable_if_t<std::is_same<T, bool>::value> evaluate(BrushMappingData *mapdata = nullptr)
+  {
+    double val = static_cast<double>(_channel->fvalue);
+
+    val = _evaluate(val, t, 0UL, mapdata);
+    return std::floor(val) != 0;
+  }
+
+  /** Curve evaluator. Unlike other channel types, this takes a float
+      argument, runs it through the brush curve and returns the result as
+      a float.
+
+      \param t value to evaluate with brush curve
+      */
+  std::enable_if_t<
+      std::conditional<std::is_same<T, BrushCurve>::value, float, std::false_type>::value>
+  evaluate(float t, BrushMappingData *mapdata = nullptr)
+  {
+    t = BKE_brush_curve_strength_ex(_channel->curve.preset, _channel->curve.curve, 1.0f - t, 1.0f);
+    double val = static_cast<double>(t);
+
+    return static_cast<float>(_evaluate(val, t, 0UL, mapdata));
+  }
+
+  /** value getter for int channels */
+  std::add_lvalue_reference_t<std::enable_if_t<std::is_same<T, int>::value>> value()
+  {
+    return _channel->ivalue;
+  }
+
+  /** value getter for float channels */
+  std::add_lvalue_reference_t<std::enable_if_t<std::is_same<T, float>::value>> value()
+  {
+    return _channel->fvalue;
+  }
+
+  /** value getter for bool channels */
+  std::add_lvalue_reference_t<std::enable_if_t<std::is_same<T, bool>::value>> value()
+  {
+    return *(reinterpret_cast<bool *>(&_channel->ivalue));
+  }
+
+  /** value getter for BrushCurve channels */
+  std::add_lvalue_reference_t<std::enable_if_t<std::is_same<T, BrushCurve>::value>> value()
+  {
+    return _channel->curve;
+  }
+
+ private:
+  double _evaluate(double val, float t, unsigned int idx, BrushMappingData *mapdata = nullptr)
+  {
+    if (idx == 3 && !(ch->flag & BRUSH_CHANNEL_APPLY_MAPPING_TO_ALPHA)) {
+      return f;
+    }
+
+    if (mapdata) {
+      double factor = f;  // 1.0f;
+
+      for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
+        BrushMapping *mp = _channel->mappings + i;
+
+        if (!(mp->flag & BRUSH_MAPPING_ENABLED)) {
+          continue;
+        }
+
+        float inputf = ((float *)mapdata)[i] * mp->premultiply;
+
+        switch ((BrushMappingFunc)mp->mapfunc) {
+          case BRUSH_MAPFUNC_NONE:
+            break;
+          case BRUSH_MAPFUNC_SAW:
+            inputf -= floorf(inputf);
+            break;
+          case BRUSH_MAPFUNC_TENT:
+            inputf -= floorf(inputf);
+            inputf = 1.0f - fabs(inputf - 0.5f) * 2.0f;
+            break;
+          case BRUSH_MAPFUNC_COS:
+            inputf = 1.0f - (cos(inputf * (float)M_PI * 2.0f) * 0.5f + 0.5f);
+            break;
+          case BRUSH_MAPFUNC_CUTOFF:
+            /*Cutoff is meant to create a fadeout effect,
+              which requires inverting the input.  To avoid
+              user confusion we just do it here instead of making
+              them check the inverse checkbox.*/
+            inputf = 1.0f - inputf;
+            CLAMP(inputf, 0.0f, mp->func_cutoff * 2.0f);
+            break;
+          case BRUSH_MAPFUNC_SQUARE:
+            inputf -= floorf(inputf);
+            inputf = inputf > mp->func_cutoff ? 1.0f : 0.0f;  //(float)(inputf > 0.5f);
+            break;
+          default:
+            break;
+        }
+
+        if (mp->flag & BRUSH_MAPPING_INVERT) {
+          inputf = 1.0f - inputf;
+        }
+
+        /* ensure curve tables exist */
+        BKE_curvemapping_init(mp->curve);
+
+        double f2 = (float)BKE_curvemapping_evaluateF(mp->curve, 0, inputf);
+        f2 = mp->min + (mp->max - mp->min) * f2;
+
+        /* make sure to update blend_items in rna_brush_engine.c
+          when adding new mode implementations */
+        switch (mp->blendmode) {
+          case MA_RAMP_BLEND:
+            break;
+          case MA_RAMP_MULT:
+            f2 *= factor;
+            break;
+          case MA_RAMP_DIV:
+            f2 = factor / (f2 == 0.0f ? 0.0001f : f2);
+            break;
+          case MA_RAMP_ADD:
+            f2 += factor;
+            break;
+          case MA_RAMP_SUB:
+            f2 = factor - f2;
+            break;
+          case MA_RAMP_DIFF:
+            f2 = fabsf(factor - f2);
+            break;
+          default:
+            printf("Unsupported brush mapping blend mode for %s (%s); will mix instead\n",
+                   ch->name,
+                   ch->idname);
+            break;
+        }
+
+        factor += (f2 - factor) * mp->factor;
+      }
+
+      f = factor;
+      CLAMP(f, _channel->def->min, _channel->def->max);
+    }
+
+    return f;
+  }
+
+  BrushChannel *_channel;
+};
+
+template<typename T> class BrushChannelSetIF {
+ public:
+  BrushChannelSetIF(BrushChannelSet *chset) : _chset(chset)
+  {
+  }
+
+
+ private:
+  BrushChannelSet *_chset;
+};
+
+}  // namespace brush
+}  // namespace blender
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 2e604517dcc..0762c88084e 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -109,6 +109,7 @@ set(SRC
   intern/brush.c
   intern/brush_channel_define.h
   intern/brush_engine.c
+  intern/brush_engine.cc
   intern/brush_engine_presets.c
   intern/bvhutils.cc
   intern/cachefile.c
@@ -483,7 +484,9 @@ set(SRC
   BKE_workspace.h
   BKE_world.h
   BKE_writeavi.h
+  intern/brush_channel_names.h
   BKE_brush_engine.h
+  BKE_brush_engine.hh
 
   nla_private.h
   particle_private.h
diff --git a/source/blender/blenkernel/intern/brush_channel_define.h b/source/blender/blenkernel/intern/brush_channel_define.h
index 6c9021d1ef3..ed6aa2a8b6a 100644
--- a/source/blender/blenkernel/intern/brush_channel_define.h
+++ b/source/blender/blenkernel/intern/brush_channel_define.h
@@ -14,7 +14,8 @@ places in rna_engine_codebase are relevent:
 */
 
 /* static name checking stuff */
-#if defined(BRUSH_CHANNEL_DEFINE_TYPES) || defined(BRUSH_CHANNEL_DEFINE_EXTERNAL)
+#if defined(BRUSH_CHANNEL_DEFINE_TYPES) || defined(BRUSH_CHANNEL_DEFINE_EXTERNAL) || \
+    defined(BRUSH_CHANNEL_MAKE_NAMES)
 #  ifdef MAKE_FLOAT
 #    undef MAKE_FLOAT
 #  endif
@@ -79,6 +80,8 @@ places in rna_engine_codebase are relevent:
 
 #  ifdef BRUSH_CHANNEL_DEFINE_TYPES
 #    define MAKE_BUILTIN_CH_DEF(idname) const char *BRUSH_BUILTIN_##idname = #    idname;
+#  elif BRUSH_CHANNEL_MAKE_NAMES
+#    define MAKE_BUILTIN_CH_DEF(idname) #idname,
 #  else
 #    define MAKE_BUILTIN_CH_DEF(idname) extern const char *BRUSH_BUILTIN_##idname;
 #  endif
diff --git a/source/blender/blenkernel/intern/brush_channel_names.hh b/source/blender/blenkernel/intern/brush_channel_names.hh
new file mode 100644
index 00000000000..1b47e092346
--- /dev/null
+++ b/source/blender/blenkernel/intern/brush_channel_names.hh
@@ -0,0 +1,10 @@
+#include <string>
+
+#define BRUSH_CHANNEL_MAKE_NAMES
+
+static std::basic_string<char*> brush_channel_idnames[] = {
+#include "intern/brush_channel_define.h"
+};
+
+
+
diff --git a/source/blender/blenkernel/intern/brush_engine.cc b/source/blender/blenkernel/intern/brush_engine.cc
new file mode 100644
index 00000000000..7d22d1fe8f9
--- /dev/null
+++ b/source/blender/blenkernel/intern/brush_engine.cc
@@ -0,0 +1,2 @@
+#include "BKE_brush_engine.hh"
+



More information about the Bf-blender-cvs mailing list