diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/armature/meshlaplacian.c | 6 | ||||
-rw-r--r-- | source/blender/editors/include/ED_armature.h | 1 | ||||
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 49 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_meshdeform.c | 55 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_surfacedeform.c | 2 |
6 files changed, 54 insertions, 61 deletions
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 001c8ce215f..96799304845 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1427,7 +1427,7 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind EIG_linear_solver_delete(context); } -static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierData *mmd, MeshDeformBind *mdb) +static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBind *mdb) { MDefBindInfluence *inf; MDefInfluence *mdinf; @@ -1578,7 +1578,7 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa } void ED_mesh_deform_bind_callback( - Scene *scene, MeshDeformModifierData *mmd, Mesh *cagemesh, + MeshDeformModifierData *mmd, Mesh *cagemesh, float *vertexcos, int totvert, float cagemat[4][4]) { MeshDeformBind mdb; @@ -1606,7 +1606,7 @@ void ED_mesh_deform_bind_callback( mul_v3_m4v3(mdb.vertexcos[a], mdb.cagemat, vertexcos + a * 3); /* solve */ - harmonic_coordinates_bind(scene, mmd, &mdb); + harmonic_coordinates_bind(mmd, &mdb); /* assign bind variables */ mmd->bindcagecos = (float *)mdb.cagecos; diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index d5698ecadf7..3131e5221d8 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -238,7 +238,6 @@ struct Object *ED_pose_object_from_context(struct bContext *C); /* meshlaplacian.c */ void ED_mesh_deform_bind_callback( - struct Scene *scene, struct MeshDeformModifierData *mmd, struct Mesh *cagemesh, float *vertexcos, int totvert, float cagemat[4][4]); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 7b4fba23551..200ff1ab0d6 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -1944,52 +1944,41 @@ static bool meshdeform_poll(bContext *C) static int meshdeform_bind_exec(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); Depsgraph *depsgraph = CTX_data_depsgraph(C); + Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); MeshDeformModifierData *mmd = (MeshDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_MeshDeform); - if (!mmd) + if (mmd == NULL) { return OPERATOR_CANCELLED; + } - if (mmd->bindcagecos) { - MEM_freeN(mmd->bindcagecos); - if (mmd->dyngrid) MEM_freeN(mmd->dyngrid); - if (mmd->dyninfluences) MEM_freeN(mmd->dyninfluences); - if (mmd->bindinfluences) MEM_freeN(mmd->bindinfluences); - if (mmd->bindoffsets) MEM_freeN(mmd->bindoffsets); - if (mmd->dynverts) MEM_freeN(mmd->dynverts); - if (mmd->bindweights) MEM_freeN(mmd->bindweights); /* deprecated */ - if (mmd->bindcos) MEM_freeN(mmd->bindcos); /* deprecated */ - - mmd->bindcagecos = NULL; - mmd->dyngrid = NULL; - mmd->dyninfluences = NULL; - mmd->bindinfluences = NULL; - mmd->bindoffsets = NULL; - mmd->dynverts = NULL; - mmd->bindweights = NULL; /* deprecated */ - mmd->bindcos = NULL; /* deprecated */ + if (mmd->bindcagecos != NULL) { + MEM_SAFE_FREE(mmd->bindcagecos); + MEM_SAFE_FREE(mmd->dyngrid); + MEM_SAFE_FREE(mmd->dyninfluences); + MEM_SAFE_FREE(mmd->bindinfluences); + MEM_SAFE_FREE(mmd->bindoffsets); + MEM_SAFE_FREE(mmd->dynverts); + MEM_SAFE_FREE(mmd->bindweights); /* Deprecated */ + MEM_SAFE_FREE(mmd->bindcos); /* Deprecated */ mmd->totvert = 0; mmd->totcagevert = 0; mmd->totinfluence = 0; } else { - int mode = mmd->modifier.mode; - mmd->bindfunc = ED_mesh_deform_bind_callback; + /* Force modifier to run, it will call binding routine (this has to happen outside of depsgraph evaluation). */ + const int mode = mmd->modifier.mode; mmd->modifier.mode |= eModifierMode_Realtime; - - /* Force depsgraph update, this will do binding. */ - DEG_id_tag_update(&ob->id, OB_RECALC_DATA); - BKE_scene_graph_update_tagged(depsgraph, bmain); - - mmd->bindfunc = NULL; + mmd->bindfunc = ED_mesh_deform_bind_callback; + object_force_modifier_update_for_bind(depsgraph, scene, ob); mmd->modifier.mode = mode; + mmd->bindfunc = NULL; } - DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + /* We need DEG_TAG_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */ + DEG_id_tag_update(&ob->id, DEG_TAG_GEOMETRY | DEG_TAG_COPY_ON_WRITE); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); - return OPERATOR_FINISHED; } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 1d8df99af7a..345958ce397 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -770,7 +770,7 @@ typedef struct MeshDeformModifierData { float *bindcos; /* deprecated storage of cage coords */ /* runtime */ - void (*bindfunc)(struct Scene *scene, struct MeshDeformModifierData *mmd, struct Mesh *cagemesh, + void (*bindfunc)(struct MeshDeformModifierData *mmd, struct Mesh *cagemesh, float *vertexcos, int totvert, float cagemat[4][4]); } MeshDeformModifierData; 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); } diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index 5a2b54824cc..6c6cbe3a538 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -1126,7 +1126,7 @@ static void surfacedeformModifier_do( } target = BKE_modifier_get_evaluated_mesh_from_evaluated_object(smd->target, &free_target); - if (!target && smd->verts == NULL && ob == DEG_get_original_object(ob)) { + if (target == NULL && smd->verts == 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. */ target = mesh_create_eval_final_view(ctx->depsgraph, DEG_get_input_scene(ctx->depsgraph), smd->target, 0); |