From 28e144db920699a13e6cd196ac91f13e11b2877c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 16 Oct 2010 20:43:16 +0000 Subject: [PATCH] Fix #24139: Edge loop + Multi-Resolution modifier results weird artifacts - mdisp_corners used to return incorrect number of verts in some cases - fixed memory corruption when face changed vertex count in edit mode (forgot displacement for such faces atm, could be changed in the future) --- source/blender/blenkernel/intern/customdata.c | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index f4db8e953f9..58cd08f1c4c 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -442,8 +442,15 @@ static void mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, fl static int mdisp_corners(MDisps *s) { - /* silly trick because we don't get it from callback */ - return (s->totdisp % (3*3) == 0)? 3: 4; + int lvl= 13; + + while(lvl > 0) { + int side = (1 << (lvl-1)) + 1; + if ((s->totdisp % (side*side)) == 0) return s->totdisp / (side*side); + lvl--; + } + + return 0; } static void layerSwap_mdisps(void *data, const int *ci) @@ -452,19 +459,28 @@ static void layerSwap_mdisps(void *data, const int *ci) float (*d)[3] = NULL; int corners, cornersize, S; - /* this function is untested .. */ if(s->disps) { - corners = mdisp_corners(s); - cornersize = s->totdisp/corners; + int nverts= (ci[1] == 3) ? 4 : 3; /* silly way to know vertex count of face */ + corners= mdisp_corners(s); + cornersize= s->totdisp/corners; - d = MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap"); + if(corners!=nverts) { + /* happens when face changed vertex count in edit mode + if it happened, just forgot displacement */ + + MEM_freeN(s->disps); + s->disps= NULL; + s->totdisp= 0; /* flag to update totdisp */ + return; + } + + d= MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap"); for(S = 0; S < corners; S++) memcpy(d + cornersize*S, s->disps + cornersize*ci[S], cornersize*3*sizeof(float)); - if(s->disps) - MEM_freeN(s->disps); - s->disps = d; + MEM_freeN(s->disps); + s->disps= d; } }