diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index d6a33892e75..2897ef1a0b6 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -457,10 +457,10 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time) BL::Scene::object_bases_iterator b_base; BL::Scene b_sce = b_scene; /* modifier result type (not exposed as enum in C++ API) - * 1 : eModifierMode_Realtime - * 2 : eModifierMode_Render - */ - int dupli_settings = preview ? 1 : 2; + * 1 : DAG_EVAL_PREVIEW + * 2 : DAG_EVAL_RENDER + */ + int dupli_settings = preview ? 1 : 2; bool cancel = false; diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h index bde15d29a1b..2ac5e5eb4be 100644 --- a/source/blender/blenkernel/BKE_depsgraph.h +++ b/source/blender/blenkernel/BKE_depsgraph.h @@ -56,10 +56,15 @@ struct ListBase; * which is needed for it's evaluation, */ typedef struct EvaluationContext { - bool for_render; /* Set to true if evaluation shall be performed for render purposes, - * keep at false if update shall happen for the viewport. */ + int mode; /* evaluation mode */ } EvaluationContext; +typedef enum eEvaluationMode { + DAG_EVAL_VIEWPORT = 0, /* evaluate for OpenGL viewport */ + DAG_EVAL_PREVIEW = 1, /* evaluate for render with preview settings */ + DAG_EVAL_RENDER = 2, /* evaluate for render purposes */ +} eEvaluationMode; + /* DagNode->eval_flags */ enum { /* Regardless to curve->path animation flag path is to be evaluated anyway, diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 47aeb18ff36..43b19f0c869 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -2280,7 +2280,7 @@ void BKE_mball_polygonize(EvaluationContext *eval_ctx, Scene *scene, Object *ob, mball_count(eval_ctx, &process, scene, ob); if (process.totelem == 0) return; - if ((eval_ctx->for_render == false) && (mb->flag == MB_UPDATE_NEVER)) return; + if ((eval_ctx->mode != DAG_EVAL_RENDER) && (mb->flag == MB_UPDATE_NEVER)) return; if ((G.moving & (G_TRANSFORM_OBJ | G_TRANSFORM_EDIT)) && mb->flag == MB_UPDATE_FAST) return; process.thresh = mb->thresh; @@ -2318,7 +2318,7 @@ void BKE_mball_polygonize(EvaluationContext *eval_ctx, Scene *scene, Object *ob, } /* width is size per polygonize cube */ - if (eval_ctx->for_render) { + if (eval_ctx->mode == DAG_EVAL_RENDER) { width = mb->rendersize; } else { diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 7c6164a8174..2bf33b97a70 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -2179,7 +2179,7 @@ Mesh *BKE_mesh_new_from_object( * implemented, this is to be rethinked. */ EvaluationContext eval_ctx = {0}; - eval_ctx.for_render = render; + eval_ctx.mode = DAG_EVAL_RENDER; BKE_displist_make_mball_forRender(&eval_ctx, sce, ob, &disp); BKE_mesh_from_metaball(&disp, tmpmesh); BKE_displist_free(&disp); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 415606d1fdc..cfa2dbe0eff 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2989,7 +2989,7 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx, if (psys_check_enabled(ob, psys)) { /* check use of dupli objects here */ - if (psys->part && (psys->part->draw_as == PART_DRAW_REND || eval_ctx->for_render) && + if (psys->part && (psys->part->draw_as == PART_DRAW_REND || eval_ctx->mode == DAG_EVAL_RENDER) && ((psys->part->ren_as == PART_DRAW_OB && psys->part->dup_ob) || (psys->part->ren_as == PART_DRAW_GR && psys->part->dup_group))) { @@ -3009,7 +3009,7 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx, psys = psys->next; } - if (eval_ctx->for_render && ob->transflag & OB_DUPLIPARTS) { + if (eval_ctx->mode == DAG_EVAL_RENDER && ob->transflag & OB_DUPLIPARTS) { /* this is to make sure we get render level duplis in groups: * the derivedmesh must be created before init_render_mesh, * since object_duplilist does dupliparticles before that */ diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index 84e626a3104..0f8f7ad410d 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -101,7 +101,7 @@ static void init_context(DupliContext *r_ctx, EvaluationContext *eval_ctx, Scene r_ctx->eval_ctx = eval_ctx; r_ctx->scene = scene; /* don't allow BKE_object_handle_update for viewport during render, can crash */ - r_ctx->do_update = update && !(G.is_rendering && !eval_ctx->for_render); + r_ctx->do_update = update && !(G.is_rendering && eval_ctx->mode != DAG_EVAL_RENDER); r_ctx->animated = false; r_ctx->group = NULL; @@ -268,7 +268,7 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild /* OB_DUPLIGROUP */ static void make_duplis_group(const DupliContext *ctx) { - bool for_render = ctx->eval_ctx->for_render; + bool for_render = (ctx->eval_ctx->mode == DAG_EVAL_RENDER); Object *ob = ctx->object; Group *group; GroupObject *go; @@ -524,7 +524,7 @@ static void make_duplis_verts(const DupliContext *ctx) { Scene *scene = ctx->scene; Object *parent = ctx->object; - bool for_render = ctx->eval_ctx->for_render; + bool use_texcoords = ELEM(ctx->eval_ctx->mode, DAG_EVAL_RENDER, DAG_EVAL_PREVIEW); VertexDupliData vdd; vdd.ctx = ctx; @@ -534,7 +534,7 @@ static void make_duplis_verts(const DupliContext *ctx) { Mesh *me = parent->data; BMEditMesh *em = BKE_editmesh_from_object(parent); - CustomDataMask dm_mask = (for_render ? CD_MASK_BAREMESH | CD_MASK_ORCO : CD_MASK_BAREMESH); + CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO : CD_MASK_BAREMESH); if (em) vdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask); @@ -542,7 +542,7 @@ static void make_duplis_verts(const DupliContext *ctx) vdd.dm = mesh_get_derived_final(scene, parent, dm_mask); vdd.edit_btmesh = me->edit_btmesh; - if (for_render) + if (use_texcoords) vdd.orco = vdd.dm->getVertDataArray(vdd.dm, CD_ORCO); else vdd.orco = NULL; @@ -724,6 +724,7 @@ static void make_child_duplis_faces(const DupliContext *ctx, void *userdata, Obj float (*orco)[3] = fdd->orco; MLoopUV *mloopuv = fdd->mloopuv; int a, totface = fdd->totface; + bool use_texcoords = ELEM(ctx->eval_ctx->mode, DAG_EVAL_RENDER, DAG_EVAL_PREVIEW); float child_imat[4][4]; DupliObject *dob; @@ -762,7 +763,7 @@ static void make_child_duplis_faces(const DupliContext *ctx, void *userdata, Obj mul_m4_m4m4(space_mat, obmat, inst_ob->imat); dob = make_dupli(ctx, inst_ob, obmat, a, false, false); - if (ctx->eval_ctx->for_render) { + if (use_texcoords) { float w = 1.0f / (float)mp->totloop; if (orco) { @@ -789,7 +790,7 @@ static void make_duplis_faces(const DupliContext *ctx) { Scene *scene = ctx->scene; Object *parent = ctx->object; - bool for_render = ctx->eval_ctx->for_render; + bool use_texcoords = ELEM(ctx->eval_ctx->mode, DAG_EVAL_RENDER, DAG_EVAL_PREVIEW); FaceDupliData fdd; fdd.use_scale = ((parent->transflag & OB_DUPLIFACES_SCALE) != 0); @@ -797,14 +798,14 @@ static void make_duplis_faces(const DupliContext *ctx) /* gather mesh info */ { BMEditMesh *em = BKE_editmesh_from_object(parent); - CustomDataMask dm_mask = (for_render ? CD_MASK_BAREMESH | CD_MASK_ORCO | CD_MASK_MLOOPUV : CD_MASK_BAREMESH); + CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO | CD_MASK_MLOOPUV : CD_MASK_BAREMESH); if (em) fdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask); else fdd.dm = mesh_get_derived_final(scene, parent, dm_mask); - if (for_render) { + if (use_texcoords) { fdd.orco = fdd.dm->getVertDataArray(fdd.dm, CD_ORCO); fdd.mloopuv = fdd.dm->getLoopDataArray(fdd.dm, CD_MLOOPUV); } @@ -834,7 +835,8 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem { Scene *scene = ctx->scene; Object *par = ctx->object; - bool for_render = ctx->eval_ctx->for_render; + bool for_render = ctx->eval_ctx->mode == DAG_EVAL_RENDER; + bool use_texcoords = ELEM(ctx->eval_ctx->mode, DAG_EVAL_RENDER, DAG_EVAL_PREVIEW); GroupObject *go; Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL; @@ -1051,7 +1053,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem dob = make_dupli(ctx, go->ob, mat, a, false, false); dob->particle_system = psys; - if (for_render) + if (use_texcoords) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); } } @@ -1100,7 +1102,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem dob = make_dupli(ctx, ob, mat, a, false, false); dob->particle_system = psys; - if (for_render) + if (use_texcoords) psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco); /* XXX blender internal needs this to be set to dupligroup to render * groups correctly, but we don't want this hack for cycles */ @@ -1161,7 +1163,7 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx) return NULL; /* Should the dupli's be generated for this object? - Respect restrict flags */ - if (ctx->eval_ctx->for_render ? (restrictflag & OB_RESTRICT_RENDER) : (restrictflag & OB_RESTRICT_VIEW)) + if (ctx->eval_ctx->mode == DAG_EVAL_RENDER ? (restrictflag & OB_RESTRICT_RENDER) : (restrictflag & OB_RESTRICT_VIEW)) return NULL; if (transflag & OB_DUPLIPARTS) { diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 4c5fa03a361..831e5486236 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -42,6 +42,8 @@ #include "DNA_modifier_types.h" #include "DNA_object_types.h" +#include "BKE_depsgraph.h" + #include "rna_internal.h" /* own include */ static EnumPropertyItem space_items[] = { @@ -66,7 +68,6 @@ static EnumPropertyItem space_items[] = { #include "BKE_constraint.h" #include "BKE_context.h" #include "BKE_customdata.h" -#include "BKE_depsgraph.h" #include "BKE_font.h" #include "BKE_global.h" #include "BKE_main.h" @@ -167,9 +168,9 @@ static void dupli_render_particle_set(Scene *scene, Object *ob, int level, int e /* When no longer needed, duplilist should be freed with Object.free_duplilist */ static void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce, int settings) { - int for_render = settings == eModifierMode_Render; + bool for_render = (settings == DAG_EVAL_RENDER); EvaluationContext eval_ctx = {0}; - eval_ctx.for_render = for_render; + eval_ctx.mode = settings; if (!(ob->transflag & OB_DUPLI)) { BKE_report(reports, RPT_ERROR, "Object does not have duplis"); @@ -432,6 +433,13 @@ void RNA_api_object(StructRNA *srna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem dupli_eval_mode_items[] = { + {DAG_EVAL_VIEWPORT, "VIEWPORT", 0, "Viewport", "Generate duplis using viewport settings"}, + {DAG_EVAL_PREVIEW, "PREVIEW", 0, "Preview", "Generate duplis using preview settings"}, + {DAG_EVAL_RENDER, "RENDER", 0, "Render", "Generate duplis using render settings"}, + {0, NULL, 0, NULL, NULL} + }; + #ifndef NDEBUG static EnumPropertyItem mesh_dm_info_items[] = { {0, "SOURCE", 0, "Source", "Source mesh"}, @@ -483,7 +491,7 @@ void RNA_api_object(StructRNA *srna) "objects real matrix and layers"); parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene within which to evaluate duplis"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); - RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Generate texture coordinates for rendering"); + RNA_def_enum(func, "settings", dupli_eval_mode_items, 0, "", "Generate texture coordinates for rendering"); RNA_def_function_flag(func, FUNC_USE_REPORTS); func = RNA_def_function(srna, "dupli_list_clear", "rna_Object_free_duplilist"); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index a7a85847648..e6a9303a982 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -387,7 +387,7 @@ Render *RE_NewRender(const char *name) 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->eval_ctx->mode = DAG_EVAL_RENDER; } RE_InitRenderCB(re); @@ -661,6 +661,11 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, re->result->recty = re->recty; } + if (re->r.scemode & R_VIEWPORT_PREVIEW) + re->eval_ctx->mode = DAG_EVAL_PREVIEW; + else + re->eval_ctx->mode = DAG_EVAL_RENDER; + /* ensure renderdatabase can use part settings correct */ RE_parts_clamp(re);