Found after fixing T84002: Sculpt: Masking operations crash if multires is in play.
BLI_assert(grid_element.mask != NULL) in multires_reshape_assign_final_coords_from_ccg() will fail after undoing from Sculpt mode to Object mode, since in Object mode mesh data does not have paint mask cdlayers yet (it is added when switching to Sculpt mode), while runtime subdiv_ccg coming from sculpt undo step does.
Will commit a temp workaround to make Blender usable, but not sure at all if this is actually valid/expected situation, or if there are more layers of worms in that giant barrel. Need @Sergey Sharybin (sergey)'s enlightenment here, both on depsgraph side and multires side of the question.
Steps to reproduce:
- Default startup cube
- Add multires, subdivide at least once.
- Switch to sculpt mode, draw a sculpt stroke.
- Undo twice to object mode
And it asserts:
1 __GI_raise raise.c 50 0x7fae6ac53c81 2 __GI_abort abort.c 79 0x7fae6ac3d537 3 _BLI_assert_abort BLI_assert.c 50 0x290e6d84 4 multires_reshape_assign_final_coords_from_ccg multires_reshape_ccg.c 78 0x1091bc37 5 multiresModifier_reshapeFromCCG multires_reshape.c 158 0x1091613b 6 object_update_from_subsurf_ccg object.c 1476 0x109bcc4d 7 BKE_object_free_derived_caches object.c 1557 0x109bd60d 8 blender::deg::ObjectRuntimeBackup::restore_to_object deg_eval_runtime_backup_object.cc 112 0x28d41ddc 9 blender::deg::RuntimeBackup::restore_to_id deg_eval_runtime_backup.cc 97 0x28d3584f 10 blender::deg::deg_update_copy_on_write_datablock deg_eval_copy_on_write.cc 954 0x28c8f38f 11 blender::deg::deg_evaluate_copy_on_write deg_eval_copy_on_write.cc 1088 0x28c902bf 12 std::__invoke_impl<void, void ( *&)(Depsgraph *, blender::deg::IDNode const *), Depsgraph *, blender::deg::IDNode *&> invoke.h 60 0x28d19f6d 13 std::__invoke<void ( *&)(Depsgraph *, blender::deg::IDNode const *), Depsgraph *, blender::deg::IDNode *&> invoke.h 95 0x28d153cf 14 std::_Bind<void ( *(std::_Placeholder<1>, blender::deg::IDNode *))(Depsgraph *, blender::deg::IDNode const *)>::__call<void, Depsgraph *&&, 0ul, 1ul>(std::tuple<Depsgraph *&&>&&, std::_Index_tuple<0ul, 1ul>) functional 416 0x28d0cea4 15 std::_Bind<void ( *(std::_Placeholder<1>, blender::deg::IDNode *))(Depsgraph *, blender::deg::IDNode const *)>::operator()<Depsgraph *, void>(Depsgraph *&&) functional 499 0x28d05809 16 std::__invoke_impl<void, std::_Bind<void ( *(std::_Placeholder<1>, blender::deg::IDNode *))(Depsgraph *, blender::deg::IDNode const *)>&, Depsgraph *>(std::__invoke_other, std::_Bind<void ( *(std::_Placeholder<1>, blender::deg::IDNode *))(Depsgraph *, blender::deg::IDNode const *)>&, Depsgraph *&&) invoke.h 60 0x28cfca8c 17 std::__invoke_r<void, std::_Bind<void ( *(std::_Placeholder<1>, blender::deg::IDNode *))(Depsgraph *, blender::deg::IDNode const *)>&, Depsgraph *>(std::_Bind<void ( *(std::_Placeholder<1>, blender::deg::IDNode *))(Depsgraph *, blender::deg::IDNode const *)>&, Depsgraph *&&) invoke.h 110 0x28cf1cca 18 std::_Function_handler<void (Depsgraph *), std::_Bind<void ( *(std::_Placeholder<1>, blender::deg::IDNode *))(Depsgraph *, blender::deg::IDNode const *)>>::_M_invoke(std::_Any_data const&, Depsgraph *&&) std_function.h 291 0x28ce9b7c 19 std::function<void (Depsgraph *)>::operator()(Depsgraph *) const std_function.h 622 0x28e2c749 20 blender::deg::(anonymous namespace)::evaluate_node deg_eval.cc 113 0x28e27e58 ... <More>