diff options
author | Howard Trickey <howard.trickey@gmail.com> | 2019-06-18 17:07:53 +0300 |
---|---|---|
committer | Howard Trickey <howard.trickey@gmail.com> | 2019-06-18 17:07:53 +0300 |
commit | 1a9e698099b5f965baeb4c038dd8f37f142710d9 (patch) | |
tree | 29877791228ff44fdc8001476e05d6782c066477 /source/blender/modifiers | |
parent | c8e3fe608e7ab02ef0ae2a4f57dab85e3c1d5eba (diff) |
Fix T65660 Mirror modifier didn't work with custom normals.
Diffstat (limited to 'source/blender/modifiers')
-rw-r--r-- | source/blender/modifiers/intern/MOD_mirror.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index ba1681b3ac3..70258a8415e 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -334,6 +334,67 @@ static Mesh *doMirrorOnAxis(MirrorModifierData *mmd, } } + /* handle custom split normals */ + if ((((Mesh *)ob->data)->flag & ME_AUTOSMOOTH) && + CustomData_has_layer(&result->ldata, CD_CUSTOMLOOPNORMAL)) { + const int totloop = result->totloop; + const int totpoly = result->totpoly; + float(*loop_normals)[3] = MEM_calloc_arrayN((size_t)totloop, sizeof(*loop_normals), __func__); + CustomData *ldata = &result->ldata; + short(*clnors)[2] = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL); + MLoopNorSpaceArray lnors_spacearr = {NULL}; + float(*poly_normals)[3] = MEM_mallocN(sizeof(*poly_normals) * totpoly, __func__); + + /* calculate custom normals into loop_normals, then mirror first half into second half */ + + BKE_mesh_calc_normals_poly(result->mvert, + NULL, + result->totvert, + result->mloop, + result->mpoly, + totloop, + totpoly, + poly_normals, + false); + + BKE_mesh_normals_loop_split(result->mvert, + result->totvert, + result->medge, + result->totedge, + result->mloop, + loop_normals, + totloop, + result->mpoly, + poly_normals, + totpoly, + true, + mesh->smoothresh, + &lnors_spacearr, + clnors, + NULL); + + /* mirroring has to account for loops being reversed in polys in second half */ + mp = result->mpoly; + for (i = 0; i < maxPolys; i++, mp++) { + MPoly *mpmirror = result->mpoly + maxPolys + i; + int j; + + for (j = mp->loopstart; j < mp->loopstart + mp->totloop; j++) { + int mirrorj = mpmirror->loopstart; + if (j > mp->loopstart) + mirrorj += mpmirror->totloop - (j - mp->loopstart); + copy_v3_v3(loop_normals[mirrorj], loop_normals[j]); + loop_normals[mirrorj][axis] = -loop_normals[j][axis]; + BKE_lnor_space_custom_normal_to_data( + lnors_spacearr.lspacearr[mirrorj], loop_normals[mirrorj], clnors[mirrorj]); + } + } + + MEM_freeN(poly_normals); + MEM_freeN(loop_normals); + BKE_lnor_spacearr_free(&lnors_spacearr); + } + /* handle vgroup stuff */ if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&result->vdata, CD_MDEFORMVERT)) { MDeformVert *dvert = (MDeformVert *)CustomData_get_layer(&result->vdata, CD_MDEFORMVERT) + |