diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-05-08 12:33:31 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-05-08 12:46:28 +0300 |
commit | 1c0be0e90fb17775ca4fdbe91cc0fb377dd446d7 (patch) | |
tree | 45c933937aa284b01a82a3af73fac8bf0cedea05 /source/blender/modifiers/intern | |
parent | abb58eec5393820ee990926915c176664e205bab (diff) |
Ported Mesh Deform modifier
This modifier still has issues that are not related to this port:
- While editing the deformation mesh, the deformed mesh doesn't update.
This update only happens after exiting edit mode, making editing
cumbersome.
- Binding doesn't work yet. It works fine when binding in master and
loading pre-bound in 2.8. This was also an issue before this port, and
will be investigated separately.
Diffstat (limited to 'source/blender/modifiers/intern')
-rw-r--r-- | source/blender/modifiers/intern/MOD_meshdeform.c | 80 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_util.c | 45 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_util.h | 2 |
3 files changed, 89 insertions, 38 deletions
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 8b25d192f7f..de3c3d94ad0 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -32,6 +32,7 @@ * \ingroup modifiers */ +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -40,9 +41,10 @@ #include "BLI_task.h" #include "BLI_utildefines.h" -#include "BKE_cdderivedmesh.h" #include "BKE_global.h" +#include "BKE_library.h" #include "BKE_library_query.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_deform.h" #include "BKE_editmesh.h" @@ -273,17 +275,18 @@ static void meshdeform_vert_task( } static void meshdeformModifier_do( - ModifierData *md, struct Depsgraph *depsgraph, Object *ob, DerivedMesh *dm, + ModifierData *md, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts) { MeshDeformModifierData *mmd = (MeshDeformModifierData *) md; - DerivedMesh *tmpdm, *cagedm; + Mesh *cagemesh; MDeformVert *dvert = NULL; float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4]; float co[3], (*dco)[3], (*bindcagecos)[3]; int a, totvert, totcagevert, defgrp_index; float (*cagecos)[3]; MeshdeformUserdata data; + bool free_cagemesh = false; if (!mmd->object || (!mmd->bindcagecos && !mmd->bindfunc)) return; @@ -299,23 +302,24 @@ static void meshdeformModifier_do( * We'll support this case once granular dependency graph is landed. */ if (mmd->object->mode & OB_MODE_EDIT) { - BMEditMesh *em = BKE_editmesh_from_object(mmd->object); - tmpdm = editbmesh_get_derived_cage_and_final(depsgraph, md->scene, mmd->object, em, 0, &cagedm); - if (tmpdm) - tmpdm->release(tmpdm); + /* TODO(Sybren): do we need to check the modifier mode in this case? */ + /* TODO(Sybren): should we get from BMEditMesh *em = BKE_editmesh_from_object(mmd->object) instead? */ + cagemesh = get_mesh_eval_for_modifier(ob, md->mode & eModifierMode_Render ? MOD_APPLY_RENDER : 0); + } + else { + cagemesh = get_mesh_eval_for_modifier(ob, md->mode & eModifierMode_Render ? MOD_APPLY_RENDER : 0); } - else - cagedm = mmd->object->derivedFinal; /* if we don't have one computed, use derivedmesh from data * without any modifiers */ - if (!cagedm) { - cagedm = get_dm(mmd->object, NULL, NULL, NULL, false, false); - if (cagedm) - cagedm->needsFree = 1; + if (!cagemesh) { + cagemesh = get_mesh(mmd->object, NULL, NULL, NULL, false, false); + if (cagemesh) { + free_cagemesh = true; + } } - if (!cagedm) { + if (!cagemesh) { modifier_setError(md, "Cannot get mesh from cage object"); return; } @@ -334,35 +338,33 @@ static void meshdeformModifier_do( /* progress bar redraw can make this recursive .. */ if (!recursive) { recursive = 1; - mmd->bindfunc(md->scene, mmd, cagedm, (float *)vertexCos, numVerts, cagemat); + mmd->bindfunc(md->scene, mmd, cagemesh, (float *)vertexCos, numVerts, cagemat); recursive = 0; } } /* verify we have compatible weights */ totvert = numVerts; - totcagevert = cagedm->getNumVerts(cagedm); + totcagevert = cagemesh->totvert; if (mmd->totvert != totvert) { modifier_setError(md, "Verts changed from %d to %d", mmd->totvert, totvert); - cagedm->release(cagedm); + if (free_cagemesh) BKE_id_free(NULL, cagemesh); return; } else if (mmd->totcagevert != totcagevert) { modifier_setError(md, "Cage verts changed from %d to %d", mmd->totcagevert, totcagevert); - cagedm->release(cagedm); + if (free_cagemesh) BKE_id_free(NULL, cagemesh); return; } else if (mmd->bindcagecos == NULL) { modifier_setError(md, "Bind data missing"); - cagedm->release(cagedm); + if (free_cagemesh) BKE_id_free(NULL, cagemesh); return; } - cagecos = MEM_malloc_arrayN(totcagevert, sizeof(*cagecos), "meshdeformModifier vertCos"); - /* setup deformation data */ - cagedm->getVertCos(cagedm, cagecos); + cagecos = BKE_mesh_vertexCos_get(cagemesh, NULL); bindcagecos = (float(*)[3])mmd->bindcagecos; /* We allocate 1 element extra to make it possible to @@ -383,7 +385,7 @@ static void meshdeformModifier_do( copy_v3_v3(dco[a], co); } - modifier_get_vgroup(ob, dm, mmd->defgrp_name, &dvert, &defgrp_index); + modifier_get_vgroup_mesh(ob, mesh, mmd->defgrp_name, &dvert, &defgrp_index); /* Initialize data to be pass to the for body function. */ data.mmd = mmd; @@ -406,36 +408,38 @@ static void meshdeformModifier_do( /* release cage derivedmesh */ MEM_freeN(dco); MEM_freeN(cagecos); - cagedm->release(cagedm); + if (free_cagemesh) BKE_id_free(NULL, cagemesh); } static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, - DerivedMesh *derivedData, + Mesh *mesh, float (*vertexCos)[3], int numVerts) { - DerivedMesh *dm = get_dm(ctx->object, NULL, derivedData, NULL, false, false); + Mesh *mesh_src = get_mesh(ctx->object, NULL, mesh, NULL, false, false); modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */ - meshdeformModifier_do(md, ctx->depsgraph, ctx->object, dm, vertexCos, numVerts); + meshdeformModifier_do(md, ctx->object, mesh, vertexCos, numVerts); - if (dm && dm != derivedData) - dm->release(dm); + if (mesh_src && mesh_src != mesh) { + BKE_id_free(NULL, mesh_src); + } } static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *UNUSED(editData), - DerivedMesh *derivedData, + Mesh *mesh, float (*vertexCos)[3], int numVerts) { - DerivedMesh *dm = get_dm(ctx->object, NULL, derivedData, NULL, false, false); + Mesh *mesh_src = get_mesh(ctx->object, NULL, mesh, NULL, false, false); - meshdeformModifier_do(md, ctx->depsgraph, ctx->object, dm, vertexCos, numVerts); + meshdeformModifier_do(md, ctx->object, mesh, vertexCos, numVerts); - if (dm && dm != derivedData) - dm->release(dm); + if (mesh_src && mesh_src != mesh) { + BKE_id_free(NULL, mesh_src); + } } #define MESHDEFORM_MIN_INFLUENCE 0.00001f @@ -512,16 +516,16 @@ ModifierTypeInfo modifierType_MeshDeform = { /* copyData */ copyData, - /* deformVerts_DM */ deformVerts, + /* deformVerts_DM */ NULL, /* deformMatrices_DM */ NULL, - /* deformVertsEM_DM */ deformVertsEM, + /* deformVertsEM_DM */ NULL, /* deformMatricesEM_DM*/NULL, /* applyModifier_DM */ NULL, /* applyModifierEM_DM */NULL, - /* deformVerts */ NULL, + /* deformVerts */ deformVerts, /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, + /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* applyModifier */ NULL, /* applyModifierEM */ NULL, diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index a5e4a33b791..fd3f9e91b9e 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -46,8 +46,10 @@ #include "BKE_cdderivedmesh.h" #include "BKE_deform.h" +#include "BKE_editmesh.h" #include "BKE_image.h" #include "BKE_lattice.h" +#include "BKE_library.h" #include "BKE_mesh.h" #include "BKE_modifier.h" @@ -57,6 +59,8 @@ #include "MEM_guardedalloc.h" +#include "bmesh.h" + void modifier_init_texture(const Scene *scene, Tex *tex) { if (!tex) @@ -281,6 +285,47 @@ DerivedMesh *get_dm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, return dm; } +/* returns a mesh if mesh == NULL, for deforming modifiers that need it */ +Mesh *get_mesh(Object *ob, struct BMEditMesh *em, Mesh *mesh, + float (*vertexCos)[3], bool use_normals, bool use_orco) +{ + if (mesh) { + /* pass */ + } + else if (ob->type == OB_MESH) { + struct BMeshToMeshParams bmtmp = {0}; + if (em) mesh = BKE_bmesh_to_mesh_nomain(em->bm, &bmtmp); + else { + BKE_id_copy_ex(NULL, ob->data, (ID **)&mesh, + LIB_ID_CREATE_NO_MAIN | + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_DEG_TAG, + false); + } + + if (vertexCos) { + BKE_mesh_apply_vert_coords(mesh, vertexCos); + mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL; + } + + if (use_orco) { + CustomData_add_layer(&mesh->vdata, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob), mesh->totvert); + } + } + else if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { + /* TODO(sybren): get evaluated mesh from depsgraph once that's properly generated for curves. */ + mesh = BKE_new_mesh_nomain_from_curve(ob); + } + + if (use_normals) { + if (LIKELY(mesh)) { + BKE_mesh_ensure_normals(mesh); + } + } + + return mesh; +} + /* Get derived mesh for other object, which is used as an operand for the modifier, * i.e. second operand for boolean modifier. */ diff --git a/source/blender/modifiers/intern/MOD_util.h b/source/blender/modifiers/intern/MOD_util.h index 4ac864a17ef..c3858084354 100644 --- a/source/blender/modifiers/intern/MOD_util.h +++ b/source/blender/modifiers/intern/MOD_util.h @@ -54,6 +54,8 @@ struct DerivedMesh *get_cddm(struct Object *ob, struct BMEditMesh *em, struct De float (*vertexCos)[3], bool use_normals); struct DerivedMesh *get_dm(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3], bool use_normals, bool use_orco); +struct Mesh *get_mesh(struct Object *ob, struct BMEditMesh *em, struct Mesh *mesh, + float (*vertexCos)[3], bool use_normals, bool use_orco); struct DerivedMesh *get_dm_for_modifier(struct Object *ob, ModifierApplyFlag flag); struct Mesh *get_mesh_eval_for_modifier(struct Object *ob, ModifierApplyFlag flag); |