From d1be30f77978539070c64a80393ff3ad55719a24 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 4 May 2018 11:40:27 +0200 Subject: Fix T54935: Particle group instances don't render when hidden in viewport Seems to be only related on linked nature of particles. This is caused by some conflicting optimization done for viewport, which does not do particles re-calculation if they do not depend on time (which is crucial for big layout scene grass fields) and particle render setting switch which was relying on fact that render pipeline will do particle update via time dependency. Now we extent an old workaround for invisible objects, which now also deals with particles in the same way as old dependency graph was dealing with this: tag object data for update if there is particle system. There shouldn't be any speed difference between old and new depsgraph, since tagging was already needed and was happening. In Blender 2.8 such things should be easier to deal with since the whole depsgraph is to be evaluated for render engine anyway. --- source/blender/render/intern/source/pipeline.c | 148 +++++++++++++++---------- 1 file changed, 87 insertions(+), 61 deletions(-) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 67c87d5d9b8..d1de985e4d6 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -2058,77 +2058,103 @@ bool RE_allow_render_generic_object(Object *ob) #define DEPSGRAPH_WORKAROUND_HACK #ifdef DEPSGRAPH_WORKAROUND_HACK -static void tag_dependend_objects_for_render(Scene *scene, int renderlay) +static void tag_dependend_object_for_render(Scene *scene, Object *object); + +static void tag_dependend_group_for_render(Scene *scene, Group *group) { - Scene *sce_iter; - Base *base; - for (SETLOOPER(scene, sce_iter, base)) { - Object *object = base->object; + if (group->id.tag & LIB_TAG_DOIT) { + return; + } + group->id.tag |= LIB_TAG_DOIT; - if ((base->lay & renderlay) == 0) { - continue; - } + for (GroupObject *go = group->gobject.first; go != NULL; go = go->next) { + Object *object = go->ob; + tag_dependend_object_for_render(scene, object); + } +} - if (object->type == OB_MESH) { - if (RE_allow_render_generic_object(object)) { - ModifierData *md; - VirtualModifierData virtualModifierData; +static void tag_dependend_object_for_render(Scene *scene, Object *object) +{ + if (object->type == OB_MESH) { + if (RE_allow_render_generic_object(object)) { + ModifierData *md; + VirtualModifierData virtualModifierData; - for (md = modifiers_getVirtualModifierList(object, &virtualModifierData); - md; - md = md->next) - { - if (!modifier_isEnabled(scene, md, eModifierMode_Render)) { - continue; - } + if (object->particlesystem.first) { + DAG_id_tag_update(&object->id, OB_RECALC_DATA); + } - if (md->type == eModifierType_Boolean) { - BooleanModifierData *bmd = (BooleanModifierData *)md; - if (bmd->object && bmd->object->type == OB_MESH) { - DAG_id_tag_update(&bmd->object->id, OB_RECALC_DATA); - } + for (md = modifiers_getVirtualModifierList(object, &virtualModifierData); + md; + md = md->next) + { + if (!modifier_isEnabled(scene, md, eModifierMode_Render)) { + continue; + } + + if (md->type == eModifierType_Boolean) { + BooleanModifierData *bmd = (BooleanModifierData *)md; + if (bmd->object && bmd->object->type == OB_MESH) { + DAG_id_tag_update(&bmd->object->id, OB_RECALC_DATA); } - else if (md->type == eModifierType_Array) { - ArrayModifierData *amd = (ArrayModifierData *)md; - if (amd->start_cap && amd->start_cap->type == OB_MESH) { - DAG_id_tag_update(&amd->start_cap->id, OB_RECALC_DATA); - } - if (amd->end_cap && amd->end_cap->type == OB_MESH) { - DAG_id_tag_update(&amd->end_cap->id, OB_RECALC_DATA); - } + } + else if (md->type == eModifierType_Array) { + ArrayModifierData *amd = (ArrayModifierData *)md; + if (amd->start_cap && amd->start_cap->type == OB_MESH) { + DAG_id_tag_update(&amd->start_cap->id, OB_RECALC_DATA); } - else if (md->type == eModifierType_Shrinkwrap) { - ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md; - if (smd->target && smd->target->type == OB_MESH) { - DAG_id_tag_update(&smd->target->id, OB_RECALC_DATA); - } + if (amd->end_cap && amd->end_cap->type == OB_MESH) { + DAG_id_tag_update(&amd->end_cap->id, OB_RECALC_DATA); } - else if (md->type == eModifierType_ParticleSystem) { - ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - ParticleSystem *psys = psmd->psys; - ParticleSettings *part = psys->part; - switch (part->ren_as) { - case PART_DRAW_OB: - if (part->dup_ob != NULL) { - DAG_id_tag_update(&part->dup_ob->id, OB_RECALC_DATA); - } - break; - case PART_DRAW_GR: - if (part->dup_group != NULL) { - for (GroupObject *go = part->dup_group->gobject.first; - go != NULL; - go = go->next) - { - DAG_id_tag_update(&go->ob->id, OB_RECALC_DATA); - } + } + else if (md->type == eModifierType_Shrinkwrap) { + ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md; + if (smd->target && smd->target->type == OB_MESH) { + DAG_id_tag_update(&smd->target->id, OB_RECALC_DATA); + } + } + else if (md->type == eModifierType_ParticleSystem) { + ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; + ParticleSystem *psys = psmd->psys; + ParticleSettings *part = psys->part; + switch (part->ren_as) { + case PART_DRAW_OB: + if (part->dup_ob != NULL) { + DAG_id_tag_update(&part->dup_ob->id, OB_RECALC_DATA); + } + break; + case PART_DRAW_GR: + if (part->dup_group != NULL) { + for (GroupObject *go = part->dup_group->gobject.first; + go != NULL; + go = go->next) + { + DAG_id_tag_update(&go->ob->id, OB_RECALC_DATA); } - break; - } + } + break; } } } } } + if (object->dup_group != NULL) { + tag_dependend_group_for_render(scene, object->dup_group); + } +} + +static void tag_dependend_objects_for_render(Main *bmain, Scene *scene, int renderlay) +{ + Scene *sce_iter; + Base *base; + BKE_main_id_tag_idcode(bmain, ID_GR, LIB_TAG_DOIT, false); + for (SETLOOPER(scene, sce_iter, base)) { + Object *object = base->object; + if ((base->lay & renderlay) == 0) { + continue; + } + tag_dependend_object_for_render(scene, object); + } } #endif @@ -2143,7 +2169,7 @@ static void tag_scenes_for_render(Render *re) for (sce = re->main->scene.first; sce; sce = sce->id.next) { sce->id.tag &= ~LIB_TAG_DOIT; #ifdef DEPSGRAPH_WORKAROUND_HACK - tag_dependend_objects_for_render(sce, renderlay); + tag_dependend_objects_for_render(re->main, sce, renderlay); #endif } @@ -2152,7 +2178,7 @@ static void tag_scenes_for_render(Render *re) for (sce = re->freestyle_bmain->scene.first; sce; sce = sce->id.next) { sce->id.tag &= ~LIB_TAG_DOIT; #ifdef DEPSGRAPH_WORKAROUND_HACK - tag_dependend_objects_for_render(sce, renderlay); + tag_dependend_objects_for_render(re->freestyle_bmain, sce, renderlay); #endif } } @@ -2161,7 +2187,7 @@ static void tag_scenes_for_render(Render *re) if (RE_GetCamera(re) && composite_needs_render(re->scene, 1)) { re->scene->id.tag |= LIB_TAG_DOIT; #ifdef DEPSGRAPH_WORKAROUND_HACK - tag_dependend_objects_for_render(re->scene, renderlay); + tag_dependend_objects_for_render(re->main, re->scene, renderlay); #endif } @@ -2194,7 +2220,7 @@ static void tag_scenes_for_render(Render *re) node->flag |= NODE_TEST; node->id->tag |= LIB_TAG_DOIT; #ifdef DEPSGRAPH_WORKAROUND_HACK - tag_dependend_objects_for_render(scene, renderlay); + tag_dependend_objects_for_render(re->main, scene, renderlay); #endif } } -- cgit v1.2.3