diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2018-05-07 19:15:27 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2018-05-07 19:18:05 +0300 |
commit | 3800be695bc19dcbefc23fe7b157f104b1efb8dc (patch) | |
tree | de6ed183d07f85eccdbb31739b88db425b743269 /source/blender | |
parent | 15f9ca05d1307dcaf63f9ead81ea95283b9484e5 (diff) |
Modifier stack: move vgroup editing modifiers to new Mesh-based system.
Some notes here:
* Proximity with non-mesh objects (like curve, see TEST_2 scene in
weightvg testfile) are not working currently. This is known TODO of COW
depsgraph project.
* Proximity modifier is slower, due to some other TODO pending on
BVHTree creation/caching for Mesh.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/modifiers/intern/MOD_weightvg_util.c | 24 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_weightvg_util.h | 12 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_weightvgedit.c | 75 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_weightvgmix.c | 84 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_weightvgproximity.c | 142 |
5 files changed, 199 insertions, 138 deletions
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index 416f2964d6e..bb8ccb8899e 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -34,13 +34,14 @@ #include "BLI_utildefines.h" #include "DNA_color_types.h" /* CurveMapping. */ +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "BKE_cdderivedmesh.h" #include "BKE_colortools.h" /* CurveMapping. */ +#include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_modifier.h" #include "BKE_texture.h" /* Texture masking. */ @@ -114,9 +115,9 @@ void weightvg_do_map(int num, float *new_w, short falloff_type, CurveMapping *cm * vertex index (in case the weight tables do not cover the whole vertices...). * XXX The standard "factor" value is assumed in [0.0, 1.0] range. Else, weird results might appear. */ -void weightvg_do_mask(int num, const int *indices, float *org_w, const float *new_w, - Object *ob, DerivedMesh *dm, float fact, const char defgrp_name[MAX_VGROUP_NAME], - Scene *scene, Tex *texture, int tex_use_channel, int tex_mapping, +void weightvg_do_mask(const int num, const int *indices, float *org_w, const float *new_w, + Object *ob, Mesh *mesh, const float fact, const char defgrp_name[MAX_VGROUP_NAME], + Scene *scene, Tex *texture, const int tex_use_channel, const int tex_mapping, Object *tex_map_object, const char *tex_uvlayer_name) { int ref_didx; @@ -131,8 +132,7 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne float (*tex_co)[3]; /* See mapping note below... */ MappingInfoModifierData t_map; - float (*v_co)[3]; - int numVerts = dm->getNumVerts(dm); + const int numVerts = mesh->totvert; /* Use new generic get_texture_coords, but do not modify our DNA struct for it... * XXX Why use a ModifierData stuff here ? Why not a simple, generic struct for parameters ? @@ -143,11 +143,9 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne t_map.map_object = tex_map_object; BLI_strncpy(t_map.uvlayer_name, tex_uvlayer_name, sizeof(t_map.uvlayer_name)); t_map.texmapping = tex_mapping; - v_co = MEM_malloc_arrayN(numVerts, sizeof(*v_co), "WeightVG Modifier, TEX mode, v_co"); - dm->getVertCos(dm, v_co); + tex_co = MEM_calloc_arrayN(numVerts, sizeof(*tex_co), "WeightVG Modifier, TEX mode, tex_co"); - get_texture_coords(&t_map, ob, dm, v_co, tex_co, num); - MEM_freeN(v_co); + get_texture_coords_mesh(&t_map, ob, mesh, tex_co); modifier_init_texture(scene, texture); @@ -209,9 +207,11 @@ void weightvg_do_mask(int num, const int *indices, float *org_w, const float *ne /* Proceed only if vgroup is valid, else use constant factor. */ /* Get actual dverts (ie vertex group data). */ - dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); + dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); /* Proceed only if vgroup is valid, else assume factor = O. */ - if (dvert == NULL) return; + if (dvert == NULL) { + return; + } /* For each weight (vertex), make the mix between org and new weights. */ for (i = 0; i < num; i++) { diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.h b/source/blender/modifiers/intern/MOD_weightvg_util.h index 03bcbb6eb97..73552e50d0f 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.h +++ b/source/blender/modifiers/intern/MOD_weightvg_util.h @@ -32,7 +32,9 @@ #define __MOD_WEIGHTVG_UTIL_H__ struct CurveMapping; -struct DerivedMesh; +struct MDeformVert; +struct MDeformWeight; +struct Mesh; struct Object; struct Tex; struct Scene; @@ -70,16 +72,16 @@ void weightvg_do_map(int num, float *new_w, short mode, struct CurveMapping *cma * vertex index (in case the weight tables do not cover the whole vertices...). * XXX The standard "factor" value is assumed in [0.0, 1.0] range. Else, weird results might appear. */ -void weightvg_do_mask(int num, const int *indices, float *org_w, const float *new_w, Object *ob, - DerivedMesh *dm, float fact, const char defgrp_name[MAX_VGROUP_NAME], - struct Scene *scene, Tex *texture, int tex_use_channel, int tex_mapping, +void weightvg_do_mask(const int num, const int *indices, float *org_w, const float *new_w, Object *ob, + struct Mesh *mesh, const float fact, const char defgrp_name[MAX_VGROUP_NAME], + struct Scene *scene, Tex *texture, const int tex_use_channel, const int tex_mapping, Object *tex_map_object, const char *tex_uvlayer_name); /* Applies weights to given vgroup (defgroup), and optionally add/remove vertices from the group. * If indices is not NULL, it must be a table of same length as weights, mapping to the real * vertex index (in case the weight table does not cover the whole vertices...). */ -void weightvg_update_vg(MDeformVert *dvert, int defgrp_idx, MDeformWeight **dws, int num, +void weightvg_update_vg(struct MDeformVert *dvert, int defgrp_idx, struct MDeformWeight **dws, int num, const int *indices, const float *weights, const bool do_add, const float add_thresh, const bool do_rem, const float rem_thresh); diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index 1a9651909dd..cc000cbee09 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -34,11 +34,11 @@ #include "BLI_rand.h" #include "DNA_color_types.h" /* CurveMapping. */ +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" -#include "BKE_cdderivedmesh.h" #include "BKE_colortools.h" /* CurveMapping. */ #include "BKE_deform.h" #include "BKE_library.h" @@ -154,19 +154,18 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams)) return (wmd->defgrp_name[0] == '\0'); } -static DerivedMesh *applyModifier(ModifierData *md, +static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, - DerivedMesh *derivedData) + Mesh *mesh) { WeightVGEditModifierData *wmd = (WeightVGEditModifierData *) md; - DerivedMesh *dm = derivedData; + MDeformVert *dvert = NULL; MDeformWeight **dw = NULL; float *org_w; /* Array original weights. */ float *new_w; /* Array new weights. */ - int numVerts; - int defgrp_index; int i; + /* Flags. */ const bool do_add = (wmd->edit_flags & MOD_WVG_EDIT_ADD2VG) != 0; const bool do_rem = (wmd->edit_flags & MOD_WVG_EDIT_REMFVG) != 0; @@ -176,30 +175,50 @@ static DerivedMesh *applyModifier(ModifierData *md, #endif /* Get number of verts. */ - numVerts = dm->getNumVerts(dm); + const int numVerts = mesh->totvert; /* Check if we can just return the original mesh. * Must have verts and therefore verts assigned to vgroups to do anything useful! */ - if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) - return dm; + if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) { + return mesh; + } /* Get vgroup idx from its name. */ - defgrp_index = defgroup_name_index(ctx->object, wmd->defgrp_name); - if (defgrp_index == -1) - return dm; + const int defgrp_index = defgroup_name_index(ctx->object, wmd->defgrp_name); + if (defgrp_index == -1) { + return mesh; + } - dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts); + const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT); /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ - if (!dvert) { + if (!has_mdef) { /* If this modifier is not allowed to add vertices, just return. */ - if (!do_add) - return dm; - /* Else, add a valid data layer! */ - dvert = CustomData_add_layer(&dm->vertData, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); - /* Ultimate security check. */ - if (!dvert) - return dm; + if (!do_add) { + return mesh; + } + } + + Mesh *result; + BKE_id_copy_ex( + NULL, &mesh->id, (ID **)&result, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG| + LIB_ID_COPY_NO_PREVIEW, + false); + + if (has_mdef) { + dvert = CustomData_get_layer(&result->vdata, CD_MDEFORMVERT); + } + else { + /* Add a valid data layer! */ + dvert = CustomData_add_layer(&result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); + } + /* Ultimate security check. */ + if (!dvert) { + BKE_id_free(NULL, result); + return mesh; } /* Get org weights, assuming 0.0 for vertices not in given vgroup. */ @@ -220,17 +239,19 @@ static DerivedMesh *applyModifier(ModifierData *md, if (wmd->falloff_type != MOD_WVG_MAPPING_NONE) { RNG *rng = NULL; - if (wmd->falloff_type == MOD_WVG_MAPPING_RANDOM) + if (wmd->falloff_type == MOD_WVG_MAPPING_RANDOM) { rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ctx->object->id.name + 2)); + } weightvg_do_map(numVerts, new_w, wmd->falloff_type, wmd->cmap_curve, rng); - if (rng) + if (rng) { BLI_rng_free(rng); + } } /* Do masking. */ - weightvg_do_mask(numVerts, NULL, org_w, new_w, ctx->object, dm, wmd->mask_constant, + weightvg_do_mask(numVerts, NULL, org_w, new_w, ctx->object, result, wmd->mask_constant, wmd->mask_defgrp_name, wmd->modifier.scene, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); @@ -251,7 +272,7 @@ static DerivedMesh *applyModifier(ModifierData *md, MEM_freeN(dw); /* Return the vgroup-modified mesh. */ - return dm; + return result; } @@ -271,14 +292,14 @@ ModifierTypeInfo modifierType_WeightVGEdit = { /* deformMatrices_DM */ NULL, /* deformVertsEM_DM */ NULL, /* deformMatricesEM_DM*/NULL, - /* applyModifier_DM */ applyModifier, + /* applyModifier_DM */ NULL, /* applyModifierEM_DM */NULL, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* applyModifier */ applyModifier, /* applyModifierEM */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index 9f32d5c6e30..2ea721c1982 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -32,11 +32,12 @@ #include "BLI_math.h" #include "BLI_listbase.h" +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" -#include "BKE_cdderivedmesh.h" +#include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_library.h" #include "BKE_library_query.h" @@ -201,15 +202,12 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams)) return (wmd->defgrp_name_a[0] == '\0'); } -static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, - DerivedMesh *derivedData) +static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md; - DerivedMesh *dm = derivedData; + MDeformVert *dvert = NULL; MDeformWeight **dw1, **tdw1, **dw2, **tdw2; - int numVerts; - int defgrp_index, defgrp_index_other = -1; float *org_w; float *new_w; int *tidx, *indices = NULL; @@ -221,37 +219,60 @@ static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *c #endif /* Get number of verts. */ - numVerts = dm->getNumVerts(dm); + const int numVerts = mesh->totvert; /* Check if we can just return the original mesh. * Must have verts and therefore verts assigned to vgroups to do anything useful! */ - if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) - return dm; + if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) { + return mesh; + } /* Get vgroup idx from its name. */ - defgrp_index = defgroup_name_index(ctx->object, wmd->defgrp_name_a); - if (defgrp_index == -1) - return dm; + const int defgrp_index = defgroup_name_index(ctx->object, wmd->defgrp_name_a); + if (defgrp_index == -1) { + return mesh; + } /* Get second vgroup idx from its name, if given. */ - if (wmd->defgrp_name_b[0] != (char)0) { + int defgrp_index_other = -1; + if (wmd->defgrp_name_b[0] != '\0') { defgrp_index_other = defgroup_name_index(ctx->object, wmd->defgrp_name_b); - if (defgrp_index_other == -1) - return dm; + if (defgrp_index_other == -1) { + return mesh; + } } - dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts); + const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT); /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ - if (!dvert) { + if (!has_mdef) { /* If not affecting all vertices, just return. */ - if (wmd->mix_set != MOD_WVG_SET_ALL) - return dm; - /* Else, add a valid data layer! */ - dvert = CustomData_add_layer(&dm->vertData, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); - /* Ultimate security check. */ - if (!dvert) - return dm; + if (wmd->mix_set != MOD_WVG_SET_ALL) { + return mesh; + } + } + + Mesh *result; + BKE_id_copy_ex( + NULL, &mesh->id, (ID **)&result, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG| + LIB_ID_COPY_NO_PREVIEW, + false); + + if (has_mdef) { + dvert = CustomData_get_layer(&result->vdata, CD_MDEFORMVERT); } + else { + /* Add a valid data layer! */ + dvert = CustomData_add_layer(&result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); + } + /* Ultimate security check. */ + if (!dvert) { + BKE_id_free(NULL, result); + return mesh; + } + /* Find out which vertices to work on. */ tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGMix Modifier, tidx"); tdw1 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw1"); @@ -318,7 +339,8 @@ static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *c MEM_freeN(tdw1); MEM_freeN(tdw2); MEM_freeN(tidx); - return dm; + BKE_id_free(NULL, result); + return mesh; } if (numIdx != -1) { indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGMix Modifier, indices"); @@ -352,7 +374,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *c } /* Do masking. */ - weightvg_do_mask(numIdx, indices, org_w, new_w, ctx->object, dm, wmd->mask_constant, + weightvg_do_mask(numIdx, indices, org_w, new_w, ctx->object, result, wmd->mask_constant, wmd->mask_defgrp_name, wmd->modifier.scene, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); @@ -373,12 +395,10 @@ static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *c MEM_freeN(new_w); MEM_freeN(dw1); MEM_freeN(dw2); - - if (indices) - MEM_freeN(indices); + MEM_SAFE_FREE(indices); /* Return the vgroup-modified mesh. */ - return dm; + return result; } @@ -398,14 +418,14 @@ ModifierTypeInfo modifierType_WeightVGMix = { /* deformMatrices_DM */ NULL, /* deformVertsEM_DM */ NULL, /* deformMatricesEM_DM*/NULL, - /* applyModifier_DM */ applyModifier, + /* applyModifier_DM */ NULL, /* applyModifierEM_DM */NULL, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* applyModifier */ applyModifier, /* applyModifierEM */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index b0416ed9f7a..85d647c3f41 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -41,9 +41,11 @@ #include "DNA_object_types.h" #include "BKE_cdderivedmesh.h" +#include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_library.h" #include "BKE_library_query.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_texture.h" /* Texture masking. */ @@ -53,6 +55,7 @@ #include "MOD_weightvg_util.h" #include "MOD_modifiertypes.h" +#include "MOD_util.h" //#define USE_TIMEIT @@ -137,7 +140,7 @@ static void vert2geom_task_cb_ex( */ static void get_vert2geom_distance(int numVerts, float (*v_cos)[3], float *dist_v, float *dist_e, float *dist_f, - DerivedMesh *target, const SpaceTransform *loc2trgt) + Mesh *target, const SpaceTransform *loc2trgt) { Vert2GeomData data = {0}; Vert2GeomDataChunk data_chunk = {{{0}}}; @@ -146,9 +149,12 @@ static void get_vert2geom_distance(int numVerts, float (*v_cos)[3], BVHTreeFromMesh treeData_e = {NULL}; BVHTreeFromMesh treeData_f = {NULL}; + /* XXX TODO horrible, but simpler for now, bvhtree needs some love first! */ + DerivedMesh *target_dm = CDDM_from_mesh(target); + if (dist_v) { /* Create a bvh-tree of the given target's verts. */ - bvhtree_from_mesh_get(&treeData_v, target, BVHTREE_FROM_VERTS, 2); + bvhtree_from_mesh_get(&treeData_v, target_dm, BVHTREE_FROM_VERTS, 2); if (treeData_v.tree == NULL) { OUT_OF_MEMORY(); return; @@ -156,7 +162,7 @@ static void get_vert2geom_distance(int numVerts, float (*v_cos)[3], } if (dist_e) { /* Create a bvh-tree of the given target's edges. */ - bvhtree_from_mesh_get(&treeData_e, target, BVHTREE_FROM_EDGES, 2); + bvhtree_from_mesh_get(&treeData_e, target_dm, BVHTREE_FROM_EDGES, 2); if (treeData_e.tree == NULL) { OUT_OF_MEMORY(); return; @@ -164,7 +170,7 @@ static void get_vert2geom_distance(int numVerts, float (*v_cos)[3], } if (dist_f) { /* Create a bvh-tree of the given target's faces. */ - bvhtree_from_mesh_get(&treeData_f, target, BVHTREE_FROM_LOOPTRI, 2); + bvhtree_from_mesh_get(&treeData_f, target_dm, BVHTREE_FROM_LOOPTRI, 2); if (treeData_f.tree == NULL) { OUT_OF_MEMORY(); return; @@ -197,6 +203,8 @@ static void get_vert2geom_distance(int numVerts, float (*v_cos)[3], free_bvhtree_from_mesh(&treeData_e); if (dist_f) free_bvhtree_from_mesh(&treeData_f); + + target_dm->release(target_dm); } /** @@ -257,13 +265,15 @@ static void do_map(Object *ob, float *weights, const int nidx, const float min_d if (!ELEM(mode, MOD_WVG_MAPPING_NONE, MOD_WVG_MAPPING_CURVE)) { RNG *rng = NULL; - if (mode == MOD_WVG_MAPPING_RANDOM) + if (mode == MOD_WVG_MAPPING_RANDOM) { rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ob->id.name + 2)); + } weightvg_do_map(nidx, weights, mode, NULL, rng); - if (rng) + if (rng) { BLI_rng_free(rng); + } } } @@ -368,14 +378,11 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams)) return (wmd->proximity_ob_target == NULL); } -static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, - DerivedMesh *derivedData) +static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md; - DerivedMesh *dm = derivedData; MDeformVert *dvert = NULL; MDeformWeight **dw, **tdw; - int numVerts; float (*v_cos)[3] = NULL; /* The vertices coordinates. */ Object *ob = ctx->object; Object *obr = NULL; /* Our target object. */ @@ -396,32 +403,57 @@ static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *c #endif /* Get number of verts. */ - numVerts = dm->getNumVerts(dm); + const int numVerts = mesh->totvert; /* Check if we can just return the original mesh. * Must have verts and therefore verts assigned to vgroups to do anything useful! */ - if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) - return dm; + if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) { + return mesh; + } /* Get our target object. */ obr = wmd->proximity_ob_target; - if (obr == NULL) - return dm; + if (obr == NULL) { + return mesh; + } /* Get vgroup idx from its name. */ defgrp_index = defgroup_name_index(ob, wmd->defgrp_name); - if (defgrp_index == -1) - return dm; + if (defgrp_index == -1) { + return mesh; + } - dvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MDEFORMVERT, numVerts); - /* If no vertices were ever added to an object's vgroup, dvert might be NULL. - * As this modifier never add vertices to vgroup, just return. */ - if (!dvert) - return dm; + const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT); + /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ + /* As this modifier never add vertices to vgroup, just return. */ + if (!has_mdef) { + return mesh; + } - /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. - */ + Mesh *result; + BKE_id_copy_ex( + NULL, &mesh->id, (ID **)&result, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG| + LIB_ID_COPY_NO_PREVIEW, + false); + + if (has_mdef) { + dvert = CustomData_get_layer(&result->vdata, CD_MDEFORMVERT); + } + else { + /* Add a valid data layer! */ + dvert = CustomData_add_layer(&result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts); + } + /* Ultimate security check. */ + if (!dvert) { + BKE_id_free(NULL, result); + return mesh; + } + + /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */ tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGProximity Modifier, tidx"); tw = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGProximity Modifier, tw"); tdw = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGProximity Modifier, tdw"); @@ -438,7 +470,8 @@ static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *c MEM_freeN(tidx); MEM_freeN(tw); MEM_freeN(tdw); - return dm; + BKE_id_free(NULL, result); + return mesh; } if (numIdx != numVerts) { indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGProximity Modifier, indices"); @@ -458,25 +491,24 @@ static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *c MEM_freeN(tidx); /* Get our vertex coordinates. */ - v_cos = MEM_malloc_arrayN(numIdx, sizeof(float[3]), "WeightVGProximity Modifier, v_cos"); if (numIdx != numVerts) { - /* XXX In some situations, this code can be up to about 50 times more performant - * than simply using getVertCo for each affected vertex... - */ - float (*tv_cos)[3] = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "WeightVGProximity Modifier, tv_cos"); - dm->getVertCos(dm, tv_cos); - for (i = 0; i < numIdx; i++) + float (*tv_cos)[3] = BKE_mesh_vertexCos_get(result, NULL); + v_cos = MEM_malloc_arrayN(numIdx, sizeof(float[3]), "WeightVGProximity Modifier, v_cos"); + for (i = 0; i < numIdx; i++) { copy_v3_v3(v_cos[i], tv_cos[indices[i]]); + } MEM_freeN(tv_cos); } - else - dm->getVertCos(dm, v_cos); + else { + v_cos = BKE_mesh_vertexCos_get(result, NULL); + } /* Compute wanted distances. */ if (wmd->proximity_mode == MOD_WVG_PROXIMITY_OBJECT) { const float dist = get_ob2ob_distance(ob, obr); - for (i = 0; i < numIdx; i++) + for (i = 0; i < numIdx; i++) { new_w[i] = dist; + } } else if (wmd->proximity_mode == MOD_WVG_PROXIMITY_GEOMETRY) { const bool use_trgt_verts = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_VERTS) != 0; @@ -484,23 +516,10 @@ static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *c const bool use_trgt_faces = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_FACES) != 0; if (use_trgt_verts || use_trgt_edges || use_trgt_faces) { - DerivedMesh *target_dm = obr->derivedFinal; - bool free_target_dm = false; - if (!target_dm) { - if (ELEM(obr->type, OB_CURVE, OB_SURF, OB_FONT)) - target_dm = CDDM_from_curve(obr); - else if (obr->type == OB_MESH) { - Mesh *me = (Mesh *)obr->data; - if (me->edit_btmesh) - target_dm = CDDM_from_editbmesh(me->edit_btmesh, false, false); - else - target_dm = CDDM_from_mesh(me); - } - free_target_dm = true; - } + Mesh *target_mesh = get_mesh_eval_for_modifier(obr, ctx->flag); - /* We must check that we do have a valid target_dm! */ - if (target_dm) { + /* We must check that we do have a valid target_mesh! */ + if (target_mesh) { SpaceTransform loc2trgt; float *dists_v = use_trgt_verts ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_v") : NULL; float *dists_e = use_trgt_edges ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_e") : NULL; @@ -508,7 +527,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *c BLI_SPACE_TRANSFORM_SETUP(&loc2trgt, ob, obr); get_vert2geom_distance(numIdx, v_cos, dists_v, dists_e, dists_f, - target_dm, &loc2trgt); + target_mesh, &loc2trgt); for (i = 0; i < numIdx; i++) { new_w[i] = dists_v ? dists_v[i] : FLT_MAX; if (dists_e) @@ -516,10 +535,10 @@ static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *c if (dists_f) new_w[i] = min_ff(dists_f[i], new_w[i]); } - if (free_target_dm) target_dm->release(target_dm); - if (dists_v) MEM_freeN(dists_v); - if (dists_e) MEM_freeN(dists_e); - if (dists_f) MEM_freeN(dists_f); + + MEM_SAFE_FREE(dists_v); + MEM_SAFE_FREE(dists_e); + MEM_SAFE_FREE(dists_f); } /* Else, fall back to default obj2vert behavior. */ else { @@ -535,7 +554,7 @@ static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *c do_map(ob, new_w, numIdx, wmd->min_dist, wmd->max_dist, wmd->falloff_type); /* Do masking. */ - weightvg_do_mask(numIdx, indices, org_w, new_w, ob, dm, wmd->mask_constant, + weightvg_do_mask(numIdx, indices, org_w, new_w, ob, result, wmd->mask_constant, wmd->mask_defgrp_name, wmd->modifier.scene, wmd->mask_texture, wmd->mask_tex_use_channel, wmd->mask_tex_mapping, wmd->mask_tex_map_obj, wmd->mask_tex_uvlayer_name); @@ -553,16 +572,15 @@ static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *c MEM_freeN(org_w); MEM_freeN(new_w); MEM_freeN(dw); - if (indices) - MEM_freeN(indices); MEM_freeN(v_cos); + MEM_SAFE_FREE(indices); #ifdef USE_TIMEIT TIMEIT_END(perf); #endif /* Return the vgroup-modified mesh. */ - return dm; + return result; } @@ -582,14 +600,14 @@ ModifierTypeInfo modifierType_WeightVGProximity = { /* deformMatrices_DM */ NULL, /* deformVertsEM_DM */ NULL, /* deformMatricesEM_DM*/NULL, - /* applyModifier_DM */ applyModifier, + /* applyModifier_DM */ NULL, /* applyModifierEM_DM */NULL, /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* applyModifier */ applyModifier, /* applyModifierEM */ NULL, /* initData */ initData, |