Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / effect.c
index 749c5897abbded3f4b1976e1c6acb2441493563b..84f12c3a239e44127790e88f42db40ee4553fa9d 100644 (file)
@@ -64,6 +64,8 @@
 #include "BKE_cdderivedmesh.h"
 #include "BKE_effect.h"
 #include "BKE_global.h"
+#include "BKE_group.h"
+#include "BKE_layer.h"
 #include "BKE_library.h"
 #include "BKE_modifier.h"
 #include "BKE_object.h"
@@ -71,6 +73,7 @@
 #include "BKE_scene.h"
 #include "BKE_smoke.h"
 
+#include "DEG_depsgraph.h"
 
 #include "RE_render_ext.h"
 #include "RE_shader_ext.h"
@@ -145,9 +148,10 @@ void free_partdeflect(PartDeflect *pd)
        MEM_freeN(pd);
 }
 
-static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
+static EffectorCache *new_effector_cache(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
 {
        EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache");
+       eff->eval_ctx = eval_ctx;
        eff->scene = scene;
        eff->ob = ob;
        eff->psys = psys;
@@ -155,7 +159,7 @@ static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSyste
        eff->frame = -1;
        return eff;
 }
-static void add_object_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src, bool for_simulation)
+static void add_object_to_effectors(ListBase **effectors, const struct EvaluationContext *eval_ctx, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src, bool for_simulation)
 {
        EffectorCache *eff = NULL;
 
@@ -173,14 +177,14 @@ static void add_object_to_effectors(ListBase **effectors, Scene *scene, Effector
        if (*effectors == NULL)
                *effectors = MEM_callocN(sizeof(ListBase), "effectors list");
 
-       eff = new_effector_cache(scene, ob, NULL, ob->pd);
+       eff = new_effector_cache(eval_ctx, scene, ob, NULL, ob->pd);
 
        /* make sure imat is up to date */
        invert_m4_m4(ob->imat, ob->obmat);
 
        BLI_addtail(*effectors, eff);
 }
-static void add_particles_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src, bool for_simulation)
+static void add_particles_to_effectors(ListBase **effectors, const struct EvaluationContext *eval_ctx, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src, bool for_simulation)
 {
        ParticleSettings *part= psys->part;
 
@@ -194,61 +198,59 @@ static void add_particles_to_effectors(ListBase **effectors, Scene *scene, Effec
                if (*effectors == NULL)
                        *effectors = MEM_callocN(sizeof(ListBase), "effectors list");
 
-               BLI_addtail(*effectors, new_effector_cache(scene, ob, psys, part->pd));
+               BLI_addtail(*effectors, new_effector_cache(eval_ctx, scene, ob, psys, part->pd));
        }
 
        if (part->pd2 && part->pd2->forcefield && (!for_simulation || weights->weight[part->pd2->forcefield] != 0.0f)) {
                if (*effectors == NULL)
                        *effectors = MEM_callocN(sizeof(ListBase), "effectors list");
 
-               BLI_addtail(*effectors, new_effector_cache(scene, ob, psys, part->pd2));
+               BLI_addtail(*effectors, new_effector_cache(eval_ctx, scene, ob, psys, part->pd2));
        }
 }
 
 /* returns ListBase handle with objects taking part in the effecting */
-ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src,
-                          EffectorWeights *weights, bool for_simulation)
+ListBase *pdInitEffectors(
+        const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, ParticleSystem *psys_src,
+        EffectorWeights *weights, bool for_simulation)
 {
+       ViewLayer *view_layer;
        Base *base;
-       unsigned int layer= ob_src->lay;
        ListBase *effectors = NULL;
-       
+
        if (weights->group) {
-               GroupObject *go;
-               
-               for (go= weights->group->gobject.first; go; go= go->next) {
-                       if ( (go->ob->lay & layer) ) {
-                               if ( go->ob->pd && go->ob->pd->forcefield )
-                                       add_object_to_effectors(&effectors, scene, weights, go->ob, ob_src, for_simulation);
+               view_layer = weights->group->view_layer;
+       }
+       else if (eval_ctx) {
+               view_layer = eval_ctx->view_layer;
+       }
+       else {
+               /* eval_ctx is NULL during deg build */
+               view_layer = BKE_view_layer_context_active_PLACEHOLDER(scene);
+       }
 
-                               if ( go->ob->particlesystem.first ) {
-                                       ParticleSystem *psys= go->ob->particlesystem.first;
+       for (base = FIRSTBASE(view_layer); base; base = base->next) {
+               if ((base->flag & BASE_VISIBLED) == 0) {
+                       continue;
+               }
 
-                                       for ( ; psys; psys=psys->next )
-                                               add_particles_to_effectors(&effectors, scene, weights, go->ob, psys, psys_src, for_simulation);
-                               }
-                       }
+               if (base->object->pd && base->object->pd->forcefield) {
+                       add_object_to_effectors(&effectors, eval_ctx, scene, weights, base->object, ob_src, for_simulation);
                }
-       }
-       else {
-               for (base = scene->base.first; base; base= base->next) {
-                       if ( (base->lay & layer) ) {
-                               if ( base->object->pd && base->object->pd->forcefield )
-                                       add_object_to_effectors(&effectors, scene, weights, base->object, ob_src, for_simulation);
 
-                               if ( base->object->particlesystem.first ) {
-                                       ParticleSystem *psys= base->object->particlesystem.first;
+               if (base->object->particlesystem.first) {
+                       ParticleSystem *psys= base->object->particlesystem.first;
 
-                                       for ( ; psys; psys=psys->next )
-                                               add_particles_to_effectors(&effectors, scene, weights, base->object, psys, psys_src, for_simulation);
-                               }
+                       for (; psys; psys=psys->next) {
+                               add_particles_to_effectors(&effectors, eval_ctx, scene, weights, base->object, psys, psys_src, for_simulation);
                        }
                }
        }
-       
-       if (for_simulation)
-               pdPrecalculateEffectors(effectors);
-       
+
+       if (for_simulation) {
+               pdPrecalculateEffectors(eval_ctx, effectors);
+       }
+
        return effectors;
 }
 
@@ -268,7 +270,7 @@ void pdEndEffectors(ListBase **effectors)
        }
 }
 
-static void precalculate_effector(EffectorCache *eff)
+static void precalculate_effector(const struct EvaluationContext *eval_ctx, EffectorCache *eff)
 {
        unsigned int cfra = (unsigned int)(eff->scene->r.cfra >= 0 ? eff->scene->r.cfra : -eff->scene->r.cfra);
        if (!eff->pd->rng)
@@ -280,7 +282,7 @@ static void precalculate_effector(EffectorCache *eff)
                Curve *cu= eff->ob->data;
                if (cu->flag & CU_PATH) {
                        if (eff->ob->curve_cache == NULL || eff->ob->curve_cache->path==NULL || eff->ob->curve_cache->path->data==NULL)
-                               BKE_displist_make_curveTypes(eff->scene, eff->ob, 0);
+                               BKE_displist_make_curveTypes(eval_ctx, eff->scene, eff->ob, 0);
 
                        if (eff->ob->curve_cache->path && eff->ob->curve_cache->path->data) {
                                where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL);
@@ -301,19 +303,19 @@ static void precalculate_effector(EffectorCache *eff)
        if (eff->ob) {
                float old_vel[3];
 
-               BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra - 1.0f);
+               BKE_object_where_is_calc_time(eval_ctx, eff->scene, eff->ob, cfra - 1.0f);
                copy_v3_v3(old_vel, eff->ob->obmat[3]);
-               BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra);
+               BKE_object_where_is_calc_time(eval_ctx, eff->scene, eff->ob, cfra);
                sub_v3_v3v3(eff->velocity, eff->ob->obmat[3], old_vel);
        }
 }
 
-void pdPrecalculateEffectors(ListBase *effectors)
+void pdPrecalculateEffectors(const struct EvaluationContext *eval_ctx, ListBase *effectors)
 {
        if (effectors) {
                EffectorCache *eff = effectors->first;
                for (; eff; eff=eff->next)
-                       precalculate_effector(eff);
+                       precalculate_effector(eval_ctx, eff);
        }
 }
 
@@ -612,6 +614,7 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
                }
                else {
                        ParticleSimulationData sim= {NULL};
+                       sim.eval_ctx = eff->eval_ctx;
                        sim.scene= eff->scene;
                        sim.ob= eff->ob;
                        sim.psys= eff->psys;