Much cleaner and satisfying code in weightvg modifiers' "init": copy only the CD_DEFORMVERT data layer (if it's the org one), and not the whole DerivedMesh!

Quite oddly, for Proximity mod, this increases the performances of the apply func (about 20-25%, e.g. from 0.04 to 0.03 sec), but decreases the global framerate (e.g. in TEST_5 scene of testing file, I lose about 7%, from 4.6 to 4.3fps (open ATI driver)...).
This commit is contained in:
Bastien Montagne
2011-12-19 14:09:36 +00:00
parent 26b3dfa30e
commit 41c992ce85
3 changed files with 27 additions and 155 deletions

View File

@@ -177,10 +177,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
int UNUSED(useRenderParams), int UNUSED(isFinalCalc))
{
WeightVGEditModifierData *wmd = (WeightVGEditModifierData*) md;
DerivedMesh *dm = derivedData, *ret = NULL;
#if 0
Mesh *ob_m = NULL;
#endif
DerivedMesh *dm = derivedData;
MDeformVert *dvert = NULL;
MDeformWeight **dw = NULL;
float *org_w; /* Array original weights. */
@@ -188,7 +185,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
int numVerts;
int defgrp_idx;
int i;
char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */
/* Flags. */
int do_add = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0;
int do_rem = (wmd->edit_flags & MOD_WVG_EDIT_REMFVG) != 0;
@@ -207,49 +203,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
if (defgrp_idx < 0)
return dm;
/* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute
* time! See scene 5 of the WeighVG test file...
*/
#if 0
/* Get actual dverts (ie vertex group data). */
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
/* If no dverts, return unmodified data... */
if (dvert == NULL)
return dm;
/* Get org mesh, only to test whether affected cdata layer has already been copied
* somewhere up in the modifiers stack.
*/
ob_m = get_mesh(ob);
if (ob_m == NULL)
return dm;
/* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */
if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) {
/* XXX Seems to create problems with weightpaint mode???
* I'm missing something here, I guess...
*/
// DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */
ret = CDDM_copy(dm);
dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT);
if (dvert == NULL) {
ret->release(ret);
return dm;
}
rel_ret = 1;
}
else
ret = dm;
#else
ret = CDDM_copy(dm);
rel_ret = 1;
dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT);
if (dvert == NULL) {
if (rel_ret)
ret->release(ret);
return dm;
}
#endif
dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts);
/* Get org weights, assuming 0.0 for vertices not in given vgroup. */
org_w = MEM_mallocN(sizeof(float) * numVerts, "WeightVGEdit Modifier, org_w");
@@ -271,7 +225,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
}
/* Do masking. */
weightvg_do_mask(numVerts, NULL, org_w, new_w, ob, ret, wmd->mask_constant,
weightvg_do_mask(numVerts, NULL, org_w, new_w, ob, dm, wmd->mask_constant,
wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel,
wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);
@@ -285,7 +239,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
MEM_freeN(dw);
/* Return the vgroup-modified mesh. */
return ret;
return dm;
}
static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,

View File

@@ -219,10 +219,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
int UNUSED(useRenderParams), int UNUSED(isFinalCalc))
{
WeightVGMixModifierData *wmd = (WeightVGMixModifierData*) md;
DerivedMesh *dm = derivedData, *ret = NULL;
#if 0
Mesh *ob_m = NULL;
#endif
DerivedMesh *dm = derivedData;
MDeformVert *dvert = NULL;
MDeformWeight **dw1, **tdw1, **dw2, **tdw2;
int numVerts;
@@ -232,7 +229,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
int *tidx, *indices = NULL;
int numIdx = 0;
int i;
char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */
/* Get number of verts. */
numVerts = dm->getNumVerts(dm);
@@ -254,49 +250,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
return dm;
}
/* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute
* time! See scene 5 of the WeighVG test file...
*/
#if 0
/* Get actual dverts (ie vertex group data). */
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
/* If no dverts, return unmodified data... */
if (dvert == NULL)
return dm;
/* Get org mesh, only to test whether affected cdata layer has already been copied
* somewhere up in the modifiers stack.
*/
ob_m = get_mesh(ob);
if (ob_m == NULL)
return dm;
/* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */
if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) {
/* XXX Seems to create problems with weightpaint mode???
* I'm missing something here, I guess...
*/
// DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */
ret = CDDM_copy(dm);
dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT);
if (dvert == NULL) {
ret->release(ret);
return dm;
}
rel_ret = 1;
}
else
ret = dm;
#else
ret = CDDM_copy(dm);
rel_ret = 1;
dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT);
if (dvert == NULL) {
if (rel_ret)
ret->release(ret);
return dm;
}
#endif
dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts);
/* Find out which vertices to work on. */
tidx = MEM_mallocN(sizeof(int) * numVerts, "WeightVGMix Modifier, tidx");
@@ -364,8 +318,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
MEM_freeN(tdw1);
MEM_freeN(tdw2);
MEM_freeN(tidx);
if (rel_ret)
ret->release(ret);
return dm;
}
if (numIdx != -1) {
@@ -400,7 +352,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
}
/* Do masking. */
weightvg_do_mask(numIdx, indices, org_w, new_w, ob, ret, wmd->mask_constant,
weightvg_do_mask(numIdx, indices, org_w, new_w, ob, dm, wmd->mask_constant,
wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel,
wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);
@@ -419,7 +371,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
MEM_freeN(indices);
/* Return the vgroup-modified mesh. */
return ret;
return dm;
}
static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,

View File

@@ -28,11 +28,17 @@
* \ingroup modifiers
*/
#define DO_PROFILE 0
#include "BLI_editVert.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#if DO_PROFILE
#include "PIL_time.h"
#endif
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -334,10 +340,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
int UNUSED(useRenderParams), int UNUSED(isFinalCalc))
{
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData*) md;
DerivedMesh *dm = derivedData, *ret = NULL;
#if 0
Mesh *ob_m = NULL;
#endif
DerivedMesh *dm = derivedData;
MDeformVert *dvert = NULL;
MDeformWeight **dw, **tdw;
int numVerts;
@@ -350,7 +353,10 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
int *tidx, *indices = NULL;
int numIdx = 0;
int i;
char rel_ret = 0; /* Boolean, whether we have to release ret dm or not, when not using it! */
#if DO_PROFILE
TIMEIT_START(perf)
#endif
/* Get number of verts. */
numVerts = dm->getNumVerts(dm);
@@ -371,49 +377,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
if (defgrp_idx < 0)
return dm;
/* XXX All this to avoid copying dm when not needed... However, it nearly doubles compute
* time! See scene 5 of the WeighVG test file...
*/
#if 0
/* Get actual dverts (ie vertex group data). */
dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
/* If no dverts, return unmodified data... */
if (dvert == NULL)
return dm;
/* Get org mesh, only to test whether affected cdata layer has already been copied
* somewhere up in the modifiers stack.
*/
ob_m = get_mesh(ob);
if (ob_m == NULL)
return dm;
/* Create a copy of our dmesh, only if our affected cdata layer is the same as org mesh. */
if (dvert == CustomData_get_layer(&ob_m->vdata, CD_MDEFORMVERT)) {
/* XXX Seems to create problems with weightpaint mode???
* I'm missing something here, I guess...
*/
// DM_set_only_copy(dm, CD_MASK_MDEFORMVERT); /* Only copy defgroup layer. */
ret = CDDM_copy(dm);
dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT);
if (dvert == NULL) {
ret->release(ret);
return dm;
}
rel_ret = 1;
}
else
ret = dm;
#else
ret = CDDM_copy(dm);
rel_ret = 1;
dvert = ret->getVertDataArray(ret, CD_MDEFORMVERT);
if (dvert == NULL) {
if (rel_ret)
ret->release(ret);
return dm;
}
#endif
dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts);
/* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight.
*/
@@ -433,8 +397,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
MEM_freeN(tidx);
MEM_freeN(tw);
MEM_freeN(tdw);
if (rel_ret)
ret->release(ret);
return dm;
}
indices = MEM_mallocN(sizeof(int) * numIdx, "WeightVGProximity Modifier, indices");
@@ -455,7 +417,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
*/
float (*tv_cos)[3] = MEM_mallocN(sizeof(float[3]) * numVerts, "WeightVGProximity Modifier, tv_cos");
v_cos = MEM_mallocN(sizeof(float[3]) * numIdx, "WeightVGProximity Modifier, v_cos");
ret->getVertCos(ret, tv_cos);
dm->getVertCos(dm, tv_cos);
for (i = 0; i < numIdx; i++)
copy_v3_v3(v_cos[i], tv_cos[indices[i]]);
MEM_freeN(tv_cos);
@@ -524,7 +486,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
do_map(new_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type);
/* Do masking. */
weightvg_do_mask(numIdx, indices, org_w, new_w, ob, ret, wmd->mask_constant,
weightvg_do_mask(numIdx, indices, org_w, new_w, ob, dm, wmd->mask_constant,
wmd->mask_defgrp_name, wmd->mask_texture, wmd->mask_tex_use_channel,
wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name);
@@ -538,8 +500,12 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
MEM_freeN(indices);
MEM_freeN(v_cos);
#if DO_PROFILE
TIMEIT_END(perf)
#endif
/* Return the vgroup-modified mesh. */
return ret;
return dm;
}
static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,