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.
This commit is contained in:
parent
af5428aa2b
commit
aefd181b0b
|
@ -2886,19 +2886,28 @@ Gwn_Batch *DRW_cache_particles_get_dots(Object *object, ParticleSystem *psys)
|
|||
return DRW_particles_batch_cache_get_dots(object, psys);
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_cache_particles_get_edit_strands(Object *object, struct PTCacheEdit *edit)
|
||||
Gwn_Batch *DRW_cache_particles_get_edit_strands(
|
||||
Object *object,
|
||||
ParticleSystem *psys,
|
||||
struct PTCacheEdit *edit)
|
||||
{
|
||||
return DRW_particles_batch_cache_get_edit_strands(object, edit);
|
||||
return DRW_particles_batch_cache_get_edit_strands(object, psys, edit);
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_cache_particles_get_edit_inner_points(Object *object, struct PTCacheEdit *edit)
|
||||
Gwn_Batch *DRW_cache_particles_get_edit_inner_points(
|
||||
Object *object,
|
||||
ParticleSystem *psys,
|
||||
struct PTCacheEdit *edit)
|
||||
{
|
||||
return DRW_particles_batch_cache_get_edit_inner_points(object, edit);
|
||||
return DRW_particles_batch_cache_get_edit_inner_points(object, psys, edit);
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_cache_particles_get_edit_tip_points(Object *object, struct PTCacheEdit *edit)
|
||||
Gwn_Batch *DRW_cache_particles_get_edit_tip_points(
|
||||
Object *object,
|
||||
ParticleSystem *psys,
|
||||
struct PTCacheEdit *edit)
|
||||
{
|
||||
return DRW_particles_batch_cache_get_edit_tip_points(object, edit);
|
||||
return DRW_particles_batch_cache_get_edit_tip_points(object, psys, edit);
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_cache_particles_get_prim(int type)
|
||||
|
|
|
@ -169,9 +169,9 @@ struct Gwn_Batch *DRW_cache_lattice_vert_overlay_get(struct Object *ob);
|
|||
/* Particles */
|
||||
struct Gwn_Batch *DRW_cache_particles_get_hair(struct ParticleSystem *psys, struct ModifierData *md);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_dots(struct Object *object, struct ParticleSystem *psys);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_edit_strands(struct Object *object, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_edit_inner_points(struct Object *object, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_edit_tip_points(struct Object *object, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_edit_strands(struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_edit_inner_points(struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_edit_tip_points(struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_prim(int type);
|
||||
|
||||
/* Metaball */
|
||||
|
|
|
@ -125,8 +125,8 @@ void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me);
|
|||
/* Particles */
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_hair(struct ParticleSystem *psys, struct ModifierData *md);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_dots(struct Object *object, struct ParticleSystem *psys);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(struct Object *object, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points(struct Object *object, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points(struct Object *object, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points(struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
|
||||
struct Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points(struct Object *object, struct ParticleSystem *psys, struct PTCacheEdit *edit);
|
||||
|
||||
#endif /* __DRAW_CACHE_IMPL_H__ */
|
||||
|
|
|
@ -597,25 +597,12 @@ Gwn_Batch *DRW_particles_batch_cache_get_dots(Object *object, ParticleSystem *ps
|
|||
return cache->hairs;
|
||||
}
|
||||
|
||||
/* TODO(sergey): Avoid linear lookup. */
|
||||
static ParticleBatchCache *particle_batch_cache_get_edit(Object *object, PTCacheEdit *edit)
|
||||
Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(
|
||||
Object *UNUSED(object),
|
||||
ParticleSystem *psys,
|
||||
PTCacheEdit *edit)
|
||||
{
|
||||
ParticleSystem *psys_orig = edit->psys;
|
||||
for (ParticleSystem *psys_eval = object->particlesystem.first;
|
||||
psys_eval != NULL;
|
||||
psys_eval = psys_eval->next)
|
||||
{
|
||||
if (STREQ(psys_orig->name, psys_eval->name)) {
|
||||
return particle_batch_cache_get(psys_eval);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_particles_batch_cache_get_edit_strands(Object *object, PTCacheEdit *edit)
|
||||
{
|
||||
ParticleSystem *psys = edit->psys;
|
||||
ParticleBatchCache *cache = particle_batch_cache_get_edit(object, edit);
|
||||
ParticleBatchCache *cache = particle_batch_cache_get(psys);
|
||||
if (cache->hairs != NULL) {
|
||||
return cache->hairs;
|
||||
}
|
||||
|
@ -691,9 +678,12 @@ static void particle_batch_cache_ensure_edit_inner_pos(
|
|||
}
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points(Object *object, PTCacheEdit *edit)
|
||||
Gwn_Batch *DRW_particles_batch_cache_get_edit_inner_points(
|
||||
Object *UNUSED(object),
|
||||
ParticleSystem *psys,
|
||||
PTCacheEdit *edit)
|
||||
{
|
||||
ParticleBatchCache *cache = particle_batch_cache_get_edit(object, edit);
|
||||
ParticleBatchCache *cache = particle_batch_cache_get(psys);
|
||||
if (cache->edit_inner_points != NULL) {
|
||||
return cache->edit_inner_points;
|
||||
}
|
||||
|
@ -752,9 +742,12 @@ static void particle_batch_cache_ensure_edit_tip_pos(
|
|||
}
|
||||
}
|
||||
|
||||
Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points(Object *object, PTCacheEdit *edit)
|
||||
Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points(
|
||||
Object *UNUSED(object),
|
||||
ParticleSystem *psys,
|
||||
PTCacheEdit *edit)
|
||||
{
|
||||
ParticleBatchCache *cache = particle_batch_cache_get_edit(object, edit);
|
||||
ParticleBatchCache *cache = particle_batch_cache_get(psys);
|
||||
if (cache->edit_tip_points != NULL) {
|
||||
return cache->edit_tip_points;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -47,6 +47,7 @@ void PE_free_ptcache_edit(struct PTCacheEdit *edit);
|
|||
int PE_start_edit(struct PTCacheEdit *edit);
|
||||
|
||||
/* access */
|
||||
struct PTCacheEdit *PE_get_current_from_psys(struct ParticleSystem *psys);
|
||||
struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob);
|
||||
struct PTCacheEdit *PE_create_current(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
|
||||
void PE_current_changed(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
|
||||
|
|
|
@ -191,6 +191,24 @@ static float pe_brush_size_get(const Scene *UNUSED(scene), ParticleBrushData *br
|
|||
return brush->size * U.pixelsize;
|
||||
}
|
||||
|
||||
PTCacheEdit *PE_get_current_from_psys(ParticleSystem *psys)
|
||||
{
|
||||
if (psys->part && psys->part->type == PART_HAIR) {
|
||||
if ((psys->flag & PSYS_HAIR_DYNAMICS) != 0 &&
|
||||
(psys->pointcache->flag & PTCACHE_BAKED) != 0)
|
||||
{
|
||||
return psys->pointcache->edit;
|
||||
}
|
||||
else {
|
||||
return psys->edit;
|
||||
}
|
||||
}
|
||||
else if (psys->pointcache->flag & PTCACHE_BAKED) {
|
||||
return psys->pointcache->edit;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* always gets at least the first particlesystem even if PSYS_CURRENT flag is not set
|
||||
*
|
||||
* note: this function runs on poll, therefor it can runs many times a second
|
||||
|
|
Loading…
Reference in New Issue