diff options
Diffstat (limited to 'source/blender/render')
4 files changed, 126 insertions, 20 deletions
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 2a43cab7bce..02a9f1eb347 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -52,6 +52,7 @@ #include "BLI_sys_types.h" // for intptr_t support +struct EvaluationContext; struct Object; struct MemArena; struct VertTableNode; @@ -270,6 +271,7 @@ struct Render struct ReportList *reports; struct ImagePool *pool; + struct EvaluationContext *eval_ctx; }; /* ------------------------------------------------------------------------- */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 1f3e961c151..e3a8c57de66 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -39,8 +39,8 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_rand.h" +#include "BLI_task.h" #include "BLI_memarena.h" -#include "BLI_ghash.h" #include "BLI_linklist.h" #ifdef WITH_FREESTYLE # include "BLI_edgehash.h" @@ -79,6 +79,7 @@ #include "BKE_constraint.h" #include "BKE_displist.h" #include "BKE_deform.h" +#include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" #include "BKE_effect.h" #include "BKE_global.h" @@ -2221,7 +2222,7 @@ static void init_render_mball(Render *re, ObjectRen *obr) need_orco= 1; } - BKE_displist_make_mball_forRender(re->scene, ob, &dispbase); + BKE_displist_make_mball_forRender(re->eval_ctx, re->scene, ob, &dispbase); dl= dispbase.first; if (dl == NULL) return; @@ -4981,7 +4982,7 @@ static void database_init_objects(Render *re, unsigned int renderlay, int nolamp /* create list of duplis generated by this object, particle * system need to have render settings set for dupli particles */ dupli_render_particle_set(re, ob, timeoffset, 0, 1); - lb= object_duplilist(re->scene, ob, TRUE); + lb= object_duplilist(re->eval_ctx, re->scene, ob); dupli_render_particle_set(re, ob, timeoffset, 0, 0); for (dob= lb->first; dob; dob= dob->next) { @@ -5133,12 +5134,12 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l /* applies changes fully */ if ((re->r.scemode & (R_NO_FRAME_UPDATE|R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) - BKE_scene_update_for_newframe(re->main, re->scene, lay); + BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, lay); /* if no camera, viewmat should have been set! */ if (use_camera_view && camera) { /* called before but need to call again in case of lens animation from the - * above call to BKE_scene_update_for_newframe, fixes bug. [#22702]. + * above call to BKE_scene_update_for_newframe_render, fixes bug. [#22702]. * following calls don't depend on 'RE_SetCamera' */ RE_SetCamera(re, camera); @@ -5310,7 +5311,7 @@ static void database_fromscene_vectors(Render *re, Scene *scene, unsigned int la /* applies changes fully */ scene->r.cfra += timeoffset; - BKE_scene_update_for_newframe(re->main, re->scene, lay); + BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, lay); /* if no camera, viewmat should have been set! */ if (camera) { diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index c3628e99d04..cccfeed6e47 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -459,7 +459,7 @@ int RE_engine_render(Render *re, int do_all) lay &= non_excluded_lay; } - BKE_scene_update_for_newframe(re->main, re->scene, lay); + BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, lay); } /* create render result */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index ba8265a83fe..4ec7ce1c0d2 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -59,9 +59,11 @@ #include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */ #include "BKE_camera.h" +#include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_main.h" +#include "BKE_modifier.h" #include "BKE_node.h" #include "BKE_pointcache.h" #include "BKE_report.h" @@ -373,6 +375,8 @@ Render *RE_NewRender(const char *name) BLI_addtail(&RenderGlobal.renderlist, re); BLI_strncpy(re->name, name, RE_MAXNAME); BLI_rw_mutex_init(&re->resultmutex); + re->eval_ctx = MEM_callocN(sizeof(EvaluationContext), "re->eval_ctx"); + re->eval_ctx->for_render = true; } RE_InitRenderCB(re); @@ -420,6 +424,7 @@ void RE_FreeRender(Render *re) render_result_free(re->pushedresult); BLI_remlink(&RenderGlobal.renderlist, re); + MEM_freeN(re->eval_ctx); MEM_freeN(re); } @@ -1320,8 +1325,9 @@ static void do_render_blur_3d(Render *re) re->i.curblur = 0; /* stats */ /* make sure motion blur changes get reset to current frame */ - if ((re->r.scemode & (R_NO_FRAME_UPDATE|R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) - BKE_scene_update_for_newframe(re->main, re->scene, re->lay); + if ((re->r.scemode & (R_NO_FRAME_UPDATE|R_BUTS_PREVIEW|R_VIEWPORT_PREVIEW))==0) { + BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, re->lay); + } /* weak... the display callback wants an active renderlayer pointer... */ re->result->renlay = render_get_active_layer(re, re->result); @@ -1590,21 +1596,117 @@ static bool rlayer_node_uses_alpha(bNodeTree *ntree, bNode *node) return false; } +/* Issue here is that it's possible that object which is used by boolean, + * array or shrinkwrap modifiers weren't displayed in the viewport before + * rendering. This leads to situations when apply() of this modifiers + * could not get ob->derivedFinal and modifiers are not being applied. + * + * This was worked around by direct call of get_derived_final() from those + * modifiers, but such approach leads to write conflicts with threaded + * update. + * + * Here we make sure derivedFinal will be calculated by update_for_newframe + * function later in the pipeline and all the modifiers are applied + * properly without hacks from their side. + * - sergey - + */ +#define DEPSGRAPH_WORKAROUND_HACK + +#ifdef DEPSGRAPH_WORKAROUND_HACK +static bool allow_render_mesh_object(Object *ob) +{ + /* override not showing object when duplis are used with particles */ + if (ob->transflag & OB_DUPLIPARTS) { + /* pass */ /* let particle system(s) handle showing vs. not showing */ + } + else if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) { + return false; + } + return true; +} + +static void tag_dependend_objects_for_render(Scene *scene, int renderlay) +{ + Scene *sce_iter; + Base *base; + for (SETLOOPER(scene, sce_iter, base)) { + Object *object = base->object; + + if ((base->lay & renderlay) == 0) { + continue; + } + + if (object->type == OB_MESH) { + if (allow_render_mesh_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 (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_Shrinkwrap) { + ShrinkwrapModifierData *smd = (ShrinkwrapModifierData *)md; + if (smd->target && smd->target->type == OB_MESH) { + DAG_id_tag_update(&smd->target->id, OB_RECALC_DATA); + } + } + } + } + } + } +} +#endif + static void tag_scenes_for_render(Render *re) { bNode *node; Scene *sce; +#ifdef DEPSGRAPH_WORKAROUND_HACK + int renderlay = re->lay; +#endif - for (sce = re->main->scene.first; sce; sce = sce->id.next) + for (sce = re->main->scene.first; sce; sce = sce->id.next) { sce->id.flag &= ~LIB_DOIT; +#ifdef DEPSGRAPH_WORKAROUND_HACK + tag_dependend_objects_for_render(sce, renderlay); +#endif + } #ifdef WITH_FREESTYLE - for (sce = re->freestyle_bmain.scene.first; sce; sce = sce->id.next) + for (sce = re->freestyle_bmain.scene.first; sce; sce = sce->id.next) { sce->id.flag &= ~LIB_DOIT; +#ifdef DEPSGRAPH_WORKAROUND_HACK + tag_dependend_objects_for_render(sce, renderlay); +#endif + } #endif - if (RE_GetCamera(re) && composite_needs_render(re->scene, 1)) + if (RE_GetCamera(re) && composite_needs_render(re->scene, 1)) { re->scene->id.flag |= LIB_DOIT; +#ifdef DEPSGRAPH_WORKAROUND_HACK + tag_dependend_objects_for_render(re->scene, renderlay); +#endif + } if (re->scene->nodetree == NULL) return; @@ -1632,6 +1734,9 @@ static void tag_scenes_for_render(Render *re) if ((node->id->flag & LIB_DOIT) == 0) { node->flag |= NODE_TEST; node->id->flag |= LIB_DOIT; +#ifdef DEPSGRAPH_WORKAROUND_HACK + tag_dependend_objects_for_render((Scene *) node->id, renderlay); +#endif } } } @@ -2020,7 +2125,7 @@ static void do_render_composite_fields_blur_3d(Render *re) R.stats_draw = re->stats_draw; if (update_newframe) - BKE_scene_update_for_newframe(re->main, re->scene, re->lay); + BKE_scene_update_for_newframe(re->eval_ctx, re->main, re->scene, re->lay); if (re->r.scemode & R_FULL_SAMPLE) do_merge_fullsample(re, ntree); @@ -2095,14 +2200,12 @@ static void do_render_seq(Render *re) if ((re->r.mode & R_BORDER) && (re->r.mode & R_CROP) == 0) { /* if border rendering is used and cropping is disabled, final buffer should * be as large as the whole frame */ - context = BKE_sequencer_new_render_data(re->main, re->scene, - re->winx, re->winy, - 100); + context = BKE_sequencer_new_render_data(re->eval_ctx, re->main, re->scene, + re->winx, re->winy, 100); } else { - context = BKE_sequencer_new_render_data(re->main, re->scene, - re->result->rectx, re->result->recty, - 100); + context = BKE_sequencer_new_render_data(re->eval_ctx, re->main, re->scene, + re->result->rectx, re->result->recty, 100); } out = BKE_sequencer_give_ibuf(context, cfra, 0); @@ -2704,7 +2807,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri else updatelay = re->lay; - BKE_scene_update_for_newframe(bmain, scene, updatelay); + BKE_scene_update_for_newframe(re->eval_ctx, bmain, scene, updatelay); continue; } else |