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')
-rw-r--r--source/blender/blenkernel/BKE_modifier.h10
-rw-r--r--source/blender/blenkernel/intern/modifier.c20
-rw-r--r--source/blender/editors/armature/meshlaplacian.c16
-rw-r--r--source/blender/editors/object/object_modifier.c92
-rw-r--r--source/blender/modifiers/intern/MOD_correctivesmooth.c27
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c18
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c36
7 files changed, 130 insertions, 89 deletions
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index a375ed3044c..9f522c11733 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -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(
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index fe955ced5f5..8f52e579a91 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -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);
+}
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 34fea2e0996..66bd7a8db80 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -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);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index c3a562df037..1944d2989ac 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -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;
}
diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c
index ac1c0d46d7b..d9e6ed78070 100644
--- a/source/blender/modifiers/intern/MOD_correctivesmooth.c
+++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c
@@ -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);
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index 310b05d4580..7ae03cc43f3 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -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;
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 44307b4271e..46f4f9c78e9 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -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. */