[Bf-blender-cvs] [15cb3130c34] sculpt-dev: Sculpt-dev: fix crash related to curve cache

Joseph Eagar noreply at git.blender.org
Wed Jan 12 08:28:51 CET 2022


Commit: 15cb3130c3448ccb5a10343e3f17d2ed06cf5a60
Author: Joseph Eagar
Date:   Tue Jan 11 23:26:56 2022 -0800
Branches: sculpt-dev
https://developer.blender.org/rB15cb3130c3448ccb5a10343e3f17d2ed06cf5a60

Sculpt-dev: fix crash related to curve
            cache

* Fixed a few bugs in the curvemapping
  cache code.
* Fixed bug in how BKE_channelset_compat_load
  was copying brush.curve to/from the falloff_curve
  brush channel.

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

M	source/blender/blenkernel/intern/brush_engine.c
M	source/blender/blenkernel/intern/brush_engine_presets.c
M	source/blender/blenkernel/intern/colortools.c
M	source/blender/blenkernel/intern/curvemapping_cache.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/makesdna/DNA_color_types.h

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

diff --git a/source/blender/blenkernel/intern/brush_engine.c b/source/blender/blenkernel/intern/brush_engine.c
index 36de8cfbfc8..0db8869632f 100644
--- a/source/blender/blenkernel/intern/brush_engine.c
+++ b/source/blender/blenkernel/intern/brush_engine.c
@@ -129,7 +129,11 @@ void BKE_brush_channel_system_exit()
 bool BKE_brush_mapping_ensure_write(BrushMapping *mp)
 {
   if (IS_CACHE_CURVE(mp->curve)) {
-    mp->curve = BKE_curvemapping_copy(mp->curve);
+    CurveMapping *newcurve = BKE_curvemapping_copy(mp->curve);
+    RELEASE_CACHE_CURVE(mp->curve);
+
+    mp->curve = newcurve;
+
     return true;
   }
 
@@ -391,6 +395,7 @@ void BKE_brush_channel_copy_data(BrushChannel *dst,
     }
     else if (dst->curve.curve) {
       BKE_curvemapping_free(dst->curve.curve);
+      dst->curve.curve = NULL;
     }
   }
 
@@ -1090,6 +1095,9 @@ double BKE_brush_channel_eval_mappings(BrushChannel *ch,
         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;
 
@@ -1182,7 +1190,9 @@ bool BKE_brush_mapping_is_enabled(BrushChannel *child, BrushChannel *parent, int
   }
 }
 
-void BKE_brush_channel_apply_mapping_flags(BrushChannel *dst, BrushChannel *child, BrushChannel *parent)
+void BKE_brush_channel_apply_mapping_flags(BrushChannel *dst,
+                                           BrushChannel *child,
+                                           BrushChannel *parent)
 {
   for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
     BrushMapping *mp = dst->mappings + i;
@@ -2034,7 +2044,7 @@ void BKE_brush_channelset_read(BlendDataReader *reader, BrushChannelSet *chset)
         BKE_curvemapping_init(curve);
       }
 
-      ch->mappings[i].curve = GET_CACHE_CURVE(curve);  // frees curve, returns new one
+      mp->curve = GET_CACHE_CURVE(curve);  // frees curve, returns new one
 
       // paranoia check to make sure BrushMapping.type is correct
       mp->type = i;
@@ -2065,7 +2075,10 @@ void BKE_brush_channelset_write(BlendWriter *writer, BrushChannelSet *chset)
     }
 
     for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
+      /* instantiate cached curves to ensure they get written
+         (and susequently read) seperately. */
       BKE_brush_mapping_ensure_write(ch->mappings + i);
+
       BKE_curvemapping_blend_write(writer, ch->mappings[i].curve);
     }
   }
diff --git a/source/blender/blenkernel/intern/brush_engine_presets.c b/source/blender/blenkernel/intern/brush_engine_presets.c
index c33577c520f..29cc7285bfc 100644
--- a/source/blender/blenkernel/intern/brush_engine_presets.c
+++ b/source/blender/blenkernel/intern/brush_engine_presets.c
@@ -33,6 +33,7 @@
 #include "BKE_colorband.h"
 #include "BKE_colortools.h"
 #include "BKE_context.h"
+#include "BKE_curvemapping_cache.h"
 #include "BKE_node.h"
 #include "BKE_paint.h"
 
@@ -266,7 +267,7 @@ static bool check_builtin_init()
   SUBTYPE_SET(smooth_stroke_radius, BRUSH_CHANNEL_PIXEL);
   SUBTYPE_SET(normal_mask_limit, BRUSH_CHANNEL_ANGLE);
   SUBTYPE_SET(view_normal_mask_limit, BRUSH_CHANNEL_ANGLE);
-  
+
   SUBTYPE_SET(jitter_absolute, BRUSH_CHANNEL_PIXEL);
 
   SUBTYPE_SET(radius, BRUSH_CHANNEL_PIXEL);
@@ -304,7 +305,7 @@ static bool check_builtin_init()
     mdef->blendmode = MA_RAMP_ADD;
   }
 
-  //SETCAT(enhance_detail_presteps, "Enhancement");
+  // SETCAT(enhance_detail_presteps, "Enhancement");
   SETCAT(concave_mask_factor, "Automasking");
   SETCAT(automasking, "Automasking");
   SETCAT(automasking_boundary_edges_propagation_steps, "Automasking");
@@ -972,16 +973,32 @@ void BKE_brush_channelset_compat_load(BrushChannelSet *chset, Brush *brush, bool
     }
   }
 
+#if 1
   if (brush_to_channels) {
     BrushChannel *ch = BRUSHSET_LOOKUP(chset, falloff_curve);
 
     if (ch) {
       ch->curve.preset = brush->curve_preset;
-      BKE_brush_channel_curve_ensure_write(&ch->curve);
 
-      if (brush->curve && brush->curve_preset == BRUSH_CURVE_CUSTOM) {
-        BKE_curvemapping_free_data(ch->curve.curve);
-        BKE_curvemapping_copy_data(ch->curve.curve, brush->curve);
+      if (brush->curve_preset == BRUSH_CURVE_CUSTOM) {
+        BKE_curvemapping_cache_release_or_free(brush_curve_cache, ch->curve.curve);
+
+        if (brush->curve) {
+          ch->curve.curve = BKE_curvemapping_copy(brush->curve);
+        }
+        else {
+          printf("%s: missing curve in brush\n", __func__);
+
+          ch->curve.curve = MEM_callocN(sizeof(CurveMapping), "CurveMapping");
+
+          BKE_curvemapping_set_defaults(ch->curve.curve, 1, 0.0f, 0.0f, 1.0f, 1.0f);
+          BKE_curvemap_reset(ch->curve.curve->cm,
+                             &(struct rctf){.xmin = 0, .ymin = 0.0, .xmax = 1.0, .ymax = 1.0},
+                             CURVE_PRESET_LINE,
+                             1);
+
+        }
+        BKE_curvemapping_init(ch->curve.curve);
       }
     }
   }
@@ -991,12 +1008,14 @@ void BKE_brush_channelset_compat_load(BrushChannelSet *chset, Brush *brush, bool
     if (ch) {
       brush->curve_preset = ch->curve.preset;
 
-      if (ch->curve.curve && ch->curve.preset == BRUSH_CURVE_CUSTOM) {
-        BKE_curvemapping_free_data(brush->curve);
-        BKE_curvemapping_copy_data(brush->curve, ch->curve.curve);
+      if (ch->curve.preset == BRUSH_CURVE_CUSTOM) {
+        BKE_curvemapping_cache_release_or_free(brush_curve_cache, brush->curve);
+        brush->curve = BKE_curvemapping_copy(ch->curve.curve);
+        BKE_curvemapping_init(brush->curve);
       }
     }
   }
+#endif
 }
 
 /* todo: move into BKE_brush_reset_mapping*/
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index ffca925ee09..9dce8caf4e0 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -120,6 +120,7 @@ void BKE_curvemapping_free(CurveMapping *cumap)
 {
   if (cumap) {
     BKE_curvemapping_free_data(cumap);
+    cumap->flag |= CUMA_IS_FREED;
     MEM_freeN(cumap);
   }
 }
@@ -194,6 +195,7 @@ CurveMapping *BKE_curvemapping_copy(const CurveMapping *cumap)
     CurveMapping *cumapn = MEM_dupallocN(cumap);
     BKE_curvemapping_copy_data(cumapn, cumap);
     cumapn->flag &= ~CUMA_PART_OF_CACHE;
+    cumapn->cache_users = 0;
     return cumapn;
   }
   return NULL;
diff --git a/source/blender/blenkernel/intern/curvemapping_cache.c b/source/blender/blenkernel/intern/curvemapping_cache.c
index 21aa0dc3ece..b88a8f3795c 100644
--- a/source/blender/blenkernel/intern/curvemapping_cache.c
+++ b/source/blender/blenkernel/intern/curvemapping_cache.c
@@ -182,13 +182,17 @@ CurveMappingCache *BKE_curvemapping_cache_create()
 void BKE_curvemapping_cache_aquire(CurveMappingCache *cache, CurveMapping *curve)
 {
   curve->cache_users++;
+
+  // printf("%s: %d flag: %d\n", __func__, curve->cache_users, curve->flag);
 }
 
 void BKE_curvemapping_cache_release(CurveMappingCache *cache, CurveMapping *curve)
 {
   curve->cache_users--;
 
-  if ((curve->flag & CUMA_PART_OF_CACHE) && curve->cache_users < 0) {
+  //printf("%s: %d flag: %d\n", __func__, curve->cache_users, curve->flag);
+
+  if ((curve->flag & CUMA_PART_OF_CACHE) && curve->cache_users <= 0) {
     if (!BLI_ghash_remove(cache->gh, curve, NULL, NULL)) {
       printf("error, curve was not in cache! %p\n", curve);
     }
@@ -272,6 +276,10 @@ void BKE_curvemapping_cache_exit()
 // releases a curve if it's in the cache, otherwise frees it
 void BKE_curvemapping_cache_release_or_free(CurveMappingCache *cache, CurveMapping *curve)
 {
+  if (!curve) {
+    return;
+  }
+
   if (curve->flag & CUMA_PART_OF_CACHE) {
     BKE_curvemapping_cache_release(cache, curve);
   }
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index bba49f3f95a..f2b36a3fee9 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -5050,7 +5050,7 @@ static void sculpt_topology_update(Sculpt *sd,
     BMVert *v = (BMVert *)BM_ELEM_FROM_ID_SAFE(ss->bm, actv);
 
     if (v && v->head.htype == BM_VERT) {
-      ss->active_vertex_index.i == (intptr_t)v;
+      ss->active_vertex_index.i = (intptr_t)v;
     }
     else {
       ss->active_vertex_index.i = SCULPT_REF_NONE;
@@ -5061,7 +5061,7 @@ static void sculpt_topology_update(Sculpt *sd,
     BMFace *f = (BMFace *)BM_ELEM_FROM_ID_SAFE(ss->bm, actf);
 
     if (f && f->head.htype == BM_FACE) {
-      ss->active_face_index.i == (intptr_t)f;
+      ss->active_face_index.i = (intptr_t)f;
     }
     else {
       ss->active_face_index.i = SCULPT_REF_NONE;
@@ -5847,14 +5847,11 @@ static void SCULPT_run_command(
 
   *brush2 = *brush;
 
-  BrushChannel *ch = BRUSHSET_LOOKUP(cmd->params_final, falloff_curve);
-  if (ch) {
-    brush2->curve_preset = ch->curve.preset;
-    brush2->curve = ch->curve.curve;
-  }
+  /* prevent auto freeing of brush2->curve in BKE_brush_channelset_compat_load */
+  brush2->curve = NULL;
 
-  // Load parameters into brush2 for compatibility with old code
-  // Make sure to remove all pen pressure/tilt old code
+  /* Load parameters into brush2 for compatibility with old code
+     Make sure to remove all old code for pen pressure/tilt */
   BKE_brush_channelset_compat_load(cmd->params_mapped, brush2, false);
 
   ss->cache->use_plane_trim = BRUSHSET_GET_INT(cmd->params_mapped, use_plane_trim, NULL);
@@ -6154,6 +6151,9 @@ static void SCULPT_run_commandlist(
     Brush brush2 = *brush;
     brush2.sculpt_tool = cmd->tool;
 
+    /* prevent auto freeing of brush2->curve in BKE_brush_channelset_compat_load */
+    brush2.curve = NULL;
+
     // Load parameters into brush2 for compatibility with old code
     BKE_brush_channelset_compat_load(cmd->params_final, &brush2, false);
 
@@ -6863,6 +6863,8 @@ static const char *sculpt_tool_name(Sculpt *sd)
       return "Relax";
     case SCULPT_TOOL_ENHANCE_DETAILS:
       return "Enhance Details";
+    case SCULPT_TOOL_DISPLACEMENT_HEAL:
+      return "Multires Heal";
   }
 
   return "Sculpting";
diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h
index

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list