Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiddhartha Jejurkar <f20180617@goa.bits-pilani.ac.in>2021-11-19 21:34:44 +0300
committerSiddhartha Jejurkar <f20180617@goa.bits-pilani.ac.in>2021-11-19 21:34:44 +0300
commit99a2af76d10e05a18987be5d554ada197b1ca086 (patch)
tree9f9ceccccbd117c05a701b6769eb69055be6a28e /source/blender/blenkernel/intern/particle.c
parent139606bd370f96e0a8685547d515a2335591d5de (diff)
parent50ad0e15fe0adde7335c89c6fcfa0948c341a08a (diff)
Merge branch 'master' into soc-2021-uv-edge-select-support
Diffstat (limited to 'source/blender/blenkernel/intern/particle.c')
-rw-r--r--source/blender/blenkernel/intern/particle.c22
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++) {