diff options
Diffstat (limited to 'source/blender/blenkernel/intern/mesh_evaluate.c')
-rw-r--r-- | source/blender/blenkernel/intern/mesh_evaluate.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 40a09eba658..d17ca751c5e 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -226,7 +226,7 @@ void BKE_mesh_calc_normals_poly(MVert *mverts, int numVerts, MLoop *mloop, MPoly MPoly *mp; if (only_face_normals) { - BLI_assert(pnors != NULL); + BLI_assert((pnors != NULL) || (numPolys == 0)); #pragma omp parallel for if (numPolys > BKE_MESH_OMP_LIMIT) for (i = 0; i < numPolys; i++) { @@ -252,12 +252,12 @@ void BKE_mesh_calc_normals_poly(MVert *mverts, int numVerts, MLoop *mloop, MPoly } } - /* following Mesh convention; we use vertex coordinate itself for normal in this case */ for (i = 0; i < numVerts; i++) { MVert *mv = &mverts[i]; float *no = tnorms[i]; if (UNLIKELY(normalize_v3(no) == 0.0f)) { + /* following Mesh convention; we use vertex coordinate itself for normal in this case */ normalize_v3_v3(no, mv->co); } @@ -372,6 +372,10 @@ void BKE_lnor_space_define(MLoopNorSpace *lnor_space, const float lnor[3], /* If vec_ref or vec_other are too much aligned with lnor, we can't build lnor space, * tag it as invalid and abort. */ lnor_space->ref_alpha = lnor_space->ref_beta = 0.0f; + + if (edge_vectors) { + BLI_stack_clear(edge_vectors); + } return; } @@ -387,7 +391,9 @@ void BKE_lnor_space_define(MLoopNorSpace *lnor_space, const float lnor[3], BLI_stack_discard(edge_vectors); nbr++; } - BLI_assert(nbr > 2); /* This piece of code shall only be called for more than one loop... */ + /* Note: In theory, this could be 'nbr > 2', but there is one case where we only have two edges for + * two loops: a smooth vertex with only two edges and two faces (our Monkey's nose has that, e.g.). */ + BLI_assert(nbr >= 2); /* This piece of code shall only be called for more than one loop... */ lnor_space->ref_alpha = alpha / (float)nbr; } else { @@ -1347,6 +1353,10 @@ static void mesh_normals_loop_custom_set( const int nidx = lidx; float *nor = custom_loopnors[nidx]; + if (is_zero_v3(nor)) { + nor = lnors[nidx]; + } + if (!org_nor) { org_nor = nor; } @@ -1406,6 +1416,10 @@ static void mesh_normals_loop_custom_set( const int nidx = use_vertices ? (int)mloops[lidx].v : lidx; float *nor = custom_loopnors[nidx]; + if (is_zero_v3(nor)) { + nor = lnors[nidx]; + } + nbr_nors++; add_v3_v3(avg_nor, nor); BLI_SMALLSTACK_PUSH(clnors_data, (short *)r_clnors_data[lidx]); @@ -2243,12 +2257,15 @@ void BKE_mesh_loops_to_tessdata(CustomData *fdata, CustomData *ldata, CustomData /** * Recreate tessellation. * - * \param do_face_nor_copy controls whether the normals from the poly are copied to the tessellated faces. + * \param do_face_nor_copy: Controls whether the normals from the poly are copied to the tessellated faces. * * \return number of tessellation faces. */ -int BKE_mesh_recalc_tessellation(CustomData *fdata, CustomData *ldata, CustomData *pdata, - MVert *mvert, int totface, int totloop, int totpoly, const bool do_face_nor_cpy) +int BKE_mesh_recalc_tessellation( + CustomData *fdata, CustomData *ldata, CustomData *pdata, + MVert *mvert, + int totface, int totloop, int totpoly, + const bool do_face_nor_copy) { /* use this to avoid locking pthread for _every_ polygon * and calling the fill function */ @@ -2458,7 +2475,7 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, CustomData *ldata, CustomDat CustomData_add_layer(fdata, CD_ORIGINDEX, CD_ASSIGN, mface_to_poly_map, totface); CustomData_from_bmeshpoly(fdata, pdata, ldata, totface); - if (do_face_nor_cpy) { + if (do_face_nor_copy) { /* If polys have a normals layer, copying that to faces can help * avoid the need to recalculate normals later */ if (CustomData_has_layer(pdata, CD_NORMAL)) { |