From 4143b8a6c7ce3b513b7267096ce4548c54e8411e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 15 Jul 2015 14:32:11 +1000 Subject: [PATCH] Fix autosmooth with recent DM optimizations Also avoid multiple float->short conversions for the same normal. --- .../blender/blenkernel/intern/cdderivedmesh.c | 42 +++++++++++-------- .../blender/blenkernel/intern/subsurf_ccg.c | 31 +++++++------- 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 90d2fa7ea7b..b773bfe1e8f 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1419,10 +1419,9 @@ static void cdDM_buffer_copy_normal( { int i, totface; int start; - float f_no[3]; const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); - short (*tlnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); + const short (*tlnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); MVert *mvert = dm->getVertArray(dm); MFace *f = dm->getTessFaceArray(dm); @@ -1432,16 +1431,16 @@ static void cdDM_buffer_copy_normal( const int smoothnormal = (f->flag & ME_SMOOTH); if (tlnors) { - short (*tlnor)[3] = tlnors[i]; + const short (*ln)[3] = tlnors[i]; /* Copy loop normals */ - copy_v3_v3_short(&varray[start], tlnor[0]); - copy_v3_v3_short(&varray[start + 3], tlnor[1]); - copy_v3_v3_short(&varray[start + 6], tlnor[2]); - start += 9; + copy_v3_v3_short(&varray[start], ln[0]); + copy_v3_v3_short(&varray[start + 4], ln[1]); + copy_v3_v3_short(&varray[start + 8], ln[2]); + start += 12; if (f->v4) { - copy_v3_v3_short(&varray[start], tlnor[3]); - start += 3; + copy_v3_v3_short(&varray[start], ln[3]); + start += 4; } } else if (smoothnormal) { @@ -1458,30 +1457,39 @@ static void cdDM_buffer_copy_normal( } else if (nors) { /* copy cached face normal */ - normal_float_to_short_v3(&varray[start], &nors[i * 3]); - normal_float_to_short_v3(&varray[start + 4], &nors[i * 3]); - normal_float_to_short_v3(&varray[start + 8], &nors[i * 3]); + short f_no_s[3]; + + normal_float_to_short_v3(f_no_s, &nors[i * 3]); + + copy_v3_v3_short(&varray[start], f_no_s); + copy_v3_v3_short(&varray[start + 4], f_no_s); + copy_v3_v3_short(&varray[start + 8], f_no_s); start += 12; if (f->v4) { - normal_float_to_short_v3(&varray[start], &nors[i * 3]); + copy_v3_v3_short(&varray[start], f_no_s); start += 4; } } else { /* calculate face normal */ + float f_no[3]; + short f_no_s[3]; + if (f->v4) normal_quad_v3(f_no, mvert[f->v1].co, mvert[f->v2].co, mvert[f->v3].co, mvert[f->v4].co); else normal_tri_v3(f_no, mvert[f->v1].co, mvert[f->v2].co, mvert[f->v3].co); - normal_float_to_short_v3(&varray[start], f_no); - normal_float_to_short_v3(&varray[start + 4], f_no); - normal_float_to_short_v3(&varray[start + 8], f_no); + normal_float_to_short_v3(f_no_s, f_no); + + copy_v3_v3_short(&varray[start], f_no_s); + copy_v3_v3_short(&varray[start + 4], f_no_s); + copy_v3_v3_short(&varray[start + 8], f_no_s); start += 12; if (f->v4) { - normal_float_to_short_v3(&varray[start], f_no); + copy_v3_v3_short(&varray[start], f_no_s); start += 4; } } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 74e5ce0e60e..d089660b83a 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1769,7 +1769,7 @@ static void ccgDM_buffer_copy_normal( CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm; CCGSubSurf *ss = ccgdm->ss; CCGKey key; - short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); + const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL); int gridSize = ccgSubSurf_getGridSize(ss); int gridFaces = gridSize - 1; DMFlagMat *faceFlags = ccgdm->faceFlags; @@ -1784,7 +1784,7 @@ static void ccgDM_buffer_copy_normal( CCGFace *f = ccgdm->faceMap[i].face; int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f)); - short (*ln)[4][3] = NULL; + const short (*ln)[3] = NULL; if (faceFlags) { shademodel = (lnors || (faceFlags[index].flag & ME_SMOOTH)) ? GL_SMOOTH : GL_FLAT; @@ -1794,7 +1794,7 @@ static void ccgDM_buffer_copy_normal( } if (lnors) { - ln = lnors; + ln = *lnors; lnors += gridFaces * gridFaces * numVerts; } @@ -1805,13 +1805,13 @@ static void ccgDM_buffer_copy_normal( /* Can't use quad strips here... */ for (y = 0; y < gridFaces; y ++) { for (x = 0; x < gridFaces; x ++) { - copy_v3_v3_short(&varray[start], ln[0][0]); - copy_v3_v3_short(&varray[start + 4], ln[0][3]); - copy_v3_v3_short(&varray[start + 8], ln[0][2]); - copy_v3_v3_short(&varray[start + 12], ln[0][1]); + copy_v3_v3_short(&varray[start], ln[0]); + copy_v3_v3_short(&varray[start + 4], ln[3]); + copy_v3_v3_short(&varray[start + 8], ln[2]); + copy_v3_v3_short(&varray[start + 12], ln[1]); start += 16; - ln ++; + ln += 4; } } } @@ -1835,18 +1835,21 @@ static void ccgDM_buffer_copy_normal( else { for (y = 0; y < gridFaces; y ++) { for (x = 0; x < gridFaces; x ++) { - float no[3]; + float f_no[3]; + short f_no_s[3]; + float *a = CCG_grid_elem_co(&key, faceGridData, x, y ); float *b = CCG_grid_elem_co(&key, faceGridData, x + 1, y ); float *c = CCG_grid_elem_co(&key, faceGridData, x + 1, y + 1); float *d = CCG_grid_elem_co(&key, faceGridData, x, y + 1); - ccgDM_NormalFast(a, b, c, d, no); + ccgDM_NormalFast(a, b, c, d, f_no); + normal_float_to_short_v3(f_no_s, f_no); - normal_float_to_short_v3(&varray[start], no); - normal_float_to_short_v3(&varray[start + 4], no); - normal_float_to_short_v3(&varray[start + 8], no); - normal_float_to_short_v3(&varray[start + 12], no); + copy_v3_v3_short(&varray[start], f_no_s); + copy_v3_v3_short(&varray[start + 4], f_no_s); + copy_v3_v3_short(&varray[start + 8], f_no_s); + copy_v3_v3_short(&varray[start + 12], f_no_s); start += 16; }