Fix #136873: Edit mesh knife crash with no valid evaluated edit mesh

When the evaluated mesh doesn't have an edit mesh that corresponds
to the original edit mesh, don't use evaluated deformed positions, just
use the mesh's original positions instead.
This commit is contained in:
Hans Goudey
2025-04-02 12:45:39 -04:00
parent 1be036d883
commit f3aa425d81

View File

@@ -41,6 +41,7 @@
#include "BKE_context.hh"
#include "BKE_editmesh.hh"
#include "BKE_layer.hh"
#include "BKE_mesh_types.hh"
#include "BKE_report.hh"
#include "BKE_scene.hh"
#include "BKE_screen.hh"
@@ -60,6 +61,7 @@
#include "WM_api.hh"
#include "WM_types.hh"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "UI_interface.hh"
@@ -3800,22 +3802,30 @@ static void knifetool_init_obinfo(KnifeTool_OpData *kcd,
int ob_index,
bool use_tri_indices)
{
Scene *scene_eval = (Scene *)DEG_get_evaluated_id(kcd->vc.depsgraph, &kcd->scene->id);
Object *obedit_eval = (Object *)DEG_get_evaluated_id(kcd->vc.depsgraph, &ob->id);
BMEditMesh *em_eval = BKE_editmesh_from_object(obedit_eval);
BM_mesh_elem_index_ensure(em_eval->bm, BM_VERT);
const Mesh &mesh_orig = *static_cast<const Mesh *>(ob->data);
const Mesh &mesh_eval = *static_cast<const Mesh *>(obedit_eval->data);
KnifeObjectInfo *obinfo = &kcd->objects_info[ob_index];
obinfo->em = em_eval;
obinfo->positions_cage = BKE_editmesh_vert_coords_alloc(
kcd->vc.depsgraph, em_eval, scene_eval, obedit_eval);
if (BKE_editmesh_eval_orig_map_available(mesh_eval, &mesh_orig)) {
BMEditMesh &em_eval = *mesh_eval.runtime->edit_mesh;
obinfo->em = &em_eval;
obinfo->positions_cage = BKE_editmesh_vert_coords_alloc(
kcd->vc.depsgraph, &em_eval, scene_eval, obedit_eval);
}
else {
obinfo->em = mesh_orig.runtime->edit_mesh.get();
obinfo->positions_cage = BM_mesh_vert_coords_alloc(obinfo->em->bm);
}
BM_mesh_elem_index_ensure(obinfo->em->bm, BM_VERT);
if (use_tri_indices) {
obinfo->tri_indices.reinitialize(em_eval->looptris.size());
for (int i = 0; i < em_eval->looptris.size(); i++) {
const std::array<BMLoop *, 3> &ltri = em_eval->looptris[i];
obinfo->tri_indices.reinitialize(obinfo->em->looptris.size());
for (int i = 0; i < obinfo->em->looptris.size(); i++) {
const std::array<BMLoop *, 3> &ltri = obinfo->em->looptris[i];
obinfo->tri_indices[i][0] = BM_elem_index_get(ltri[0]->v);
obinfo->tri_indices[i][1] = BM_elem_index_get(ltri[1]->v);
obinfo->tri_indices[i][2] = BM_elem_index_get(ltri[2]->v);