diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_meshdeform.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_meshdeform.c | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 9af76916788..d3450e61709 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -45,6 +45,7 @@ #include "BKE_library.h" #include "BKE_library_query.h" #include "BKE_mesh.h" +#include "BKE_mesh_runtime.h" #include "BKE_modifier.h" #include "BKE_deform.h" #include "BKE_editmesh.h" @@ -286,12 +287,14 @@ static void meshdeformModifier_do( 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]; + float co[3], (*dco)[3] = NULL, (*bindcagecos)[3]; int a, totvert, totcagevert, defgrp_index; - float (*cagecos)[3]; + float (*cagecos)[3] = NULL; MeshdeformUserdata data; bool free_cagemesh = false; + static int recursive_bind_sentinel = 0; + if (!mmd->object || (!mmd->bindcagecos && !mmd->bindfunc)) return; @@ -306,6 +309,12 @@ static void meshdeformModifier_do( * We'll support this case once granular dependency graph is landed. */ cagemesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(mmd->object, &free_cagemesh); + if (cagemesh == NULL && mmd->bindcagecos == NULL && ob == DEG_get_original_object(ob)) { + /* Special case, binding happens outside of depsgraph evaluation, so we can build our own + * target mesh if needed. */ + cagemesh = mesh_create_eval_final_view(ctx->depsgraph, DEG_get_input_scene(ctx->depsgraph), mmd->object, 0); + free_cagemesh = cagemesh != NULL; + } if (cagemesh == NULL) { modifier_setError(md, "Cannot get mesh from cage object"); @@ -321,22 +330,20 @@ static void meshdeformModifier_do( /* bind weights if needed */ if (!mmd->bindcagecos) { - static int recursive = 0; - /* progress bar redraw can make this recursive .. */ - if (!recursive) { - /* Write binding data to original modifier. */ - Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); - Object *ob_orig = DEG_get_original_object(ob); - MeshDeformModifierData *mmd_orig = (MeshDeformModifierData *)modifiers_findByName( - ob_orig, mmd->modifier.name); - - recursive = 1; - mmd->bindfunc(scene, mmd_orig, cagemesh, (float *)vertexCos, numVerts, cagemat); - recursive = 0; + if (!recursive_bind_sentinel) { + if (ob != DEG_get_original_object(ob)) { + BLI_assert(!"Trying to bind inside of depsgraph evaluation"); + modifier_setError(md, "Trying to bind inside of depsgraph evaluation"); + goto finally; + } + + recursive_bind_sentinel = 1; + mmd->bindfunc(mmd, cagemesh, (float *)vertexCos, numVerts, cagemat); + recursive_bind_sentinel = 0; } - return; + goto finally; } /* verify we have compatible weights */ @@ -345,18 +352,15 @@ static void meshdeformModifier_do( if (mmd->totvert != totvert) { modifier_setError(md, "Verts changed from %d to %d", mmd->totvert, totvert); - if (free_cagemesh) BKE_id_free(NULL, cagemesh); - return; + goto finally; } else if (mmd->totcagevert != totcagevert) { modifier_setError(md, "Cage verts changed from %d to %d", mmd->totcagevert, totcagevert); - if (free_cagemesh) BKE_id_free(NULL, cagemesh); - return; + goto finally; } else if (mmd->bindcagecos == NULL) { modifier_setError(md, "Bind data missing"); - if (free_cagemesh) BKE_id_free(NULL, cagemesh); - return; + goto finally; } /* setup deformation data */ @@ -377,8 +381,9 @@ static void meshdeformModifier_do( /* compute difference with world space bind coord */ sub_v3_v3v3(dco[a], co, bindcagecos[a]); } - else + else { copy_v3_v3(dco[a], co); + } } MOD_get_vgroup(ob, mesh, mmd->defgrp_name, &dvert, &defgrp_index); @@ -401,9 +406,9 @@ static void meshdeformModifier_do( meshdeform_vert_task, &settings); - /* release cage mesh */ - MEM_freeN(dco); - MEM_freeN(cagecos); +finally: + MEM_SAFE_FREE(dco); + MEM_SAFE_FREE(cagecos); if (cagemesh != NULL && free_cagemesh) { BKE_id_free(NULL, cagemesh); } |