Fix particle-edit crash on undo/redo

Undo/redo was crashing & asserting.

There ware two bugs:

- Entering particle system edit-mode requires an evaluated depsgraph.

- The active object could get out of sync when undo/redo
  moves between different modes.

The new test 'view3d_mesh_particle_edit_mode_simple'
in `tests/ui_simulate/test_undo.py` exposes both issues.
This commit is contained in:
Campbell Barton
2021-02-26 16:30:08 +11:00
parent b7939a059f
commit 9059ee81ef
3 changed files with 17 additions and 3 deletions

View File

@@ -25,6 +25,7 @@ set(INC
../../makesdna
../../makesrna
../../windowmanager
../../../../intern/clog
../../../../intern/glew-mx
../../../../intern/guardedalloc
../../../../intern/mantaflow/extern

View File

@@ -5395,6 +5395,9 @@ static void free_all_psys_edit(Object *object)
void ED_object_particle_edit_mode_enter_ex(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
/* Needed so #ParticleSystemModifierData.mesh_final is set. */
BKE_scene_graph_evaluated_ensure(depsgraph, G_MAIN);
PTCacheEdit *edit;
ob->mode |= OB_MODE_PARTICLE_EDIT;

View File

@@ -27,6 +27,8 @@
#include "MEM_guardedalloc.h"
#include "CLG_log.h"
#include "DNA_meshdata_types.h"
#include "DNA_scene_types.h"
#include "DNA_windowmanager_types.h"
@@ -44,11 +46,15 @@
#include "ED_object.h"
#include "ED_particle.h"
#include "ED_physics.h"
#include "ED_undo.h"
#include "particle_edit_utildefines.h"
#include "physics_intern.h"
/** Only needed this locally. */
static CLG_LogRef LOG = {"ed.undo.particle_edit"};
/* -------------------------------------------------------------------- */
/** \name Undo Conversion
* \{ */
@@ -251,13 +257,13 @@ static void particle_undosys_step_decode(struct bContext *C,
bool UNUSED(is_final))
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
/* TODO(campbell): undo_system: use low-level API to set mode. */
ED_object_mode_set_ex(C, OB_MODE_PARTICLE_EDIT, false, NULL);
BLI_assert(particle_undosys_poll(C));
ParticleUndoStep *us = (ParticleUndoStep *)us_p;
Scene *scene = us->scene_ref.ptr;
Object *ob = us->object_ref.ptr;
ED_object_particle_edit_mode_enter_ex(depsgraph, scene, ob);
PTCacheEdit *edit = PE_get_current(depsgraph, scene, ob);
if (edit) {
undoptcache_to_editcache(&us->data, edit);
@@ -267,6 +273,10 @@ static void particle_undosys_step_decode(struct bContext *C,
BKE_particle_batch_cache_dirty_tag(edit->psys, BKE_PARTICLE_BATCH_DIRTY_ALL);
}
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
ED_undo_object_set_active_or_warn(scene, CTX_data_view_layer(C), ob, us_p->name, &LOG);
BLI_assert(particle_undosys_poll(C));
}
else {
BLI_assert(0);