Fix T59339: Particle render without baking issues
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 31 Jan 2019 15:53:19 +0000 (16:53 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 31 Jan 2019 15:53:19 +0000 (16:53 +0100)
The issue was caused by dependency graph resetting particles
when evaluating copy-on-write version of object. Solved by
only doing reset from dependency graph on user edits.

Other issue was caused by modifier itself trying to compare
topology and reset particles when number of vertices or faces
changed. This isn't reliable, since topology might change even
with same number of elements. But also, since copy-on-written
object initially always have those fields zero-ed the reset
was happening on every F12.

The latter issue is solved by moving reset from modifier stack
to places where we exit edit/paint modes which might be changing
topology.

There is still weird issue of particles generated at some
weird location after tapping tab twice, but this is not a new
issue in 2.8 branch and is to be looked separately.

source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/intern/particle_system.c
source/blender/depsgraph/intern/builder/deg_builder_relations.cc
source/blender/editors/object/object_edit.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/modifiers/intern/MOD_particlesystem.c

index c23aa2f709c40016c5092546a6acd439fba5d826..72170da4ea2c4ebf62d00d9cacd38f139e18b3e8 100644 (file)
@@ -418,6 +418,9 @@ typedef void (*ParticleSystemIDFunc)(struct ParticleSystem *psys, struct ID **id
 
 void BKE_particlesystem_id_loop(struct ParticleSystem *psys, ParticleSystemIDFunc func, void *userdata);
 
+/* Reset all particle systems in the given object. */
+void BKE_particlesystem_reset_all(struct Object *object);
+
 /* ----------- functions needed only inside particlesystem ------------ */
 /* particle.c */
 void psys_disable_all(struct Object *ob);
index 458aec77379afb475c28fa779dd6691622a040b6..f61786903f8a8706352306621b6b44fe751e475d 100644 (file)
@@ -4414,6 +4414,18 @@ void BKE_particlesystem_id_loop(ParticleSystem *psys, ParticleSystemIDFunc func,
        }
 }
 
+void BKE_particlesystem_reset_all(struct Object *object)
+{
+       for (ModifierData *md = object->modifiers.first; md != NULL; md = md->next) {
+               if (md->type != eModifierType_ParticleSystem) {
+                       continue;
+               }
+               ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
+               ParticleSystem *psys = psmd->psys;
+               psys->recalc |= ID_RECALC_PSYS_RESET;
+       }
+}
+
 /* **** Depsgraph evaluation **** */
 
 void BKE_particle_settings_eval_reset(
index 0ca1222f5ba4c9f968fcc56ce16492a6293aad79..a27507954fbd83092b3ac255ec41404bb291081d 100644 (file)
@@ -1705,7 +1705,10 @@ void DepsgraphRelationBuilder::build_particle_systems(Object *object)
        ComponentKey eval_key(&object->id, NodeType::PARTICLE_SYSTEM);
        if (BKE_ptcache_object_has(scene_, object, 0)) {
                ComponentKey point_cache_key(&object->id, NodeType::POINT_CACHE);
-               add_relation(eval_key, point_cache_key, "Particle Point Cache");
+               add_relation(eval_key,
+                            point_cache_key,
+                            "Particle Point Cache",
+                            RELATION_FLAG_FLUSH_USER_EDIT_ONLY);
        }
        /* Particle systems. */
        LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) {
index dff78d156922f5e66085570e1c0b7e046f149395..958d9c088140865a0d7145b520630f643044a49e 100644 (file)
@@ -78,6 +78,7 @@
 #include "BKE_modifier.h"
 #include "BKE_object.h"
 #include "BKE_paint.h"
+#include "BKE_particle.h"
 #include "BKE_pointcache.h"
 #include "BKE_softbody.h"
 #include "BKE_editmesh.h"
@@ -537,6 +538,7 @@ bool ED_object_editmode_exit_ex(Main *bmain, Scene *scene, Object *obedit, int f
                }
                BLI_freelistN(&pidlist);
 
+               BKE_particlesystem_reset_all(obedit);
                BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED);
 
                /* also flush ob recalc, doesn't take much overhead, but used for particles */
index d7ecfadcfc5f36b9baf282c8abf25bf86789b5cf..f3a06988f1b2a40aec5901ffdd576d047cf316ab 100644 (file)
@@ -67,7 +67,9 @@
 #include "BKE_node.h"
 #include "BKE_object.h"
 #include "BKE_paint.h"
+#include "BKE_particle.h"
 #include "BKE_pbvh.h"
+#include "BKE_pointcache.h"
 #include "BKE_report.h"
 #include "BKE_screen.h"
 #include "BKE_subsurf.h"
@@ -5569,6 +5571,9 @@ void sculpt_dynamic_topology_disable_ex(
                ss->bm_log = NULL;
        }
 
+       BKE_particlesystem_reset_all(ob);
+       BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_OUTDATED);
+
        /* Refresh */
        sculpt_update_after_dynamic_topology_toggle(depsgraph, scene, ob);
 }
index bc1fb300cacbba3934e8b07cd47c22da82b78dcd..2c541c52919889761733f3d1e49e6c4c7f4d0471 100644 (file)
@@ -187,18 +187,6 @@ static void deformVerts(
                BKE_id_free(NULL, mesh_src);
        }
 
-       /* report change in mesh structure */
-       if (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;