diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_smoke.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_smoke.c | 177 |
1 files changed, 169 insertions, 8 deletions
diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c index f260c0491ee..657c4e09d96 100644 --- a/source/blender/modifiers/intern/MOD_smoke.c +++ b/source/blender/modifiers/intern/MOD_smoke.c @@ -47,10 +47,13 @@ #include "BKE_cdderivedmesh.h" +#include "BKE_library.h" +#include "BKE_main.h" #include "BKE_modifier.h" #include "BKE_smoke.h" #include "depsgraph_private.h" +#include "DEG_depsgraph_build.h" static void initData(ModifierData *md) { @@ -114,7 +117,65 @@ static bool dependsOnTime(ModifierData *UNUSED(md)) return true; } +static void update_depsgraph_flow_coll_object(DagForest *forest, + DagNode *obNode, + Object *object2) +{ + SmokeModifierData *smd; + if ((object2->id.flag & LIB_DOIT) == 0) { + return; + } + object2->id.flag &= ~LIB_DOIT; + smd = (SmokeModifierData *)modifiers_findByType(object2, eModifierType_Smoke); + if (smd && (((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) || + ((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll))) + { + DagNode *curNode = dag_get_node(forest, object2); + dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Smoke Flow/Coll"); + } + if ((object2->transflag & OB_DUPLIGROUP) && object2->dup_group) { + GroupObject *go; + for (go = object2->dup_group->gobject.first; + go != NULL; + go = go->next) + { + if (go->ob == NULL) { + continue; + } + update_depsgraph_flow_coll_object(forest, obNode, go->ob); + } + } +} + +static void update_depsgraph_field_source_object(DagForest *forest, + DagNode *obNode, + Object *object, + Object *object2) +{ + if ((object2->id.flag & LIB_DOIT) == 0) { + return; + } + object2->id.flag &= ~LIB_DOIT; + if (object2->pd && object2->pd->forcefield == PFIELD_SMOKEFLOW && object2->pd->f_source == object) { + DagNode *node2 = dag_get_node(forest, object2); + dag_add_relation(forest, obNode, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Source Object"); + } + if ((object2->transflag & OB_DUPLIGROUP) && object2->dup_group) { + GroupObject *go; + for (go = object2->dup_group->gobject.first; + go != NULL; + go = go->next) + { + if (go->ob == NULL) { + continue; + } + update_depsgraph_field_source_object(forest, obNode, object, go->ob); + } + } +} + static void updateDepgraph(ModifierData *md, DagForest *forest, + struct Main *bmain, struct Scene *scene, struct Object *ob, DagNode *obNode) { @@ -152,23 +213,122 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, } } else { + BKE_main_id_tag_listbase(&bmain->object, true); base = scene->base.first; for (; base; base = base->next) { - SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(base->object, eModifierType_Smoke); + update_depsgraph_flow_coll_object(forest, obNode, base->object); + } + } + /* add relation to all "smoke flow" force fields */ + base = scene->base.first; + BKE_main_id_tag_listbase(&bmain->object, true); + for (; base; base = base->next) { + update_depsgraph_field_source_object(forest, obNode, ob, base->object); + } + } +} + +static void update_depsgraph_flow_coll_object_new(struct DepsNodeHandle *node, + Object *object2) +{ + SmokeModifierData *smd; + if ((object2->id.flag & LIB_DOIT) == 0) { + return; + } + object2->id.flag &= ~LIB_DOIT; + smd = (SmokeModifierData *)modifiers_findByType(object2, eModifierType_Smoke); + if (smd && (((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) || + ((smd->type & MOD_SMOKE_TYPE_COLL) && smd->coll))) + { + DEG_add_object_relation(node, object2, DEG_OB_COMP_TRANSFORM, "Smoke Flow/Coll"); + DEG_add_object_relation(node, object2, DEG_OB_COMP_GEOMETRY, "Smoke Flow/Coll"); + } + if ((object2->transflag & OB_DUPLIGROUP) && object2->dup_group) { + GroupObject *go; + for (go = object2->dup_group->gobject.first; + go != NULL; + go = go->next) + { + if (go->ob == NULL) { + continue; + } + update_depsgraph_flow_coll_object_new(node, go->ob); + } + } +} - if (smd2 && (((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) || ((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll))) { - DagNode *curNode = dag_get_node(forest, base->object); - dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Smoke Flow/Coll"); +static void update_depsgraph_field_source_object_new(struct DepsNodeHandle *node, + Object *object, + Object *object2) +{ + if ((object2->id.flag & LIB_DOIT) == 0) { + return; + } + object2->id.flag &= ~LIB_DOIT; + if (object2->pd && object2->pd->forcefield == PFIELD_SMOKEFLOW && object2->pd->f_source == object) { + DEG_add_object_relation(node, object2, DEG_OB_COMP_TRANSFORM, "Field Source Object"); + DEG_add_object_relation(node, object2, DEG_OB_COMP_GEOMETRY, "Field Source Object"); + } + if ((object2->transflag & OB_DUPLIGROUP) && object2->dup_group) { + GroupObject *go; + for (go = object2->dup_group->gobject.first; + go != NULL; + go = go->next) + { + if (go->ob == NULL) { + continue; + } + update_depsgraph_field_source_object_new(node, object, go->ob); + } + } +} + +static void updateDepsgraph(ModifierData *md, + struct Main *bmain, + struct Scene *scene, + Object *ob, + struct DepsNodeHandle *node) +{ + SmokeModifierData *smd = (SmokeModifierData *)md; + Base *base; + if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { + if (smd->domain->fluid_group || smd->domain->coll_group) { + GroupObject *go = NULL; + if (smd->domain->fluid_group != NULL) { + for (go = smd->domain->fluid_group->gobject.first; go; go = go->next) { + if (go->ob != NULL) { + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(go->ob, eModifierType_Smoke); + /* Check for initialized smoke object. */ + if (smd2 && (smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) { + DEG_add_object_relation(node, go->ob, DEG_OB_COMP_TRANSFORM, "Smoke Flow"); + } + } + } + } + if (smd->domain->coll_group != NULL) { + for (go = smd->domain->coll_group->gobject.first; go; go = go->next) { + if (go->ob != NULL) { + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(go->ob, eModifierType_Smoke); + /* Check for initialized smoke object. */ + if (smd2 && (smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) { + DEG_add_object_relation(node, go->ob, DEG_OB_COMP_TRANSFORM, "Smoke Coll"); + } + } } } } + else { + BKE_main_id_tag_listbase(&bmain->object, true); + base = scene->base.first; + for (; base; base = base->next) { + update_depsgraph_flow_coll_object_new(node, base->object); + } + } /* add relation to all "smoke flow" force fields */ base = scene->base.first; + BKE_main_id_tag_listbase(&bmain->object, true); for (; base; base = base->next) { - if (base->object->pd && base->object->pd->forcefield == PFIELD_SMOKEFLOW && base->object->pd->f_source == ob) { - DagNode *node2 = dag_get_node(forest, base->object); - dag_add_relation(forest, obNode, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Source Object"); - } + update_depsgraph_field_source_object_new(node, ob, base->object); } } } @@ -214,6 +374,7 @@ ModifierTypeInfo modifierType_Smoke = { /* freeData */ freeData, /* isDisabled */ NULL, /* updateDepgraph */ updateDepgraph, + /* updateDepsgraph */ updateDepsgraph, /* dependsOnTime */ dependsOnTime, /* dependsOnNormals */ NULL, /* foreachObjectLink */ NULL, |