Fix #25272: shrinkwrap with dependency cycle could lead to eternal
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 17 Dec 2010 20:13:54 +0000 (20:13 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 17 Dec 2010 20:13:54 +0000 (20:13 +0000)
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.

source/blender/blenkernel/BKE_shrinkwrap.h
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/shrinkwrap.c
source/blender/modifiers/intern/MOD_shrinkwrap.c

index 47fb5049278c496e331b33bacd065a61109ba836..6b8e7860db80652128e215e0ed87bcb5bef4e074 100644 (file)
@@ -35,7 +35,7 @@
 #include "BKE_customdata.h"
 struct DerivedMesh;
 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 */
@@ -121,7 +121,7 @@ typedef struct 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:
index f92f2326aeb7c7892ba107bbf6d9dff2832add25..bb0fc23c02c39705e170b1f98be06ccbd8ada9ce 100644 (file)
@@ -3423,7 +3423,7 @@ static void shrinkwrap_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
                float dist;
                
                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;
                BVHTreeNearest nearest;
                
index 936fb1bfeabdbc674383f2e3adbfd62b9bdaeecc..16e4933332c460c24b015b1118b6ab717bba9068 100644 (file)
@@ -48,6 +48,7 @@
 #include "BKE_mesh.h"
 #include "BKE_subsurf.h"
 
+#include "BLI_editVert.h"
 #include "BLI_math.h"
 
 
@@ -82,21 +83,18 @@ typedef void ( *Shrinkwrap_ForeachVertexCallback) (DerivedMesh *target, float *c
 
 /* get derived mesh */
 //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;
-       struct EditMesh *em = BKE_mesh_get_editmesh(me);
+       EditMesh *em = BKE_mesh_get_editmesh(me);
 
-       if (em)
-       {
-               DerivedMesh *final = NULL;
-               editmesh_get_derived_cage_and_final(scene, ob, em, &final, dataMask);
-               
+       if(em) {
+               DerivedMesh *dm = em->derivedFinal;
                BKE_mesh_end_editmesh(me, em);
-               return final;
+               return dm;
        }
-       else
-               return mesh_get_derived_final(scene, ob, dataMask);
+
+       return ob->derivedFinal;
 }
 
 /* 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;
 
@@ -327,7 +325,9 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, struct S
 
        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);
        }
 
@@ -499,7 +499,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
 }
 
 /* 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;
@@ -530,7 +530,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Scene *scene, Object
 
        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
                //because it will no longer be nearest surface, not sphere projection
@@ -587,7 +587,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Scene *scene, Object
                        break;
 
                        case MOD_SHRINKWRAP_PROJECT:
-                               BENCH(shrinkwrap_calc_normal_projection(&calc, scene));
+                               BENCH(shrinkwrap_calc_normal_projection(&calc));
                        break;
 
                        case MOD_SHRINKWRAP_NEAREST_VERTEX:
index 417c73eba9877cc08ad1d4dbf7097ea518429cdc..ff0ed5d841ad98ae3a71ef9c2292fb08a985f61b 100644 (file)
@@ -117,7 +117,7 @@ static void deformVerts(ModifierData *md, Object *ob,
        if(dataMask)
                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)
                dm->release(dm);
@@ -132,7 +132,7 @@ static void deformVertsEM(ModifierData *md, Object *ob, struct EditMesh *editDat
        if(dataMask)
                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)
                dm->release(dm);