[Bf-blender-cvs] [907a718ebe3] master: Fix T80224: Crash after duplicating and hiding vertices while using X Axis Mirror

Germano Cavalcante noreply at git.blender.org
Tue Sep 1 17:13:43 CEST 2020


Commit: 907a718ebe3e242d923929af9dd7bd73130c6940
Author: Germano Cavalcante
Date:   Tue Sep 1 12:13:25 2020 -0300
Branches: master
https://developer.blender.org/rB907a718ebe3e242d923929af9dd7bd73130c6940

Fix T80224: Crash after duplicating and hiding vertices while using X Axis Mirror

The mirror map can reference a hidden vertex that is currently ignored
in the transformation.

Thus the mirror element array is not filled.

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

M	source/blender/editors/include/ED_mesh.h
M	source/blender/editors/mesh/editmesh_select.c
M	source/blender/editors/mesh/editmesh_tools.c
M	source/blender/editors/mesh/editmesh_utils.c
M	source/blender/editors/object/object_vgroup.c
M	source/blender/editors/transform/transform_convert_mesh.c

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

diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index f2cad1acc84..660e4de09d3 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -59,6 +59,7 @@ void EDBM_verts_mirror_cache_begin_ex(struct BMEditMesh *em,
                                       const int axis,
                                       const bool use_self,
                                       const bool use_select,
+                                      const bool respecthide,
                                       const bool use_topology,
                                       float maxdist,
                                       int *r_index);
@@ -66,6 +67,7 @@ void EDBM_verts_mirror_cache_begin(struct BMEditMesh *em,
                                    const int axis,
                                    const bool use_self,
                                    const bool use_select,
+                                   const bool respecthide,
                                    const bool use_toplogy);
 void EDBM_verts_mirror_apply(struct BMEditMesh *em, const int sel_from, const int sel_to);
 struct BMVert *EDBM_verts_mirror_get(struct BMEditMesh *em, struct BMVert *v);
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index efcf4abda06..52c109b3854 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -110,7 +110,7 @@ void EDBM_select_mirrored(BMEditMesh *em,
     }
   }
 
-  EDBM_verts_mirror_cache_begin(em, axis, true, true, use_topology);
+  EDBM_verts_mirror_cache_begin(em, axis, true, true, false, use_topology);
 
   if (!extend) {
     EDBM_flag_disable_all(em, BM_ELEM_SELECT);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 1e4144db47e..4e1a56b3b55 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -2513,7 +2513,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op)
 
     /* mirror before smooth */
     if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) {
-      EDBM_verts_mirror_cache_begin(em, 0, false, true, use_topology);
+      EDBM_verts_mirror_cache_begin(em, 0, false, true, false, use_topology);
     }
 
     /* if there is a mirror modifier with clipping, flag the verts that
@@ -2658,7 +2658,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op)
 
     /* Mirror before smooth. */
     if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) {
-      EDBM_verts_mirror_cache_begin(em, 0, false, true, use_topology);
+      EDBM_verts_mirror_cache_begin(em, 0, false, true, false, use_topology);
     }
 
     bool failed_repeat_loop = false;
@@ -7600,7 +7600,7 @@ static int mesh_symmetry_snap_exec(bContext *C, wmOperator *op)
     BMVert *v;
     int i;
 
-    EDBM_verts_mirror_cache_begin_ex(em, axis, true, true, use_topology, thresh, index);
+    EDBM_verts_mirror_cache_begin_ex(em, axis, true, true, false, use_topology, thresh, index);
 
     BM_mesh_elem_table_ensure(bm, BM_VERT);
 
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index e454328e2d4..a90c8dea87b 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -1059,6 +1059,7 @@ static BMVert *cache_mirr_intptr_as_bmvert(const intptr_t *index_lookup, int ind
  * \param em: Editmesh.
  * \param use_self: Allow a vertex to point to its self (middle verts).
  * \param use_select: Restrict to selected verts.
+ * \param respecthide: Skip hidden vertices.
  * \param use_topology: Use topology mirror.
  * \param maxdist: Distance for close point test.
  * \param r_index: Optional array to write into, as an alternative to a customdata layer
@@ -1068,6 +1069,7 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em,
                                       const int axis,
                                       const bool use_self,
                                       const bool use_select,
+                                      const bool respecthide,
                                       /* extra args */
                                       const bool use_topology,
                                       float maxdist,
@@ -1110,6 +1112,10 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em,
   else {
     tree = BLI_kdtree_3d_new(bm->totvert);
     BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
+      if (respecthide && BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
+        continue;
+      }
+
       BLI_kdtree_3d_insert(tree, i, v->co);
     }
     BLI_kdtree_3d_balance(tree);
@@ -1118,44 +1124,45 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em,
 #define VERT_INTPTR(_v, _i) (r_index ? &r_index[_i] : BM_ELEM_CD_GET_VOID_P(_v, cd_vmirr_offset))
 
   BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
-    BLI_assert(BM_elem_index_get(v) == i);
+    if (respecthide && BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
+      continue;
+    }
 
-    /* temporary for testing, check for selection */
     if (use_select && !BM_elem_flag_test(v, BM_ELEM_SELECT)) {
-      /* do nothing */
+      continue;
     }
-    else {
-      BMVert *v_mirr;
-      int *idx = VERT_INTPTR(v, i);
 
-      if (use_topology) {
-        v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, i);
-      }
-      else {
-        int i_mirr;
-        float co[3];
-        copy_v3_v3(co, v->co);
-        co[axis] *= -1.0f;
-
-        v_mirr = NULL;
-        i_mirr = BLI_kdtree_3d_find_nearest(tree, co, NULL);
-        if (i_mirr != -1) {
-          BMVert *v_test = BM_vert_at_index(bm, i_mirr);
-          if (len_squared_v3v3(co, v_test->co) < maxdist_sq) {
-            v_mirr = v_test;
-          }
+    BLI_assert(BM_elem_index_get(v) == i);
+    BMVert *v_mirr;
+    int *idx = VERT_INTPTR(v, i);
+
+    if (use_topology) {
+      v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, i);
+    }
+    else {
+      int i_mirr;
+      float co[3];
+      copy_v3_v3(co, v->co);
+      co[axis] *= -1.0f;
+
+      v_mirr = NULL;
+      i_mirr = BLI_kdtree_3d_find_nearest(tree, co, NULL);
+      if (i_mirr != -1) {
+        BMVert *v_test = BM_vert_at_index(bm, i_mirr);
+        if (len_squared_v3v3(co, v_test->co) < maxdist_sq) {
+          v_mirr = v_test;
         }
       }
+    }
 
-      if (v_mirr && (use_self || (v_mirr != v))) {
-        const int i_mirr = BM_elem_index_get(v_mirr);
-        *idx = i_mirr;
-        idx = VERT_INTPTR(v_mirr, i_mirr);
-        *idx = i;
-      }
-      else {
-        *idx = -1;
-      }
+    if (v_mirr && (use_self || (v_mirr != v))) {
+      const int i_mirr = BM_elem_index_get(v_mirr);
+      *idx = i_mirr;
+      idx = VERT_INTPTR(v_mirr, i_mirr);
+      *idx = i;
+    }
+    else {
+      *idx = -1;
     }
   }
 
@@ -1173,12 +1180,14 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em,
                                    const int axis,
                                    const bool use_self,
                                    const bool use_select,
+                                   const bool respecthide,
                                    const bool use_topology)
 {
   EDBM_verts_mirror_cache_begin_ex(em,
                                    axis,
                                    use_self,
                                    use_select,
+                                   respecthide,
                                    /* extra args */
                                    use_topology,
                                    BM_SEARCH_MAXDIST_MIRR,
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 795d9f4e9fe..de9cca38a6e 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -2430,7 +2430,7 @@ void ED_vgroup_mirror(Object *ob,
         goto cleanup;
       }
 
-      EDBM_verts_mirror_cache_begin(em, 0, true, false, use_topology);
+      EDBM_verts_mirror_cache_begin(em, 0, true, false, false, use_topology);
 
       BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
 
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index 573f4550fec..7ad54a56545 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -507,7 +507,7 @@ static void editmesh_mirror_data_calc(BMEditMesh *em,
 
     index[a] = MEM_mallocN(totvert * sizeof(*index[a]), __func__);
     EDBM_verts_mirror_cache_begin_ex(
-        em, a, false, test_selected_only, use_topology, TRANSFORM_MAXDIST_MIRROR, index[a]);
+        em, a, false, test_selected_only, true, use_topology, TRANSFORM_MAXDIST_MIRROR, index[a]);
 
     flag = TD_MIRROR_X << a;
     BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {



More information about the Bf-blender-cvs mailing list