[Bf-blender-cvs] [939b63bcd6c] master: Sculpt: Fix more attribute bugs when switching PBVH modes

Joseph Eagar noreply at git.blender.org
Tue Dec 13 22:52:52 CET 2022


Commit: 939b63bcd6c2e2bb92c7d5feb466bb44f4427fc8
Author: Joseph Eagar
Date:   Tue Dec 13 13:42:25 2022 -0800
Branches: master
https://developer.blender.org/rB939b63bcd6c2e2bb92c7d5feb466bb44f4427fc8

Sculpt: Fix more attribute bugs when switching PBVH modes

Fixed more cases where attributes weren't being reinitialized
on switching PBVH mode:

* When PBVH_GRIDS and PBVH_BMESH force attributes into simple
  array mode they no longer override simple_array in the
  SculptAttributeParams parameters, instead they set a field
  in SculptAttribute itself.  Thus if the attribute is
  reinitialized in another mode it won't retain the simple_array
  parameter.
* sculpt_attribute_ensure_ex now calls sculpt_attr_update if
  the attribute already exists.
* Fixed a bug from a couple commits ago that set
  SculptAttribute.data_for_bmesh wrong.

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

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/intern/multires.cc
M	source/blender/blenkernel/intern/paint.cc
M	source/blender/draw/intern/draw_pbvh.cc

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

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 434255b2d9c..4acaa7b05e1 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -516,6 +516,11 @@ typedef struct SculptAttribute {
   int elem_size, elem_num;
   bool data_for_bmesh; /* Temporary data store as array outside of bmesh. */
 
+  /* Data is a flat array outside the CustomData system.
+   * This will be true if simple_array is requested in
+   * SculptAttributeParams, or the PBVH type is PBVH_GRIDS or PBVH_BMESH.
+   */
+  bool simple_array; 
   /* Data stored per BMesh element. */
   int bmesh_cd_offset;
 
diff --git a/source/blender/blenkernel/intern/multires.cc b/source/blender/blenkernel/intern/multires.cc
index 7f9a0d64e4b..3700432696a 100644
--- a/source/blender/blenkernel/intern/multires.cc
+++ b/source/blender/blenkernel/intern/multires.cc
@@ -426,6 +426,28 @@ void multires_flush_sculpt_updates(Object *object)
   }
 
   Mesh *mesh = static_cast<Mesh *>(object->data);
+
+  /* Check that the multires modifier still exists.
+   * Fixes crash when deleting multires modifier
+   * from within sculpt mode.
+   */
+  ModifierData *md;
+  MultiresModifierData *mmd = nullptr;
+  VirtualModifierData virtualModifierData;
+
+  for (md = BKE_modifiers_get_virtual_modifierlist(object, &virtualModifierData); md;
+       md = md->next) {
+    if (md->type == eModifierType_Multires) {
+      if (BKE_modifier_is_enabled(nullptr, md, eModifierMode_Realtime)) {
+        mmd = (MultiresModifierData *)md;
+      }
+    }
+  }
+
+  if (!mmd) {
+    return;
+  }
+
   multiresModifier_reshapeFromCCG(
       sculpt_session->multires.modifier->totlvl, mesh, sculpt_session->subdiv_ccg);
 
diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc
index 3100b4cc20c..718ec5318ac 100644
--- a/source/blender/blenkernel/intern/paint.cc
+++ b/source/blender/blenkernel/intern/paint.cc
@@ -2454,7 +2454,7 @@ static bool sculpt_attribute_create(SculptSession *ss,
       permanent = (out->params.permanent = false);
     }
 
-    simple_array = (out->params.simple_array = true);
+    simple_array = true;
   }
 
   BLI_assert(!(simple_array && permanent));
@@ -2466,8 +2466,8 @@ static bool sculpt_attribute_create(SculptSession *ss,
 
     out->data = MEM_calloc_arrayN(totelem, elemsize, __func__);
 
-    out->data_for_bmesh = false;
-    out->params.simple_array = true;
+    out->data_for_bmesh = ss->bm != nullptr;
+    out->simple_array = true;
     out->bmesh_cd_offset = -1;
     out->layer = nullptr;
     out->elem_size = elemsize;
@@ -2477,6 +2477,8 @@ static bool sculpt_attribute_create(SculptSession *ss,
     return true;
   }
 
+  out->simple_array = false;
+
   switch (BKE_pbvh_type(ss->pbvh)) {
     case PBVH_BMESH: {
       CustomData *cdata = nullptr;
@@ -2512,8 +2514,6 @@ static bool sculpt_attribute_create(SculptSession *ss,
     case PBVH_FACES: {
       CustomData *cdata = nullptr;
 
-      out->data_for_bmesh = false;
-
       switch (domain) {
         case ATTR_DOMAIN_POINT:
           cdata = &me->vdata;
@@ -2535,10 +2535,10 @@ static bool sculpt_attribute_create(SculptSession *ss,
         cdata->layers[index].flag |= CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY;
       }
 
-      out->data = nullptr;
       out->layer = cdata->layers + index;
-      out->bmesh_cd_offset = -1;
       out->data = out->layer->data;
+      out->data_for_bmesh = false;
+      out->bmesh_cd_offset = -1;
       out->elem_size = CustomData_get_elem_size(out->layer);
 
       break;
@@ -2566,31 +2566,36 @@ static bool sculpt_attr_update(Object *ob, SculptAttribute *attr)
 
   bool bad = false;
 
-  if (attr->params.simple_array) {
+  if (attr->data) {
     bad = attr->elem_num != elem_num;
-
-    if (bad) {
-      MEM_SAFE_FREE(attr->data);
-    }
-    else {
-      attr->data_for_bmesh = false;
-    }
   }
-  else {
-    CustomData *cdata = sculpt_get_cdata(ob, attr->domain);
 
-    if (cdata) {
-      int layer_index = CustomData_get_named_layer_index(cdata, attr->proptype, attr->name);
+  /* Check if we are a coerced simple array and shouldn't be. */
+  bad |= attr->simple_array && !attr->params.simple_array &&
+         !ELEM(BKE_pbvh_type(ss->pbvh), PBVH_GRIDS, PBVH_BMESH);
 
-      bad |= (ss->bm != nullptr) != attr->data_for_bmesh;
+  CustomData *cdata = sculpt_get_cdata(ob, attr->domain);
+  if (cdata && !attr->simple_array) {
+    int layer_index = CustomData_get_named_layer_index(cdata, attr->proptype, attr->name);
 
+    bad |= layer_index == -1;
+    bad |= (ss->bm != nullptr) != attr->data_for_bmesh;
+
+    if (!bad) {
       if (attr->data_for_bmesh) {
         attr->bmesh_cd_offset = cdata->layers[layer_index].offset;
       }
+      else {
+        attr->data = cdata->layers[layer_index].data;
+      }
     }
   }
 
   if (bad) {
+    if (attr->simple_array) {
+      MEM_SAFE_FREE(attr->data);
+    }
+
     sculpt_attribute_create(ss,
                             ob,
                             attr->domain,
@@ -2725,6 +2730,8 @@ static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob,
   SculptAttribute *attr = BKE_sculpt_attribute_get(ob, domain, proptype, name);
 
   if (attr) {
+    sculpt_attr_update(ob, attr);
+
     return attr;
   }
 
@@ -2763,7 +2770,7 @@ static void sculptsession_bmesh_attr_update_internal(Object *ob)
   }
 }
 
-void sculptsession_bmesh_add_layers(Object *ob)
+static void sculptsession_bmesh_add_layers(Object *ob)
 {
   SculptSession *ss = ob->sculpt;
   SculptAttributeParams params = {0};
@@ -2870,7 +2877,7 @@ bool BKE_sculpt_attribute_destroy(Object *ob, SculptAttribute *attr)
 
   Mesh *me = BKE_object_get_original_mesh(ob);
 
-  if (attr->params.simple_array) {
+  if (attr->simple_array) {
     MEM_SAFE_FREE(attr->data);
   }
   else if (ss->bm) {
diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc
index 0bdfbf11cb8..c3d660b8ecd 100644
--- a/source/blender/draw/intern/draw_pbvh.cc
+++ b/source/blender/draw/intern/draw_pbvh.cc
@@ -1368,6 +1368,8 @@ GPUBatch *DRW_pbvh_tris_get(PBVHBatches *batches,
                             int *r_prim_count,
                             bool do_coarse_grids)
 {
+  do_coarse_grids &= args->pbvh_type == PBVH_GRIDS;
+
   PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args, do_coarse_grids);
 
   *r_prim_count = batch.tris_count;
@@ -1382,6 +1384,8 @@ GPUBatch *DRW_pbvh_lines_get(PBVHBatches *batches,
                              int *r_prim_count,
                              bool do_coarse_grids)
 {
+  do_coarse_grids &= args->pbvh_type == PBVH_GRIDS;
+
   PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args, do_coarse_grids);
 
   *r_prim_count = batch.lines_count;



More information about the Bf-blender-cvs mailing list