[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