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:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_modifier.h36
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c18
-rw-r--r--source/blender/blenkernel/intern/displist.c18
-rw-r--r--source/blender/blenkernel/intern/hair.c61
-rw-r--r--source/blender/blenkernel/intern/lattice.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c2
-rw-r--r--source/blender/blenkernel/intern/modifier.c8
-rw-r--r--source/blender/blenkernel/intern/multires.c2
-rw-r--r--source/blender/blenkernel/intern/object.c30
-rw-r--r--source/blender/blenkernel/intern/pointcloud.c61
-rw-r--r--source/blender/blenkernel/intern/volume.cc48
11 files changed, 225 insertions, 61 deletions
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index c37e56149eb..3a3be7e82c2 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -100,7 +100,7 @@ typedef enum {
/* For modifiers that use CD_PREVIEW_MCOL for preview. */
eModifierTypeFlag_UsesPreview = (1 << 9),
- eModifierTypeFlag_AcceptsLattice = (1 << 10),
+ eModifierTypeFlag_AcceptsVertexCosOnly = (1 << 10),
} ModifierTypeFlag;
/* IMPORTANT! Keep ObjectWalkFunc and IDWalkFunc signatures compatible. */
@@ -211,18 +211,28 @@ typedef struct ModifierTypeInfo {
/********************* Non-deform modifier functions *********************/
- /* For non-deform types: apply the modifier and return a mesh object.
+ /* For non-deform types: apply the modifier and return a mesh datablock.
*
- * The mesh argument should always be non-NULL; the modifier
- * should read the object data from the mesh object instead of the
- * actual object data.
+ * The mesh argument should always be non-NULL; the modifier should use the
+ * passed in mesh datablock rather than object->data, as it contains the mesh
+ * with modifier applied up to this point.
*
- * The modifier may reuse the mesh argument (i.e. return it in
- * modified form), but must not release it.
+ * The modifier may modify and return the mesh argument, but must not free it
+ * and must ensure any referenced data layers are converted to non-referenced
+ * before modification.
*/
- struct Mesh *(*applyModifier)(struct ModifierData *md,
- const struct ModifierEvalContext *ctx,
- struct Mesh *mesh);
+ struct Mesh *(*modifyMesh)(struct ModifierData *md,
+ const struct ModifierEvalContext *ctx,
+ struct Mesh *mesh);
+ struct Hair *(*modifyHair)(struct ModifierData *md,
+ const struct ModifierEvalContext *ctx,
+ struct Hair *hair);
+ struct PointCloud *(*modifyPointCloud)(struct ModifierData *md,
+ const struct ModifierEvalContext *ctx,
+ struct PointCloud *pointcloud);
+ struct Volume *(*modifyVolume)(struct ModifierData *md,
+ const struct ModifierEvalContext *ctx,
+ struct Volume *volume);
/********************* Optional functions *********************/
@@ -450,9 +460,9 @@ struct ModifierData *modifier_get_evaluated(struct Depsgraph *depsgraph,
/* wrappers for modifier callbacks that ensure valid normals */
-struct Mesh *modwrap_applyModifier(ModifierData *md,
- const struct ModifierEvalContext *ctx,
- struct Mesh *me);
+struct Mesh *modwrap_modifyMesh(ModifierData *md,
+ const struct ModifierEvalContext *ctx,
+ struct Mesh *me);
void modwrap_deformVerts(ModifierData *md,
const struct ModifierEvalContext *ctx,
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index baef2b2290e..f67e49aef06 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -907,10 +907,10 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !use_render;
/* Modifier evaluation contexts for different types of modifiers. */
- ModifierApplyFlag app_render = use_render ? MOD_APPLY_RENDER : 0;
- ModifierApplyFlag app_cache = use_cache ? MOD_APPLY_USECACHE : 0;
- const ModifierEvalContext mectx = {depsgraph, ob, app_render | app_cache};
- const ModifierEvalContext mectx_orco = {depsgraph, ob, app_render | MOD_APPLY_ORCO};
+ ModifierApplyFlag apply_render = use_render ? MOD_APPLY_RENDER : 0;
+ ModifierApplyFlag apply_cache = use_cache ? MOD_APPLY_USECACHE : 0;
+ const ModifierEvalContext mectx = {depsgraph, ob, apply_render | apply_cache};
+ const ModifierEvalContext mectx_orco = {depsgraph, ob, apply_render | MOD_APPLY_ORCO};
/* Get effective list of modifiers to execute. Some effects like shape keys
* are added as virtual modifiers before the user created modifiers. */
@@ -1176,7 +1176,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
}
}
- Mesh *mesh_next = modwrap_applyModifier(md, &mectx, mesh_final);
+ Mesh *mesh_next = modwrap_modifyMesh(md, &mectx, mesh_final);
ASSERT_IS_VALID_MESH(mesh_next);
if (mesh_next) {
@@ -1212,7 +1212,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
CustomData_MeshMasks_update(&temp_cddata_masks, &nextmask);
mesh_set_only_copy(mesh_orco, &temp_cddata_masks);
- mesh_next = modwrap_applyModifier(md, &mectx_orco, mesh_orco);
+ mesh_next = modwrap_modifyMesh(md, &mectx_orco, mesh_orco);
ASSERT_IS_VALID_MESH(mesh_next);
if (mesh_next) {
@@ -1238,7 +1238,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
nextmask.pmask |= CD_MASK_ORIGINDEX;
mesh_set_only_copy(mesh_orco_cloth, &nextmask);
- mesh_next = modwrap_applyModifier(md, &mectx_orco, mesh_orco_cloth);
+ mesh_next = modwrap_modifyMesh(md, &mectx_orco, mesh_orco_cloth);
ASSERT_IS_VALID_MESH(mesh_next);
if (mesh_next) {
@@ -1595,7 +1595,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
mask.pmask |= CD_MASK_ORIGINDEX;
mesh_set_only_copy(mesh_orco, &mask);
- Mesh *mesh_next = modwrap_applyModifier(md, &mectx_orco, mesh_orco);
+ Mesh *mesh_next = modwrap_modifyMesh(md, &mectx_orco, mesh_orco);
ASSERT_IS_VALID_MESH(mesh_next);
if (mesh_next) {
@@ -1626,7 +1626,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
}
}
- Mesh *mesh_next = modwrap_applyModifier(md, &mectx, mesh_final);
+ Mesh *mesh_next = modwrap_modifyMesh(md, &mectx, mesh_final);
ASSERT_IS_VALID_MESH(mesh_next);
if (mesh_next) {
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 907e7eb66ec..a18579f9402 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -857,7 +857,7 @@ static void curve_calc_modifiers_pre(
Curve *cu = ob->data;
int numElems = 0, numVerts = 0;
const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
- ModifierApplyFlag app_flag = 0;
+ ModifierApplyFlag apply_flag = 0;
float(*deformedVerts)[3] = NULL;
float *keyVerts = NULL;
int required_mode;
@@ -865,17 +865,17 @@ static void curve_calc_modifiers_pre(
modifiers_clearErrors(ob);
if (editmode) {
- app_flag |= MOD_APPLY_USECACHE;
+ apply_flag |= MOD_APPLY_USECACHE;
}
if (for_render) {
- app_flag |= MOD_APPLY_RENDER;
+ apply_flag |= MOD_APPLY_RENDER;
required_mode = eModifierMode_Render;
}
else {
required_mode = eModifierMode_Realtime;
}
- const ModifierEvalContext mectx = {depsgraph, ob, app_flag};
+ const ModifierEvalContext mectx = {depsgraph, ob, apply_flag};
pretessellatePoint = curve_get_tessellate_point(scene, ob, for_render, editmode);
@@ -985,10 +985,10 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
Mesh *modified = NULL, *mesh_applied;
float(*vertCos)[3] = NULL;
int useCache = !for_render;
- ModifierApplyFlag app_flag = 0;
+ ModifierApplyFlag apply_flag = 0;
if (for_render) {
- app_flag |= MOD_APPLY_RENDER;
+ apply_flag |= MOD_APPLY_RENDER;
required_mode = eModifierMode_Render;
}
else {
@@ -996,9 +996,9 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
}
const ModifierEvalContext mectx_deform = {
- depsgraph, ob, editmode ? app_flag | MOD_APPLY_USECACHE : app_flag};
+ depsgraph, ob, editmode ? apply_flag | MOD_APPLY_USECACHE : apply_flag};
const ModifierEvalContext mectx_apply = {
- depsgraph, ob, useCache ? app_flag | MOD_APPLY_USECACHE : app_flag};
+ depsgraph, ob, useCache ? apply_flag | MOD_APPLY_USECACHE : apply_flag};
pretessellatePoint = curve_get_tessellate_point(scene, ob, for_render, editmode);
@@ -1095,7 +1095,7 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
if (need_normal) {
BKE_mesh_ensure_normals(modified);
}
- mesh_applied = mti->applyModifier(md, &mectx_apply, modified);
+ mesh_applied = mti->modifyMesh(md, &mectx_apply, modified);
if (mesh_applied) {
/* Modifier returned a new derived mesh */
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 5cdb7761540..9d66b509c72 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -247,12 +247,65 @@ Hair *BKE_hair_copy_for_eval(Hair *hair_src, bool reference)
return result;
}
-static Hair *hair_evaluate_modifiers(struct Depsgraph *UNUSED(depsgraph),
- struct Scene *UNUSED(scene),
- Object *UNUSED(object),
+static Hair *hair_evaluate_modifiers(struct Depsgraph *depsgraph,
+ struct Scene *scene,
+ Object *object,
Hair *hair_input)
{
- return hair_input;
+ Hair *hair = hair_input;
+
+ /* Modifier evaluation modes. */
+ const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
+ const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
+ ModifierApplyFlag apply_flag = use_render ? MOD_APPLY_RENDER : MOD_APPLY_USECACHE;
+ const ModifierEvalContext mectx = {depsgraph, object, apply_flag};
+
+ /* Get effective list of modifiers to execute. Some effects like shape keys
+ * are added as virtual modifiers before the user created modifiers. */
+ VirtualModifierData virtualModifierData;
+ ModifierData *md = modifiers_getVirtualModifierList(object, &virtualModifierData);
+
+ /* Evaluate modifiers. */
+ for (; md; md = md->next) {
+ const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+ if (!modifier_isEnabled(scene, md, required_mode)) {
+ continue;
+ }
+
+ if ((mti->type == eModifierTypeType_OnlyDeform) &&
+ (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly)) {
+ /* Ensure we are not modifying the input. */
+ if (hair == hair_input) {
+ hair = BKE_hair_copy_for_eval(hair, true);
+ }
+
+ /* Ensure we are not overwriting referenced data. */
+ CustomData_duplicate_referenced_layer(&hair->pdata, CD_LOCATION, hair->totpoint);
+ BKE_hair_update_customdata_pointers(hair);
+
+ /* Created deformed coordinates array on demand. */
+ mti->deformVerts(md, &mectx, NULL, hair->co, hair->totpoint);
+ }
+ else if (mti->modifyHair) {
+ /* Ensure we are not modifying the input. */
+ if (hair == hair_input) {
+ hair = BKE_hair_copy_for_eval(hair, true);
+ }
+
+ Hair *hair_next = mti->modifyHair(md, &mectx, hair);
+
+ if (hair_next && hair_next != hair) {
+ /* If the modifier returned a new hair, release the old one. */
+ if (hair != hair_input) {
+ BKE_id_free(NULL, hair);
+ }
+ hair = hair_next;
+ }
+ }
+ }
+
+ return hair;
}
void BKE_hair_data_update(struct Depsgraph *depsgraph, struct Scene *scene, Object *object)
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index d371af93bb7..68893ad8877 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -1134,7 +1134,7 @@ void BKE_lattice_modifiers_calc(struct Depsgraph *depsgraph, Scene *scene, Objec
for (; md; md = md->next) {
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
- if (!(mti->flags & eModifierTypeFlag_AcceptsLattice)) {
+ if (!(mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly)) {
continue;
}
if (!(md->mode & eModifierMode_Realtime)) {
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 28a32e1573b..e7dbd7be664 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -1353,7 +1353,7 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
add_shapekey_layers(mesh_temp, me);
}
- result = mti->applyModifier(md_eval, &mectx, mesh_temp);
+ result = mti->modifyMesh(md_eval, &mectx, mesh_temp);
ASSERT_IS_VALID_MESH(result);
if (mesh_temp != result) {
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 0a76b61cdb1..4b05f4635a2 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -945,11 +945,9 @@ void modifier_path_init(char *path, int path_maxlen, const char *name)
BLI_join_dirfile(path, path_maxlen, G.relbase_valid ? "//" : BKE_tempdir_session(), name);
}
-/* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */
+/* wrapper around ModifierTypeInfo.modifyMesh that ensures valid normals */
-struct Mesh *modwrap_applyModifier(ModifierData *md,
- const ModifierEvalContext *ctx,
- struct Mesh *me)
+struct Mesh *modwrap_modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct Mesh *me)
{
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
BLI_assert(CustomData_has_layer(&me->pdata, CD_NORMAL) == false);
@@ -957,7 +955,7 @@ struct Mesh *modwrap_applyModifier(ModifierData *md,
if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
BKE_mesh_calc_normals(me);
}
- return mti->applyModifier(md, ctx, me);
+ return mti->modifyMesh(md, ctx, me);
}
void modwrap_deformVerts(ModifierData *md,
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 69cd338e15f..6dc03c518fe 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -290,7 +290,7 @@ Mesh *BKE_multires_create_mesh(struct Depsgraph *depsgraph,
};
const ModifierTypeInfo *mti = modifierType_getInfo(mmd->modifier.type);
- Mesh *result = mti->applyModifier(&mmd->modifier, &modifier_ctx, deformed_mesh);
+ Mesh *result = mti->modifyMesh(&mmd->modifier, &modifier_ctx, deformed_mesh);
if (result == deformed_mesh) {
result = BKE_mesh_copy_for_eval(deformed_mesh, true);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 2f281a29211..a12307b7c18 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -514,21 +514,31 @@ bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type)
mti = modifierType_getInfo(modifier_type);
- /* only geometry objects should be able to get modifiers [#25291] */
- if (!ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
- return false;
+ /* Only geometry objects should be able to get modifiers [#25291] */
+ if (ob->type == OB_HAIR) {
+ return (mti->modifyHair != NULL) || (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly);
}
-
- if (ob->type == OB_LATTICE && (mti->flags & eModifierTypeFlag_AcceptsLattice) == 0) {
- return false;
+ else if (ob->type == OB_POINTCLOUD) {
+ return (mti->modifyPointCloud != NULL) ||
+ (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly);
+ }
+ else if (ob->type == OB_VOLUME) {
+ return (mti->modifyVolume != NULL);
}
+ else if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
+ if (ob->type == OB_LATTICE && (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly) == 0) {
+ return false;
+ }
- if (!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
- (ob->type == OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh)))) {
- return false;
+ if (!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
+ (ob->type == OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh)))) {
+ return false;
+ }
+
+ return true;
}
- return true;
+ return false;
}
void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_src)
diff --git a/source/blender/blenkernel/intern/pointcloud.c b/source/blender/blenkernel/intern/pointcloud.c
index 717d84c1c1e..c943d30aaa5 100644
--- a/source/blender/blenkernel/intern/pointcloud.c
+++ b/source/blender/blenkernel/intern/pointcloud.c
@@ -211,12 +211,65 @@ PointCloud *BKE_pointcloud_copy_for_eval(struct PointCloud *pointcloud_src, bool
return result;
}
-static PointCloud *pointcloud_evaluate_modifiers(struct Depsgraph *UNUSED(depsgraph),
- struct Scene *UNUSED(scene),
- Object *UNUSED(object),
+static PointCloud *pointcloud_evaluate_modifiers(struct Depsgraph *depsgraph,
+ struct Scene *scene,
+ Object *object,
PointCloud *pointcloud_input)
{
- return pointcloud_input;
+ PointCloud *pointcloud = pointcloud_input;
+
+ /* Modifier evaluation modes. */
+ const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
+ const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
+ ModifierApplyFlag apply_flag = use_render ? MOD_APPLY_RENDER : MOD_APPLY_USECACHE;
+ const ModifierEvalContext mectx = {depsgraph, object, apply_flag};
+
+ /* Get effective list of modifiers to execute. Some effects like shape keys
+ * are added as virtual modifiers before the user created modifiers. */
+ VirtualModifierData virtualModifierData;
+ ModifierData *md = modifiers_getVirtualModifierList(object, &virtualModifierData);
+
+ /* Evaluate modifiers. */
+ for (; md; md = md->next) {
+ const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+ if (!modifier_isEnabled(scene, md, required_mode)) {
+ continue;
+ }
+
+ if ((mti->type == eModifierTypeType_OnlyDeform) &&
+ (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly)) {
+ /* Ensure we are not modifying the input. */
+ if (pointcloud == pointcloud_input) {
+ pointcloud = BKE_pointcloud_copy_for_eval(pointcloud, true);
+ }
+
+ /* Ensure we are not overwriting referenced data. */
+ CustomData_duplicate_referenced_layer(&pointcloud->pdata, CD_LOCATION, pointcloud->totpoint);
+ BKE_pointcloud_update_customdata_pointers(pointcloud);
+
+ /* Created deformed coordinates array on demand. */
+ mti->deformVerts(md, &mectx, NULL, pointcloud->co, pointcloud->totpoint);
+ }
+ else if (mti->modifyPointCloud) {
+ /* Ensure we are not modifying the input. */
+ if (pointcloud == pointcloud_input) {
+ pointcloud = BKE_pointcloud_copy_for_eval(pointcloud, true);
+ }
+
+ PointCloud *pointcloud_next = mti->modifyPointCloud(md, &mectx, pointcloud);
+
+ if (pointcloud_next && pointcloud_next != pointcloud) {
+ /* If the modifier returned a new pointcloud, release the old one. */
+ if (pointcloud != pointcloud_input) {
+ BKE_id_free(NULL, pointcloud);
+ }
+ pointcloud = pointcloud_next;
+ }
+ }
+ }
+
+ return pointcloud;
}
void BKE_pointcloud_data_update(struct Depsgraph *depsgraph, struct Scene *scene, Object *object)
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 9d9e8423bcf..1098ad6d95c 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -795,12 +795,52 @@ bool BKE_volume_is_points_only(const Volume *volume)
/* Dependency Graph */
-static Volume *volume_evaluate_modifiers(struct Depsgraph *UNUSED(depsgraph),
- struct Scene *UNUSED(scene),
- Object *UNUSED(object),
+static Volume *volume_evaluate_modifiers(struct Depsgraph *depsgraph,
+ struct Scene *scene,
+ Object *object,
Volume *volume_input)
{
- return volume_input;
+ Volume *volume = volume_input;
+
+ /* Modifier evaluation modes. */
+ const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
+ const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
+ ModifierApplyFlag apply_flag = use_render ? MOD_APPLY_RENDER : MOD_APPLY_USECACHE;
+ const ModifierEvalContext mectx = {depsgraph, object, apply_flag};
+
+ /* Get effective list of modifiers to execute. Some effects like shape keys
+ * are added as virtual modifiers before the user created modifiers. */
+ VirtualModifierData virtualModifierData;
+ ModifierData *md = modifiers_getVirtualModifierList(object, &virtualModifierData);
+
+ /* Evaluate modifiers. */
+ for (; md; md = md->next) {
+ const ModifierTypeInfo *mti = (const ModifierTypeInfo *)modifierType_getInfo(
+ (ModifierType)md->type);
+
+ if (!modifier_isEnabled(scene, md, required_mode)) {
+ continue;
+ }
+
+ if (mti->modifyVolume) {
+ /* Ensure we are not modifying the input. */
+ if (volume == volume_input) {
+ volume = BKE_volume_copy_for_eval(volume, true);
+ }
+
+ Volume *volume_next = mti->modifyVolume(md, &mectx, volume);
+
+ if (volume_next && volume_next != volume) {
+ /* If the modifier returned a new volume, release the old one. */
+ if (volume != volume_input) {
+ BKE_id_free(NULL, volume);
+ }
+ volume = volume_next;
+ }
+ }
+ }
+
+ return volume;
}
void BKE_volume_eval_geometry(struct Depsgraph *depsgraph, Volume *volume)