[Bf-blender-cvs] [548c77d] temp_depsgraph_split_ubereval: Cleanup for mesh_calc_modifiers: Context and Iteration structs.

Lukas Tönne noreply at git.blender.org
Wed Sep 23 19:31:44 CEST 2015


Commit: 548c77d5e15fea657aa9e451d6f760cd54f975e0
Author: Lukas Tönne
Date:   Wed Sep 23 18:19:39 2015 +0200
Branches: temp_depsgraph_split_ubereval
https://developer.blender.org/rB548c77d5e15fea657aa9e451d6f760cd54f975e0

Cleanup for mesh_calc_modifiers: Context and Iteration structs.

These gather most of the large number of local variables in that function,
in order to gain some clarity on their usage and scope.

Context is where immutable settings and global precomputed data is stored
during the computation. These values are initialized once and not touched
by modifiers.

Iterator struct holds the combined md/datamask pointers and some (hackish)
mutable data that gets updated during the process.

Where possible local variables have also been moved into narrower code blocks
to make the overall procedure less confusing.

===================================================================

M	source/blender/blenkernel/intern/DerivedMesh.c

===================================================================

diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index b5349bd..5c62708 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1688,97 +1688,160 @@ 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 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 has_multires;
+	
+	VirtualModifierData virtualModifierData;
+	
+	ModifierData *firstmd;
+	ModifierData *previewmd;
+	CDMaskLink *datamasks;
+} ModifierEvalContext;
+
+static void mesh_init_modifier_context(ModifierEvalContext *ctx,
+                                       Scene *scene, Object *ob,
+                                       const bool useRenderParams, int useDeform,
+                                       const bool UNUSED(need_mapping),
+                                       CustomDataMask dataMask,
+                                       const int UNUSED(index),
+                                       const bool useCache,
+                                       const bool UNUSED(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);
+	CustomDataMask previewmask = 0;
+	const bool skipVirtualArmature = (useDeform < 0);
 
+	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);
+	ctx->required_mode = useRenderParams ? eModifierMode_Render : eModifierMode_Realtime;
+	
 	/* 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;
-
-	const bool do_loop_normals = (me->flag & ME_AUTOSMOOTH) != 0;
-	const float loop_normals_split_angle = me->smoothresh;
+	ctx->do_mod_wmcol = ctx->do_init_wmcol;
 
-	VirtualModifierData virtualModifierData;
+	ctx->do_loop_normals = (me->flag & ME_AUTOSMOOTH) != 0;
+	ctx->loop_normals_split_angle = me->smoothresh;
 
-	ModifierApplyFlag app_flags = useRenderParams ? MOD_APPLY_RENDER : 0;
-	ModifierApplyFlag deform_app_flags = app_flags;
+	ctx->sculpt_mode = (ob->mode & OB_MODE_SCULPT) && ob->sculpt && !useRenderParams;
+	ctx->sculpt_dyntopo = (ctx->sculpt_mode && ob->sculpt->bm)  && !useRenderParams;
 
+	ctx->has_multires = (mmd && mmd->sculptlvl != 0);
 
-	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->firstmd = modifiers_getVirtualModifierList(ob, &ctx->virtualModifierData);
 	}
 	else {
 		/* game engine exception */
-		firstmd = ob->modifiers.first;
-		if (firstmd && firstmd->type == eModifierType_Armature)
-			firstmd = firstmd->next;
+		ctx->firstmd = ob->modifiers.first;
+		if (ctx->firstmd && ctx->firstmd->type == eModifierType_Armature)
+			ctx->firstmd = ctx->firstmd->next;
 	}
 
-	md = firstmd;
-
-	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->firstmd, 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;
+	ctx->datamasks = modifiers_calcDataMasks(scene, ob, ctx->firstmd, dataMask, ctx->required_mode, ctx->previewmd, previewmask);
+}
+
+static void mesh_free_modifier_context(ModifierEvalContext *ctx)
+{
+	BLI_linklist_free((LinkNode *)ctx->datamasks, NULL);
+}
+
+/* combined iterator for modifier and associated data mask */
+typedef struct ModifierEvalIterator {
+	ModifierData *modifier;
+	CDMaskLink *datamask;
+
+	/* mutable flags */
+	bool multires_applied;
+	bool isPrevDeform;
+	CustomDataMask append_mask;
+} ModifierEvalIterator;
+
+/**
+ * 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)
+{
+	Mesh *me = ob->data;
+	ModifierEvalContext ctx;
+	ModifierEvalIterator iter;
+	float (*deformedVerts)[3] = NULL;
+	DerivedMesh *dm = NULL, *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.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;
@@ -1790,12 +1853,13 @@ static void mesh_calc_modifiers(
 			deformedVerts = inputVertexCos;
 		
 		/* Apply all leading deforming modifiers */
-		for (; md; md = md->next, curr = curr->next) {
+		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, required_mode)) {
+			if (!modifier_isEnabled(scene, md, ctx.required_mode)) {
 				continue;
 			}
 
@@ -1803,11 +1867,11 @@ static void mesh_calc_modifiers(
 				continue;
 			}
 
-			if (mti->type == eModifierTypeType_OnlyDeform && !sculpt_dyntopo) {
+			if (mti->type == eModifierTypeType_OnlyDeform && !ctx.sculpt_dyntopo) {
 				if (!deformedVerts)
 					deformedVerts = BKE_mesh_vertexCos_get(me, &numVerts);
 
-				modwrap_deformVerts(md, ob, NULL, deformedVerts, numVerts, deform_app_flags);
+				modwrap_deformVerts(md, ob, NULL, deformedVerts, numVerts, ctx.deform_app_flags);
 			}
 			else {
 				break;
@@ -1849,12 +1913,13 @@ static void mesh_calc_modifiers(
 	orcodm = NULL;
 	clothorcodm = NULL;
 
-	for (; md; md = md->next, curr = curr->next) {
+	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, required_mode)) {
+		if (!modifier

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list