diff options
-rw-r--r-- | source/blender/blenkernel/BKE_editmesh.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/editmesh.c | 29 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_loopcut.c | 33 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c | 21 |
4 files changed, 74 insertions, 16 deletions
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); |