[Bf-blender-cvs] [2374b21] temp_depsgraph_split_ubereval: Use a common function for deform-only modifier evaluation.
Lukas Tönne
noreply at git.blender.org
Fri Sep 25 11:13:38 CEST 2015
Commit: 2374b2103ba8686e70c746ed5f64369a98211d1f
Author: Lukas Tönne
Date: Fri Sep 25 11:10:40 2015 +0200
Branches: temp_depsgraph_split_ubereval
https://developer.blender.org/rB2374b2103ba8686e70c746ed5f64369a98211d1f
Use a common function for deform-only modifier evaluation.
The distinction between leading and interspersed deform modifier in the
evaluation loop is superficial. The primary difference is the existence of
a derived mesh (dm), which can be handled optionally. Further conditionals
can be moved outside the loop (dyntopo would immediately cancel leading
deform eval anyway).
===================================================================
M source/blender/blenkernel/intern/DerivedMesh.c
===================================================================
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index acbe020..1d6fe9d 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1707,12 +1707,15 @@ typedef struct ModifierEvalContext {
bool sculpt_mode;
bool sculpt_dyntopo;
bool sculpt_only_deform;
-
bool has_multires;
+ bool build_shapekey_layers;
+ bool special_gameengine_hack;
+
VirtualModifierData virtualModifierData;
- ModifierData *firstmd;
+ ModifierData *md_begin;
+ ModifierData *md_end;
ModifierData *previewmd;
CDMaskLink *datamasks;
} ModifierEvalContext;
@@ -1722,9 +1725,9 @@ static void mesh_init_modifier_context(ModifierEvalContext *ctx,
const bool useRenderParams, int useDeform,
const bool UNUSED(need_mapping),
CustomDataMask dataMask,
- const int UNUSED(index),
+ const int index,
const bool useCache,
- const bool UNUSED(build_shapekey_layers),
+ const bool build_shapekey_layers,
const bool allow_gpu)
{
Mesh *me = ob->data;
@@ -1762,24 +1765,37 @@ static void mesh_init_modifier_context(ModifierEvalContext *ctx,
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;
+
/* precompute data */
if (!skipVirtualArmature) {
- ctx->firstmd = modifiers_getVirtualModifierList(ob, &ctx->virtualModifierData);
+ ctx->md_begin = modifiers_getVirtualModifierList(ob, &ctx->virtualModifierData);
}
else {
/* game engine exception */
- ctx->firstmd = ob->modifiers.first;
- if (ctx->firstmd && ctx->firstmd->type == eModifierType_Armature)
- ctx->firstmd = ctx->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;
}
+ /* only handle modifiers until index */
+ ctx->md_end = (index >= 0) ? BLI_findlink(&ob->modifiers, index) : NULL;
+
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! */
- ctx->previewmd = modifiers_getLastPreview(scene, ctx->firstmd, ctx->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 (ctx->previewmd) {
@@ -1791,7 +1807,7 @@ static void mesh_init_modifier_context(ModifierEvalContext *ctx,
else
ctx->previewmd = NULL;
- ctx->datamasks = modifiers_calcDataMasks(scene, ob, ctx->firstmd, dataMask, ctx->required_mode, ctx->previewmd, previewmask);
+ ctx->datamasks = modifiers_calcDataMasks(scene, ob, ctx->md_begin, dataMask, ctx->required_mode, ctx->previewmd, previewmask);
}
static void mesh_free_modifier_context(ModifierEvalContext *ctx)
@@ -1813,8 +1829,9 @@ typedef struct ModifierEvalIterator {
static bool mesh_calc_modifier_sculptmode_skip(const ModifierEvalContext *ctx, ModifierData *md,
const bool multires_applied)
{
- if (ctx->sculpt_mode
- && (!ctx->has_multires || multires_applied || ctx->sculpt_dyntopo))
+ 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;
@@ -1850,13 +1867,57 @@ static bool mesh_calc_modifier_sculptmode_skip(const ModifierEvalContext *ctx, M
return false;
}
-/**
- * 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_deform_modifier(Object *ob, const ModifierEvalContext *ctx, const ModifierEvalIterator *iter,
+ DerivedMesh *dm, DerivedMesh *orcodm, float (**deformedVerts)[3], int *numVerts)
+{
+ 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 (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);
+ }
+
+ /* 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 (iter->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, ctx->deform_app_flags);
+}
+
static void mesh_calc_modifiers(
Scene *scene, Object *ob, float (*inputVertexCos)[3],
const bool useRenderParams, int useDeform,
@@ -1870,13 +1931,13 @@ static void mesh_calc_modifiers(
ModifierEvalContext ctx;
ModifierEvalIterator iter;
float (*deformedVerts)[3] = inputVertexCos;
- DerivedMesh *dm = NULL, *orcodm, *clothorcodm, *finaldm;
+ DerivedMesh *dm, *orcodm, *clothorcodm, *finaldm;
int numVerts = me->totvert;
mesh_init_modifier_context(&ctx, scene, ob, useRenderParams, useDeform, need_mapping,
dataMask, index, useCache, build_shapekey_layers, allow_gpu);
- iter.modifier = ctx.firstmd;
+ iter.modifier = ctx.md_begin;
iter.datamask = ctx.datamasks;
iter.multires_applied = false;
iter.isPrevDeform = false;
@@ -1885,53 +1946,42 @@ static void mesh_calc_modifiers(
modifiers_clearErrors(ob);
- if (r_deform) {
+ if (r_deform)
*r_deform = NULL;
- }
*r_final = NULL;
if (useDeform) {
- /* Apply all leading deforming modifiers */
- for (; iter.modifier; 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 (!modifier_isEnabled(scene, md, ctx.required_mode)) {
- continue;
- }
-
- if (useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) {
- continue;
- }
-
- if (mti->type == eModifierTypeType_OnlyDeform && !ctx.sculpt_dyntopo) {
- if (!deformedVerts)
- deformedVerts = BKE_mesh_vertexCos_get(me, &numVerts);
-
- modwrap_deformVerts(md, ob, NULL, deformedVerts, numVerts, ctx.deform_app_flags);
- }
- else {
- break;
+ 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, NULL, NULL, &deformedVerts, &numVerts);
+ }
+ else {
+ break;
+ }
}
-
- /* grab modifiers until index i */
- if ((index != -1) && (BLI_findindex(&ob->modifiers, md) >= index))
- 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);
-
- if (build_shapekey_layers)
- add_shapekey_layers(dm, me, ob);
+
+ /* XXX build_shapekey_layers is never true,
+ * unreachable code path!
+ */
+ if (ctx.build_shapekey_layers)
+ add_shapekey_layers(*r_deform, me, ob);
- if (deformedVerts) {
+ if (*deformedVerts) {
CDDM_apply_vert_coords(*r_deform, deformedVerts);
}
}
@@ -1950,86 +2000,52 @@ static void mesh_calc_modifiers(
orcodm = NULL;
clothorcodm = NULL;
- for (; iter.modifier; iter.modifier = iter.modifier->next, iter.datamask = iter.datamask->next) {
+ 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 (!modifier_isEnabled(scene, md, ctx.required_mode)) {
- continue;
- }
-
- if (mti->type == eModifierTypeType_OnlyDeform && !useDeform) {
- continue;
- }
-
if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
modifier_setError(md, "Modifier requires original data, bad stack position");
continue;
}
- if (mesh_calc_modifi
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list