Fix #25272: shrinkwrap with dependency cycle could lead to eternal

loop and increasing memory usage.

Modifiers should never call mesh_get_derived_final or similar, only
use ob->derivedFinal if it exists, if the dependencies are set correct
and there are no cycles, it will be there.
This commit is contained in:
Brecht Van Lommel 2010-12-17 20:13:54 +00:00
parent 4b0c455093
commit 8b28c24d16
4 changed files with 20 additions and 20 deletions

@ -35,7 +35,7 @@
#include "BKE_customdata.h" #include "BKE_customdata.h"
struct DerivedMesh; struct DerivedMesh;
struct Object; struct Object;
struct DerivedMesh *object_get_derived_final(struct Scene *scene, struct Object *ob, CustomDataMask dataMask); struct DerivedMesh *object_get_derived_final(struct Object *ob);
/* SpaceTransform stuff */ /* SpaceTransform stuff */
@ -121,7 +121,7 @@ typedef struct ShrinkwrapCalcData
} ShrinkwrapCalcData; } ShrinkwrapCalcData;
void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts); void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3], int numVerts);
/* /*
* This function casts a ray in the given BVHTree.. but it takes into consideration the space_transform, that is: * This function casts a ray in the given BVHTree.. but it takes into consideration the space_transform, that is:

@ -3423,7 +3423,7 @@ static void shrinkwrap_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
float dist; float dist;
SpaceTransform transform; SpaceTransform transform;
DerivedMesh *target = object_get_derived_final(cob->scene, ct->tar, CD_MASK_BAREMESH); DerivedMesh *target = object_get_derived_final(ct->tar);
BVHTreeRayHit hit; BVHTreeRayHit hit;
BVHTreeNearest nearest; BVHTreeNearest nearest;

@ -48,6 +48,7 @@
#include "BKE_mesh.h" #include "BKE_mesh.h"
#include "BKE_subsurf.h" #include "BKE_subsurf.h"
#include "BLI_editVert.h"
#include "BLI_math.h" #include "BLI_math.h"
@ -82,21 +83,18 @@ typedef void ( *Shrinkwrap_ForeachVertexCallback) (DerivedMesh *target, float *c
/* get derived mesh */ /* get derived mesh */
//TODO is anyfunction that does this? returning the derivedFinal witouth we caring if its in edit mode or not? //TODO is anyfunction that does this? returning the derivedFinal witouth we caring if its in edit mode or not?
DerivedMesh *object_get_derived_final(struct Scene *scene, Object *ob, CustomDataMask dataMask) DerivedMesh *object_get_derived_final(Object *ob)
{ {
Mesh *me= ob->data; Mesh *me= ob->data;
struct EditMesh *em = BKE_mesh_get_editmesh(me); EditMesh *em = BKE_mesh_get_editmesh(me);
if (em) if(em) {
{ DerivedMesh *dm = em->derivedFinal;
DerivedMesh *final = NULL;
editmesh_get_derived_cage_and_final(scene, ob, em, &final, dataMask);
BKE_mesh_end_editmesh(me, em); BKE_mesh_end_editmesh(me, em);
return final; return dm;
} }
else
return mesh_get_derived_final(scene, ob, dataMask); return ob->derivedFinal;
} }
/* Space transform */ /* Space transform */
@ -282,7 +280,7 @@ int normal_projection_project_vertex(char options, const float *vert, const floa
} }
static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, struct Scene *scene) static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
{ {
int i; int i;
@ -327,7 +325,9 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, struct S
if(calc->smd->auxTarget) if(calc->smd->auxTarget)
{ {
auxMesh = object_get_derived_final(scene, calc->smd->auxTarget, CD_MASK_BAREMESH); auxMesh = object_get_derived_final(calc->smd->auxTarget);
if(!auxMesh)
return;
space_transform_setup( &local2aux, calc->ob, calc->smd->auxTarget); space_transform_setup( &local2aux, calc->ob, calc->smd->auxTarget);
} }
@ -499,7 +499,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
} }
/* Main shrinkwrap function */ /* Main shrinkwrap function */
void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
{ {
DerivedMesh *ss_mesh = NULL; DerivedMesh *ss_mesh = NULL;
@ -530,7 +530,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Scene *scene, Object
if(smd->target) if(smd->target)
{ {
calc.target = object_get_derived_final(scene, smd->target, CD_MASK_BAREMESH); calc.target = object_get_derived_final(smd->target);
//TODO there might be several "bugs" on non-uniform scales matrixs //TODO there might be several "bugs" on non-uniform scales matrixs
//because it will no longer be nearest surface, not sphere projection //because it will no longer be nearest surface, not sphere projection
@ -587,7 +587,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Scene *scene, Object
break; break;
case MOD_SHRINKWRAP_PROJECT: case MOD_SHRINKWRAP_PROJECT:
BENCH(shrinkwrap_calc_normal_projection(&calc, scene)); BENCH(shrinkwrap_calc_normal_projection(&calc));
break; break;
case MOD_SHRINKWRAP_NEAREST_VERTEX: case MOD_SHRINKWRAP_NEAREST_VERTEX:

@ -117,7 +117,7 @@ static void deformVerts(ModifierData *md, Object *ob,
if(dataMask) if(dataMask)
dm= get_cddm(ob, NULL, dm, vertexCos); dm= get_cddm(ob, NULL, dm, vertexCos);
shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts); shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, ob, dm, vertexCos, numVerts);
if(dm != derivedData) if(dm != derivedData)
dm->release(dm); dm->release(dm);
@ -132,7 +132,7 @@ static void deformVertsEM(ModifierData *md, Object *ob, struct EditMesh *editDat
if(dataMask) if(dataMask)
dm= get_cddm(ob, editData, dm, vertexCos); dm= get_cddm(ob, editData, dm, vertexCos);
shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, md->scene, ob, dm, vertexCos, numVerts); shrinkwrapModifier_deform((ShrinkwrapModifierData*)md, ob, dm, vertexCos, numVerts);
if(dm != derivedData) if(dm != derivedData)
dm->release(dm); dm->release(dm);