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:
authorBastien Montagne <montagne29@wanadoo.fr>2015-02-15 20:46:46 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2015-02-15 21:00:06 +0300
commita98fc4f8f9bb887b934f999b8988727eb285b6d7 (patch)
treed08981441a6ec3a82bc68e6bf101d4609e44078c /source/blender/modifiers/intern
parent1c64543aefd5c78540dc3de5254c0dd54649ca81 (diff)
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.
Diffstat (limited to 'source/blender/modifiers/intern')
-rw-r--r--source/blender/modifiers/intern/MOD_datatransfer.c20
-rw-r--r--source/blender/modifiers/intern/MOD_normal_edit.c29
2 files changed, 40 insertions, 9 deletions
diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c
index 2dca3218e41..acb58f6b767 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 58ef850bb4f..db20823bf0c 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 = {