From ac51e2f326965816e23f7948e2e3fbdfb07cb66c Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 4 Sep 2015 22:41:10 +0200 Subject: Fix T46015: normals_split_custom_set_from_vertices doesn't work with zero vectors This was simply broken for vertex case (indexing loop normals with vert indices...). Turns out to be rather verbose to replace on-the-fly zero normals by default ones correctly, and do not want to make a full copy of the given custom normals array, so now this one is editied in place (replacing zero vectors by correct default normals). Don't think this could be a serious issue anyway. --- source/blender/blenkernel/BKE_mesh.h | 4 +- source/blender/blenkernel/intern/mesh_evaluate.c | 50 +++++++++++++----------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 41241988f2b..a27688c1c61 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -234,11 +234,11 @@ void BKE_mesh_normals_loop_split( void BKE_mesh_normals_loop_custom_set( const struct MVert *mverts, const int numVerts, struct MEdge *medges, const int numEdges, - struct MLoop *mloops, float (*custom_loopnors)[3], const int numLoops, + struct MLoop *mloops, float (*r_custom_loopnors)[3], const int numLoops, struct MPoly *mpolys, const float (*polynors)[3], const int numPolys, short (*r_clnors_data)[2]); void BKE_mesh_normals_loop_custom_from_vertices_set( - const struct MVert *mverts, float (*custom_vertnors)[3], const int numVerts, + const struct MVert *mverts, float (*r_custom_vertnors)[3], const int numVerts, struct MEdge *medges, const int numEdges, struct MLoop *mloops, const int numLoops, struct MPoly *mpolys, const float (*polynors)[3], const int numPolys, short (*r_clnors_data)[2]); diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index a25ea463718..e8c71079519 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -1338,12 +1338,14 @@ void BKE_mesh_normals_loop_split( * Compute internal representation of given custom normals (as an array of float[2]). * It also makes sure the mesh matches those custom normals, by setting sharp edges flag as needed to get a * same custom lnor for all loops sharing a same smooth fan. - * If use_vertices if true, custom_loopnors is assumed to be per-vertex, not per-loop + * If use_vertices if true, r_custom_loopnors is assumed to be per-vertex, not per-loop * (this allows to set whole vert's normals at once, useful in some cases). + * r_custom_loopnors is expected to have normalized normals, or zero ones, in which case they will be replaced + * by default loop/vertex normal. */ static void mesh_normals_loop_custom_set( const MVert *mverts, const int numVerts, MEdge *medges, const int numEdges, - MLoop *mloops, float (*custom_loopnors)[3], const int numLoops, + MLoop *mloops, float (*r_custom_loopnors)[3], const int numLoops, MPoly *mpolys, const float (*polynors)[3], const int numPolys, short (*r_clnors_data)[2], const bool use_vertices) { @@ -1369,6 +1371,22 @@ static void mesh_normals_loop_custom_set( mpolys, polynors, numPolys, use_split_normals, split_angle, &lnors_spacearr, NULL, loop_to_poly); + /* Set all given zero vectors to their default value. */ + if (use_vertices) { + for (i = 0; i < numVerts; i++) { + if (is_zero_v3(r_custom_loopnors[i])) { + normal_short_to_float_v3(r_custom_loopnors[i], mverts[i].no); + } + } + } + else { + for (i = 0; i < numLoops; i++) { + if (is_zero_v3(r_custom_loopnors[i])) { + copy_v3_v3(r_custom_loopnors[i], lnors[i]); + } + } + } + /* Now, check each current smooth fan (one lnor space per smooth fan!), and if all its matching custom lnors * are not (enough) equal, add sharp edges as needed. * This way, next time we run BKE_mesh_normals_loop_split(), we'll get lnor spacearr/smooth fans matching @@ -1406,11 +1424,7 @@ static void mesh_normals_loop_custom_set( const int lidx = GET_INT_FROM_POINTER(loops->link); MLoop *ml = &mloops[lidx]; const int nidx = lidx; - float *nor = custom_loopnors[nidx]; - - if (is_zero_v3(nor)) { - nor = lnors[nidx]; - } + float *nor = r_custom_loopnors[nidx]; if (!org_nor) { org_nor = nor; @@ -1441,11 +1455,7 @@ static void mesh_normals_loop_custom_set( const int lidx = GET_INT_FROM_POINTER(loops->link); MLoop *ml = &mloops[lidx]; const int nidx = lidx; - float *nor = custom_loopnors[nidx]; - - if (is_zero_v3(nor)) { - nor = lnors[nidx]; - } + float *nor = r_custom_loopnors[nidx]; if (dot_v3v3(org_nor, nor) < LNOR_SPACE_TRIGO_THRESHOLD) { const MPoly *mp = &mpolys[loop_to_poly[lidx]]; @@ -1492,11 +1502,7 @@ static void mesh_normals_loop_custom_set( while (loops) { const int lidx = GET_INT_FROM_POINTER(loops->link); const int nidx = use_vertices ? (int)mloops[lidx].v : lidx; - float *nor = custom_loopnors[nidx]; - - if (is_zero_v3(nor)) { - nor = lnors[nidx]; - } + float *nor = r_custom_loopnors[nidx]; nbr_nors++; add_v3_v3(avg_nor, nor); @@ -1516,7 +1522,7 @@ static void mesh_normals_loop_custom_set( } else { const int nidx = use_vertices ? (int)mloops[i].v : i; - float *nor = custom_loopnors[nidx]; + float *nor = r_custom_loopnors[nidx]; BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], nor, r_clnors_data[i]); BLI_BITMAP_DISABLE(done_loops, i); @@ -1532,21 +1538,21 @@ static void mesh_normals_loop_custom_set( void BKE_mesh_normals_loop_custom_set( const MVert *mverts, const int numVerts, MEdge *medges, const int numEdges, - MLoop *mloops, float (*custom_loopnors)[3], const int numLoops, + MLoop *mloops, float (*r_custom_loopnors)[3], const int numLoops, MPoly *mpolys, const float (*polynors)[3], const int numPolys, short (*r_clnors_data)[2]) { - mesh_normals_loop_custom_set(mverts, numVerts, medges, numEdges, mloops, custom_loopnors, numLoops, + mesh_normals_loop_custom_set(mverts, numVerts, medges, numEdges, mloops, r_custom_loopnors, numLoops, mpolys, polynors, numPolys, r_clnors_data, false); } void BKE_mesh_normals_loop_custom_from_vertices_set( - const MVert *mverts, float (*custom_vertnors)[3], const int numVerts, + const MVert *mverts, float (*r_custom_vertnors)[3], const int numVerts, MEdge *medges, const int numEdges, MLoop *mloops, const int numLoops, MPoly *mpolys, const float (*polynors)[3], const int numPolys, short (*r_clnors_data)[2]) { - mesh_normals_loop_custom_set(mverts, numVerts, medges, numEdges, mloops, custom_vertnors, numLoops, + mesh_normals_loop_custom_set(mverts, numVerts, medges, numEdges, mloops, r_custom_vertnors, numLoops, mpolys, polynors, numPolys, r_clnors_data, true); } -- cgit v1.2.3