Fix T63788: Crash if particle system is turned off in particle editing mode
Make sure particle system edit never points to a modifier or particle system which becomes inactive. This is needed because copy-on-write will change pointers of them and those pointers are supposed to be restored from particle system evaluation. But since the particle system is disabled it never updates pointers. Reviewers: brecht Reviewed By: brecht Differential Revision: https://developer.blender.org/D5180
This commit is contained in:
@@ -3291,6 +3291,10 @@ void psys_cache_edit_paths(Depsgraph *depsgraph,
|
||||
int segments = 1 << pset->draw_step;
|
||||
int totpart = edit->totpoint, recalc_set = 0;
|
||||
|
||||
if (edit->psmd_eval == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
segments = MAX2(segments, 4);
|
||||
|
||||
if (!cache || edit->totpoint != edit->totcached) {
|
||||
|
||||
@@ -87,6 +87,7 @@ extern "C" {
|
||||
#include "BKE_library_query.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_pointcache.h"
|
||||
#include "BKE_sequencer.h"
|
||||
#include "BKE_sound.h"
|
||||
}
|
||||
@@ -683,10 +684,22 @@ void set_particle_system_modifiers_loaded(Object *object_cow)
|
||||
}
|
||||
}
|
||||
|
||||
void reset_particle_system_edit_eval(Object *object_cow)
|
||||
{
|
||||
LISTBASE_FOREACH (ParticleSystem *, psys, &object_cow->particlesystem) {
|
||||
ParticleSystem *orig_psys = psys->orig_psys;
|
||||
if (orig_psys->edit != NULL) {
|
||||
orig_psys->edit->psys_eval = NULL;
|
||||
orig_psys->edit->psmd_eval = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void update_particles_after_copy(const Object *object_orig, Object *object_cow)
|
||||
{
|
||||
update_particle_system_orig_pointers(object_orig, object_cow);
|
||||
set_particle_system_modifiers_loaded(object_cow);
|
||||
reset_particle_system_edit_eval(object_cow);
|
||||
}
|
||||
|
||||
void update_pose_orig_pointers(const bPose *pose_orig, bPose *pose_cow)
|
||||
|
||||
@@ -97,23 +97,38 @@ bool PE_poll(bContext *C)
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
|
||||
if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
return (PE_get_current(scene, ob) != NULL);
|
||||
|
||||
PTCacheEdit *edit = PE_get_current(scene, ob);
|
||||
if (edit == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (edit->psmd_eval == NULL || edit->psmd_eval->mesh_final == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PE_hair_poll(bContext *C)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
PTCacheEdit *edit;
|
||||
|
||||
if (!scene || !ob || !(ob->mode & OB_MODE_PARTICLE_EDIT)) {
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
edit = PE_get_current(scene, ob);
|
||||
|
||||
return (edit && edit->psys);
|
||||
PTCacheEdit *edit = PE_get_current(scene, ob);
|
||||
if (edit == NULL || edit->psys == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (edit->psmd_eval == NULL || edit->psmd_eval->mesh_final == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PE_poll_view3d(bContext *C)
|
||||
@@ -1085,7 +1100,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys)
|
||||
edit = psys->edit;
|
||||
psmd_eval = edit->psmd_eval;
|
||||
|
||||
if (!psmd_eval->mesh_final) {
|
||||
if (psmd_eval == NULL || psmd_eval->mesh_final == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1217,7 +1232,7 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
|
||||
|
||||
psys = edit->psys;
|
||||
|
||||
if (!edit->psmd_eval->mesh_final) {
|
||||
if (edit->psmd_eval == NULL || edit->psmd_eval->mesh_final == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1489,7 +1504,7 @@ void update_world_cos(Depsgraph *UNUSED(depsgraph), Object *ob, PTCacheEdit *edi
|
||||
KEY_K;
|
||||
float hairmat[4][4];
|
||||
|
||||
if (psys == 0 || psys->edit == 0 || psmd_eval->mesh_final == NULL) {
|
||||
if (psys == 0 || psys->edit == 0 || psmd_eval == NULL || psmd_eval->mesh_final == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user