Fix T63252: Bind in Mesh Deform Modifier fails
A regression since 64c8d72ef1
.
The solution is to force modifier evaluation for an evaluated
object, and let it to copy binding data back to original when
is being evaluated for binding.
Reviewers: brecht
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D4642
This commit is contained in:
parent
c81eca3d98
commit
59f6371a85
Notes:
blender-bot
2023-02-14 06:42:54 +01:00
Referenced by issue #63252, Bind in Mesh Deform Modifier fails
|
@ -403,6 +403,16 @@ void modifier_path_init(char *path, int path_maxlen, const char *name);
|
|||
const char *modifier_path_relbase(struct Main *bmain, struct Object *ob);
|
||||
const char *modifier_path_relbase_from_global(struct Object *ob);
|
||||
|
||||
/* Accessors of original/evaluated modifiers. */
|
||||
|
||||
/* For a given modifier data, get corresponding original one.
|
||||
* If the modifier data is already original, return it as-is. */
|
||||
struct ModifierData *modifier_get_original(struct ModifierData *md);
|
||||
struct ModifierData *modifier_get_evaluated(
|
||||
struct Depsgraph* depsgraph,
|
||||
struct Object *object,
|
||||
struct ModifierData *md);
|
||||
|
||||
/* wrappers for modifier callbacks that ensure valid normals */
|
||||
|
||||
struct Mesh *modwrap_applyModifier(
|
||||
|
|
|
@ -885,3 +885,23 @@ Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval, con
|
|||
|
||||
return me;
|
||||
}
|
||||
|
||||
ModifierData *modifier_get_original(ModifierData *md)
|
||||
{
|
||||
if (md->orig_modifier_data == NULL) {
|
||||
return md;
|
||||
}
|
||||
return md->orig_modifier_data;
|
||||
}
|
||||
|
||||
struct ModifierData *modifier_get_evaluated(
|
||||
Depsgraph* depsgraph,
|
||||
Object *object,
|
||||
ModifierData *md)
|
||||
{
|
||||
Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
|
||||
if (object_eval == object) {
|
||||
return md;
|
||||
}
|
||||
return modifiers_findByName(object_eval, md->name);
|
||||
}
|
||||
|
|
|
@ -1577,6 +1577,8 @@ void ED_mesh_deform_bind_callback(
|
|||
MeshDeformModifierData *mmd, Mesh *cagemesh,
|
||||
float *vertexcos, int totvert, float cagemat[4][4])
|
||||
{
|
||||
MeshDeformModifierData *mmd_orig =
|
||||
(MeshDeformModifierData *)modifier_get_original(&mmd->modifier);
|
||||
MeshDeformBind mdb;
|
||||
MVert *mvert;
|
||||
int a;
|
||||
|
@ -1602,23 +1604,23 @@ void ED_mesh_deform_bind_callback(
|
|||
mul_v3_m4v3(mdb.vertexcos[a], mdb.cagemat, vertexcos + a * 3);
|
||||
|
||||
/* solve */
|
||||
harmonic_coordinates_bind(mmd, &mdb);
|
||||
harmonic_coordinates_bind(mmd_orig, &mdb);
|
||||
|
||||
/* assign bind variables */
|
||||
mmd->bindcagecos = (float *)mdb.cagecos;
|
||||
mmd->totvert = mdb.totvert;
|
||||
mmd->totcagevert = mdb.totcagevert;
|
||||
copy_m4_m4(mmd->bindmat, mmd->object->obmat);
|
||||
mmd_orig->bindcagecos = (float *)mdb.cagecos;
|
||||
mmd_orig->totvert = mdb.totvert;
|
||||
mmd_orig->totcagevert = mdb.totcagevert;
|
||||
copy_m4_m4(mmd_orig->bindmat, mmd_orig->object->obmat);
|
||||
|
||||
/* transform bindcagecos to world space */
|
||||
for (a = 0; a < mdb.totcagevert; a++)
|
||||
mul_m4_v3(mmd->object->obmat, mmd->bindcagecos + a * 3);
|
||||
mul_m4_v3(mmd_orig->object->obmat, mmd_orig->bindcagecos + a * 3);
|
||||
|
||||
/* free */
|
||||
MEM_freeN(mdb.vertexcos);
|
||||
|
||||
/* compact weights */
|
||||
modifier_mdef_compact_influences((ModifierData *)mmd);
|
||||
modifier_mdef_compact_influences((ModifierData *)mmd_orig);
|
||||
|
||||
end_progress_bar();
|
||||
waitcursor(0);
|
||||
|
|
|
@ -93,23 +93,38 @@ static void modifier_skin_customdata_delete(struct Object *ob);
|
|||
|
||||
/******************************** API ****************************/
|
||||
|
||||
static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Scene *scene, Object *ob)
|
||||
static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object *ob)
|
||||
{
|
||||
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
|
||||
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
|
||||
BKE_object_eval_reset(ob_eval);
|
||||
if (ob->type == OB_MESH) {
|
||||
Mesh *me_eval = mesh_create_eval_final_view(depsgraph, scene, ob, &CD_MASK_BAREMESH);
|
||||
Mesh *me_eval = mesh_create_eval_final_view(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
|
||||
BKE_id_free(NULL, me_eval);
|
||||
}
|
||||
else if (ob->type == OB_LATTICE) {
|
||||
BKE_lattice_modifiers_calc(depsgraph, scene, ob);
|
||||
BKE_lattice_modifiers_calc(depsgraph, scene_eval, ob_eval);
|
||||
}
|
||||
else if (ob->type == OB_MBALL) {
|
||||
BKE_displist_make_mball(depsgraph, scene, ob);
|
||||
BKE_displist_make_mball(depsgraph, scene_eval, ob_eval);
|
||||
}
|
||||
else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
|
||||
BKE_displist_make_curveTypes(depsgraph, scene, ob, false, false, NULL);
|
||||
BKE_displist_make_curveTypes(depsgraph, scene_eval, ob_eval, false, false, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void object_force_modifier_bind_simple_options(
|
||||
Depsgraph *depsgraph,
|
||||
Object *object,
|
||||
ModifierData *md)
|
||||
{
|
||||
ModifierData *md_eval = (ModifierData *)modifier_get_evaluated(depsgraph, object, md);
|
||||
const int mode = md_eval->mode;
|
||||
md_eval->mode |= eModifierMode_Realtime;
|
||||
object_force_modifier_update_for_bind(depsgraph, object);
|
||||
md_eval->mode = mode;
|
||||
}
|
||||
|
||||
ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
|
||||
{
|
||||
ModifierData *md = NULL, *new_md = NULL;
|
||||
|
@ -1926,19 +1941,17 @@ static int correctivesmooth_bind_exec(bContext *C, wmOperator *op)
|
|||
csmd->bind_coords_num = 0;
|
||||
}
|
||||
else {
|
||||
/* signal to modifier to recalculate */
|
||||
csmd->bind_coords_num = (unsigned int)-1;
|
||||
/* Signal to modifier to recalculate. */
|
||||
CorrectiveSmoothModifierData *csmd_eval =
|
||||
(CorrectiveSmoothModifierData *)modifier_get_evaluated(depsgraph, ob, &csmd->modifier);
|
||||
csmd_eval->bind_coords_num = (unsigned int)-1;
|
||||
|
||||
/* Force modifier to run, it will call binding routine
|
||||
* (this has to happen outside of depsgraph evaluation). */
|
||||
const int mode = csmd->modifier.mode;
|
||||
csmd->modifier.mode |= eModifierMode_Realtime;
|
||||
object_force_modifier_update_for_bind(depsgraph, scene, ob);
|
||||
csmd->modifier.mode = mode;
|
||||
object_force_modifier_bind_simple_options(depsgraph, ob, &csmd->modifier);
|
||||
}
|
||||
|
||||
/* We need ID_RECALC_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -1979,7 +1992,6 @@ static bool meshdeform_poll(bContext *C)
|
|||
static int meshdeform_bind_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
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);
|
||||
|
||||
|
@ -2002,16 +2014,14 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
else {
|
||||
/* 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;
|
||||
mmd->bindfunc = ED_mesh_deform_bind_callback;
|
||||
object_force_modifier_update_for_bind(depsgraph, scene, ob);
|
||||
mmd->modifier.mode = mode;
|
||||
mmd->bindfunc = NULL;
|
||||
MeshDeformModifierData *mmd_eval =
|
||||
(MeshDeformModifierData *)modifier_get_evaluated(depsgraph, ob, &mmd->modifier);
|
||||
mmd_eval->bindfunc = ED_mesh_deform_bind_callback;
|
||||
object_force_modifier_bind_simple_options(depsgraph, ob, &mmd->modifier);
|
||||
mmd_eval->bindfunc = NULL;
|
||||
}
|
||||
|
||||
/* We need ID_RECALC_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
@ -2188,7 +2198,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
|
|||
|
||||
if (free) {
|
||||
BKE_ocean_free_modifier_cache(omd);
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
@ -2288,7 +2298,6 @@ static bool laplaciandeform_poll(bContext *C)
|
|||
|
||||
static int laplaciandeform_bind_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *ob = ED_object_active_context(C);
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph(C);
|
||||
LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_LaplacianDeform);
|
||||
|
@ -2304,15 +2313,25 @@ static int laplaciandeform_bind_exec(bContext *C, wmOperator *op)
|
|||
lmd->flag |= MOD_LAPLACIANDEFORM_BIND;
|
||||
}
|
||||
|
||||
LaplacianDeformModifierData *lmd_eval =
|
||||
(LaplacianDeformModifierData *)modifier_get_evaluated(depsgraph, ob, &lmd->modifier);
|
||||
lmd_eval->flag = lmd->flag;
|
||||
|
||||
/* Force modifier to run, it will call binding routine
|
||||
* (this has to happen outside of depsgraph evaluation). */
|
||||
const int mode = lmd->modifier.mode;
|
||||
lmd->modifier.mode |= eModifierMode_Realtime;
|
||||
object_force_modifier_update_for_bind(depsgraph, scene, ob);
|
||||
lmd->modifier.mode = mode;
|
||||
object_force_modifier_bind_simple_options(depsgraph, ob, &lmd->modifier);
|
||||
|
||||
/* We need ID_RECALC_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
|
||||
/* This is hard to know from the modifier itself whether the evaluation is
|
||||
* happening for binding or not. So we copy all the required data here. */
|
||||
lmd->total_verts = lmd_eval->total_verts;
|
||||
if (lmd_eval->vertexco == NULL) {
|
||||
MEM_SAFE_FREE(lmd->vertexco);
|
||||
}
|
||||
else {
|
||||
lmd->vertexco = MEM_dupallocN(lmd_eval->vertexco);
|
||||
}
|
||||
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
@ -2351,7 +2370,6 @@ static bool surfacedeform_bind_poll(bContext *C)
|
|||
|
||||
static int surfacedeform_bind_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *ob = ED_object_active_context(C);
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph(C);
|
||||
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_SurfaceDeform);
|
||||
|
@ -2367,15 +2385,15 @@ static int surfacedeform_bind_exec(bContext *C, wmOperator *op)
|
|||
smd->flags |= MOD_SDEF_BIND;
|
||||
}
|
||||
|
||||
SurfaceDeformModifierData *smd_eval =
|
||||
(SurfaceDeformModifierData *)modifier_get_evaluated(depsgraph, ob, &smd->modifier);
|
||||
smd_eval->flags = smd->flags;
|
||||
|
||||
/* Force modifier to run, it will call binding routine
|
||||
* (this has to happen outside of depsgraph evaluation). */
|
||||
const int mode = smd->modifier.mode;
|
||||
smd->modifier.mode |= eModifierMode_Realtime;
|
||||
object_force_modifier_update_for_bind(depsgraph, scene, ob);
|
||||
smd->modifier.mode = mode;
|
||||
object_force_modifier_bind_simple_options(depsgraph, ob, &smd->modifier);
|
||||
|
||||
/* We need ID_RECALC_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
#include "BLI_strict_flags.h"
|
||||
|
||||
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
|
||||
// #define DEBUG_TIME
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
@ -558,7 +561,7 @@ static void calc_deltas(
|
|||
|
||||
|
||||
static void correctivesmooth_modifier_do(
|
||||
ModifierData *md, Object *ob, Mesh *mesh,
|
||||
ModifierData *md, Depsgraph *depsgraph, Object *ob, Mesh *mesh,
|
||||
float (*vertexCos)[3], unsigned int numVerts,
|
||||
struct BMEditMesh *em)
|
||||
{
|
||||
|
@ -580,10 +583,20 @@ static void correctivesmooth_modifier_do(
|
|||
/* signal to recalculate, whoever sets MUST also free bind coords */
|
||||
(csmd->bind_coords_num == (unsigned int)-1))
|
||||
{
|
||||
BLI_assert(csmd->bind_coords == NULL);
|
||||
csmd->bind_coords = MEM_dupallocN(vertexCos);
|
||||
csmd->bind_coords_num = numVerts;
|
||||
BLI_assert(csmd->bind_coords != NULL);
|
||||
if (DEG_is_active(depsgraph)) {
|
||||
BLI_assert(csmd->bind_coords == NULL);
|
||||
csmd->bind_coords = MEM_dupallocN(vertexCos);
|
||||
csmd->bind_coords_num = numVerts;
|
||||
BLI_assert(csmd->bind_coords != NULL);
|
||||
/* Copy bound data to the original modifier. */
|
||||
CorrectiveSmoothModifierData *csmd_orig =
|
||||
(CorrectiveSmoothModifierData *)modifier_get_original(&csmd->modifier);
|
||||
csmd_orig->bind_coords = MEM_dupallocN(csmd->bind_coords);
|
||||
csmd_orig->bind_coords_num = csmd->bind_coords_num;
|
||||
}
|
||||
else {
|
||||
modifier_setError(md, "Attempt to bind from inactive dependency graph");
|
||||
}
|
||||
}
|
||||
|
||||
if (UNLIKELY(use_only_smooth)) {
|
||||
|
@ -711,7 +724,7 @@ static void deformVerts(
|
|||
{
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
|
||||
|
||||
correctivesmooth_modifier_do(md, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, NULL);
|
||||
correctivesmooth_modifier_do(md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, NULL);
|
||||
|
||||
if (mesh_src != mesh) {
|
||||
BKE_id_free(NULL, mesh_src);
|
||||
|
@ -725,7 +738,7 @@ static void deformVertsEM(
|
|||
{
|
||||
Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
|
||||
|
||||
correctivesmooth_modifier_do(md, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, editData);
|
||||
correctivesmooth_modifier_do(md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (unsigned int)numVerts, editData);
|
||||
|
||||
if (mesh_src != mesh) {
|
||||
BKE_id_free(NULL, mesh_src);
|
||||
|
|
|
@ -298,14 +298,6 @@ static void meshdeformModifier_do(
|
|||
*/
|
||||
Object *ob_target = mmd->object;
|
||||
cagemesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false);
|
||||
#if 0 /* This shall not be needed if we always get evaluated target object... */
|
||||
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, &CD_MASK_BAREMESH);
|
||||
free_cagemesh = cagemesh != NULL;
|
||||
}
|
||||
#endif
|
||||
if (cagemesh == NULL) {
|
||||
modifier_setError(md, "Cannot get mesh from cage object");
|
||||
return;
|
||||
|
@ -321,13 +313,11 @@ static void meshdeformModifier_do(
|
|||
/* bind weights if needed */
|
||||
if (!mmd->bindcagecos) {
|
||||
/* progress bar redraw can make this recursive .. */
|
||||
if (!DEG_is_active(ctx->depsgraph)) {
|
||||
modifier_setError(md, "Attempt to bind from inactive dependency graph");
|
||||
goto finally;
|
||||
}
|
||||
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;
|
||||
|
|
|
@ -1124,7 +1124,7 @@ static void deformVert(
|
|||
|
||||
static void surfacedeformModifier_do(
|
||||
ModifierData *md,
|
||||
const ModifierEvalContext *UNUSED(ctx),
|
||||
const ModifierEvalContext *ctx,
|
||||
float (*vertexCos)[3], unsigned int numverts, Object *ob)
|
||||
{
|
||||
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
|
||||
|
@ -1133,30 +1133,19 @@ static void surfacedeformModifier_do(
|
|||
|
||||
/* Exit function if bind flag is not set (free bind data if any). */
|
||||
if (!(smd->flags & MOD_SDEF_BIND)) {
|
||||
/* Note: with new CoW system, we expect unbinding to be done by a special call from main thread,
|
||||
* outside of depsgraph evaluation (see object_force_modifier_update_for_bind() in object_modifier.c). */
|
||||
if (smd->verts != NULL) {
|
||||
if (ob != DEG_get_original_object(ob)) {
|
||||
BLI_assert(!"Trying to unbind inside of depsgraph evaluation");
|
||||
modifier_setError(md, "Trying to unbind inside of depsgraph evaluation");
|
||||
}
|
||||
else {
|
||||
freeData(md);
|
||||
if (!DEG_is_active(ctx->depsgraph)) {
|
||||
modifier_setError(md, "Attempt to bind from inactive dependency graph");
|
||||
return;
|
||||
}
|
||||
ModifierData *md_orig = modifier_get_original(md);
|
||||
freeData(md_orig);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Object *ob_target = smd->target;
|
||||
target = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false);
|
||||
#if 0 /* Should not be needed anymore since we always get that mesh from eval object ? */
|
||||
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, CD_MASK_BAREMESH);
|
||||
free_target = target != NULL;
|
||||
}
|
||||
#endif
|
||||
if (!target) {
|
||||
modifier_setError(md, "No valid target mesh");
|
||||
return;
|
||||
|
@ -1166,20 +1155,19 @@ static void surfacedeformModifier_do(
|
|||
tnumpoly = target->totpoly;
|
||||
|
||||
/* If not bound, execute bind. */
|
||||
/* Note: with new CoW system, we expect binding to be done by a special call from main thread,
|
||||
* outside of depsgraph evaluation (see object_force_modifier_update_for_bind() in object_modifier.c). */
|
||||
if (smd->verts == NULL) {
|
||||
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");
|
||||
if (!DEG_is_active(ctx->depsgraph)) {
|
||||
modifier_setError(md, "Attempt to unbind from inactive dependency graph");
|
||||
return;
|
||||
}
|
||||
|
||||
SurfaceDeformModifierData *smd_orig = (SurfaceDeformModifierData *)modifier_get_original(md);
|
||||
float tmp_mat[4][4];
|
||||
|
||||
invert_m4_m4(tmp_mat, ob->obmat);
|
||||
mul_m4_m4m4(smd->mat, tmp_mat, ob_target->obmat);
|
||||
mul_m4_m4m4(smd_orig->mat, tmp_mat, ob_target->obmat);
|
||||
|
||||
if (!surfacedeformBind(smd, vertexCos, numverts, tnumpoly, tnumverts, target)) {
|
||||
if (!surfacedeformBind(smd_orig, vertexCos, numverts, tnumpoly, tnumverts, target)) {
|
||||
smd->flags &= ~MOD_SDEF_BIND;
|
||||
}
|
||||
/* Early abort, this is binding 'call', no need to perform whole evaluation. */
|
||||
|
|
Loading…
Reference in New Issue