Fix T74876: Crash when snapping to faces

The crash occurs after operators change the amount of editmesh looptris.
The looptris of the evaluated object's editmesh are not updated.
This commit is contained in:
Germano Cavalcante 2020-03-18 09:58:08 -03:00
parent 52c0742560
commit efdc93fcc6
Notes: blender-bot 2023-02-14 11:07:28 +01:00
Referenced by issue #74876, geometry extrude crash
1 changed files with 36 additions and 18 deletions

View File

@ -245,8 +245,9 @@ static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx, Object
return sod;
}
static struct LinkNode **snap_object_data_editmesh_bvh_cache_get(Object *ob, BMEditMesh *em)
static struct LinkNode **snap_object_data_editmesh_bvh_cache_get(Object *ob)
{
BMEditMesh *em = BKE_editmesh_from_object(ob);
if (em->mesh_eval_final) {
return &em->mesh_eval_final->runtime.bvh_cache;
}
@ -263,7 +264,7 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
{
SnapObjectData *sod;
void **sod_p;
bool init = false, init_min_max = true, clear_cached = false;
bool init = false, init_min_max = true, clear_cache = false;
{
/* Use object-data as the key in ghash since the editmesh
@ -288,12 +289,12 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
clear = true;
}
else if (sod->treedata_editmesh.em != em) {
clear_cached = true;
clear_cache = true;
init = true;
}
else if (sod->bvh_cache_p) {
if (sod->bvh_cache_p != snap_object_data_editmesh_bvh_cache_get(ob, em)) {
clear_cached = true;
if (sod->bvh_cache_p != snap_object_data_editmesh_bvh_cache_get(ob)) {
clear_cache = true;
init = true;
}
else if (sod->treedata_editmesh.tree && sod->treedata_editmesh.cached &&
@ -327,7 +328,7 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
sod->type = SNAP_EDIT_MESH;
sod->treedata_editmesh.em = em;
if (clear_cached) {
if (clear_cache) {
/* Only init min and max when you have a non-custom bvhtree pending. */
init_min_max = false;
if (sod->treedata_editmesh.cached) {
@ -346,7 +347,7 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
bm_mesh_minmax(em->bm, sod->min, sod->max);
}
sod->bvh_cache_p = snap_object_data_editmesh_bvh_cache_get(ob, em);
sod->bvh_cache_p = snap_object_data_editmesh_bvh_cache_get(ob);
}
return sod;
@ -819,7 +820,8 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
BVHTreeFromEditMesh *treedata = &sod->treedata_editmesh;
if (treedata->tree == NULL) {
BLI_assert(sod->treedata_editmesh.em == BKE_editmesh_from_object(ob));
/* Operators only update the editmesh looptris of the original mesh. */
BLI_assert(sod->treedata_editmesh.em == BKE_editmesh_from_object(DEG_get_original_object(ob)));
BMEditMesh *em = sod->treedata_editmesh.em;
if (sctx->callbacks.edit_mesh.test_face_fn) {
@ -962,13 +964,14 @@ static bool raycastObj(SnapObjectContext *sctx,
Mesh *me = ob->data;
bool use_hide = false;
if (BKE_object_is_in_editmode(ob)) {
BMEditMesh *em = BKE_editmesh_from_object(ob);
if (use_obedit) {
/* Operators only update the editmesh looptris of the original mesh. */
BMEditMesh *em_orig = BKE_editmesh_from_object(DEG_get_original_object(ob));
retval = raycastEditMesh(sctx,
ray_start,
ray_dir,
ob,
em,
em_orig,
obmat,
ob_index,
use_backface_culling,
@ -979,9 +982,12 @@ static bool raycastObj(SnapObjectContext *sctx,
r_hit_list);
break;
}
else if (em->mesh_eval_final) {
me = em->mesh_eval_final;
use_hide = true;
else {
BMEditMesh *em = BKE_editmesh_from_object(ob);
if (em->mesh_eval_final) {
me = em->mesh_eval_final;
use_hide = true;
}
}
}
retval = raycastMesh(sctx,
@ -2677,14 +2683,26 @@ static short snapObject(SnapObjectContext *sctx,
case OB_MESH: {
Mesh *me = ob->data;
if (BKE_object_is_in_editmode(ob)) {
BMEditMesh *em = BKE_editmesh_from_object(ob);
if (use_obedit) {
retval = snapEditMesh(
sctx, snapdata, ob, em, obmat, use_backface_culling, dist_px, r_loc, r_no, r_index);
/* Operators only update the editmesh looptris of the original mesh. */
BMEditMesh *em_orig = BKE_editmesh_from_object(DEG_get_original_object(ob));
retval = snapEditMesh(sctx,
snapdata,
ob,
em_orig,
obmat,
use_backface_culling,
dist_px,
r_loc,
r_no,
r_index);
break;
}
else if (em->mesh_eval_final) {
me = em->mesh_eval_final;
else {
BMEditMesh *em = BKE_editmesh_from_object(ob);
if (em->mesh_eval_final) {
me = em->mesh_eval_final;
}
}
}
else if (ob->dt == OB_BOUNDBOX) {