[Bf-blender-cvs] [862b5b18421] master: Fix T81511: Loop-cut overlay doesn't follow deformed cage

Campbell Barton noreply at git.blender.org
Wed Oct 14 05:59:11 CEST 2020


Commit: 862b5b18421a986b3d2cf8b0951f1a58797aaa52
Author: Campbell Barton
Date:   Wed Oct 14 14:49:22 2020 +1100
Branches: master
https://developer.blender.org/rB862b5b18421a986b3d2cf8b0951f1a58797aaa52

Fix T81511: Loop-cut overlay doesn't follow deformed cage

With constructive + deform modifiers, loop-cut visualization
wasn't following the displayed mesh.

This now gets the coordinates from the cage when available.

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

M	source/blender/blenkernel/BKE_editmesh.h
M	source/blender/blenkernel/intern/editmesh.c
M	source/blender/editors/mesh/editmesh_loopcut.c
M	source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c

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

diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h
index 819e91b438e..6febbb4e136 100644
--- a/source/blender/blenkernel/BKE_editmesh.h
+++ b/source/blender/blenkernel/BKE_editmesh.h
@@ -99,6 +99,13 @@ float (*BKE_editmesh_vert_coords_alloc(struct Depsgraph *depsgraph,
                                        struct Object *ob,
                                        int *r_vert_len))[3];
 float (*BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em, int *r_vert_len))[3];
+const float (*BKE_editmesh_vert_coords_when_deformed(struct Depsgraph *depsgraph,
+                                                     struct BMEditMesh *em,
+                                                     struct Scene *scene,
+                                                     struct Object *obedit,
+                                                     int *r_vert_len,
+                                                     bool *r_is_alloc))[3];
+
 void BKE_editmesh_lnorspace_update(BMEditMesh *em, struct Mesh *me);
 void BKE_editmesh_ensure_autosmooth(BMEditMesh *em, struct Mesh *me);
 struct BoundBox *BKE_editmesh_cage_boundbox_get(BMEditMesh *em);
diff --git a/source/blender/blenkernel/intern/editmesh.c b/source/blender/blenkernel/intern/editmesh.c
index 1a5b7685c0e..c5a4b48aed8 100644
--- a/source/blender/blenkernel/intern/editmesh.c
+++ b/source/blender/blenkernel/intern/editmesh.c
@@ -36,6 +36,7 @@
 #include "BKE_lib_id.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_iterators.h"
+// #include "BKE_jesh_runtime.h"
 #include "BKE_mesh_wrapper.h"
 #include "BKE_object.h"
 
@@ -228,6 +229,34 @@ float (*BKE_editmesh_vert_coords_alloc(struct Depsgraph *depsgraph,
   return cos_cage;
 }
 
+const float (*BKE_editmesh_vert_coords_when_deformed(struct Depsgraph *depsgraph,
+                                                     BMEditMesh *em,
+                                                     struct Scene *scene,
+                                                     Object *ob,
+                                                     int *r_vert_len,
+                                                     bool *r_is_alloc))[3]
+{
+  const float(*coords)[3] = NULL;
+  *r_is_alloc = false;
+
+  Mesh *me = ob->data;
+
+  if ((me->runtime.edit_data != NULL) && (me->runtime.edit_data->vertexCos != NULL)) {
+    /* Deformed, and we have deformed coords already. */
+    coords = me->runtime.edit_data->vertexCos;
+  }
+  else if ((em->mesh_eval_final != NULL) &&
+           (em->mesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH)) {
+    /* If this is an edit-mesh type, leave NULL as we can use the vertex coords. . */
+  }
+  else {
+    /* Constructive modifiers have been used, we need to allocate coordinates. */
+    *r_is_alloc = true;
+    coords = BKE_editmesh_vert_coords_alloc(depsgraph, em, scene, ob, r_vert_len);
+  }
+  return coords;
+}
+
 float (*BKE_editmesh_vert_coords_alloc_orco(BMEditMesh *em, int *r_vert_len))[3]
 {
   return BM_mesh_vert_coords_alloc(em->bm, r_vert_len);
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index d19e7799fbe..69d27cd5ffa 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -64,6 +64,11 @@
 
 /* ringsel operator */
 
+struct MeshCoordsCache {
+  bool is_init, is_alloc;
+  const float (*coords)[3];
+};
+
 /* struct for properties used while drawing */
 typedef struct RingSelOpData {
   ARegion *region;   /* region that ringsel was activated in */
@@ -78,6 +83,8 @@ typedef struct RingSelOpData {
   Base **bases;
   uint bases_len;
 
+  struct MeshCoordsCache *geom_cache;
+
   /* These values switch objects based on the object under the cursor. */
   uint base_index;
   Object *ob;
@@ -138,15 +145,18 @@ static void edgering_select(RingSelOpData *lcd)
 static void ringsel_find_edge(RingSelOpData *lcd, const int previewlines)
 {
   if (lcd->eed) {
-    const float(*coords)[3] = NULL;
-    {
-      Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(lcd->depsgraph, lcd->ob->data);
-      if (me_eval->runtime.edit_data) {
-        coords = me_eval->runtime.edit_data->vertexCos;
-      }
+    struct MeshCoordsCache *gcache = &lcd->geom_cache[lcd->base_index];
+    if (gcache->is_init == false) {
+      Scene *scene_eval = (Scene *)DEG_get_evaluated_id(lcd->vc.depsgraph, &lcd->vc.scene->id);
+      Object *ob_eval = DEG_get_evaluated_object(lcd->vc.depsgraph, lcd->ob);
+      BMEditMesh *em_eval = BKE_editmesh_from_object(ob_eval);
+      gcache->coords = BKE_editmesh_vert_coords_when_deformed(
+          lcd->vc.depsgraph, em_eval, scene_eval, ob_eval, NULL, &gcache->is_alloc);
+      gcache->is_init = true;
     }
+
     EDBM_preselect_edgering_update_from_edge(
-        lcd->presel_edgering, lcd->em->bm, lcd->eed, previewlines, coords);
+        lcd->presel_edgering, lcd->em->bm, lcd->eed, previewlines, gcache->coords);
   }
   else {
     EDBM_preselect_edgering_clear(lcd->presel_edgering);
@@ -250,6 +260,14 @@ static void ringsel_exit(bContext *UNUSED(C), wmOperator *op)
 
   EDBM_preselect_edgering_destroy(lcd->presel_edgering);
 
+  for (uint i = 0; i < lcd->bases_len; i++) {
+    struct MeshCoordsCache *gcache = &lcd->geom_cache[i];
+    if (gcache->is_alloc) {
+      MEM_freeN((void *)gcache->coords);
+    }
+  }
+  MEM_freeN(lcd->geom_cache);
+
   MEM_freeN(lcd->bases);
 
   ED_region_tag_redraw(lcd->region);
@@ -415,6 +433,7 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
 
   lcd->bases = bases;
   lcd->bases_len = bases_len;
+  lcd->geom_cache = MEM_callocN(sizeof(*lcd->geom_cache) * bases_len, __func__);
 
   if (is_interactive) {
     copy_v2_v2_int(lcd->vc.mval, event->mval);
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
index e17993445df..aa8905721b4 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
@@ -364,16 +364,19 @@ static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const
   }
   else {
     if (best.eed) {
-      const float(*coords)[3] = NULL;
-      {
-        Object *ob = gz_ring->bases[gz_ring->base_index]->object;
-        Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
-        Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
-        if (me_eval->runtime.edit_data) {
-          coords = me_eval->runtime.edit_data->vertexCos;
-        }
-      }
+      Object *ob = gz_ring->bases[gz_ring->base_index]->object;
+      Scene *scene_eval = (Scene *)DEG_get_evaluated_id(vc.depsgraph, &vc.scene->id);
+      Object *ob_eval = DEG_get_evaluated_object(vc.depsgraph, ob);
+      BMEditMesh *em_eval = BKE_editmesh_from_object(ob_eval);
+      /* Re-allocate coords each update isn't ideal, however we can't be sure
+       * the mesh hasn't been edited since last update. */
+      bool is_alloc = false;
+      const float(*coords)[3] = BKE_editmesh_vert_coords_when_deformed(
+          vc.depsgraph, em_eval, scene_eval, ob_eval, NULL, &is_alloc);
       EDBM_preselect_edgering_update_from_edge(gz_ring->psel, bm, best.eed, 1, coords);
+      if (is_alloc) {
+        MEM_freeN((void *)coords);
+      }
     }
     else {
       EDBM_preselect_edgering_clear(gz_ring->psel);



More information about the Bf-blender-cvs mailing list