diff options
author | Sergey Sharybin <sergey@blender.org> | 2021-11-16 19:25:48 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey@blender.org> | 2021-11-16 19:25:48 +0300 |
commit | ba6427adfaec0d405386f14fef5728f0114f7589 (patch) | |
tree | 303a245fa7e2474febf1a1b4d42bdb89a8ef3e69 /source/blender/blenkernel/intern/particle.c | |
parent | bee7a56687283cc3642d625357d8d2b1847b67a1 (diff) | |
parent | b3529ecf0eb5e942267eb168fc078188de193400 (diff) |
Merge branch 'blender-v3.0-release'
Diffstat (limited to 'source/blender/blenkernel/intern/particle.c')
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 5b62761bd91..b158633294e 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1149,7 +1149,27 @@ void psys_copy_particles(ParticleSystem *psys_dst, ParticleSystem *psys_src) /* Copy particles and children. */ psys_dst->particles = MEM_dupallocN(psys_src->particles); psys_dst->child = MEM_dupallocN(psys_src->child); - if (psys_dst->part->type == PART_HAIR) { + + /* Ideally this should only be performed if `(psys_dst->part->type == PART_HAIR)`. + * + * But #ParticleData (`psys_dst`) is some sub-data of the #Object ID, while #ParticleSettings + * (`psys_dst->part`) is another ID. In case the particle settings is a linked ID that gets + * missing, it will be replaced (in readfile code) by a place-holder, which defaults to a + * `PART_EMITTER` type of particle settings. + * + * This leads to a situation where each particle of `psys_dst` still has a valid allocated `hair` + * data, which should still be preserved in case the missing particle settings ID becomes valid + * again. + * + * Furthermore, #free_hair() always frees `pa->hair` if it's not NULL, regardless of the + * particle type. So *not* copying here would cause a double free (or more), e.g. freeing the + * copy-on-write copy and the original data will crash Blender. + * In any case, sharing pointers between `psys_src` and `psys_dst` should be forbidden. + * + * So while we could in theory 'sanitize' the situation by setting `pa->hair` to NULL in the new + * copy (in case of non-`PART_HAIR` type), it is probably safer for now to systematically + * duplicate the `hair` data if available. */ + { ParticleData *pa; int p; for (p = 0, pa = psys_dst->particles; p < psys_dst->totpart; p++, pa++) { |