[Bf-blender-cvs] [7b95d64d2f5] master: Cleanup: better naming, comments, variable scoping in mesh_calc_modifiers.

Brecht Van Lommel noreply at git.blender.org
Thu Mar 28 20:04:50 CET 2019


Commit: 7b95d64d2f521cafe6a521af5b082c0a13cf8460
Author: Brecht Van Lommel
Date:   Thu Mar 28 11:42:53 2019 +0100
Branches: master
https://developer.blender.org/rB7b95d64d2f521cafe6a521af5b082c0a13cf8460

Cleanup: better naming, comments, variable scoping in mesh_calc_modifiers.

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

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

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

diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 886545ff4b1..ac2ae8a1e35 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -879,18 +879,18 @@ static Mesh *create_orco_mesh(Object *ob, Mesh *me, BMEditMesh *em, int layer)
 
 static void add_orco_mesh(
         Object *ob, BMEditMesh *em, Mesh *mesh,
-        Mesh *me_orco, int layer)
+        Mesh *mesh_orco, int layer)
 {
 	float (*orco)[3], (*layerorco)[3];
 	int totvert, free;
 
 	totvert = mesh->totvert;
 
-	if (me_orco) {
+	if (mesh_orco) {
 		free = 1;
 
-		if (me_orco->totvert == totvert) {
-			orco = BKE_mesh_vertexCos_get(me_orco, NULL);
+		if (mesh_orco->totvert == totvert) {
+			orco = BKE_mesh_vertexCos_get(mesh_orco, NULL);
 		}
 		else {
 			orco = BKE_mesh_vertexCos_get(mesh, NULL);
@@ -991,6 +991,59 @@ static void mesh_copy_autosmooth(Mesh *me, Mesh *me_orig)
 	}
 }
 
+static void mesh_calc_modifier_final_normals(
+        const Mesh *mesh_input,
+        const CustomData_MeshMasks *dataMask,
+        const bool sculpt_dyntopo,
+		Mesh *mesh_final)
+{
+	/* Compute normals. */
+	const bool do_loop_normals = ((mesh_input->flag & ME_AUTOSMOOTH) != 0 ||
+	                              (dataMask->lmask & CD_MASK_NORMAL) != 0);
+	/* Some modifiers may need this info from their target (other) object, simpler to generate it here as well.
+	 * Note that they will always be generated when no loop normals are comptuted,
+	 * since they are needed by drawing code. */
+	const bool do_poly_normals = ((dataMask->pmask & CD_MASK_NORMAL) != 0);
+
+	if (do_loop_normals) {
+		/* In case we also need poly normals, add the layer here, then BKE_mesh_calc_normals_split() will fill it. */
+		if (do_poly_normals) {
+			if (!CustomData_has_layer(&mesh_final->pdata, CD_NORMAL)) {
+				CustomData_add_layer(&mesh_final->pdata, CD_NORMAL, CD_CALLOC, NULL, mesh_final->totpoly);
+			}
+		}
+		/* Compute loop normals (note: will compute poly and vert normals as well, if needed!) */
+		BKE_mesh_calc_normals_split(mesh_final);
+		BKE_mesh_tessface_clear(mesh_final);
+	}
+
+	if (sculpt_dyntopo == false) {
+		/* watch this! after 2.75a we move to from tessface to looptri (by default) */
+		if (dataMask->fmask & CD_MASK_MFACE) {
+			BKE_mesh_tessface_ensure(mesh_final);
+		}
+
+		/* without this, drawing ngon tri's faces will show ugly tessellated face
+		 * normals and will also have to calculate normals on the fly, try avoid
+		 * this where possible since calculating polygon normals isn't fast,
+		 * note that this isn't a problem for subsurf (only quads) or editmode
+		 * which deals with drawing differently.
+		 *
+		 * Only calc vertex normals if they are flagged as dirty.
+		 * If using loop normals, poly nors have already been computed.
+		 */
+		if (!do_loop_normals) {
+			BKE_mesh_ensure_normals_for_display(mesh_final);
+		}
+	}
+
+	/* Some modifiers, like datatransfer, may generate those data as temp layer, we do not want to keep them,
+	 * as they are used by display code when available (i.e. even if autosmooth is disabled). */
+	if (!do_loop_normals && CustomData_has_layer(&mesh_final->ldata, CD_NORMAL)) {
+		CustomData_free_layers(&mesh_final->ldata, CD_NORMAL, mesh_final->totloop);
+	}
+}
+
 static void mesh_calc_modifiers(
         struct Depsgraph *depsgraph,
         Scene *scene, Object *ob,
@@ -998,58 +1051,62 @@ static void mesh_calc_modifiers(
         const bool need_mapping,
         const CustomData_MeshMasks *dataMask,
         const int index,
-        const bool useCache,
+        const bool use_cache,
         /* return args */
         Mesh **r_deform,
         Mesh **r_final)
 {
-	ModifierData *firstmd, *md, *previewmd = NULL;
-	CDMaskLink *datamasks, *curr;
-	/* XXX Always copying POLYINDEX, else tessellated data are no more valid! */
-	CustomData_MeshMasks mask, nextmask, previewmask = {0}, append_mask = CD_MASK_BAREMESH_ORIGINDEX;
-
-	float (*deformedVerts)[3] = NULL;
-	int numVerts = ((Mesh *)ob->data)->totvert;
-	const bool useRenderParams = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
-	const int required_mode = useRenderParams ? eModifierMode_Render : eModifierMode_Realtime;
+	/* Input and final mesh. Final mesh is only created the moment the first
+	 * constructive modifier is executed, or a deform modifier needs normals
+	 * or certain data layers. */
+	Mesh *mesh_input = ob->data;
+	Mesh *mesh_final = NULL;
+	Mesh *mesh_deform = NULL;
+	BLI_assert((mesh_input->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0);
+
+	/* Deformed vertex locations array. Deform only modifier need this type of
+	 * float array rather than MVert*. Tracked along with mesh_final as an
+	 * optimization to avoid copying coordinates back and forth if there are
+	 * multiple sequential deform only modifiers. */
+	float (*deformed_verts)[3] = NULL;
+	int num_deformed_verts = mesh_input->totvert;
 	bool isPrevDeform = false;
+
+	/* Mesh with constructive modifiers but no deformation applied. Tracked
+	 * along with final mesh if undeformed / orco coordinates are requested
+	 * for texturing. */
+	Mesh *mesh_orco = NULL;
+	Mesh *mesh_orco_cloth = NULL;
+
+	/* Modifier evaluation modes. */
+	const bool use_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
+	const int required_mode = use_render ? eModifierMode_Render : eModifierMode_Realtime;
+
+	/* Sculpt can skip certain modifiers. */
 	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 bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !use_render;
+	const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm)  && !use_render;
 
-	/* Generic preview only in object mode! */
-	const bool do_mod_mcol = (ob->mode == OB_MODE_OBJECT);
-	const bool do_loop_normals = ((((Mesh *)ob->data)->flag & ME_AUTOSMOOTH) != 0 ||
-	                              (dataMask->lmask & CD_MASK_NORMAL) != 0);
-	/* Some modifiers may need this info from their target (other) object, simpler to generate it here as well.
-	 * Note that they will always be generated when no loop normals are comptuted,
-	 * since they are needed by drawing code. */
-	const bool do_poly_normals = ((dataMask->pmask & CD_MASK_NORMAL) != 0);
+	/* 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};
 
+	/* 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 *firstmd = modifiers_getVirtualModifierList(ob, &virtualModifierData);
+	ModifierData *md = firstmd;
 
-	ModifierApplyFlag app_flags = useRenderParams ? MOD_APPLY_RENDER : 0;
-	ModifierApplyFlag deform_app_flags = app_flags;
-
-	BLI_assert((((Mesh *)ob->data)->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0);
-
-	if (useCache)
-		app_flags |= MOD_APPLY_USECACHE;
-	if (useDeform)
-		deform_app_flags |= MOD_APPLY_USECACHE;
-
-	/* TODO(sybren): do we really need three context objects? Or do we modify
-	 * them on the fly to change the flags where needed? */
-	const ModifierEvalContext mectx_deform = {depsgraph, ob, deform_app_flags};
-	const ModifierEvalContext mectx_apply = {depsgraph, ob, app_flags};
-	const ModifierEvalContext mectx_orco = {depsgraph, ob, (app_flags & ~MOD_APPLY_USECACHE) | MOD_APPLY_ORCO};
-
-	md = firstmd = modifiers_getVirtualModifierList(ob, &virtualModifierData);
-
-	modifiers_clearErrors(ob);
-
+	/* Preview colors by modifiers such as dynamic paint, to show the results
+	 * even if the resulting data is not used in a material. Only in object mode.
+	 * TODO: this is broken, not drawn by the drawn manager. */
+	const bool do_mod_mcol = (ob->mode == OB_MODE_OBJECT);
+	ModifierData *previewmd = NULL;
+	CustomData_MeshMasks previewmask = {0};
 	if (do_mod_mcol) {
 		/* Find the last active modifier generating a preview, or NULL if none. */
 		/* XXX Currently, DPaint modifier just ignores this.
@@ -1058,21 +1115,21 @@ static void mesh_calc_modifiers(
 		previewmd = modifiers_getLastPreview(scene, md, required_mode);
 	}
 
-	datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode, previewmd, &previewmask);
-	curr = datamasks;
-
-	if (r_deform) {
-		*r_deform = NULL;
-	}
-	*r_final = NULL;
+	/* Compute accumulated datamasks needed by each modifier. It helps to do
+	 * this fine grained so that for example vertex groups are preserved up to
+	 * an armature modifier, but not through a following subsurf modifier where
+	 * subdividing them is expensive. */
+	CDMaskLink *datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode, previewmd, &previewmask);
+	CDMaskLink *md_datamask = datamasks;
+	/* XXX Always copying POLYINDEX, else tessellated data are no more valid! */
+	CustomData_MeshMasks append_mask = CD_MASK_BAREMESH_ORIGINDEX;
 
-	/* We need mesh even for deform-only part of the stack, in cases where some modifier needs
-	 * e.g. access to updated normals. See T62633 for an example. */
-	Mesh *me = NULL;
+	/* Clear errors before evaluation. */
+	modifiers_clearErrors(ob);
 
+	/* Apply all leading deform modifiers. */
 	if (useDeform) {
-		/* Apply all leading deforming modifiers */
-		for (; md; md = md->next, curr = curr->next) {
+		for (; md; md = md->next, md_datamask = md_datamask->next) {
 			const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
 
 			if (!modifier_isEnabled(scene, md, required_mode)) {
@@ -1084,19 +1141,18 @@ static void mesh_calc_modifiers(
 			}
 
 			if (mti->type == eModifierTypeType_OnlyDeform && !sculpt_dyntopo) {
-				if (!deformedVerts) {
-					deformedVerts = BKE_mesh_vertexCo

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list