Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h4
-rw-r--r--source/blender/blenkernel/BKE_armature.h4
-rw-r--r--source/blender/blenkernel/BKE_curve.h4
-rw-r--r--source/blender/blenkernel/BKE_lattice.h4
-rw-r--r--source/blender/blenkernel/BKE_mball.h4
-rw-r--r--source/blender/blenkernel/BKE_object.h14
-rw-r--r--source/blender/blenkernel/BKE_particle.h4
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c898
-rw-r--r--source/blender/blenkernel/intern/armature_update.c15
-rw-r--r--source/blender/blenkernel/intern/curve.c7
-rw-r--r--source/blender/blenkernel/intern/lattice.c6
-rw-r--r--source/blender/blenkernel/intern/mball.c7
-rw-r--r--source/blender/blenkernel/intern/object_update.c154
-rw-r--r--source/blender/blenkernel/intern/particle_system.c49
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build_nodes.cc87
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build_relations.cc105
-rw-r--r--source/blender/depsgraph/intern/depsnode_opcodes.h21
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)