[Bf-blender-cvs] [1cd88104f09] sculpt-dev: Sculpt-dev: fix bmesh python bug
Joseph Eagar
noreply at git.blender.org
Tue Jun 14 05:16:49 CEST 2022
Commit: 1cd88104f09d4b70b8c5bd49e0e0931673d5909c
Author: Joseph Eagar
Date: Mon Jun 13 20:13:02 2022 -0700
Branches: sculpt-dev
https://developer.blender.org/rB1cd88104f09d4b70b8c5bd49e0e0931673d5909c
Sculpt-dev: fix bmesh python bug
Save and restore python pointers when
adding or removing customdata layers, this is needed
since tool flags are a customdata layer in sculpt-dev.
Reallocating tool flags shouldn't clear python pointers.
===================================================================
M source/blender/bmesh/CMakeLists.txt
M source/blender/bmesh/intern/bmesh_interp.c
M source/blender/python/bmesh/bmesh_py_types.c
===================================================================
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index 4856e57f412..96e0236e4aa 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -13,6 +13,7 @@ set(INC
../../../intern/eigen
../../../intern/guardedalloc
../../../extern/rangetree
+ ../python/bmesh
)
set(INC_SYS
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index e3f568d47f9..a51571a9b7e 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -1238,6 +1238,9 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v_dst, const BMFace *f_src)
CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, f_src->len, v_dst->head.data);
}
+void BPy_bm_new_customdata_layout(BMesh *bm, CustomData *cdata, void *state, char htype);
+void *BPy_bm_new_customdata_layout_pre(BMesh *bm, CustomData *cdata, char htype);
+
static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
{
BMIter iter;
@@ -1259,6 +1262,7 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
BMVert *eve;
CustomData_bmesh_init_pool_ex(data, bm->totvert, BM_VERT, __func__);
+ void *state = BPy_bm_new_customdata_layout_pre(bm, olddata, BM_VERT);
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
block = NULL;
@@ -1267,11 +1271,15 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
CustomData_bmesh_free_block(olddata, &eve->head.data);
eve->head.data = block;
}
+
+ BPy_bm_new_customdata_layout(bm, &bm->vdata, state, BM_VERT);
+ MEM_SAFE_FREE(state);
}
else if (data == &bm->edata) {
BMEdge *eed;
CustomData_bmesh_init_pool_ex(data, bm->totedge, BM_EDGE, __func__);
+ void *state = BPy_bm_new_customdata_layout_pre(bm, olddata, BM_EDGE);
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
block = NULL;
@@ -1280,6 +1288,9 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
CustomData_bmesh_free_block(olddata, &eed->head.data);
eed->head.data = block;
}
+
+ BPy_bm_new_customdata_layout(bm, &bm->edata, state, BM_EDGE);
+ MEM_SAFE_FREE(state);
}
else if (data == &bm->ldata) {
BMIter liter;
@@ -1287,6 +1298,8 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
BMLoop *l;
CustomData_bmesh_init_pool_ex(data, bm->totloop, BM_LOOP, __func__);
+ void *state = BPy_bm_new_customdata_layout_pre(bm, olddata, BM_LOOP);
+
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
block = NULL;
@@ -1296,11 +1309,15 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
l->head.data = block;
}
}
+
+ BPy_bm_new_customdata_layout(bm, &bm->ldata, state, BM_LOOP);
+ MEM_SAFE_FREE(state);
}
else if (data == &bm->pdata) {
BMFace *efa;
CustomData_bmesh_init_pool_ex(data, bm->totface, BM_FACE, __func__);
+ void *state = BPy_bm_new_customdata_layout_pre(bm, olddata, BM_FACE);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
block = NULL;
@@ -1309,6 +1326,9 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
CustomData_bmesh_free_block(olddata, &efa->head.data);
efa->head.data = block;
}
+
+ BPy_bm_new_customdata_layout(bm, &bm->pdata, state, BM_FACE);
+ MEM_SAFE_FREE(state);
}
else {
/* should never reach this! */
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index 23dc7f7c0e2..6cc51366fd1 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -5,6 +5,8 @@
* \ingroup pybmesh
*/
+#include "MEM_guardedalloc.h"
+
#include "BLI_math.h"
#include "BLI_sort.h"
@@ -4047,6 +4049,134 @@ int bpy_bm_generic_valid_check_source(BMesh *bm_source,
return ret;
}
+void *BPy_bm_new_customdata_layout_pre(BMesh *bm, CustomData *cdata, char htype)
+{
+ if (!CustomData_has_layer(cdata, CD_BM_ELEM_PYPTR)) {
+ return NULL;
+ }
+
+ BLI_mempool *pool = NULL;
+ int num = 0;
+
+ switch (htype) {
+ case BM_VERT:
+ pool = bm->vpool;
+ num = bm->totvert;
+ break;
+ case BM_EDGE:
+ pool = bm->epool;
+ num = bm->totedge;
+ break;
+ case BM_LOOP:
+ pool = bm->fpool;
+ num = bm->totloop;
+ break;
+ case BM_FACE:
+ pool = bm->fpool;
+ num = bm->totface;
+ break;
+ }
+
+ void **ptrs = MEM_malloc_arrayN(num, sizeof(void *), __func__);
+
+ int cd_py = CustomData_get_offset(cdata, CD_BM_ELEM_PYPTR);
+
+ BMElem *elem;
+ BLI_mempool_iter iter;
+
+ int i = 0;
+
+ if (htype != BM_LOOP) {
+ BLI_mempool_iternew(pool, &iter);
+ while ((elem = BLI_mempool_iterstep(&iter))) {
+ ptrs[i++] = *((void **)BM_ELEM_CD_GET_VOID_P(elem, cd_py));
+ }
+ }
+ else {
+ BMFace *f;
+
+ BLI_mempool_iternew(pool, &iter);
+ while ((f = BLI_mempool_iterstep(&iter))) {
+ BMLoop *l = f->l_first;
+
+ do {
+ ptrs[i++] = *((void **)BM_ELEM_CD_GET_VOID_P(l, cd_py));
+ } while ((l = l->next) != f->l_first);
+ }
+ }
+
+ return ptrs;
+}
+
+ATTR_NO_OPT void BPy_bm_new_customdata_layout(BMesh *bm, CustomData *cdata, void *state, char htype)
+{
+ /*
+ * Un-invalidate python pointers, which got invalidated when the customdata layout
+ * changed.
+ */
+
+ if (!state || !CustomData_has_layer(cdata, CD_BM_ELEM_PYPTR)) {
+ return;
+ }
+
+ BLI_mempool *pool = NULL;
+ void **ptrs = (void **)state;
+
+ switch (htype) {
+ case BM_VERT:
+ pool = bm->vpool;
+ break;
+ case BM_EDGE:
+ pool = bm->epool;
+ break;
+ case BM_LOOP:
+ pool = bm->fpool;
+ break;
+ case BM_FACE:
+ pool = bm->fpool;
+ break;
+ }
+
+ int cd_py = CustomData_get_offset(cdata, CD_BM_ELEM_PYPTR);
+
+ BMElem *elem;
+ BLI_mempool_iter iter;
+ int i = 0;
+
+ if (htype != BM_LOOP) {
+ BLI_mempool_iternew(pool, &iter);
+ while ((elem = BLI_mempool_iterstep(&iter))) {
+ void **ptr = BM_ELEM_CD_GET_VOID_P(elem, cd_py);
+
+ *ptr = ptrs[i++];
+ BPy_BMGeneric *bpy_ptr = (BPy_BMGeneric *)*ptr;
+
+ if (bpy_ptr) {
+ bpy_ptr->bm = bm;
+ }
+ }
+ }
+ else {
+ BMFace *f;
+
+ BLI_mempool_iternew(pool, &iter);
+ while ((f = BLI_mempool_iterstep(&iter))) {
+ BMLoop *l = f->l_first;
+
+ do {
+ void **ptr = BM_ELEM_CD_GET_VOID_P(l, cd_py);
+
+ *ptr = ptrs[i++];
+ BPy_BMGeneric *bpy_ptr = (BPy_BMGeneric *)*ptr;
+
+ if (bpy_ptr) {
+ bpy_ptr->bm = bm;
+ }
+ } while ((l = l->next) != f->l_first);
+ }
+ }
+}
+
void bpy_bm_generic_invalidate(BPy_BMGeneric *self)
{
self->bm = NULL;
More information about the Bf-blender-cvs
mailing list