Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2018-12-07 13:17:25 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2018-12-07 13:22:31 +0300
commit989fbff16f49204ca31a67f56f87c2221e0246f4 (patch)
treeee4109fb816cd7d23a3dd8900d6482166b485b81 /source/blender/modifiers/intern/MOD_meshdeform.c
parent41e4059f3c41234016dfabf6b3ae9e40c735483e (diff)
Cleanup/refactor binding code for MeshDeform modifier.
We had two different ways of doing it, SurfaceDeform and LaplacianDeform would do it through a special modifier stack evaluation triggered from binding operator, while MeshDeform would do it through a regular depsgraph update/eval (also triggered from its binding op). This enforces the later to search back for orig modifier data inside modifier code (to apply binding on that one, and not on useless CoW one). Besides the question of safety about modifying orig data from threaded despgraph (that was *probably* OK, but think it's bad idea in general), it's much better to have a common way of doing that kind of things. For now it remains rather dodgy, but at least it's reasonably consistent and safe now. This commit also fixes a potential memleak from binding process of MeshDeform, and does some general cleanup a bit.
Diffstat (limited to 'source/blender/modifiers/intern/MOD_meshdeform.c')
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c55
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);
}