Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_mesh.c')
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c116
1 files changed, 96 insertions, 20 deletions
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 2c4a98b0b7e..9036e882b0b 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -1438,6 +1438,24 @@ int BM_mesh_elem_count(BMesh *bm, const char htype)
}
/**
+ * Special case: Python uses custom-data layers to hold PyObject references.
+ * These have to be kept in-place, else the PyObject's we point to, wont point back to us.
+ *
+ * \note ``ele_src`` Is a duplicate, so we don't need to worry about getting in a feedback loop.
+ *
+ * \note If there are other customdata layers which need this functionality, it should be generalized.
+ * However #BM_mesh_remap is currently the only place where this is done.
+ */
+static void bm_mesh_remap_cd_update(
+ BMHeader *ele_dst, BMHeader *ele_src,
+ const int cd_elem_pyptr)
+{
+ void **pyptr_dst_p = BM_ELEM_CD_GET_VOID_P(((BMElem *)ele_dst), cd_elem_pyptr);
+ void **pyptr_src_p = BM_ELEM_CD_GET_VOID_P(((BMElem *)ele_src), cd_elem_pyptr);
+ *pyptr_dst_p = *pyptr_src_p;
+}
+
+/**
* Remaps the vertices, edges and/or faces of the bmesh as indicated by vert/edge/face_idx arrays
* (xxx_idx[org_index] = new_index).
*
@@ -1477,6 +1495,7 @@ void BM_mesh_remap(
BMVert **verts_pool, *verts_copy, **vep;
int i, totvert = bm->totvert;
const unsigned int *new_idx;
+ const int cd_vert_pyptr = CustomData_get_offset(&bm->vdata, CD_BM_ELEM_PYPTR);
/* Init the old-to-new vert pointers mapping */
vptr_map = BLI_ghash_ptr_new_ex("BM_mesh_remap vert pointers mapping", bm->totvert);
@@ -1498,6 +1517,9 @@ void BM_mesh_remap(
*new_vep = *ve;
/* printf("mapping vert from %d to %d (%p/%p to %p)\n", i, *new_idx, *vep, verts_pool[i], new_vep);*/
BLI_ghash_insert(vptr_map, *vep, new_vep);
+ if (cd_vert_pyptr != -1) {
+ bm_mesh_remap_cd_update(&(*vep)->head, &new_vep->head, cd_vert_pyptr);
+ }
}
bm->elem_index_dirty |= BM_VERT;
bm->elem_table_dirty |= BM_VERT;
@@ -1510,6 +1532,7 @@ void BM_mesh_remap(
BMEdge **edges_pool, *edges_copy, **edp;
int i, totedge = bm->totedge;
const unsigned int *new_idx;
+ const int cd_edge_pyptr = CustomData_get_offset(&bm->edata, CD_BM_ELEM_PYPTR);
/* Init the old-to-new vert pointers mapping */
eptr_map = BLI_ghash_ptr_new_ex("BM_mesh_remap edge pointers mapping", bm->totedge);
@@ -1530,6 +1553,9 @@ void BM_mesh_remap(
*new_edp = *ed;
BLI_ghash_insert(eptr_map, *edp, new_edp);
/* printf("mapping edge from %d to %d (%p/%p to %p)\n", i, *new_idx, *edp, edges_pool[i], new_edp);*/
+ if (cd_edge_pyptr != -1) {
+ bm_mesh_remap_cd_update(&(*edp)->head, &new_edp->head, cd_edge_pyptr);
+ }
}
bm->elem_index_dirty |= BM_EDGE;
bm->elem_table_dirty |= BM_EDGE;
@@ -1542,6 +1568,7 @@ void BM_mesh_remap(
BMFace **faces_pool, *faces_copy, **fap;
int i, totface = bm->totface;
const unsigned int *new_idx;
+ const int cd_poly_pyptr = CustomData_get_offset(&bm->pdata, CD_BM_ELEM_PYPTR);
/* Init the old-to-new vert pointers mapping */
fptr_map = BLI_ghash_ptr_new_ex("BM_mesh_remap face pointers mapping", bm->totface);
@@ -1561,6 +1588,9 @@ void BM_mesh_remap(
BMFace *new_fap = faces_pool[*new_idx];
*new_fap = *fa;
BLI_ghash_insert(fptr_map, *fap, new_fap);
+ if (cd_poly_pyptr != -1) {
+ bm_mesh_remap_cd_update(&(*fap)->head, &new_fap->head, cd_poly_pyptr);
+ }
}
bm->elem_index_dirty |= BM_FACE | BM_LOOP;
@@ -1573,8 +1603,11 @@ void BM_mesh_remap(
/* Verts' pointers, only edge pointers... */
if (eptr_map) {
BM_ITER_MESH (ve, &iter, bm, BM_VERTS_OF_MESH) {
-/* printf("Vert e: %p -> %p\n", ve->e, BLI_ghash_lookup(eptr_map, (const void *)ve->e));*/
- ve->e = BLI_ghash_lookup(eptr_map, (const void *)ve->e);
+/* printf("Vert e: %p -> %p\n", ve->e, BLI_ghash_lookup(eptr_map, ve->e));*/
+ if (ve->e) {
+ ve->e = BLI_ghash_lookup(eptr_map, ve->e);
+ BLI_assert(ve->e);
+ }
}
}
@@ -1583,24 +1616,30 @@ void BM_mesh_remap(
if (vptr_map || eptr_map) {
BM_ITER_MESH (ed, &iter, bm, BM_EDGES_OF_MESH) {
if (vptr_map) {
-/* printf("Edge v1: %p -> %p\n", ed->v1, BLI_ghash_lookup(vptr_map, (const void *)ed->v1));*/
-/* printf("Edge v2: %p -> %p\n", ed->v2, BLI_ghash_lookup(vptr_map, (const void *)ed->v2));*/
- ed->v1 = BLI_ghash_lookup(vptr_map, (const void *)ed->v1);
- ed->v2 = BLI_ghash_lookup(vptr_map, (const void *)ed->v2);
+/* printf("Edge v1: %p -> %p\n", ed->v1, BLI_ghash_lookup(vptr_map, ed->v1));*/
+/* printf("Edge v2: %p -> %p\n", ed->v2, BLI_ghash_lookup(vptr_map, ed->v2));*/
+ ed->v1 = BLI_ghash_lookup(vptr_map, ed->v1);
+ ed->v2 = BLI_ghash_lookup(vptr_map, ed->v2);
+ BLI_assert(ed->v1);
+ BLI_assert(ed->v2);
}
if (eptr_map) {
/* printf("Edge v1_disk_link prev: %p -> %p\n", ed->v1_disk_link.prev,*/
-/* BLI_ghash_lookup(eptr_map, (const void *)ed->v1_disk_link.prev));*/
+/* BLI_ghash_lookup(eptr_map, ed->v1_disk_link.prev));*/
/* printf("Edge v1_disk_link next: %p -> %p\n", ed->v1_disk_link.next,*/
-/* BLI_ghash_lookup(eptr_map, (const void *)ed->v1_disk_link.next));*/
+/* BLI_ghash_lookup(eptr_map, ed->v1_disk_link.next));*/
/* printf("Edge v2_disk_link prev: %p -> %p\n", ed->v2_disk_link.prev,*/
-/* BLI_ghash_lookup(eptr_map, (const void *)ed->v2_disk_link.prev));*/
+/* BLI_ghash_lookup(eptr_map, ed->v2_disk_link.prev));*/
/* printf("Edge v2_disk_link next: %p -> %p\n", ed->v2_disk_link.next,*/
-/* BLI_ghash_lookup(eptr_map, (const void *)ed->v2_disk_link.next));*/
- ed->v1_disk_link.prev = BLI_ghash_lookup(eptr_map, (const void *)ed->v1_disk_link.prev);
- ed->v1_disk_link.next = BLI_ghash_lookup(eptr_map, (const void *)ed->v1_disk_link.next);
- ed->v2_disk_link.prev = BLI_ghash_lookup(eptr_map, (const void *)ed->v2_disk_link.prev);
- ed->v2_disk_link.next = BLI_ghash_lookup(eptr_map, (const void *)ed->v2_disk_link.next);
+/* BLI_ghash_lookup(eptr_map, ed->v2_disk_link.next));*/
+ ed->v1_disk_link.prev = BLI_ghash_lookup(eptr_map, ed->v1_disk_link.prev);
+ ed->v1_disk_link.next = BLI_ghash_lookup(eptr_map, ed->v1_disk_link.next);
+ ed->v2_disk_link.prev = BLI_ghash_lookup(eptr_map, ed->v2_disk_link.prev);
+ ed->v2_disk_link.next = BLI_ghash_lookup(eptr_map, ed->v2_disk_link.next);
+ BLI_assert(ed->v1_disk_link.prev);
+ BLI_assert(ed->v1_disk_link.next);
+ BLI_assert(ed->v2_disk_link.prev);
+ BLI_assert(ed->v2_disk_link.next);
}
}
}
@@ -1609,20 +1648,57 @@ void BM_mesh_remap(
BM_ITER_MESH (fa, &iter, bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (lo, &iterl, fa, BM_LOOPS_OF_FACE) {
if (vptr_map) {
-/* printf("Loop v: %p -> %p\n", lo->v, BLI_ghash_lookup(vptr_map, (const void *)lo->v));*/
- lo->v = BLI_ghash_lookup(vptr_map, (const void *)lo->v);
+/* printf("Loop v: %p -> %p\n", lo->v, BLI_ghash_lookup(vptr_map, lo->v));*/
+ lo->v = BLI_ghash_lookup(vptr_map, lo->v);
+ BLI_assert(lo->v);
}
if (eptr_map) {
-/* printf("Loop e: %p -> %p\n", lo->e, BLI_ghash_lookup(eptr_map, (const void *)lo->e));*/
- lo->e = BLI_ghash_lookup(eptr_map, (const void *)lo->e);
+/* printf("Loop e: %p -> %p\n", lo->e, BLI_ghash_lookup(eptr_map, lo->e));*/
+ lo->e = BLI_ghash_lookup(eptr_map, lo->e);
+ BLI_assert(lo->e);
}
if (fptr_map) {
-/* printf("Loop f: %p -> %p\n", lo->f, BLI_ghash_lookup(fptr_map, (const void *)lo->f));*/
- lo->f = BLI_ghash_lookup(fptr_map, (const void *)lo->f);
+/* printf("Loop f: %p -> %p\n", lo->f, BLI_ghash_lookup(fptr_map, lo->f));*/
+ lo->f = BLI_ghash_lookup(fptr_map, lo->f);
+ BLI_assert(lo->f);
}
}
}
+ /* Selection history */
+ {
+ BMEditSelection *ese;
+ for (ese = bm->selected.first; ese; ese = ese->next) {
+ switch (ese->htype) {
+ case BM_VERT:
+ if (vptr_map) {
+ ese->ele = BLI_ghash_lookup(vptr_map, ese->ele);
+ BLI_assert(ese->ele);
+ }
+ break;
+ case BM_EDGE:
+ if (eptr_map) {
+ ese->ele = BLI_ghash_lookup(eptr_map, ese->ele);
+ BLI_assert(ese->ele);
+ }
+ break;
+ case BM_FACE:
+ if (fptr_map) {
+ ese->ele = BLI_ghash_lookup(fptr_map, ese->ele);
+ BLI_assert(ese->ele);
+ }
+ break;
+ }
+ }
+ }
+
+ if (fptr_map) {
+ if (bm->act_face) {
+ bm->act_face = BLI_ghash_lookup(fptr_map, bm->act_face);
+ BLI_assert(bm->act_face);
+ }
+ }
+
if (vptr_map)
BLI_ghash_free(vptr_map, NULL, NULL);
if (eptr_map)