diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2010-10-17 00:43:16 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2010-10-17 00:43:16 +0400 |
commit | 28e144db920699a13e6cd196ac91f13e11b2877c (patch) | |
tree | cb3950aea7bb34b6b4d8ba277f337bca926a5df3 | |
parent | 7415c967ff5905efbd8b89fe466cf6c4cb79e8f1 (diff) |
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)
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 34 |
1 files 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; + + if(corners!=nverts) { + /* happens when face changed vertex count in edit mode + if it happened, just forgot displacement */ - d = MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap"); + 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; } } |