diff options
-rw-r--r-- | source/blender/blenkernel/BKE_DerivedMesh.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_armature.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_curve.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_lattice.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_mball.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_object.h | 14 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_particle.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 898 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature_update.c | 15 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/curve.c | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lattice.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mball.c | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object_update.c | 154 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 49 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph_build_nodes.cc | 87 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph_build_relations.cc | 105 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/depsnode_opcodes.h | 21 |
17 files changed, 883 insertions, 504 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index d7d6daa7e2a..bdb1d448c77 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -97,6 +97,7 @@ struct ColorBand; struct GPUVertexAttribs; struct GPUDrawObject; struct PBVH; +struct EvaluationContext; /* number of sub-elements each mesh element has (for interpolation) */ #define SUB_ELEMS_VERT 0 @@ -735,6 +736,9 @@ void makeDerivedMesh( struct Scene *scene, struct Object *ob, struct BMEditMesh *em, CustomDataMask dataMask, const bool build_shapekey_layers); +void BKE_object_eval_mesh(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); +void BKE_object_eval_editmesh(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); + void weight_to_rgb(float r_rgb[3], const float weight); /** Update the weight MCOL preview layer. * If weights are NULL, use object's active vgroup(s). diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 6d00110e318..ce0e866195c 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -198,6 +198,10 @@ void BKE_pose_eval_flush(struct EvaluationContext *eval_ctx, void BKE_pose_eval_proxy_copy(struct EvaluationContext *eval_ctx, struct Object *ob); +void BKE_object_eval_armature(struct EvaluationContext *eval_ctx, + struct Scene *scene, + struct Object *ob); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 061270b8b41..5cbe70cd404 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -201,4 +201,8 @@ void BKE_curve_eval_geometry(struct EvaluationContext *eval_ctx, void BKE_curve_eval_path(struct EvaluationContext *eval_ctx, struct Curve *curve); +void BKE_object_eval_curve(struct EvaluationContext *eval_ctx, + struct Scene *scene, + struct Object *ob); + #endif /* __BKE_CURVE_H__ */ diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 828a40de1c9..51eeb16438e 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -103,4 +103,8 @@ struct EvaluationContext; void BKE_lattice_eval_geometry(struct EvaluationContext *eval_ctx, struct Lattice *latt); +void BKE_object_eval_lattice(struct EvaluationContext *eval_ctx, + struct Scene *scene, + struct Object *ob); + #endif /* __BKE_LATTICE_H__ */ diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h index 0574b88bef3..401cc2479e9 100644 --- a/source/blender/blenkernel/BKE_mball.h +++ b/source/blender/blenkernel/BKE_mball.h @@ -76,4 +76,8 @@ struct EvaluationContext; void BKE_mball_eval_geometry(struct EvaluationContext *eval_ctx, struct MetaBall *mball); +void BKE_object_eval_mball(struct EvaluationContext *eval_ctx, + struct Scene *scene, + struct Object *ob); + #endif diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 7d6096407ff..062bbde893d 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -204,13 +204,15 @@ void BKE_object_eval_modifier(struct EvaluationContext *eval_ctx, void BKE_object_eval_uber_transform(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); -void BKE_object_eval_uber_data(struct EvaluationContext *eval_ctx, - struct Scene *scene, - struct Object *ob); +void BKE_object_eval_data_ready(struct EvaluationContext *eval_ctx, + struct Scene *scene, + struct Object *ob); + +void BKE_object_handle_data_update(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); +void BKE_object_eval_empty(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); +void BKE_object_eval_material_drivers(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); +void BKE_object_eval_lamp_drivers(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); -void BKE_object_handle_data_update(struct EvaluationContext *eval_ctx, - struct Scene *scene, - struct Object *ob); void BKE_object_handle_update(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob); void BKE_object_handle_update_ex(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index e17fb9f7a02..169d6cee3a4 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -476,4 +476,8 @@ void BKE_particle_system_eval(struct EvaluationContext *eval_ctx, struct Object *ob, struct ParticleSystem *psys); +void BKE_object_eval_particles(struct EvaluationContext *eval_ctx, + struct Scene *scene, + struct Object *ob); + #endif diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index d120678c005..411d6ee4452 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -51,6 +51,7 @@ #include "BLI_linklist.h" #include "BKE_cdderivedmesh.h" +#include "BKE_depsgraph.h" #include "BKE_editmesh.h" #include "BKE_key.h" #include "BKE_library.h" @@ -1692,432 +1693,433 @@ static void dm_ensure_display_normals(DerivedMesh *dm) } } -/** - * new value for useDeform -1 (hack for the gameengine): - * - * - apply only the modifier stack of the object, skipping the virtual modifiers, - * - don't apply the key - * - apply deform modifiers and input vertexco - */ -static void mesh_calc_modifiers( - Scene *scene, Object *ob, float (*inputVertexCos)[3], - const bool useRenderParams, int useDeform, - const bool need_mapping, CustomDataMask dataMask, - const int index, const bool useCache, const bool build_shapekey_layers, - const bool allow_gpu, - /* return args */ - DerivedMesh **r_deform, DerivedMesh **r_final) +/* immutable settings and precomputed temporary data */ +typedef struct ModifierEvalContext { + int draw_flag; + int required_mode; + bool need_mapping; + + bool do_mod_mcol; + bool do_final_wmcol; + bool do_init_wmcol; + bool do_mod_wmcol; + + bool do_loop_normals; + float loop_normals_split_angle; + + ModifierApplyFlag app_flags; + ModifierApplyFlag deform_app_flags; + + bool sculpt_mode; + bool sculpt_dyntopo; + bool sculpt_only_deform; + bool has_multires; + + bool build_shapekey_layers; + bool special_gameengine_hack; + + VirtualModifierData virtualModifierData; + float (*inputVertexCos)[3]; /* XXX needed for freeing deformedVerts, not nice ... */ + + ModifierData *md_begin; + ModifierData *md_end; + ModifierData *previewmd; + CDMaskLink *datamasks; +} ModifierEvalContext; + +static void mesh_init_modifier_context(ModifierEvalContext *ctx, + Scene *scene, Object *ob, + float (*inputVertexCos)[3], + const bool useRenderParams, int useDeform, + const bool need_mapping, + CustomDataMask dataMask, + const int index, + const bool useCache, + const bool build_shapekey_layers, + const bool allow_gpu) { Mesh *me = ob->data; - ModifierData *firstmd, *md, *previewmd = NULL; - CDMaskLink *datamasks, *curr; - /* XXX Always copying POLYINDEX, else tessellated data are no more valid! */ - CustomDataMask mask, nextmask, previewmask = 0, append_mask = CD_MASK_ORIGINDEX; - float (*deformedVerts)[3] = NULL; - DerivedMesh *dm = NULL, *orcodm, *clothorcodm, *finaldm; - int numVerts = me->totvert; - const int required_mode = useRenderParams ? eModifierMode_Render : eModifierMode_Realtime; - bool isPrevDeform = false; - const bool skipVirtualArmature = (useDeform < 0); MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); - const bool has_multires = (mmd && mmd->sculptlvl != 0); - bool multires_applied = false; - const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !useRenderParams; - const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !useRenderParams; - const int draw_flag = dm_drawflag_calc(scene->toolsettings, me); + CustomDataMask previewmask = 0; + const bool skipVirtualArmature = (useDeform < 0); + + ctx->inputVertexCos = inputVertexCos; + ctx->app_flags = (useRenderParams ? MOD_APPLY_RENDER : 0) + | (useCache ? MOD_APPLY_USECACHE : 0) + | (allow_gpu ? MOD_APPLY_ALLOW_GPU : 0); + + ctx->deform_app_flags = ctx->app_flags + | (useDeform ? MOD_APPLY_USECACHE : 0); + + ctx->draw_flag = dm_drawflag_calc(scene->toolsettings, me); + ctx->required_mode = useRenderParams ? eModifierMode_Render : eModifierMode_Realtime; + ctx->need_mapping = need_mapping; + /* Generic preview only in object mode! */ - const bool do_mod_mcol = (ob->mode == OB_MODE_OBJECT); + ctx->do_mod_mcol = (ob->mode == OB_MODE_OBJECT); #if 0 /* XXX Will re-enable this when we have global mod stack options. */ - const bool do_final_wmcol = (scene->toolsettings->weights_preview == WP_WPREVIEW_FINAL) && do_wmcol; + ctx->do_final_wmcol = (scene->toolsettings->weights_preview == WP_WPREVIEW_FINAL) && do_wmcol; +#else + ctx->do_final_wmcol = false; #endif - const bool do_final_wmcol = false; - const bool do_init_wmcol = ((dataMask & CD_MASK_PREVIEW_MLOOPCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT) && !do_final_wmcol); + ctx->do_init_wmcol = ((dataMask & CD_MASK_PREVIEW_MLOOPCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT) && !ctx->do_final_wmcol); /* XXX Same as above... For now, only weights preview in WPaint mode. */ - const bool do_mod_wmcol = do_init_wmcol; + ctx->do_mod_wmcol = ctx->do_init_wmcol; - const bool do_loop_normals = (me->flag & ME_AUTOSMOOTH) != 0; - const float loop_normals_split_angle = me->smoothresh; + ctx->do_loop_normals = (me->flag & ME_AUTOSMOOTH) != 0; + ctx->loop_normals_split_angle = me->smoothresh; - VirtualModifierData virtualModifierData; + ctx->sculpt_mode = (ob->mode & OB_MODE_SCULPT) && ob->sculpt && !useRenderParams; + ctx->sculpt_dyntopo = (ctx->sculpt_mode && ob->sculpt->bm) && !useRenderParams; + ctx->sculpt_only_deform = (scene->toolsettings->sculpt->flags & SCULPT_ONLY_DEFORM); - ModifierApplyFlag app_flags = useRenderParams ? MOD_APPLY_RENDER : 0; - ModifierApplyFlag deform_app_flags = app_flags; + ctx->has_multires = (mmd && mmd->sculptlvl != 0); + /* + * new value for useDeform -1 (hack for the gameengine): + * + * - apply only the modifier stack of the object, skipping the virtual modifiers, + * - don't apply the key + * - apply deform modifiers and input vertexco + */ + ctx->special_gameengine_hack = (useDeform < 0); + ctx->build_shapekey_layers = build_shapekey_layers; - if (useCache) - app_flags |= MOD_APPLY_USECACHE; - if (allow_gpu) - app_flags |= MOD_APPLY_ALLOW_GPU; - if (useDeform) - deform_app_flags |= MOD_APPLY_USECACHE; + /* precompute data */ if (!skipVirtualArmature) { - firstmd = modifiers_getVirtualModifierList(ob, &virtualModifierData); + ctx->md_begin = modifiers_getVirtualModifierList(ob, &ctx->virtualModifierData); } else { /* game engine exception */ - firstmd = ob->modifiers.first; - if (firstmd && firstmd->type == eModifierType_Armature) - firstmd = firstmd->next; + ctx->md_begin = ob->modifiers.first; + if (ctx->md_begin && ctx->md_begin->type == eModifierType_Armature) + ctx->md_begin = ctx->md_begin->next; } - md = firstmd; + /* only handle modifiers until index */ + ctx->md_end = (index >= 0) ? BLI_findlink(&ob->modifiers, index) : NULL; - modifiers_clearErrors(ob); - - if (do_mod_wmcol || do_mod_mcol) { + if (ctx->do_mod_wmcol || ctx->do_mod_mcol) { /* Find the last active modifier generating a preview, or NULL if none. */ /* XXX Currently, DPaint modifier just ignores this. * Needs a stupid hack... * The whole "modifier preview" thing has to be (re?)designed, anyway! */ - previewmd = modifiers_getLastPreview(scene, md, required_mode); + ctx->previewmd = modifiers_getLastPreview(scene, ctx->md_begin, ctx->required_mode); /* even if the modifier doesn't need the data, to make a preview it may */ - if (previewmd) { - if (do_mod_wmcol) { + if (ctx->previewmd) { + if (ctx->do_mod_wmcol) { previewmask = CD_MASK_MDEFORMVERT; } } } + else + ctx->previewmd = NULL; - datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode, previewmd, previewmask); - curr = datamasks; - - if (r_deform) { - *r_deform = NULL; - } - *r_final = NULL; - - if (useDeform) { - if (inputVertexCos) - deformedVerts = inputVertexCos; - - /* Apply all leading deforming modifiers */ - for (; md; md = md->next, curr = curr->next) { - const ModifierTypeInfo *mti = modifierType_getInfo(md->type); - - md->scene = scene; - - if (!modifier_isEnabled(scene, md, required_mode)) { - continue; - } + ctx->datamasks = modifiers_calcDataMasks(scene, ob, ctx->md_begin, dataMask, ctx->required_mode, ctx->previewmd, previewmask); +} - if (useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) { - continue; - } +static void mesh_free_modifier_context(ModifierEvalContext *ctx) +{ + BLI_linklist_free((LinkNode *)ctx->datamasks, NULL); +} - if (mti->type == eModifierTypeType_OnlyDeform && !sculpt_dyntopo) { - if (!deformedVerts) - deformedVerts = BKE_mesh_vertexCos_get(me, &numVerts); +/* combined iterator for modifier and associated data mask */ +typedef struct ModifierEvalIterator { + ModifierData *modifier; + CDMaskLink *datamask; - modwrap_deformVerts(md, ob, NULL, deformedVerts, numVerts, deform_app_flags); - } - else { - break; - } - - /* grab modifiers until index i */ - if ((index != -1) && (BLI_findindex(&ob->modifiers, md) >= index)) - break; - } + /* mutable flags */ + bool multires_applied; + bool isPrevDeform; + CustomDataMask append_mask; +} ModifierEvalIterator; - /* Result of all leading deforming modifiers is cached for - * places that wish to use the original mesh but with deformed - * coordinates (vpaint, etc.) - */ - if (r_deform) { - *r_deform = CDDM_from_mesh(me); +static bool mesh_calc_modifier_sculptmode_skip(const ModifierEvalContext *ctx, ModifierData *md, + const bool multires_applied) +{ + const bool multires_pending = ctx->has_multires && !multires_applied; + + if (ctx->sculpt_mode && (!multires_pending || ctx->sculpt_dyntopo)) + { + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + const bool useRenderParams = ctx->app_flags & MOD_APPLY_RENDER; + bool unsupported = false; - if (build_shapekey_layers) - add_shapekey_layers(dm, me, ob); - - if (deformedVerts) { - CDDM_apply_vert_coords(*r_deform, deformedVerts); + if (md->type == eModifierType_Multires && ((MultiresModifierData *)md)->sculptlvl == 0) { + /* If multires is on level 0 skip it silently without warning message. */ + if (!ctx->sculpt_dyntopo) { + return true; } } - } - else { - /* default behavior for meshes */ - if (inputVertexCos) - deformedVerts = inputVertexCos; - else - deformedVerts = BKE_mesh_vertexCos_get(me, &numVerts); - } + if (ctx->sculpt_dyntopo && !useRenderParams) + unsupported = true; - /* Now apply all remaining modifiers. If useDeform is off then skip - * OnlyDeform ones. - */ - dm = NULL; - orcodm = NULL; - clothorcodm = NULL; - - for (; md; md = md->next, curr = curr->next) { - const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + if (ctx->sculpt_only_deform) + unsupported |= (mti->type != eModifierTypeType_OnlyDeform); - md->scene = scene; + unsupported |= multires_applied; - if (!modifier_isEnabled(scene, md, required_mode)) { - continue; - } - - if (mti->type == eModifierTypeType_OnlyDeform && !useDeform) { - continue; + if (unsupported) { + if (ctx->sculpt_dyntopo) + modifier_setError(md, "Not supported in dyntopo"); + else + modifier_setError(md, "Not supported in sculpt mode"); + return true; } - - if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) { - modifier_setError(md, "Modifier requires original data, bad stack position"); - continue; + else { + modifier_setError(md, "Hide, Mask and optimized display disabled"); } + } + + return false; +} - if (sculpt_mode && - (!has_multires || multires_applied || sculpt_dyntopo)) - { - bool unsupported = false; - - if (md->type == eModifierType_Multires && ((MultiresModifierData *)md)->sculptlvl == 0) { - /* If multires is on level 0 skip it silently without warning message. */ - if (!sculpt_dyntopo) { - continue; - } - } - - if (sculpt_dyntopo && !useRenderParams) - unsupported = true; - - if (scene->toolsettings->sculpt->flags & SCULPT_ONLY_DEFORM) - unsupported |= (mti->type != eModifierTypeType_OnlyDeform); - - unsupported |= multires_applied; +typedef struct ModifierEvalResult { + DerivedMesh *dm; + DerivedMesh *orcodm; + DerivedMesh *clothorcodm; + float (*deformedVerts)[3]; + int numVerts; +} ModifierEvalResult; - if (unsupported) { - if (sculpt_dyntopo) - modifier_setError(md, "Not supported in dyntopo"); - else - modifier_setError(md, "Not supported in sculpt mode"); - continue; - } - else { - modifier_setError(md, "Hide, Mask and optimized display disabled"); - } +static void mesh_calc_deform_modifier(Object *ob, const ModifierEvalContext *ctx, const ModifierEvalIterator *iter, + ModifierEvalResult *result) +{ + Mesh *me = ob->data; + ModifierData *md = iter->modifier; + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (!modifier_isEnabled(md->scene, md, ctx->required_mode)) + return; + if (ctx->special_gameengine_hack && mti->dependsOnTime && mti->dependsOnTime(md)) + return; + if (mesh_calc_modifier_sculptmode_skip(ctx, md, iter->multires_applied)) + return; + + if (result->dm) { + /* add an orco layer if needed by this modifier */ + CustomDataMask mask = mti->requiredDataMask ? mti->requiredDataMask(ob, md) : 0; + + if (mask & CD_MASK_ORCO) + add_orco_dm(ob, NULL, result->dm, result->orcodm, CD_ORCO); + } + + /* No existing verts to deform, need to build them. */ + if (!result->deformedVerts) { + if (result->dm) { + /* Deforming a derived mesh, read the vertex locations + * out of the mesh and deform them. Once done with this + * run of deformers verts will be written back. + */ + result->numVerts = result->dm->getNumVerts(result->dm); + result->deformedVerts = + MEM_mallocN(sizeof(*result->deformedVerts) * result->numVerts, "dfmv"); + result->dm->getVertCos(result->dm, result->deformedVerts); } - - if (need_mapping && !modifier_supportsMapping(md)) { - continue; + else { + result->deformedVerts = BKE_mesh_vertexCos_get(me, &result->numVerts); } + } - if (useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) { - continue; + /* if this is not the last modifier in the stack then recalculate the normals + * to avoid giving bogus normals to the next modifier see: [#23673] */ + if (iter->isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) { + /* XXX, this covers bug #23673, but we may need normal calc for other types */ + if (result->dm && result->dm->type == DM_TYPE_CDDM) { + CDDM_apply_vert_coords(result->dm, result->deformedVerts); } + } - /* add an orco layer if needed by this modifier */ - if (mti->requiredDataMask) - mask = mti->requiredDataMask(ob, md); - else - mask = 0; + modwrap_deformVerts(md, ob, result->dm, result->deformedVerts, result->numVerts, ctx->deform_app_flags); +} - if (dm && (mask & CD_MASK_ORCO)) +static DerivedMesh *mesh_calc_create_input_dm(Object *ob, const ModifierEvalContext *ctx, ModifierData *md, + CustomDataMask mask, CustomDataMask append_mask, CustomDataMask nextmask, + DerivedMesh *dm, DerivedMesh *orcodm, DerivedMesh *clothorcodm, + float (*deformedVerts)[3]) +{ + Mesh *me = ob->data; + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + if (dm) { + /* add an orco layer if needed by this modifier */ + CustomDataMask mask = mti->requiredDataMask ? mti->requiredDataMask(ob, md) : 0; + if (mask & CD_MASK_ORCO) add_orco_dm(ob, NULL, dm, orcodm, CD_ORCO); + + /* apply vertex coordinates or build a DerivedMesh as necessary */ + if (deformedVerts) { + DerivedMesh *tdm = CDDM_copy(dm); + dm->release(dm); + dm = tdm; - /* How to apply modifier depends on (a) what we already have as - * a result of previous modifiers (could be a DerivedMesh or just - * deformed vertices) and (b) what type the modifier is. - */ - - if (mti->type == eModifierTypeType_OnlyDeform) { - /* No existing verts to deform, need to build them. */ - if (!deformedVerts) { - if (dm) { - /* Deforming a derived mesh, read the vertex locations - * out of the mesh and deform them. Once done with this - * run of deformers verts will be written back. - */ - numVerts = dm->getNumVerts(dm); - deformedVerts = - MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv"); - dm->getVertCos(dm, deformedVerts); - } - else { - deformedVerts = BKE_mesh_vertexCos_get(me, &numVerts); - } - } - - /* if this is not the last modifier in the stack then recalculate the normals - * to avoid giving bogus normals to the next modifier see: [#23673] */ - if (isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) { - /* XXX, this covers bug #23673, but we may need normal calc for other types */ - if (dm && dm->type == DM_TYPE_CDDM) { - CDDM_apply_vert_coords(dm, deformedVerts); - } - } - - modwrap_deformVerts(md, ob, dm, deformedVerts, numVerts, deform_app_flags); + CDDM_apply_vert_coords(dm, deformedVerts); } - else { - DerivedMesh *ndm; - - /* determine which data layers are needed by following modifiers */ - if (curr->next) - nextmask = curr->next->mask; - else - nextmask = dataMask; - - /* apply vertex coordinates or build a DerivedMesh as necessary */ - if (dm) { - if (deformedVerts) { - DerivedMesh *tdm = CDDM_copy(dm); - dm->release(dm); - dm = tdm; - - CDDM_apply_vert_coords(dm, deformedVerts); - } - } - else { - dm = CDDM_from_mesh(me); - ASSERT_IS_VALID_DM(dm); + } + else { + dm = CDDM_from_mesh(me); + ASSERT_IS_VALID_DM(dm); - if (build_shapekey_layers) - add_shapekey_layers(dm, me, ob); + if (ctx->build_shapekey_layers) + add_shapekey_layers(dm, me, ob); - if (deformedVerts) { - CDDM_apply_vert_coords(dm, deformedVerts); - } + if (deformedVerts) { + CDDM_apply_vert_coords(dm, deformedVerts); + } - if (do_init_wmcol) - DM_update_weight_mcol(ob, dm, draw_flag, NULL, 0, NULL); + if (ctx->do_init_wmcol) + DM_update_weight_mcol(ob, dm, ctx->draw_flag, NULL, 0, NULL); - /* Constructive modifiers need to have an origindex - * otherwise they wont have anywhere to copy the data from. - * - * Also create ORIGINDEX data if any of the following modifiers - * requests it, this way Mirror, Solidify etc will keep ORIGINDEX - * data by using generic DM_copy_vert_data() functions. - */ - if (need_mapping || (nextmask & CD_MASK_ORIGINDEX)) { - /* calc */ - DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); - DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); - DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); + /* Constructive modifiers need to have an origindex + * otherwise they wont have anywhere to copy the data from. + * + * Also create ORIGINDEX data if any of the following modifiers + * requests it, this way Mirror, Solidify etc will keep ORIGINDEX + * data by using generic DM_copy_vert_data() functions. + */ + if (ctx->need_mapping || (nextmask & CD_MASK_ORIGINDEX)) { + /* calc */ + DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); + DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); + DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); #pragma omp parallel sections if (dm->numVertData + dm->numEdgeData + dm->numPolyData >= BKE_MESH_OMP_LIMIT) - { + { #pragma omp section - { range_vn_i(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0); } + { range_vn_i(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0); } #pragma omp section - { range_vn_i(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0); } + { range_vn_i(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0); } #pragma omp section - { range_vn_i(DM_get_poly_data_layer(dm, CD_ORIGINDEX), dm->numPolyData, 0); } - } - } + { range_vn_i(DM_get_poly_data_layer(dm, CD_ORIGINDEX), dm->numPolyData, 0); } } + } + } - - /* set the DerivedMesh to only copy needed data */ - mask = curr->mask; - /* needMapping check here fixes bug [#28112], otherwise it's - * possible that it won't be copied */ - mask |= append_mask; - DM_set_only_copy(dm, mask | (need_mapping ? CD_MASK_ORIGINDEX : 0)); - - /* add cloth rest shape key if needed */ - if (mask & CD_MASK_CLOTH_ORCO) - add_orco_dm(ob, NULL, dm, clothorcodm, CD_CLOTH_ORCO); + /* set the DerivedMesh to only copy needed data */ + /* needMapping check here fixes bug [#28112], otherwise it's + * possible that it won't be copied */ + DM_set_only_copy(dm, mask | append_mask | (ctx->need_mapping ? CD_MASK_ORIGINDEX : 0)); + + /* add cloth rest shape key if needed */ + if ((mask | append_mask) & CD_MASK_CLOTH_ORCO) + add_orco_dm(ob, NULL, dm, clothorcodm, CD_CLOTH_ORCO); + + /* add an origspace layer if needed */ + if (mask & CD_MASK_ORIGSPACE_MLOOP) { + if (!CustomData_has_layer(&dm->loopData, CD_ORIGSPACE_MLOOP)) { + DM_add_loop_layer(dm, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL); + DM_init_origspace(dm); + } + } + + return dm; +} - /* add an origspace layer if needed */ - if ((curr->mask) & CD_MASK_ORIGSPACE_MLOOP) { - if (!CustomData_has_layer(&dm->loopData, CD_ORIGSPACE_MLOOP)) { - DM_add_loop_layer(dm, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL); - DM_init_origspace(dm); - } - } +static void mesh_calc_constructive_modifier(Object *ob, const ModifierEvalContext *ctx, CustomDataMask data_mask, + ModifierEvalIterator *iter, ModifierEvalResult *result) +{ + Mesh *me = ob->data; + ModifierData *md = iter->modifier; + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); - ndm = modwrap_applyModifier(md, ob, dm, app_flags); - ASSERT_IS_VALID_DM(ndm); + CustomDataMask mask = iter->datamask->mask; + CustomDataMask append_mask = iter->append_mask; + CustomDataMask nextmask = (iter->datamask->next) ? iter->datamask->next->mask : data_mask; - if (ndm) { - /* if the modifier returned a new dm, release the old one */ - if (dm && dm != ndm) dm->release(dm); + if (!modifier_isEnabled(md->scene, md, ctx->required_mode)) + return; + if (ctx->special_gameengine_hack && mti->dependsOnTime && mti->dependsOnTime(md)) + return; - dm = ndm; + result->dm = mesh_calc_create_input_dm(ob, ctx, md, mask, append_mask, nextmask, + result->dm, result->orcodm, result->clothorcodm, result->deformedVerts); - if (deformedVerts) { - if (deformedVerts != inputVertexCos) - MEM_freeN(deformedVerts); + { + DerivedMesh *ndm; - deformedVerts = NULL; - } - } + ndm = modwrap_applyModifier(md, ob, result->dm, ctx->app_flags); + ASSERT_IS_VALID_DM(ndm); - /* create an orco derivedmesh in parallel */ - if (nextmask & CD_MASK_ORCO) { - if (!orcodm) - orcodm = create_orco_dm(ob, me, NULL, CD_ORCO); + if (ndm) { + /* if the modifier returned a new dm, release the old one */ + if ((result->dm) && result->dm != ndm) (result->dm)->release(result->dm); - nextmask &= ~CD_MASK_ORCO; - DM_set_only_copy(orcodm, nextmask | CD_MASK_ORIGINDEX | - (mti->requiredDataMask ? - mti->requiredDataMask(ob, md) : 0)); + result->dm = ndm; - ndm = modwrap_applyModifier(md, ob, orcodm, (app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO); - ASSERT_IS_VALID_DM(ndm); + if (result->deformedVerts) { + if (result->deformedVerts != ctx->inputVertexCos) + MEM_freeN(result->deformedVerts); - if (ndm) { - /* if the modifier returned a new dm, release the old one */ - if (orcodm && orcodm != ndm) orcodm->release(orcodm); - orcodm = ndm; - } + result->deformedVerts = NULL; } + } + } - /* create cloth orco derivedmesh in parallel */ - if (nextmask & CD_MASK_CLOTH_ORCO) { - if (!clothorcodm) - clothorcodm = create_orco_dm(ob, me, NULL, CD_CLOTH_ORCO); + /* create an orco derivedmesh in parallel */ + if (nextmask & CD_MASK_ORCO) { + DerivedMesh *ndm; - nextmask &= ~CD_MASK_CLOTH_ORCO; - DM_set_only_copy(clothorcodm, nextmask | CD_MASK_ORIGINDEX); + if (!result->orcodm) + result->orcodm = create_orco_dm(ob, me, NULL, CD_ORCO); - ndm = modwrap_applyModifier(md, ob, clothorcodm, (app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO); - ASSERT_IS_VALID_DM(ndm); + nextmask &= ~CD_MASK_ORCO; + DM_set_only_copy(result->orcodm, nextmask | CD_MASK_ORIGINDEX | + (mti->requiredDataMask ? + mti->requiredDataMask(ob, md) : 0)); - if (ndm) { - /* if the modifier returned a new dm, release the old one */ - if (clothorcodm && clothorcodm != ndm) { - clothorcodm->release(clothorcodm); - } - clothorcodm = ndm; - } - } + ndm = modwrap_applyModifier(md, ob, result->orcodm, (ctx->app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO); + ASSERT_IS_VALID_DM(ndm); - /* in case of dynamic paint, make sure preview mask remains for following modifiers */ - /* XXX Temp and hackish solution! */ - if (md->type == eModifierType_DynamicPaint) - append_mask |= CD_MASK_PREVIEW_MLOOPCOL; - /* In case of active preview modifier, make sure preview mask remains for following modifiers. */ - else if ((md == previewmd) && (do_mod_wmcol)) { - DM_update_weight_mcol(ob, dm, draw_flag, NULL, 0, NULL); - append_mask |= CD_MASK_PREVIEW_MLOOPCOL; - } + if (ndm) { + /* if the modifier returned a new dm, release the old one */ + if (result->orcodm && result->orcodm != ndm) result->orcodm->release(result->orcodm); + result->orcodm = ndm; } + } - isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform); + /* create cloth orco derivedmesh in parallel */ + if (nextmask & CD_MASK_CLOTH_ORCO) { + DerivedMesh *ndm; - /* grab modifiers until index i */ - if ((index != -1) && (BLI_findindex(&ob->modifiers, md) >= index)) - break; + if (!result->clothorcodm) + result->clothorcodm = create_orco_dm(ob, me, NULL, CD_CLOTH_ORCO); - if (sculpt_mode && md->type == eModifierType_Multires) { - multires_applied = true; + nextmask &= ~CD_MASK_CLOTH_ORCO; + DM_set_only_copy(result->clothorcodm, nextmask | CD_MASK_ORIGINDEX); + + ndm = modwrap_applyModifier(md, ob, result->clothorcodm, (ctx->app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO); + ASSERT_IS_VALID_DM(ndm); + + if (ndm) { + /* if the modifier returned a new dm, release the old one */ + if (result->clothorcodm && result->clothorcodm != ndm) { + result->clothorcodm->release(result->clothorcodm); + } + result->clothorcodm = ndm; } } - for (md = firstmd; md; md = md->next) - modifier_freeTemporaryData(md); + /* in case of dynamic paint, make sure preview mask remains for following modifiers */ + /* XXX Temp and hackish solution! */ + if (md->type == eModifierType_DynamicPaint) + iter->append_mask |= CD_MASK_PREVIEW_MLOOPCOL; + /* In case of active preview modifier, make sure preview mask remains for following modifiers. */ + else if ((md == ctx->previewmd) && (ctx->do_mod_wmcol)) { + DM_update_weight_mcol(ob, result->dm, ctx->draw_flag, NULL, 0, NULL); + iter->append_mask |= CD_MASK_PREVIEW_MLOOPCOL; + } +} + +static DerivedMesh *mesh_calc_finalize_dm(Object *ob, const ModifierEvalContext *ctx, CustomDataMask data_mask, + DerivedMesh *dm, DerivedMesh *orcodm, DerivedMesh *deform, float (*deformedVerts)[3]) +{ + Mesh *me = ob->data; + DerivedMesh *finaldm; - /* Yay, we are done. If we have a DerivedMesh and deformed vertices - * need to apply these back onto the DerivedMesh. If we have no - * DerivedMesh then we need to build one. - */ if (dm && deformedVerts) { finaldm = CDDM_copy(dm); @@ -2127,8 +2129,8 @@ static void mesh_calc_modifiers( #if 0 /* For later nice mod preview! */ /* In case we need modified weights in CD_PREVIEW_MCOL, we have to re-compute it. */ - if (do_final_wmcol) - DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL); + if (ctx->do_final_wmcol) + DM_update_weight_mcol(ob, finaldm, ctx->draw_flag, NULL, 0, NULL); #endif } else if (dm) { @@ -2136,14 +2138,14 @@ static void mesh_calc_modifiers( #if 0 /* For later nice mod preview! */ /* In case we need modified weights in CD_PREVIEW_MCOL, we have to re-compute it. */ - if (do_final_wmcol) - DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL); + if (ctx->do_final_wmcol) + DM_update_weight_mcol(ob, finaldm, ctx->draw_flag, NULL, 0, NULL); #endif } else { finaldm = CDDM_from_mesh(me); - if (build_shapekey_layers) { + if (ctx->build_shapekey_layers) { add_shapekey_layers(finaldm, me, ob); } @@ -2152,26 +2154,26 @@ static void mesh_calc_modifiers( } /* In this case, we should never have weight-modifying modifiers in stack... */ - if (do_init_wmcol) - DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL); + if (ctx->do_init_wmcol) + DM_update_weight_mcol(ob, finaldm, ctx->draw_flag, NULL, 0, NULL); } /* add an orco layer if needed */ - if (dataMask & CD_MASK_ORCO) { + if (data_mask & CD_MASK_ORCO) { add_orco_dm(ob, NULL, finaldm, orcodm, CD_ORCO); - if (r_deform && *r_deform) - add_orco_dm(ob, NULL, *r_deform, NULL, CD_ORCO); + if (deform) + add_orco_dm(ob, NULL, deform, NULL, CD_ORCO); } - if (do_loop_normals) { + if (ctx->do_loop_normals) { /* Compute loop normals (note: will compute poly and vert normals as well, if needed!) */ - DM_calc_loop_normals(finaldm, do_loop_normals, loop_normals_split_angle); + DM_calc_loop_normals(finaldm, ctx->do_loop_normals, ctx->loop_normals_split_angle); } - if (sculpt_dyntopo == false) { + if (!ctx->sculpt_dyntopo) { /* watch this! after 2.75a we move to from tessface to looptri (by default) */ - if (dataMask & CD_MASK_MFACE) { + if (data_mask & CD_MASK_MFACE) { DM_ensure_tessface(finaldm); } DM_ensure_looptri(finaldm); @@ -2185,10 +2187,143 @@ static void mesh_calc_modifiers( * Only calc vertex normals if they are flagged as dirty. * If using loop normals, poly nors have already been computed. */ - if (!do_loop_normals) { + if (!ctx->do_loop_normals) { dm_ensure_display_normals(finaldm); } } + + return finaldm; +} + +static void mesh_calc_modifiers( + Scene *scene, Object *ob, float (*inputVertexCos)[3], + const bool useRenderParams, int useDeform, + const bool need_mapping, CustomDataMask dataMask, + const int index, const bool useCache, const bool build_shapekey_layers, + const bool allow_gpu, + /* return args */ + DerivedMesh **r_deform, DerivedMesh **r_final) +{ + Mesh *me = ob->data; + ModifierEvalContext ctx; + ModifierEvalIterator iter; + ModifierEvalResult result = {0}; + DerivedMesh *finaldm; + + mesh_init_modifier_context(&ctx, scene, ob, inputVertexCos, useRenderParams, useDeform, need_mapping, + dataMask, index, useCache, build_shapekey_layers, allow_gpu); + + iter.modifier = ctx.md_begin; + iter.datamask = ctx.datamasks; + iter.multires_applied = false; + iter.isPrevDeform = false; + /* XXX Always copying POLYINDEX, else tessellated data are no more valid! */ + iter.append_mask = CD_MASK_ORIGINDEX; + + modifiers_clearErrors(ob); + + if (r_deform) + *r_deform = NULL; + *r_final = NULL; + + result.deformedVerts = inputVertexCos; + result.numVerts = me->totvert; + + if (useDeform) { + if (!ctx.sculpt_dyntopo) { + /* Apply all leading deforming modifiers */ + for (; iter.modifier != ctx.md_end; iter.modifier = iter.modifier->next, iter.datamask = iter.datamask->next) { + ModifierData *md = iter.modifier; + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + md->scene = scene; + + if (mti->type == eModifierTypeType_OnlyDeform) { + mesh_calc_deform_modifier(ob, &ctx, &iter, &result); + } + else { + break; + } + } + } + + /* Result of all leading deforming modifiers is cached for + * places that wish to use the original mesh but with deformed + * coordinates (vpaint, etc.) + */ + if (r_deform) { + *r_deform = CDDM_from_mesh(me); + + /* XXX build_shapekey_layers is never true, + * unreachable code path! + */ + if (ctx.build_shapekey_layers) + add_shapekey_layers(*r_deform, me, ob); + + if (result.deformedVerts) { + CDDM_apply_vert_coords(*r_deform, result.deformedVerts); + } + } + } + else { + /* default behavior for meshes */ + if (!result.deformedVerts) + result.deformedVerts = BKE_mesh_vertexCos_get(me, &result.numVerts); + } + + + /* Now apply all remaining modifiers. If useDeform is off then skip + * OnlyDeform ones. + */ + result.dm = NULL; + result.orcodm = NULL; + result.clothorcodm = NULL; + + for (; iter.modifier != ctx.md_end; iter.modifier = iter.modifier->next, iter.datamask = iter.datamask->next) { + ModifierData *md = iter.modifier; + const ModifierTypeInfo *mti = modifierType_getInfo(md->type); + + md->scene = scene; + + if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && result.dm) { + modifier_setError(md, "Modifier requires original data, bad stack position"); + continue; + } + + if (need_mapping && !modifier_supportsMapping(md)) { + continue; + } + + /* How to apply modifier depends on (a) what we already have as + * a result of previous modifiers (could be a DerivedMesh or just + * deformed vertices) and (b) what type the modifier is. + */ + + if (mti->type == eModifierTypeType_OnlyDeform) { + if (useDeform) + continue; + + mesh_calc_deform_modifier(ob, &ctx, &iter, &result); + } + else { + mesh_calc_constructive_modifier(ob, &ctx, dataMask, &iter, &result); + } + + iter.isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform); + + if (ctx.sculpt_mode && md->type == eModifierType_Multires) { + iter.multires_applied = true; + } + } + + for (iter.modifier = ctx.md_begin; iter.modifier; iter.modifier = iter.modifier->next) + modifier_freeTemporaryData(iter.modifier); + + /* Yay, we are done. If we have a DerivedMesh and deformed vertices + * need to apply these back onto the DerivedMesh. If we have no + * DerivedMesh then we need to build one. + */ + finaldm = mesh_calc_finalize_dm(ob, &ctx, dataMask, result.dm, result.orcodm, r_deform? *r_deform: NULL, result.deformedVerts); #ifdef WITH_GAMEENGINE /* NavMesh - this is a hack but saves having a NavMesh modifier */ @@ -2206,15 +2341,14 @@ static void mesh_calc_modifiers( *r_final = finaldm; - if (orcodm) - orcodm->release(orcodm); - if (clothorcodm) - clothorcodm->release(clothorcodm); - - if (deformedVerts && deformedVerts != inputVertexCos) - MEM_freeN(deformedVerts); - - BLI_linklist_free((LinkNode *)datamasks, NULL); + if (result.orcodm) + result.orcodm->release(result.orcodm); + if (result.clothorcodm) + result.clothorcodm->release(result.clothorcodm); + if (result.deformedVerts && result.deformedVerts != inputVertexCos) + MEM_freeN(result.deformedVerts); + + mesh_free_modifier_context(&ctx); } float (*editbmesh_get_vertex_cos(BMEditMesh *em, int *r_numVerts))[3] @@ -2673,6 +2807,52 @@ void makeDerivedMesh( } } +void BKE_object_eval_mesh(EvaluationContext *eval_ctx, + Scene *scene, + Object *ob) +{ + BMEditMesh *em = (ob == scene->obedit) ? BKE_editmesh_from_object(ob) : NULL; + + if (!em) { + bool need_mapping; + CustomDataMask data_mask = scene->customdata_mask | CD_MASK_BAREMESH; + data_mask |= object_get_datamask(scene, ob, &need_mapping); +#ifdef WITH_FREESTYLE + /* make sure Freestyle edge/face marks appear in DM for render (see T40315) */ + if (eval_ctx->mode != DAG_EVAL_VIEWPORT) { + data_mask |= CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE; + } +#else + UNUSED_VARS(eval_ctx); +#endif + + mesh_build_data(scene, ob, data_mask, false, need_mapping); + } +} + +void BKE_object_eval_editmesh(EvaluationContext *eval_ctx, + Scene *scene, + Object *ob) +{ + BMEditMesh *em = (ob == scene->obedit) ? BKE_editmesh_from_object(ob) : NULL; + + if (em) { + bool need_mapping; + CustomDataMask data_mask = scene->customdata_mask | CD_MASK_BAREMESH; + data_mask |= object_get_datamask(scene, ob, &need_mapping); +#ifdef WITH_FREESTYLE + /* make sure Freestyle edge/face marks appear in DM for render (see T40315) */ + if (eval_ctx->mode != DAG_EVAL_VIEWPORT) { + data_mask |= CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE; + } +#else + UNUSED_VARS(eval_ctx); +#endif + + editbmesh_build_data(scene, ob, em, data_mask); + } +} + /***/ DerivedMesh *mesh_get_derived_final(Scene *scene, Object *ob, CustomDataMask dataMask) diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c index ceda9f056bb..1e09b208ef9 100644 --- a/source/blender/blenkernel/intern/armature_update.c +++ b/source/blender/blenkernel/intern/armature_update.c @@ -695,3 +695,18 @@ void BKE_pose_eval_proxy_copy(EvaluationContext *UNUSED(eval_ctx), Object *ob) ob->id.name + 2, ob->proxy_from->id.name + 2); } } + +void BKE_object_eval_armature(EvaluationContext *UNUSED(eval_ctx), + Scene *scene, + Object *ob) +{ + if (ob->id.lib && ob->proxy_from) { + if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) { + printf("Proxy copy error, lib Object: %s proxy Object: %s\n", + ob->id.name + 2, ob->proxy_from->id.name + 2); + } + } + else { + BKE_pose_where_is(scene, ob); + } +} diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 4c099987404..12aeadc26d3 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -4671,3 +4671,10 @@ void BKE_curve_eval_path(EvaluationContext *UNUSED(eval_ctx), printf("%s on %s\n", __func__, curve->id.name); } } + +void BKE_object_eval_curve(EvaluationContext *UNUSED(eval_ctx), + Scene *scene, + Object *ob) +{ + BKE_displist_make_curveTypes(scene, ob, false); +} diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 57c02ec6329..3996a35c766 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -1267,3 +1267,9 @@ void BKE_lattice_eval_geometry(EvaluationContext *UNUSED(eval_ctx), { } +void BKE_object_eval_lattice(EvaluationContext *UNUSED(eval_ctx), + Scene *scene, + Object *ob) +{ + BKE_lattice_modifiers_calc(scene, ob); +} diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index d7019aa8458..ad9d9f6a742 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -602,3 +602,10 @@ void BKE_mball_eval_geometry(EvaluationContext *UNUSED(eval_ctx), MetaBall *UNUSED(mball)) { } + +void BKE_object_eval_mball(EvaluationContext *eval_ctx, + Scene *scene, + Object *ob) +{ + BKE_displist_make_mball(eval_ctx, scene, ob); +} diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index 03348adeabc..1233e28c9da 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -57,6 +57,8 @@ #include "BKE_scene.h" #include "BKE_material.h" #include "BKE_image.h" +#include "BKE_mball.h" +#include "BKE_curve.h" #include "DEG_depsgraph.h" @@ -156,6 +158,42 @@ void BKE_object_eval_modifier(struct EvaluationContext *eval_ctx, (void) md; /* Ignored. */ } +void BKE_object_eval_empty(EvaluationContext *UNUSED(eval_ctx), + Scene *scene, + Object *ob) +{ + if (ob->empty_drawtype == OB_EMPTY_IMAGE && ob->data) { + float ctime = BKE_scene_frame_get(scene); + if (BKE_image_is_animated(ob->data)) + BKE_image_user_check_frame_calc(ob->iuser, (int)ctime, 0); + } +} + +void BKE_object_eval_material_drivers(EvaluationContext *UNUSED(eval_ctx), + Scene *scene, + Object *ob) +{ + float ctime = BKE_scene_frame_get(scene); + int a; + BLI_mutex_lock(&material_lock); + for (a = 1; a <= ob->totcol; a++) { + Material *ma = give_current_material(ob, a); + if (ma) { + /* recursively update drivers for this material */ + material_drivers_update(scene, ma, ctime); + } + } + BLI_mutex_unlock(&material_lock); +} + +void BKE_object_eval_lamp_drivers(EvaluationContext *UNUSED(eval_ctx), + Scene *scene, + Object *ob) +{ + float ctime = BKE_scene_frame_get(scene); + lamp_drivers_update(scene, ob->data, ctime); +} + void BKE_object_handle_data_update(EvaluationContext *eval_ctx, Scene *scene, Object *ob) @@ -184,54 +222,28 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx, /* includes all keys and modifiers */ switch (ob->type) { - case OB_MESH: - { - BMEditMesh *em = (ob == scene->obedit) ? BKE_editmesh_from_object(ob) : NULL; - uint64_t data_mask = scene->customdata_mask | CD_MASK_BAREMESH; -#ifdef WITH_FREESTYLE - /* make sure Freestyle edge/face marks appear in DM for render (see T40315) */ - if (eval_ctx->mode != DAG_EVAL_VIEWPORT) { - data_mask |= CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE; - } -#endif - if (em) { - makeDerivedMesh(scene, ob, em, data_mask, false); /* was CD_MASK_BAREMESH */ - } - else { - makeDerivedMesh(scene, ob, NULL, data_mask, false); - } + case OB_MESH: { + /* note: only one of these will run, based on edit object */ + BKE_object_eval_editmesh(eval_ctx, scene, ob); + BKE_object_eval_mesh(eval_ctx, scene, ob); break; } case OB_ARMATURE: - if (ob->id.lib && ob->proxy_from) { - if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) { - printf("Proxy copy error, lib Object: %s proxy Object: %s\n", - ob->id.name + 2, ob->proxy_from->id.name + 2); - } - } - else { - BKE_pose_where_is(scene, ob); - } + BKE_object_eval_armature(eval_ctx, scene, ob); break; - case OB_MBALL: - BKE_displist_make_mball(eval_ctx, scene, ob); + BKE_object_eval_mball(eval_ctx, scene, ob); break; - case OB_CURVE: case OB_SURF: case OB_FONT: - BKE_displist_make_curveTypes(scene, ob, 0); + BKE_object_eval_curve(eval_ctx, scene, ob); break; - case OB_LATTICE: - BKE_lattice_modifiers_calc(scene, ob); + BKE_object_eval_lattice(eval_ctx, scene, ob); break; - case OB_EMPTY: - if (ob->empty_drawtype == OB_EMPTY_IMAGE && ob->data) - if (BKE_image_is_animated(ob->data)) - BKE_image_user_check_frame_calc(ob->iuser, (int)ctime, 0); + BKE_object_eval_empty(eval_ctx, scene, ob); break; } @@ -241,67 +253,15 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx, * anymore, especially due to Cycles [#31834] */ if (ob->totcol) { - int a; - if (ob->totcol != 0) { - BLI_mutex_lock(&material_lock); - for (a = 1; a <= ob->totcol; a++) { - Material *ma = give_current_material(ob, a); - if (ma) { - /* recursively update drivers for this material */ - material_drivers_update(scene, ma, ctime); - } - } - BLI_mutex_unlock(&material_lock); - } + BKE_object_eval_material_drivers(eval_ctx, scene, ob); + } + else if (ob->type == OB_LAMP) { + BKE_object_eval_lamp_drivers(eval_ctx, scene, ob); } - else if (ob->type == OB_LAMP) - lamp_drivers_update(scene, ob->data, ctime); /* particles */ if (ob != scene->obedit && ob->particlesystem.first) { - ParticleSystem *tpsys, *psys; - DerivedMesh *dm; - ob->transflag &= ~OB_DUPLIPARTS; - psys = ob->particlesystem.first; - while (psys) { - /* ensure this update always happens even if psys is disabled */ - if (psys->recalc & PSYS_RECALC_TYPE) { - psys_changed_type(ob, psys); - } - - if (psys_check_enabled(ob, psys)) { - /* check use of dupli objects here */ - 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))) - { - ob->transflag |= OB_DUPLIPARTS; - } - - particle_system_update(scene, ob, psys); - psys = psys->next; - } - else if (psys->flag & PSYS_DELETE) { - tpsys = psys->next; - BLI_remlink(&ob->particlesystem, psys); - psys_free(ob, psys); - psys = tpsys; - } - else - psys = psys->next; - } - - 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 */ - CustomDataMask data_mask = CD_MASK_BAREMESH | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL; - dm = mesh_create_derived_render(scene, ob, data_mask); - dm->release(dm); - - for (psys = ob->particlesystem.first; psys; psys = psys->next) - psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated; - } + BKE_object_eval_particles(eval_ctx, scene, ob); } /* quick cache removed */ @@ -337,13 +297,11 @@ void BKE_object_eval_uber_transform(EvaluationContext *UNUSED(eval_ctx), } } -void BKE_object_eval_uber_data(EvaluationContext *eval_ctx, - Scene *scene, - Object *ob) +/* clear recalc tags on object after calculating data */ +void BKE_object_eval_data_ready(EvaluationContext *UNUSED(eval_ctx), + Scene *UNUSED(scene), + Object *ob) { DEBUG_PRINT("%s on %s\n", __func__, ob->id.name); - BLI_assert(ob->type != OB_ARMATURE); - BKE_object_handle_data_update(eval_ctx, scene, ob); - ob->recalc &= ~(OB_RECALC_DATA | OB_RECALC_TIME); } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 1ca68f714c8..a859de40910 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -4345,3 +4345,52 @@ void BKE_particle_system_eval(EvaluationContext *UNUSED(eval_ctx), } BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH); } + +void BKE_object_eval_particles(EvaluationContext *eval_ctx, + Scene *scene, + Object *ob) +{ + ParticleSystem *tpsys, *psys; + DerivedMesh *dm; + ob->transflag &= ~OB_DUPLIPARTS; + psys = ob->particlesystem.first; + while (psys) { + /* ensure this update always happens even if psys is disabled */ + if (psys->recalc & PSYS_RECALC_TYPE) { + psys_changed_type(ob, psys); + } + + if (psys_check_enabled(ob, psys)) { + /* check use of dupli objects here */ + 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))) + { + ob->transflag |= OB_DUPLIPARTS; + } + + particle_system_update(scene, ob, psys); + psys = psys->next; + } + else if (psys->flag & PSYS_DELETE) { + tpsys = psys->next; + BLI_remlink(&ob->particlesystem, psys); + psys_free(ob, psys); + psys = tpsys; + } + else + psys = psys->next; + } + + 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 */ + CustomDataMask data_mask = CD_MASK_BAREMESH | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL; + dm = mesh_create_derived_render(scene, ob, data_mask); + dm->release(dm); + + for (psys = ob->particlesystem.first; psys; psys = psys->next) + psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated; + } +} diff --git a/source/blender/depsgraph/intern/depsgraph_build_nodes.cc b/source/blender/depsgraph/intern/depsgraph_build_nodes.cc index 0a5235a6d11..f38e81e0013 100644 --- a/source/blender/depsgraph/intern/depsgraph_build_nodes.cc +++ b/source/blender/depsgraph/intern/depsgraph_build_nodes.cc @@ -69,6 +69,9 @@ extern "C" { #include "BKE_constraint.h" #include "BKE_curve.h" #include "BKE_depsgraph.h" +#include "BKE_DerivedMesh.h" +#include "BKE_displist.h" +#include "BKE_editmesh.h" #include "BKE_effect.h" #include "BKE_fcurve.h" #include "BKE_idcode.h" @@ -917,16 +920,59 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) { ID *obdata = (ID *)ob->data; - /* Temporary uber-update node, which does everything. - * It is for the being we're porting old dependencies into the new system. - * We'll get rid of this node as soon as all the granular update functions - * are filled in. - * - * TODO(sergey): Get rid of this node. - */ + switch (ob->type) { + case OB_MESH: { + /* editmesh is unknown at depsgraph build time, + * only one of these nodes will be evaluated. + */ + add_operation_node(&ob->id, DEPSNODE_TYPE_GEOMETRY, + DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_mesh, _1, scene, ob), + DEG_OPCODE_GEOMETRY_DATA_MESH); + add_operation_node(&ob->id, DEPSNODE_TYPE_GEOMETRY, + DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_editmesh, _1, scene, ob), + DEG_OPCODE_GEOMETRY_DATA_EDITMESH); + break; + } + case OB_ARMATURE: + /* XXX pose nodes are built in build_object() - should clarify what happens where for such object data */ + break; + case OB_MBALL: + add_operation_node(&ob->id, DEPSNODE_TYPE_GEOMETRY, + DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_mball, _1, scene, ob), + DEG_OPCODE_GEOMETRY_DATA_MBALL); + break; + case OB_CURVE: + case OB_SURF: + case OB_FONT: + add_operation_node(&ob->id, DEPSNODE_TYPE_GEOMETRY, + DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_curve, _1, scene, ob), + DEG_OPCODE_GEOMETRY_DATA_CURVE); + break; + case OB_LATTICE: + add_operation_node(&ob->id, DEPSNODE_TYPE_GEOMETRY, + DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_lattice, _1, scene, ob), + DEG_OPCODE_GEOMETRY_DATA_LATTICE); + break; + case OB_EMPTY: + add_operation_node(&ob->id, DEPSNODE_TYPE_GEOMETRY, + DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_empty, _1, scene, ob), + DEG_OPCODE_GEOMETRY_DATA_EMPTY); + break; + } + add_operation_node(&ob->id, DEPSNODE_TYPE_GEOMETRY, - DEPSOP_TYPE_POST, function_bind(BKE_object_eval_uber_data, _1, scene, ob), - DEG_OPCODE_GEOMETRY_UBEREVAL); + DEPSOP_TYPE_EXEC, NULL, + DEG_OPCODE_PLACEHOLDER, "Data Update Done"); + + if (ob != scene->obedit && ob->particlesystem.first) { + add_operation_node(&ob->id, DEPSNODE_TYPE_GEOMETRY, + DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_particles, _1, scene, ob), + DEG_OPCODE_GEOMETRY_PARTICLES); + } + + add_operation_node(&ob->id, DEPSNODE_TYPE_GEOMETRY, + DEPSOP_TYPE_POST, function_bind(BKE_object_eval_data_ready, _1, scene, ob), + DEG_OPCODE_GEOMETRY_DATA_READY); add_operation_node(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEPSOP_TYPE_INIT, NULL, @@ -951,18 +997,29 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) } /* materials */ + /* XXX: without depsgraph tagging, driver eval will always need to be run, which will be slow! + * However, not doing anything (or trying to hack around this lack) is not an option + * anymore, especially due to Cycles [#31834] + */ if (ob->totcol) { - int a; - - for (a = 1; a <= ob->totcol; a++) { + for (int a = 1; a <= ob->totcol; a++) { Material *ma = give_current_material(ob, a); - + if (ma) { // XXX?! ComponentDepsNode *geom_node = add_component_node(&ob->id, DEPSNODE_TYPE_GEOMETRY); build_material(geom_node, ma); } } + + add_operation_node(&ob->id, DEPSNODE_TYPE_GEOMETRY, + DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_material_drivers, _1, scene, ob), + DEG_OPCODE_GEOMETRY_MATERIAL_DRIVERS); + } + else if (ob->type == OB_LAMP) { + add_operation_node(&ob->id, DEPSNODE_TYPE_GEOMETRY, + DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_lamp_drivers, _1, scene, ob), + DEG_OPCODE_GEOMETRY_LAMP_DRIVERS); } /* geometry collision */ @@ -970,9 +1027,13 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob) // add geometry collider relations } + /* ---- ob->data datablock updates ---- */ + /* XXX perhaps move this to a separate function? - lukas_t */ if (obdata->tag & LIB_TAG_DOIT) { + return; } + /* XXX is this missing 'obdata->flag |= LIB_DOIT' ?! - lukas_t */ build_animdata(obdata); diff --git a/source/blender/depsgraph/intern/depsgraph_build_relations.cc b/source/blender/depsgraph/intern/depsgraph_build_relations.cc index 226991e7b11..a3f00e79adf 100644 --- a/source/blender/depsgraph/intern/depsgraph_build_relations.cc +++ b/source/blender/depsgraph/intern/depsgraph_build_relations.cc @@ -1023,9 +1023,9 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene) void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) { TimeSourceKey time_src_key; - OperationKey obdata_ubereval_key(&ob->id, - DEPSNODE_TYPE_GEOMETRY, - DEG_OPCODE_GEOMETRY_UBEREVAL); + OperationKey obdata_ready_key(&ob->id, + DEPSNODE_TYPE_GEOMETRY, + DEG_OPCODE_GEOMETRY_DATA_READY); /* particle systems */ for (ParticleSystem *psys = (ParticleSystem *)ob->particlesystem.first; psys; psys = psys->next) { @@ -1053,9 +1053,9 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) * on playback. */ add_relation(psys_key, - obdata_ubereval_key, + obdata_ready_key, DEPSREL_TYPE_OPERATION, - "PSys -> UberEval"); + "PSys -> Data Ready"); #if 0 if (ELEM(part->phystype, PART_PHYS_KEYED, PART_PHYS_BOIDS)) { @@ -1140,7 +1140,7 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob) */ ComponentKey transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM); add_relation(transform_key, - obdata_ubereval_key, + obdata_ready_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Partcile Eval"); @@ -1626,41 +1626,94 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje } } + OperationKey tail_key; + if (ob->modifiers.last) { + ModifierData *md = (ModifierData *)ob->modifiers.last; + tail_key = OperationKey(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_MODIFIER, md->name); + } + else { + tail_key = geom_init_key; + } + + OperationKey obdata_update_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Data Update Done"); + + switch (ob->type) { + case OB_MESH: { + OperationKey update_mesh(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_DATA_MESH); + OperationKey update_editmesh(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_DATA_EDITMESH); + add_relation(tail_key, update_mesh, DEPSREL_TYPE_OPERATION, "Object Geometry Data Update"); + add_relation(tail_key, update_editmesh, DEPSREL_TYPE_OPERATION, "Object Geometry Data Update"); + add_relation(update_mesh, obdata_update_key, DEPSREL_TYPE_OPERATION, "Object Geometry Data Update"); + add_relation(update_editmesh, obdata_update_key, DEPSREL_TYPE_OPERATION, "Object Geometry Data Update"); + break; + } + case OB_MBALL: { + OperationKey update_mball(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_DATA_MBALL); + add_relation(tail_key, update_mball, DEPSREL_TYPE_OPERATION, "Object Geometry Data Update"); + add_relation(update_mball, obdata_update_key, DEPSREL_TYPE_OPERATION, "Object Geometry Data Update"); + break; + } + case OB_CURVE: + case OB_SURF: + case OB_FONT: { + OperationKey update_curve(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_DATA_CURVE); + add_relation(tail_key, update_curve, DEPSREL_TYPE_OPERATION, "Object Geometry Data Update"); + add_relation(update_curve, obdata_update_key, DEPSREL_TYPE_OPERATION, "Object Geometry Data Update"); + break; + } + case OB_LATTICE: { + OperationKey update_lattice(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_DATA_LATTICE); + add_relation(tail_key, update_lattice, DEPSREL_TYPE_OPERATION, "Object Geometry Data Update"); + add_relation(update_lattice, obdata_update_key, DEPSREL_TYPE_OPERATION, "Object Geometry Data Update"); + break; + } + case OB_EMPTY: { + OperationKey update_empty(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_DATA_EMPTY); + add_relation(tail_key, update_empty, DEPSREL_TYPE_OPERATION, "Object Geometry Data Update"); + add_relation(update_empty, obdata_update_key, DEPSREL_TYPE_OPERATION, "Object Geometry Data Update"); + break; + } + } + tail_key = obdata_update_key; + /* materials */ if (ob->totcol) { - int a; - - for (a = 1; a <= ob->totcol; a++) { + for (int a = 1; a <= ob->totcol; a++) { Material *ma = give_current_material(ob, a); - + if (ma) build_material(&ob->id, ma); } + + OperationKey ma_drivers_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_MATERIAL_DRIVERS); + add_relation(tail_key, ma_drivers_key, DEPSREL_TYPE_OPERATION, "Object Geometry Material Drivers"); + tail_key = ma_drivers_key; + } + else if (ob->type == OB_LAMP) { + OperationKey la_drivers_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_LAMP_DRIVERS); + add_relation(tail_key, la_drivers_key, DEPSREL_TYPE_OPERATION, "Object Geometry Material Drivers"); + tail_key = la_drivers_key; } + if (ob != scene->obedit && ob->particlesystem.first) { + OperationKey particles_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_PARTICLES); + add_relation(tail_key, particles_key, DEPSREL_TYPE_OPERATION, "Object Geometry Particles"); + tail_key = particles_key; + } + + OperationKey obdata_ready_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_DATA_READY); + add_relation(tail_key, obdata_ready_key, DEPSREL_TYPE_OPERATION, "Object Geometry Data Ready"); + /* geometry collision */ if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_LATTICE)) { // add geometry collider relations } - /* Make sure uber update is the last in the dependencies. - * - * TODO(sergey): Get rid of this node. - */ - if (ob->type != OB_ARMATURE) { - /* Armatures does no longer require uber node. */ - OperationKey obdata_ubereval_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_UBEREVAL); - if (ob->modifiers.last) { - ModifierData *md = (ModifierData *)ob->modifiers.last; - OperationKey mod_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_MODIFIER, md->name); - add_relation(mod_key, obdata_ubereval_key, DEPSREL_TYPE_OPERATION, "Object Geometry UberEval"); - } - else { - add_relation(geom_init_key, obdata_ubereval_key, DEPSREL_TYPE_OPERATION, "Object Geometry UberEval"); - } - } + /* ---- ob->data datablock updates ---- */ + /* XXX perhaps move this to a separate function? - lukas_t */ if (obdata->tag & LIB_TAG_DOIT) { + return; } obdata->tag |= LIB_TAG_DOIT; diff --git a/source/blender/depsgraph/intern/depsnode_opcodes.h b/source/blender/depsgraph/intern/depsnode_opcodes.h index b81822c0ac5..53a225f9013 100644 --- a/source/blender/depsgraph/intern/depsnode_opcodes.h +++ b/source/blender/depsgraph/intern/depsnode_opcodes.h @@ -94,8 +94,25 @@ DEF_DEG_OPCODE(OBJECT_UBEREVAL) /* Geometry ---------------------------------------- */ -/* XXX: Placeholder - UberEval */ -DEF_DEG_OPCODE(GEOMETRY_UBEREVAL) +/* main object data eval */ +DEF_DEG_OPCODE(GEOMETRY_DATA_MESH) +DEF_DEG_OPCODE(GEOMETRY_DATA_EDITMESH) +DEF_DEG_OPCODE(GEOMETRY_DATA_CURVE) +DEF_DEG_OPCODE(GEOMETRY_DATA_LATTICE) +DEF_DEG_OPCODE(GEOMETRY_DATA_MBALL) +DEF_DEG_OPCODE(GEOMETRY_DATA_EMPTY) + +/* particles eval */ +DEF_DEG_OPCODE(GEOMETRY_PARTICLES) + +/* extra material/lamp drivers + * (XXX should become redundant in new depsgraph) + */ +DEF_DEG_OPCODE(GEOMETRY_MATERIAL_DRIVERS) +DEF_DEG_OPCODE(GEOMETRY_LAMP_DRIVERS) + +/* final data tagging node */ +DEF_DEG_OPCODE(GEOMETRY_DATA_READY) /* Modifier */ DEF_DEG_OPCODE(GEOMETRY_MODIFIER) |