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.
This commit is contained in:
parent
e55c1a9b5a
commit
72f4ac99c7
|
@ -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
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -428,11 +428,7 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
|
|||
|
||||
static bool PE_create_shape_tree(PEData *data, Object *shapeob)
|
||||
{
|
||||
ModifierEvalContext ctx = {
|
||||
.depsgraph = data->depsgraph,
|
||||
.flag = 0,
|
||||
};
|
||||
Mesh *mesh = BKE_modifier_get_evaluated_mesh_from_object(&ctx, shapeob);
|
||||
Mesh *mesh = BKE_object_get_evaluated_mesh(data->depsgraph, shapeob);
|
||||
|
||||
memset(&data->shape_bvh, 0, sizeof(data->shape_bvh));
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "BKE_cdderivedmesh.h"
|
||||
#include "BKE_displist.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_library_query.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_mesh.h"
|
||||
|
@ -373,6 +374,7 @@ static Mesh *arrayModifier_doArray(
|
|||
int first_chunk_start, first_chunk_nverts, last_chunk_start, last_chunk_nverts;
|
||||
|
||||
Mesh *result, *start_cap_mesh = NULL, *end_cap_mesh = NULL;
|
||||
bool start_cap_mesh_free, end_cap_mesh_free;
|
||||
|
||||
int *vgroup_start_cap_remap = NULL;
|
||||
int vgroup_start_cap_remap_len = 0;
|
||||
|
@ -390,7 +392,7 @@ static Mesh *arrayModifier_doArray(
|
|||
vgroup_start_cap_remap = BKE_object_defgroup_index_map_create(
|
||||
amd->start_cap, ctx->object, &vgroup_start_cap_remap_len);
|
||||
|
||||
start_cap_mesh = BKE_modifier_get_evaluated_mesh_from_object(ctx, amd->start_cap);
|
||||
start_cap_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(amd->start_cap, &start_cap_mesh_free);
|
||||
if (start_cap_mesh) {
|
||||
start_cap_nverts = start_cap_mesh->totvert;
|
||||
start_cap_nedges = start_cap_mesh->totedge;
|
||||
|
@ -402,7 +404,7 @@ static Mesh *arrayModifier_doArray(
|
|||
vgroup_end_cap_remap = BKE_object_defgroup_index_map_create(
|
||||
amd->end_cap, ctx->object, &vgroup_end_cap_remap_len);
|
||||
|
||||
end_cap_mesh = BKE_modifier_get_evaluated_mesh_from_object(ctx, amd->end_cap);
|
||||
end_cap_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(amd->end_cap, &end_cap_mesh_free);
|
||||
if (end_cap_mesh) {
|
||||
end_cap_nverts = end_cap_mesh->totvert;
|
||||
end_cap_nedges = end_cap_mesh->totedge;
|
||||
|
@ -737,6 +739,12 @@ static Mesh *arrayModifier_doArray(
|
|||
if (vgroup_end_cap_remap) {
|
||||
MEM_freeN(vgroup_end_cap_remap);
|
||||
}
|
||||
if (start_cap_mesh != NULL && start_cap_mesh_free) {
|
||||
BKE_id_free(NULL, start_cap_mesh);
|
||||
}
|
||||
if (end_cap_mesh != NULL && end_cap_mesh_free) {
|
||||
BKE_id_free(NULL, end_cap_mesh);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -170,14 +170,16 @@ static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data))
|
|||
static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
|
||||
{
|
||||
BooleanModifierData *bmd = (BooleanModifierData *) md;
|
||||
Mesh *result;
|
||||
|
||||
Mesh *mesh_other;
|
||||
bool mesh_other_free;
|
||||
|
||||
if (!bmd->object)
|
||||
return mesh;
|
||||
|
||||
mesh_other = BKE_modifier_get_evaluated_mesh_from_object(ctx, bmd->object);
|
||||
mesh_other = BKE_modifier_get_evaluated_mesh_from_evaluated_object(bmd->object, &mesh_other_free);
|
||||
if (mesh_other) {
|
||||
Mesh *result;
|
||||
Object *object_eval = DEG_get_evaluated_object(ctx->depsgraph, ctx->object);
|
||||
Object *other_eval = DEG_get_evaluated_object(ctx->depsgraph, bmd->object);
|
||||
|
||||
|
@ -321,19 +323,19 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
|
|||
#ifdef DEBUG_TIME
|
||||
TIMEIT_END(boolean_bmesh);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* if new mesh returned, return it; otherwise there was
|
||||
* an error, so delete the modifier object */
|
||||
if (result)
|
||||
return result;
|
||||
else
|
||||
if (result == NULL)
|
||||
modifier_setError(md, "Cannot execute boolean operation");
|
||||
}
|
||||
|
||||
return mesh;
|
||||
if (mesh_other != NULL && mesh_other_free) {
|
||||
BKE_id_free(NULL, mesh_other);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md))
|
||||
|
|
|
@ -275,10 +275,12 @@ static void meshdeform_vert_task(
|
|||
}
|
||||
|
||||
static void meshdeformModifier_do(
|
||||
ModifierData *md, Depsgraph *depsgraph, Object *ob, Mesh *mesh,
|
||||
ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh,
|
||||
float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
|
||||
Object *ob = ctx->object;
|
||||
|
||||
Mesh *cagemesh;
|
||||
MDeformVert *dvert = NULL;
|
||||
float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
|
||||
|
@ -301,29 +303,9 @@ static void meshdeformModifier_do(
|
|||
*
|
||||
* We'll support this case once granular dependency graph is landed.
|
||||
*/
|
||||
if (mmd->object->mode & OB_MODE_EDIT) {
|
||||
BMEditMesh *em = BKE_editmesh_from_object(mmd->object);
|
||||
cagemesh = BKE_bmesh_to_mesh_nomain(em->bm, &(struct BMeshToMeshParams){0});
|
||||
free_cagemesh = true;
|
||||
}
|
||||
else {
|
||||
ModifierEvalContext ctx = {
|
||||
.depsgraph = depsgraph,
|
||||
.flag = md->mode & eModifierMode_Render ? MOD_APPLY_RENDER : 0,
|
||||
};
|
||||
cagemesh = BKE_modifier_get_evaluated_mesh_from_object(&ctx, ob);
|
||||
}
|
||||
|
||||
/* if we don't have one computed, use derivedmesh from data
|
||||
* without any modifiers */
|
||||
if (!cagemesh) {
|
||||
cagemesh = get_mesh(mmd->object, NULL, NULL, NULL, false, false);
|
||||
if (cagemesh) {
|
||||
free_cagemesh = true;
|
||||
}
|
||||
}
|
||||
cagemesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob, &free_cagemesh);
|
||||
|
||||
if (!cagemesh) {
|
||||
if (cagemesh == NULL) {
|
||||
modifier_setError(md, "Cannot get mesh from cage object");
|
||||
return;
|
||||
}
|
||||
|
@ -412,7 +394,9 @@ static void meshdeformModifier_do(
|
|||
/* release cage derivedmesh */
|
||||
MEM_freeN(dco);
|
||||
MEM_freeN(cagecos);
|
||||
if (free_cagemesh) BKE_id_free(NULL, cagemesh);
|
||||
if (cagemesh != NULL && free_cagemesh) {
|
||||
BKE_id_free(NULL, cagemesh);
|
||||
}
|
||||
}
|
||||
|
||||
static void deformVerts(
|
||||
|
@ -425,7 +409,7 @@ static void deformVerts(
|
|||
|
||||
modifier_vgroup_cache(md, vertexCos); /* if next modifier needs original vertices */
|
||||
|
||||
meshdeformModifier_do(md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, numVerts);
|
||||
meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts);
|
||||
|
||||
if (mesh_src && mesh_src != mesh) {
|
||||
BKE_id_free(NULL, mesh_src);
|
||||
|
@ -441,7 +425,7 @@ static void deformVertsEM(
|
|||
{
|
||||
Mesh *mesh_src = get_mesh(ctx->object, NULL, mesh, NULL, false, false);
|
||||
|
||||
meshdeformModifier_do(md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, numVerts);
|
||||
meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts);
|
||||
|
||||
if (mesh_src && mesh_src != mesh) {
|
||||
BKE_id_free(NULL, mesh_src);
|
||||
|
|
|
@ -111,7 +111,7 @@ static void deformVerts(
|
|||
|
||||
BLI_assert(mesh_src->totvert == numVerts);
|
||||
|
||||
shrinkwrapModifier_deform((ShrinkwrapModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts, ctx);
|
||||
shrinkwrapModifier_deform((ShrinkwrapModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts);
|
||||
}
|
||||
|
||||
static void deformVertsEM(
|
||||
|
@ -127,7 +127,7 @@ static void deformVertsEM(
|
|||
|
||||
BLI_assert(mesh_src->totvert == numVerts);
|
||||
|
||||
shrinkwrapModifier_deform((ShrinkwrapModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts, ctx);
|
||||
shrinkwrapModifier_deform((ShrinkwrapModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts);
|
||||
|
||||
if (!mesh) {
|
||||
BKE_id_free(NULL, mesh_src);
|
||||
|
|
|
@ -1041,33 +1041,6 @@ static bool surfacedeformBind(
|
|||
return data.success == 1;
|
||||
}
|
||||
|
||||
static Mesh *surfacedeform_get_mesh(Depsgraph *depsgraph, SurfaceDeformModifierData *smd, bool *r_needsfree)
|
||||
{
|
||||
Mesh *mesh;
|
||||
|
||||
/* Handle target mesh both in and out of edit mode */
|
||||
if (smd->target->mode & OB_MODE_EDIT) {
|
||||
BMEditMesh *em = BKE_editmesh_from_object(smd->target);
|
||||
mesh = BKE_bmesh_to_mesh_nomain(em->bm, &(struct BMeshToMeshParams){0});
|
||||
*r_needsfree = true;
|
||||
}
|
||||
else {
|
||||
ModifierEvalContext ctx = {
|
||||
.depsgraph = depsgraph,
|
||||
.flag = smd->modifier.mode & eModifierMode_Render ? MOD_APPLY_RENDER : 0,
|
||||
};
|
||||
mesh = BKE_modifier_get_evaluated_mesh_from_object(&ctx, smd->target);
|
||||
*r_needsfree = false;
|
||||
}
|
||||
|
||||
if (!mesh) {
|
||||
mesh = get_mesh(smd->target, NULL, NULL, NULL, false, false);
|
||||
*r_needsfree = true;
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
static void deformVert(
|
||||
void *__restrict userdata,
|
||||
const int index,
|
||||
|
@ -1127,7 +1100,7 @@ static void deformVert(
|
|||
|
||||
static void surfacedeformModifier_do(
|
||||
ModifierData *md,
|
||||
const ModifierEvalContext *ctx,
|
||||
const ModifierEvalContext *UNUSED(ctx),
|
||||
float (*vertexCos)[3], unsigned int numverts, Object *ob)
|
||||
{
|
||||
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
|
||||
|
@ -1141,7 +1114,7 @@ static void surfacedeformModifier_do(
|
|||
return;
|
||||
}
|
||||
|
||||
target = surfacedeform_get_mesh(ctx->depsgraph, smd, &free_target);
|
||||
target = BKE_modifier_get_evaluated_mesh_from_evaluated_object(smd->target, &free_target);
|
||||
if (!target) {
|
||||
modifier_setError(md, "No valid target mesh");
|
||||
return;
|
||||
|
@ -1200,7 +1173,9 @@ static void surfacedeformModifier_do(
|
|||
MEM_freeN(data.targetCos);
|
||||
}
|
||||
|
||||
if (free_target) BKE_id_free(NULL, target);
|
||||
if (target != NULL && free_target) {
|
||||
BKE_id_free(NULL, target);
|
||||
}
|
||||
}
|
||||
|
||||
static void deformVerts(
|
||||
|
|
|
@ -506,7 +506,8 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
|
|||
const bool use_trgt_faces = (wmd->proximity_flags & MOD_WVG_PROXIMITY_GEOM_FACES) != 0;
|
||||
|
||||
if (use_trgt_verts || use_trgt_edges || use_trgt_faces) {
|
||||
Mesh *target_mesh = BKE_modifier_get_evaluated_mesh_from_object(ctx, obr);
|
||||
bool target_mesh_free;
|
||||
Mesh *target_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(obr, &target_mesh_free);
|
||||
|
||||
/* We must check that we do have a valid target_mesh! */
|
||||
if (target_mesh != NULL) {
|
||||
|
@ -529,6 +530,10 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
|
|||
MEM_SAFE_FREE(dists_v);
|
||||
MEM_SAFE_FREE(dists_e);
|
||||
MEM_SAFE_FREE(dists_f);
|
||||
|
||||
if (target_mesh_free) {
|
||||
BKE_id_free(NULL, target_mesh);
|
||||
}
|
||||
}
|
||||
/* Else, fall back to default obj2vert behavior. */
|
||||
else {
|
||||
|
|
Loading…
Reference in New Issue