[Bf-blender-cvs] [a98fc4f] master: Fix T43671: Playing with Mix Factor of Data Transfer Modifier Is Overwritting Data of Base Mesh

Bastien Montagne noreply at git.blender.org
Sun Feb 15 19:00:31 CET 2015


Commit: a98fc4f8f9bb887b934f999b8988727eb285b6d7
Author: Bastien Montagne
Date:   Sun Feb 15 18:46:46 2015 +0100
Branches: master
https://developer.blender.org/rBa98fc4f8f9bb887b934f999b8988727eb285b6d7

Fix T43671: Playing with Mix Factor of Data Transfer Modifier Is Overwritting Data of Base Mesh

The issue was actually affecting all data types that are not regular CDLayer ones, since by default
DerivedMesh references mesh data (verts, edges, etc. - modifying custom normals often implies
modifying edges' sarpness too).
Modfying edge/face sharpness etc. could directly affect the mesh in this case, **bad**!

So we detect whether we are copying data types that may affect non-CDlayers data, and whether
verts array of org dm is same as mesh one - in which case we copy the DM. This avoids
useless copying in most cases.

Note Edit Normals was quite obviously suffering the same issue.

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

M	source/blender/modifiers/intern/MOD_datatransfer.c
M	source/blender/modifiers/intern/MOD_normal_edit.c

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

diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c
index 2dca321..acb58f6 100644
--- a/source/blender/modifiers/intern/MOD_datatransfer.c
+++ b/source/blender/modifiers/intern/MOD_datatransfer.c
@@ -37,6 +37,7 @@
 #include "DNA_object_types.h"
 
 #include "BKE_customdata.h"
+#include "BKE_cdderivedmesh.h"
 #include "BKE_data_transfer.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_library.h"
@@ -152,6 +153,12 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
 }
 
 #define HIGH_POLY_WARNING 10000
+#define DT_TYPES_AFFECT_MESH ( \
+	DT_TYPE_BWEIGHT_VERT | \
+	DT_TYPE_BWEIGHT_EDGE | DT_TYPE_CREASE | DT_TYPE_SHARP_EDGE | \
+	DT_TYPE_LNOR | \
+	DT_TYPE_SHARP_FACE \
+)
 
 static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData,
                                   ModifierApplyFlag UNUSED(flag))
@@ -160,6 +167,10 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
 	DerivedMesh *dm = derivedData;
 	ReportList reports;
 
+	/* Only used to check wehther we are operating on org data or not... */
+	Mesh *me = ob->data;
+	MVert *mvert;
+
 	const bool invert_vgroup = (dtmd->flags & MOD_DATATRANSFER_INVERT_VGROUP) != 0;
 
 	const float max_dist = (dtmd->flags & MOD_DATATRANSFER_MAP_MAXDIST) ? dtmd->map_max_distance : FLT_MAX;
@@ -171,6 +182,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
 		BLI_SPACE_TRANSFORM_SETUP(space_transform, ob, dtmd->ob_source);
 	}
 
+	mvert = dm->getVertArray(dm);
+	if ((me->mvert == mvert) && (dtmd->data_types & DT_TYPES_AFFECT_MESH)) {
+		/* We need to duplicate data here, otherwise setting custom normals, edges' shaprness, etc., could
+		 * modify org mesh, see T43671. */
+		dm = CDDM_copy(dm);
+	}
+
 	BKE_reports_init(&reports, RPT_STORE);
 
 	/* Note: no islands precision for now here. */
@@ -190,6 +208,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
 	return dm;
 }
 
+#undef HIGH_POLY_WARNING
+#undef DT_TYPES_AFFECT_MESH
 
 ModifierTypeInfo modifierType_DataTransfer = {
 	/* name */              "DataTransfer",
diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c
index 58ef850..db20823 100644
--- a/source/blender/modifiers/intern/MOD_normal_edit.c
+++ b/source/blender/modifiers/intern/MOD_normal_edit.c
@@ -323,7 +323,7 @@ static bool is_valid_target(NormalEditModifierData *smd)
 	return false;
 }
 
-static void normalEditModifier_do(NormalEditModifierData *smd, Object *ob, DerivedMesh *dm)
+static DerivedMesh *normalEditModifier_do(NormalEditModifierData *smd, Object *ob, DerivedMesh *dm)
 {
 	Mesh *me = ob->data;
 
@@ -331,10 +331,10 @@ static void normalEditModifier_do(NormalEditModifierData *smd, Object *ob, Deriv
 	const int num_edges = dm->getNumEdges(dm);
 	const int num_loops = dm->getNumLoops(dm);
 	const int num_polys = dm->getNumPolys(dm);
-	MVert *mvert = dm->getVertArray(dm);
-	MEdge *medge = dm->getEdgeArray(dm);
-	MLoop *mloop = dm->getLoopArray(dm);
-	MPoly *mpoly = dm->getPolyArray(dm);
+	MVert *mvert;
+	MEdge *medge;
+	MLoop *mloop;
+	MPoly *mpoly;
 
 	const bool use_invert_vgroup = ((smd->flag & MOD_NORMALEDIT_INVERT_VGROUP) != 0);
 	const bool use_current_clnors = !((smd->mix_mode == MOD_NORMALEDIT_MIX_COPY) &&
@@ -352,14 +352,24 @@ static void normalEditModifier_do(NormalEditModifierData *smd, Object *ob, Deriv
 
 	/* Do not run that modifier at all if autosmooth is disabled! */
 	if (!is_valid_target(smd) || !num_loops) {
-		return;
+		return dm;
 	}
 
 	if (!(me->flag & ME_AUTOSMOOTH)) {
 		modifier_setError((ModifierData *)smd, "Enable 'Auto Smooth' option in mesh settings");
-		return;
+		return dm;
 	}
 
+	medge = dm->getEdgeArray(dm);
+	if (me->medge == medge) {
+		/* We need to duplicate data here, otherwise setting custom normals (which may also affect sharp edges) could
+		 * modify org mesh, see T43671. */
+		dm = CDDM_copy(dm);
+		medge = dm->getEdgeArray(dm);
+	}
+	mvert = dm->getVertArray(dm);
+	mloop = dm->getLoopArray(dm);
+	mpoly = dm->getPolyArray(dm);
 
 	if (use_current_clnors) {
 		dm->calcLoopNormals(dm, true, me->smoothresh);
@@ -397,6 +407,8 @@ static void normalEditModifier_do(NormalEditModifierData *smd, Object *ob, Deriv
 	if (free_polynors) {
 		MEM_freeN(polynors);
 	}
+
+	return dm;
 }
 
 static void initData(ModifierData *md)
@@ -467,8 +479,7 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UN
 
 static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, ModifierApplyFlag UNUSED(flag))
 {
-	normalEditModifier_do((NormalEditModifierData *)md, ob, dm);
-	return dm;
+	return normalEditModifier_do((NormalEditModifierData *)md, ob, dm);
 }
 
 ModifierTypeInfo modifierType_NormalEdit = {




More information about the Bf-blender-cvs mailing list