Fix T58652: Crash editing shape keys weirdness with instances
This is a second attempt to get the crash fixed. The original fix
worked, but it was reverted by d3e0d7f082
.
Now the logic goes as:
- All pointers which we can not have shared (the ones which are
owned by the runtime) are cleared.
- The rest of runtime stays untouched.
This seems to be enough to keep particles happy.
This commit is contained in:
parent
dcc11360c6
commit
a84c823b89
Notes:
blender-bot
2023-02-14 04:44:59 +01:00
Referenced by issue #59206, Crash when editing an instancing object with modifier and cage display enabled Referenced by issue #58652, blender 2.8 - hard crash - editing shape keys weirdness with instances
|
@ -81,7 +81,6 @@ enum {
|
|||
LIB_ID_COPY_CACHES = 1 << 18, /* Copy runtime data caches. */
|
||||
LIB_ID_COPY_NO_ANIMDATA = 1 << 19, /* Don't copy id->adt, used by ID datablock localization routines. */
|
||||
LIB_ID_COPY_CD_REFERENCE = 1 << 20, /* Mesh: Reference CD data layers instead of doing real copy. */
|
||||
LIB_ID_COPY_RUNTIME = 1 << 21, /* Copy ID's runtime field (for example. object->runtime). */
|
||||
|
||||
/* XXX Hackish/not-so-nice specific behaviors needed for some corner cases.
|
||||
* Ideally we should not have those, but we need them for now... */
|
||||
|
|
|
@ -54,6 +54,7 @@ struct DerivedMesh;
|
|||
#endif
|
||||
|
||||
void BKE_mesh_runtime_reset(struct Mesh *mesh);
|
||||
void BKE_mesh_runtime_reset_on_copy(struct Mesh *mesh);
|
||||
int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh);
|
||||
void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh);
|
||||
const struct MLoopTri *BKE_mesh_runtime_looptri_ensure(struct Mesh *mesh);
|
||||
|
|
|
@ -319,6 +319,7 @@ void BKE_object_data_relink(struct Object *ob);
|
|||
struct MovieClip *BKE_object_movieclip_get(struct Scene *scene, struct Object *ob, bool use_default);
|
||||
|
||||
void BKE_object_runtime_reset(struct Object *object);
|
||||
void BKE_object_runtime_reset_on_copy(struct Object *object);
|
||||
|
||||
void BKE_object_batch_cache_dirty_tag(struct Object *ob);
|
||||
|
||||
|
|
|
@ -518,25 +518,25 @@ static int id_copy_libmanagement_cb(void *user_data, ID *UNUSED(id_self), ID **i
|
|||
return IDWALK_RET_NOP;
|
||||
}
|
||||
|
||||
static void id_copy_clear_runtime_if_needed(ID *id, int flag)
|
||||
static void id_copy_clear_runtime_pointers(ID *id, int UNUSED(flag))
|
||||
{
|
||||
if (id == NULL) {
|
||||
return;
|
||||
}
|
||||
if (flag & LIB_ID_COPY_RUNTIME) {
|
||||
return;
|
||||
}
|
||||
/* TODO(sergey): We might want to do a deep-copy of all the pointers inside.
|
||||
* This isn't currently needed, and is quite involved change (to cover all
|
||||
* things like batch cache and such). */
|
||||
switch ((ID_Type)GS(id->name)) {
|
||||
case ID_OB:
|
||||
{
|
||||
Object *object = (Object *)id;
|
||||
BKE_object_runtime_reset(object);
|
||||
BKE_object_runtime_reset_on_copy(object);
|
||||
break;
|
||||
}
|
||||
case ID_ME:
|
||||
{
|
||||
Mesh *mesh = (Mesh *)id;
|
||||
BKE_mesh_runtime_reset(mesh);
|
||||
BKE_mesh_runtime_reset_on_copy(mesh);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -709,7 +709,7 @@ bool BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag, con
|
|||
(*r_newid)->lib = id->lib;
|
||||
}
|
||||
|
||||
id_copy_clear_runtime_if_needed(*r_newid, flag);
|
||||
id_copy_clear_runtime_pointers(*r_newid, flag);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -700,8 +700,7 @@ Mesh *BKE_mesh_copy_for_eval(struct Mesh *source, bool reference)
|
|||
int flags = (LIB_ID_CREATE_NO_MAIN |
|
||||
LIB_ID_CREATE_NO_USER_REFCOUNT |
|
||||
LIB_ID_CREATE_NO_DEG_TAG |
|
||||
LIB_ID_COPY_NO_PREVIEW |
|
||||
LIB_ID_COPY_RUNTIME);
|
||||
LIB_ID_COPY_NO_PREVIEW);
|
||||
|
||||
if (reference) {
|
||||
flags |= LIB_ID_COPY_CD_REFERENCE;
|
||||
|
|
|
@ -60,6 +60,20 @@ void BKE_mesh_runtime_reset(Mesh *mesh)
|
|||
memset(&mesh->runtime, 0, sizeof(mesh->runtime));
|
||||
}
|
||||
|
||||
/* Clear all pointers which we don't want to be shared on copying the datablock.
|
||||
* However, keep all the flags which defines what the mesh is (for example, that
|
||||
* it's deformed only, or that its custom data layers are out of date.) */
|
||||
void BKE_mesh_runtime_reset_on_copy(Mesh *mesh)
|
||||
{
|
||||
Mesh_Runtime *runtime = &mesh->runtime;
|
||||
runtime->edit_data = NULL;
|
||||
runtime->batch_cache = NULL;
|
||||
runtime->subdiv_ccg = NULL;
|
||||
memset(&runtime->looptris, 0, sizeof(runtime->looptris));
|
||||
runtime->bvh_cache = NULL;
|
||||
runtime->shrinkwrap_data = NULL;
|
||||
}
|
||||
|
||||
void BKE_mesh_runtime_clear_cache(Mesh *mesh)
|
||||
{
|
||||
BKE_mesh_runtime_clear_geometry(mesh);
|
||||
|
|
|
@ -3582,6 +3582,17 @@ void BKE_object_runtime_reset(Object *object)
|
|||
memset(&object->runtime, 0, sizeof(object->runtime));
|
||||
}
|
||||
|
||||
/* Reset all pointers which we don't want to be shared when copying the object. */
|
||||
void BKE_object_runtime_reset_on_copy(Object *object)
|
||||
{
|
||||
Object_Runtime *runtime = &object->runtime;
|
||||
runtime->mesh_eval = NULL;
|
||||
runtime->mesh_deform_eval = NULL;
|
||||
runtime->curve_cache = NULL;
|
||||
runtime->gpencil_cache = NULL;
|
||||
runtime->cached_bbone_deformation = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an associated Armature object
|
||||
*/
|
||||
|
|
|
@ -925,8 +925,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
|
|||
LIB_ID_CREATE_NO_MAIN |
|
||||
LIB_ID_CREATE_NO_USER_REFCOUNT |
|
||||
LIB_ID_CREATE_NO_DEG_TAG |
|
||||
LIB_ID_COPY_NO_PREVIEW |
|
||||
LIB_ID_COPY_RUNTIME,
|
||||
LIB_ID_COPY_NO_PREVIEW,
|
||||
false);
|
||||
|
||||
BKE_mesh_tessface_ensure(mesh);
|
||||
|
|
|
@ -198,8 +198,7 @@ Mesh *MOD_deform_mesh_eval_get(
|
|||
LIB_ID_CREATE_NO_USER_REFCOUNT |
|
||||
LIB_ID_CREATE_NO_DEG_TAG |
|
||||
LIB_ID_COPY_NO_PREVIEW |
|
||||
LIB_ID_COPY_CD_REFERENCE |
|
||||
LIB_ID_COPY_RUNTIME),
|
||||
LIB_ID_COPY_CD_REFERENCE),
|
||||
false);
|
||||
mesh->runtime.deformed_only = 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue