[Bf-blender-cvs] [9bbb5f5a6ac] master: Painting: migrated curve mask generation to CPP.

Jeroen Bakker noreply at git.blender.org
Mon Nov 22 11:01:55 CET 2021


Commit: 9bbb5f5a6acd9eafd41274b55011011ebad0daaf
Author: Jeroen Bakker
Date:   Mon Nov 22 10:44:49 2021 +0100
Branches: master
https://developer.blender.org/rB9bbb5f5a6acd9eafd41274b55011011ebad0daaf

Painting: migrated curve mask generation to CPP.

Curve mask generation is done during 2d texture painting. There are some
performance issues in this part of the code. Before addressing those we
move the code to CPP.

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

M	source/blender/editors/sculpt_paint/CMakeLists.txt
M	source/blender/editors/sculpt_paint/paint_image_2d.c
A	source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc
M	source/blender/editors/sculpt_paint/paint_intern.h

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

diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 3b668a1bd4c..b826ff8701d 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -44,6 +44,7 @@ set(SRC
   paint_hide.c
   paint_image.c
   paint_image_2d.c
+  paint_image_2d_curve_mask.cc
   paint_image_proj.c
   paint_mask.c
   paint_ops.c
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index 318180e5eb4..7191431cf4c 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -78,12 +78,13 @@ typedef struct BrushPainterCache {
 
   ImBuf *ibuf;
   ImBuf *texibuf;
-  ushort *curve_mask;
   ushort *tex_mask;
   ushort *tex_mask_old;
   uint tex_mask_old_w;
   uint tex_mask_old_h;
 
+  CurveMaskCache curve_mask_cache;
+
   int image_size[2];
 } BrushPainterCache;
 
@@ -169,9 +170,6 @@ static void brush_painter_2d_require_imbuf(
     if (cache->ibuf) {
       IMB_freeImBuf(cache->ibuf);
     }
-    if (cache->curve_mask) {
-      MEM_freeN(cache->curve_mask);
-    }
     if (cache->tex_mask) {
       MEM_freeN(cache->tex_mask);
     }
@@ -179,7 +177,6 @@ static void brush_painter_2d_require_imbuf(
       MEM_freeN(cache->tex_mask_old);
     }
     cache->ibuf = NULL;
-    cache->curve_mask = NULL;
     cache->tex_mask = NULL;
     cache->lastdiameter = -1; /* force ibuf create in refresh */
     cache->invert = invert;
@@ -200,9 +197,7 @@ static void brush_painter_cache_2d_free(BrushPainterCache *cache)
   if (cache->texibuf) {
     IMB_freeImBuf(cache->texibuf);
   }
-  if (cache->curve_mask) {
-    MEM_freeN(cache->curve_mask);
-  }
+  paint_curve_mask_cache_free_data(&cache->curve_mask_cache);
   if (cache->tex_mask) {
     MEM_freeN(cache->tex_mask);
   }
@@ -380,92 +375,6 @@ static void brush_painter_mask_imbuf_partial_update(BrushPainter *painter,
   cache->tex_mask_old_h = diameter;
 }
 
-/* create a mask with the falloff strength */
-static ushort *brush_painter_curve_mask_init(
-    ushort *mask, BrushPainter *painter, int diameter, float radius, const float pos[2])
-{
-  BLI_assert_msg(MEM_allocN_len(mask) == diameter * diameter * sizeof(ushort),
-                 "Allocated size of mask doesn't match.");
-
-  Brush *brush = painter->brush;
-
-  int offset = (int)floorf(diameter / 2.0f);
-
-  ushort *m;
-  m = mask;
-
-  int aa_samples = 1.0f / (radius * 0.20f);
-  if (brush->sampling_flag & BRUSH_PAINT_ANTIALIASING) {
-    aa_samples = clamp_i(aa_samples, 3, 16);
-  }
-  else {
-    aa_samples = 1;
-  }
-
-  /* Temporal until we have the brush properties */
-  const float hardness = 1.0f;
-  const float rotation = 0.0f;
-
-  float aa_offset = 1.0f / (2.0f * (float)aa_samples);
-  float aa_step = 1.0f / (float)aa_samples;
-
-  float bpos[2];
-  bpos[0] = pos[0] - floorf(pos[0]) + offset - aa_offset;
-  bpos[1] = pos[1] - floorf(pos[1]) + offset - aa_offset;
-
-  const float co = cosf(DEG2RADF(rotation));
-  const float si = sinf(DEG2RADF(rotation));
-
-  float norm_factor = 65535.0f / (float)(aa_samples * aa_samples);
-
-  for (int y = 0; y < diameter; y++) {
-    for (int x = 0; x < diameter; x++, m++) {
-      float total_samples = 0;
-      for (int i = 0; i < aa_samples; i++) {
-        for (int j = 0; j < aa_samples; j++) {
-          float pixel_xy[2] = {x + (aa_step * i), y + (aa_step * j)};
-          float xy_rot[2];
-          sub_v2_v2(pixel_xy, bpos);
-
-          xy_rot[0] = co * pixel_xy[0] - si * pixel_xy[1];
-          xy_rot[1] = si * pixel_xy[0] + co * pixel_xy[1];
-
-          float len = len_v2(xy_rot);
-          float p = len / radius;
-          if (hardness < 1.0f) {
-            p = (p - hardness) / (1.0f - hardness);
-            p = 1.0f - p;
-            CLAMP(p, 0.0f, 1.0f);
-          }
-          else {
-            p = 1.0;
-          }
-          float hardness_factor = 3.0f * p * p - 2.0f * p * p * p;
-          float curve = BKE_brush_curve_strength_clamped(brush, len, radius);
-          total_samples += curve * hardness_factor;
-        }
-      }
-      *m = (ushort)(total_samples * norm_factor);
-    }
-  }
-
-  return mask;
-}
-
-static void brush_painter_curve_mask_refresh(
-    BrushPainter *painter, ImagePaintTile *tile, int diameter, float radius, const float pos[2])
-{
-  BrushPainterCache *cache = &tile->cache;
-
-  if (diameter != cache->lastdiameter) {
-    if (cache->curve_mask != NULL) {
-      MEM_freeN(cache->curve_mask);
-    }
-    cache->curve_mask = MEM_mallocN(sizeof(ushort) * diameter * diameter, "brush_painter_mask");
-  }
-  brush_painter_curve_mask_init(cache->curve_mask, painter, diameter, radius, pos);
-}
-
 /* create imbuf with brush color */
 static ImBuf *brush_painter_imbuf_new(
     BrushPainter *painter, ImagePaintTile *tile, const int size, float pressure, float distance)
@@ -872,7 +781,7 @@ static void brush_painter_2d_refresh_cache(ImagePaintState *s,
   }
 
   /* Re-initialize the curve mask. Mask is always recreated due to the change of position. */
-  brush_painter_curve_mask_refresh(painter, tile, diameter, size, pos);
+  paint_curve_mask_cache_update(&cache->curve_mask_cache, brush, diameter, size, pos);
 
   /* detect if we need to recreate image brush buffer */
   if (diameter != cache->lastdiameter || (tex_rotation != cache->last_tex_rotation) || do_random ||
@@ -1336,7 +1245,7 @@ static void paint_2d_do_making_brush(ImagePaintState *s,
                     &tmpbuf,
                     frombuf,
                     mask,
-                    tile->cache.curve_mask,
+                    tile->cache.curve_mask_cache.curve_mask,
                     tile->cache.tex_mask,
                     mask_max,
                     region->destx,
@@ -1485,7 +1394,7 @@ static int paint_2d_op(void *state,
                              canvas,
                              frombuf,
                              NULL,
-                             tile->cache.curve_mask,
+                             tile->cache.curve_mask_cache.curve_mask,
                              tile->cache.tex_mask,
                              mask_max,
                              region[a].destx,
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc b/source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc
new file mode 100644
index 00000000000..639dfcdae72
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/paint_image_2d_curve_mask.cc
@@ -0,0 +1,149 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup ed
+ */
+
+#include "BLI_math.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_brush_types.h"
+
+#include "BKE_brush.h"
+
+#include "paint_intern.h"
+
+namespace blender::ed::sculpt_paint {
+
+/* create a mask with the falloff strength */
+static void update_curve_mask(CurveMaskCache *curve_mask_cache,
+                              const Brush *brush,
+                              const int diameter,
+                              const float radius,
+                              const float cursor_position[2])
+{
+  BLI_assert(curve_mask_cache->curve_mask != nullptr);
+  int offset = (int)floorf(diameter / 2.0f);
+
+  unsigned short *m = curve_mask_cache->curve_mask;
+
+  int aa_samples = 1.0f / (radius * 0.20f);
+  if (brush->sampling_flag & BRUSH_PAINT_ANTIALIASING) {
+    aa_samples = clamp_i(aa_samples, 3, 16);
+  }
+  else {
+    aa_samples = 1;
+  }
+
+  /* Temporal until we have the brush properties */
+  const float hardness = 1.0f;
+  const float rotation = 0.0f;
+
+  float aa_offset = 1.0f / (2.0f * (float)aa_samples);
+  float aa_step = 1.0f / (float)aa_samples;
+
+  float bpos[2];
+  bpos[0] = cursor_position[0] - floorf(cursor_position[0]) + offset - aa_offset;
+  bpos[1] = cursor_position[1] - floorf(cursor_position[1]) + offset - aa_offset;
+
+  const float co = cosf(DEG2RADF(rotation));
+  const float si = sinf(DEG2RADF(rotation));
+
+  float norm_factor = 65535.0f / (float)(aa_samples * aa_samples);
+
+  for (int y = 0; y < diameter; y++) {
+    for (int x = 0; x < diameter; x++, m++) {
+      float total_samples = 0;
+      for (int i = 0; i < aa_samples; i++) {
+        for (int j = 0; j < aa_samples; j++) {
+          float pixel_xy[2] = {x + (aa_step * i), y + (aa_step * j)};
+          float xy_rot[2];
+          sub_v2_v2(pixel_xy, bpos);
+
+          xy_rot[0] = co * pixel_xy[0] - si * pixel_xy[1];
+          xy_rot[1] = si * pixel_xy[0] + co * pixel_xy[1];
+
+          float len = len_v2(xy_rot);
+          float p = len / radius;
+          if (hardness < 1.0f) {
+            p = (p - hardness) / (1.0f - hardness);
+            p = 1.0f - p;
+            CLAMP(p, 0.0f, 1.0f);
+          }
+          else {
+            p = 1.0;
+          }
+          float hardness_factor = 3.0f * p * p - 2.0f * p * p * p;
+          float curve = BKE_brush_curve_strength_clamped(brush, len, radius);
+          total_samples += curve * hardness_factor;
+        }
+      }
+      *m = (unsigned short)(total_samples * norm_factor);
+    }
+  }
+}
+
+static size_t diameter_to_curve_mask_size(const int diameter)
+{
+  return diameter * diameter * sizeof(ushort);
+}
+
+static bool is_curve_mask_size_valid(const CurveMaskCache *curve_mask_cache, const int diameter)
+{
+  return curve_mask_cache->curve_mask_size == diameter_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list