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.
This commit is contained in:
@@ -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",
|
||||
|
@@ -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 = {
|
||||
|
Reference in New Issue
Block a user