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:
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);
}