Fix T59339: Particle render without baking issues
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 8 Feb 2019 14:05:29 +0000 (15:05 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 8 Feb 2019 14:31:08 +0000 (15:31 +0100)
Fix T61289: Emitting particles from instances not working properly

The first issue has been re-introduced by a code which was dealing
with missing hair after opening the file. That was re-setting all
particle systems all the time because modifier flags were not copied
back to original. This made every modifier run to be seem as an
initial file open.

Now we copy flags back to an original modifier. But also we are
trying to not do any resets unless needed in that case. This way
we can preserve in-memory caches.

Other part of the change is related on re-setting particle system
if number of mesh elements changed. But we only do it if the
modifier has been already evaluated once.

source/blender/modifiers/intern/MOD_particlesystem.c

index 97b03ad92fbc42e2c125d4405a67fb8331b2f858..70404a1cb638fadf71010447288fe012d75a6b40 100644 (file)
@@ -115,6 +115,7 @@ static void deformVerts(
        }
 
        /* clear old dm */
+       bool had_mesh_final = (psmd->mesh_final != NULL);
        if (psmd->mesh_final) {
                BKE_id_free(NULL, psmd->mesh_final);
                psmd->mesh_final = NULL;
@@ -126,13 +127,9 @@ static void deformVerts(
        else if (psmd->flag & eParticleSystemFlag_file_loaded) {
                /* in file read mesh just wasn't saved in file so no need to reset everything */
                psmd->flag &= ~eParticleSystemFlag_file_loaded;
-               /* TODO(sergey): With copy-on-write this is more like duplicating an
-                * object which does need to reset particles. */
-               psys->recalc |= ID_RECALC_PSYS_RESET;
-       }
-       else {
-               /* no dm before, so recalc particles fully */
-               psys->recalc |= ID_RECALC_PSYS_RESET;
+               if (psys->particles == NULL) {
+                       psys->recalc |= ID_RECALC_PSYS_RESET;
+               }
        }
 
        /* make new mesh */
@@ -178,12 +175,35 @@ static void deformVerts(
                BKE_id_free(NULL, mesh_src);
        }
 
+       /* Report change in mesh structure.
+        * This is an unreliable check for the topology check, but allows some
+        * handy configuration like emitting particles from inside particle
+        * instance. */
+       if (had_mesh_final &&
+           (psmd->mesh_final->totvert != psmd->totdmvert ||
+            psmd->mesh_final->totedge != psmd->totdmedge ||
+            psmd->mesh_final->totface != psmd->totdmface))
+       {
+               psys->recalc |= ID_RECALC_PSYS_RESET;
+               psmd->totdmvert = psmd->mesh_final->totvert;
+               psmd->totdmedge = psmd->mesh_final->totedge;
+               psmd->totdmface = psmd->mesh_final->totface;
+       }
+
        if (!(ctx->object->transflag & OB_NO_PSYS_UPDATE)) {
                struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
                psmd->flag &= ~eParticleSystemFlag_psys_updated;
                particle_system_update(ctx->depsgraph, scene, ctx->object, psys, (ctx->flag & MOD_APPLY_RENDER) != 0);
                psmd->flag |= eParticleSystemFlag_psys_updated;
        }
+
+       if (DEG_is_active(ctx->depsgraph)) {
+               Object *object_orig = DEG_get_original_object(ctx->object);
+               ModifierData *md_orig = modifiers_findByName(object_orig, psmd->modifier.name);
+               BLI_assert(md_orig != NULL);
+               ParticleSystemModifierData *psmd_orig = (ParticleSystemModifierData *) md_orig;
+               psmd_orig->flag = psmd->flag;
+       }
 }
 
 /* disabled particles in editmode for now, until support for proper evaluated mesh