Fix T59339: Particle render without baking issues

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.
This commit is contained in:
Sergey Sharybin 2019-01-31 16:53:19 +01:00
parent 0d2b977c3b
commit d2f3378249
6 changed files with 26 additions and 13 deletions

@ -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);

@ -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(

@ -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) {

@ -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 */

@ -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);
}

@ -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;