From 72f4ac99c70b02e095cc9a71d501d6b1dc85ac3e Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 30 May 2018 11:34:08 +0200 Subject: Cleanup/fix wrong modifiers targets handling in COW context. Modifiers stack only get COW/evaluated IDs, so no need to go auery again DEG for those. Further more, now unified handling of EditBMesh case (was done on case-by-case basis in a few modifiers, not all for some reason). We are still missing the ability to get final and cage deformed meshes when in Edit mode though, this is to be defined/implemented in depsgraph. --- source/blender/blenkernel/BKE_modifier.h | 5 ++--- source/blender/blenkernel/BKE_shrinkwrap.h | 2 +- source/blender/blenkernel/intern/modifier.c | 28 ++++++++++++++++++++------- source/blender/blenkernel/intern/shrinkwrap.c | 20 ++++++++++++++----- 4 files changed, 39 insertions(+), 16 deletions(-) (limited to 'source/blender/blenkernel') diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index c8d50793e76..a7b491527f5 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -557,9 +557,8 @@ struct DerivedMesh *modifier_applyModifierEM_DM_deprecated( struct ModifierData *md, const struct ModifierEvalContext *ctx, struct BMEditMesh *editData, struct DerivedMesh *dm); -struct Mesh *BKE_modifier_get_evaluated_mesh_from_object( - const struct ModifierEvalContext *ctx, - struct Object *ob); +struct Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object( + struct Object *ob_eval, bool *r_free_mesh); #endif diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index 36caad86cf7..8a809b606f1 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -78,7 +78,7 @@ typedef struct ShrinkwrapCalcData { } ShrinkwrapCalcData; void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object *ob, struct Mesh *mesh, - float (*vertexCos)[3], int numVerts, const struct ModifierEvalContext *ctx); + float (*vertexCos)[3], int numVerts); /* * This function casts a ray in the given BVHTree.. but it takes into consideration the space_transform, that is: diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 111968ba018..86563ab797d 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -60,6 +60,7 @@ #include "BKE_appdir.h" #include "BKE_cdderivedmesh.h" +#include "BKE_editmesh.h" #include "BKE_idcode.h" #include "BKE_key.h" #include "BKE_library.h" @@ -1212,13 +1213,26 @@ struct DerivedMesh *modifier_applyModifierEM_DM_deprecated(struct ModifierData * } } -/** Get evaluated mesh for other object, which is used as an operand for the modifier, - * i.e. second operand for boolean modifier. +/** + * Get evaluated mesh for other evaluated object, which is used as an operand for the modifier, + * e.g. second operand for boolean modifier. + * Note thqt modifiers in stack always get fully evaluated COW ID pointers, never original ones. Makes things simpler. */ -Mesh *BKE_modifier_get_evaluated_mesh_from_object(const ModifierEvalContext *ctx, Object *ob) +Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval, bool *r_free_mesh) { - /* Note: we do not care about RENDER setting here, since we get data from despgraph - * (and render depsgraph shall be different from realtime one) - */ - return BKE_object_get_evaluated_mesh(ctx->depsgraph, ob); + Mesh *me; + + if ((ob_eval->type == OB_MESH) && (ob_eval->mode & OB_MODE_EDIT)) { + /* Note: currently we have no equivalent to derived cagemesh or even final dm in BMEditMesh... + * This is TODO in core depsgraph/modifier stack code still. */ + BMEditMesh *em = BKE_editmesh_from_object(ob_eval); + me = BKE_bmesh_to_mesh_nomain(em->bm, &(struct BMeshToMeshParams){0}); + *r_free_mesh = true; + } + else { + me = ob_eval->runtime.mesh_eval; + *r_free_mesh = false; + } + + return me; } diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 3d3130486cb..a7b233bc042 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -50,6 +50,7 @@ #include "BKE_cdderivedmesh.h" #include "BKE_DerivedMesh.h" #include "BKE_lattice.h" +#include "BKE_library.h" #include "BKE_modifier.h" #include "BKE_deform.h" @@ -367,7 +368,7 @@ static void shrinkwrap_calc_normal_projection_cb_ex( } } -static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, const ModifierEvalContext *ctx) +static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) { /* Options about projection direction */ float proj_axis[3] = {0.0f, 0.0f, 0.0f}; @@ -382,6 +383,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, const Mo /* auxiliary target */ Mesh *auxMesh = NULL; + bool auxMesh_free; void *auxData = NULL; SpaceTransform local2aux; @@ -414,7 +416,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, const Mo } if (calc->smd->auxTarget) { - auxMesh = BKE_modifier_get_evaluated_mesh_from_object(ctx, calc->smd->auxTarget); + auxMesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(calc->smd->auxTarget, &auxMesh_free); if (!auxMesh) return; BLI_SPACE_TRANSFORM_SETUP(&local2aux, calc->ob, calc->smd->auxTarget); @@ -482,6 +484,9 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, const Mo free_bvhtree_from_mesh(auxData); } } + if (auxMesh != NULL && auxMesh_free) { + BKE_id_free(NULL, auxMesh); + } } /* @@ -596,11 +601,12 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) /* Main shrinkwrap function */ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, Mesh *mesh, - float (*vertexCos)[3], int numVerts, const ModifierEvalContext *ctx) + float (*vertexCos)[3], int numVerts) { DerivedMesh *ss_mesh = NULL; ShrinkwrapCalcData calc = NULL_ShrinkwrapCalcData; + bool target_free; /* remove loop dependencies on derived meshes (TODO should this be done elsewhere?) */ if (smd->target == ob) smd->target = NULL; @@ -625,7 +631,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, Mesh *me if (smd->target) { - calc.target = BKE_modifier_get_evaluated_mesh_from_object(ctx, smd->target); + calc.target = BKE_modifier_get_evaluated_mesh_from_evaluated_object(smd->target, &target_free); /* TODO there might be several "bugs" on non-uniform scales matrixs * because it will no longer be nearest surface, not sphere projection @@ -681,7 +687,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, Mesh *me break; case MOD_SHRINKWRAP_PROJECT: - TIMEIT_BENCH(shrinkwrap_calc_normal_projection(&calc, ctx), deform_project); + TIMEIT_BENCH(shrinkwrap_calc_normal_projection(&calc), deform_project); break; case MOD_SHRINKWRAP_NEAREST_VERTEX: @@ -693,4 +699,8 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, Mesh *me /* free memory */ if (ss_mesh) ss_mesh->release(ss_mesh); + + if (target_free && calc.target) { + BKE_id_free(NULL, calc.target); + } } -- cgit v1.2.3