diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-05-11 15:54:50 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2018-05-11 15:55:58 +0300 |
commit | aefd181b0b19403eaa6643e63901ff1cd740f881 (patch) | |
tree | 28317d013fe44a1911fc3a6b2cc9111f69646d95 /source/blender/draw/modes/particle_mode.c | |
parent | af5428aa2b4d4c6255c98cc0c22e618ec0d43ff8 (diff) |
Fix crash going to edit mode of particles with copy on write
We can not rely on edit->psys, it is not set for particle edit,
and there is some logic deeper inside which does different things
dependent on that.
We need to replace those checks with some some HAIR vs. PARTICLES
flag and always set psys pointer.
Diffstat (limited to 'source/blender/draw/modes/particle_mode.c')
-rw-r--r-- | source/blender/draw/modes/particle_mode.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/source/blender/draw/modes/particle_mode.c b/source/blender/draw/modes/particle_mode.c index d9363a18054..ef85fe1fdc4 100644 --- a/source/blender/draw/modes/particle_mode.c +++ b/source/blender/draw/modes/particle_mode.c @@ -139,22 +139,17 @@ static void particle_cache_init(void *vedata) DRW_shgroup_uniform_float(stl->g_data->tip_points_group, "outlineWidth", &outline_width, 1); } -/* TODO(sergey): Avoid linear lookup. */ -static void draw_update_ptcache_edit(Object *object_eval, PTCacheEdit *edit) +static void draw_update_ptcache_edit(Object *object_eval, + ParticleSystem *psys, + PTCacheEdit *edit) { if (edit->psys == NULL) { return; } - ParticleSystem *psys_eval; - for (psys_eval = object_eval->particlesystem.first; - psys_eval != NULL; - psys_eval = psys_eval->next) - { - if (STREQ(edit->psys->name, psys_eval->name)) { - break; - } - } - if (psys_eval->flag & PSYS_HAIR_UPDATED) { + /* NOTE: Get flag from particle system coming from drawing object. + * this is where depsgraph will be setting flags to. + */ + if (psys->flag & PSYS_HAIR_UPDATED) { const DRWContextState *draw_ctx = DRW_context_state_get(); Scene *scene_orig = (Scene *)DEG_get_original_id(&draw_ctx->scene->id); Object *object_orig = DEG_get_original_object(object_eval); @@ -165,25 +160,26 @@ static void draw_update_ptcache_edit(Object *object_eval, PTCacheEdit *edit) static void particle_edit_cache_populate(void *vedata, Object *object, + ParticleSystem *psys, PTCacheEdit *edit) { PARTICLE_StorageList *stl = ((PARTICLE_Data *)vedata)->stl; const DRWContextState *draw_ctx = DRW_context_state_get(); - draw_update_ptcache_edit(object, edit); + draw_update_ptcache_edit(object, psys, edit); ParticleEditSettings *pset = PE_settings(draw_ctx->scene); { struct Gwn_Batch *strands = - DRW_cache_particles_get_edit_strands(object, edit); + DRW_cache_particles_get_edit_strands(object, psys, edit); DRW_shgroup_call_add(stl->g_data->strands_group, strands, NULL); } if (pset->selectmode == SCE_SELECT_POINT) { struct Gwn_Batch *points = - DRW_cache_particles_get_edit_inner_points(object, edit); + DRW_cache_particles_get_edit_inner_points(object, psys, edit); DRW_shgroup_call_add(stl->g_data->inner_points_group, points, NULL); } if (ELEM(pset->selectmode, SCE_SELECT_POINT, SCE_SELECT_END)) { struct Gwn_Batch *points = - DRW_cache_particles_get_edit_tip_points(object, edit); + DRW_cache_particles_get_edit_tip_points(object, psys, edit); DRW_shgroup_call_add(stl->g_data->tip_points_group, points, NULL); } } @@ -197,7 +193,20 @@ static void particle_cache_populate(void *vedata, Object *object) printf("Particle edit struct is NULL, not supposed to happen.\n"); return; } - particle_edit_cache_populate(vedata, object, edit); + ParticleSystem *psys = object->particlesystem.first; + ParticleSystem *psys_orig = object_orig->particlesystem.first; + while (psys_orig != NULL) { + if (PE_get_current_from_psys(psys_orig) == edit) { + break; + } + psys = psys->next; + psys_orig = psys_orig->next; + } + if (psys == NULL) { + printf("Error getting evaluated particle system for edit.\n"); + return; + } + particle_edit_cache_populate(vedata, object, psys, edit); } /* Optional: Post-cache_populate callback */ |