diff options
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_evaluate.c | 55 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_mesh_api.c | 36 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_triangulate.c | 27 |
4 files changed, 73 insertions, 62 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index d6b9f0a70ca..07d04a55496 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -295,6 +295,7 @@ enum { MLNOR_SPACEARR_BMLOOP_PTR = 1, }; +/* Low-level custom normals functions. */ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr, const int numLoops, const char data_type); void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr); void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr); @@ -308,11 +309,7 @@ void BKE_lnor_space_add_loop( void BKE_lnor_space_custom_data_to_normal(MLoopNorSpace *lnor_space, const short clnor_data[2], float r_custom_lnor[3]); void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space, const float custom_lnor[3], short r_clnor_data[2]); -bool BKE_mesh_has_custom_loop_normals(struct Mesh *me); - -void BKE_mesh_calc_normals_split(struct Mesh *mesh); -void BKE_mesh_calc_normals_split_ex(struct Mesh *mesh, struct MLoopNorSpaceArray *r_lnors_spacearr); - +/* Medium-level custom normals functions. */ void BKE_mesh_normals_loop_split( const struct MVert *mverts, const int numVerts, struct MEdge *medges, const int numEdges, struct MLoop *mloops, float (*r_loopnors)[3], const int numLoops, @@ -335,6 +332,16 @@ void BKE_mesh_normals_loop_to_vertex( const int numVerts, const struct MLoop *mloops, const int numLoops, const float (*clnors)[3], float (*r_vert_clnors)[3]); +/* High-level custom normals functions. */ +bool BKE_mesh_has_custom_loop_normals(struct Mesh *me); + +void BKE_mesh_calc_normals_split(struct Mesh *mesh); +void BKE_mesh_calc_normals_split_ex(struct Mesh *mesh, struct MLoopNorSpaceArray *r_lnors_spacearr); + +void BKE_mesh_set_custom_normals(struct Mesh *mesh, float (*r_custom_loopnors)[3]); +void BKE_mesh_set_custom_normals_from_vertices(struct Mesh *mesh, float (*r_custom_vertnors)[3]); + + void BKE_mesh_calc_poly_normal( const struct MPoly *mpoly, const struct MLoop *loopstart, const struct MVert *mvarray, float r_no[3]); diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index ccd10a77bcc..a5338b3a6be 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -1850,6 +1850,61 @@ void BKE_mesh_normals_loop_custom_from_vertices_set( mpolys, polynors, numPolys, r_clnors_data, true); } +static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const bool use_vertices) +{ + short (*clnors)[2]; + const int numloops = mesh->totloop; + + clnors = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); + if (clnors != NULL) { + memset(clnors, 0, sizeof(*clnors) * (size_t)numloops); + } + else { + clnors = CustomData_add_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, numloops); + } + + float (*polynors)[3] = CustomData_get_layer(&mesh->pdata, CD_NORMAL); + bool free_polynors = false; + if (polynors == NULL) { + polynors = MEM_mallocN(sizeof(float[3]) * (size_t)mesh->totpoly, __func__); + BKE_mesh_calc_normals_poly( + mesh->mvert, NULL, mesh->totvert, + mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly, polynors, false); + free_polynors = true; + } + + mesh_normals_loop_custom_set( + mesh->mvert, mesh->totvert, mesh->medge, mesh->totedge, mesh->mloop, r_custom_nors, mesh->totloop, + mesh->mpoly, polynors, mesh->totpoly, clnors, use_vertices); + + if (free_polynors) { + MEM_freeN(polynors); + } +} + +/** + * Higher level functions hiding most of the code needed around call to #BKE_mesh_normals_loop_custom_set(). + * + * \param r_custom_loopnors is not const, since code will replace zero_v3 normals there + * with automatically computed vectors. + */ +void BKE_mesh_set_custom_normals(Mesh *mesh, float (*r_custom_loopnors)[3]) +{ + mesh_set_custom_normals(mesh, r_custom_loopnors, false); +} + +/** + * Higher level functions hiding most of the code needed around call to #BKE_mesh_normals_loop_custom_from_vertices_set(). + * + * \param r_custom_loopnors is not const, since code will replace zero_v3 normals there + * with automatically computed vectors. + */ +void BKE_mesh_set_custom_normals_from_vertices(Mesh *mesh, float (*r_custom_vertnors)[3]) +{ + mesh_set_custom_normals(mesh, r_custom_vertnors, true); +} + + /** * Computes average per-vertex normals from given custom loop normals. * diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 444831cb75d..7bedd110947 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -112,43 +112,11 @@ static void rna_Mesh_calc_smooth_groups(Mesh *mesh, bool use_bitflags, int *r_po static void rna_Mesh_normals_split_custom_do(Mesh *mesh, float (*custom_loopnors)[3], const bool use_vertices) { - float (*polynors)[3]; - short (*clnors)[2]; - const int numloops = mesh->totloop; - bool free_polynors = false; - - clnors = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); - if (clnors) { - memset(clnors, 0, sizeof(*clnors) * numloops); - } - else { - clnors = CustomData_add_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_DEFAULT, NULL, numloops); - } - - if (CustomData_has_layer(&mesh->pdata, CD_NORMAL)) { - polynors = CustomData_get_layer(&mesh->pdata, CD_NORMAL); - } - else { - polynors = MEM_mallocN(sizeof(float[3]) * mesh->totpoly, __func__); - BKE_mesh_calc_normals_poly( - mesh->mvert, NULL, mesh->totvert, - mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly, polynors, false); - free_polynors = true; - } - if (use_vertices) { - BKE_mesh_normals_loop_custom_from_vertices_set( - mesh->mvert, custom_loopnors, mesh->totvert, mesh->medge, mesh->totedge, mesh->mloop, mesh->totloop, - mesh->mpoly, (const float (*)[3])polynors, mesh->totpoly, clnors); + BKE_mesh_set_custom_normals_from_vertices(mesh, custom_loopnors); } else { - BKE_mesh_normals_loop_custom_set( - mesh->mvert, mesh->totvert, mesh->medge, mesh->totedge, mesh->mloop, custom_loopnors, mesh->totloop, - mesh->mpoly, (const float (*)[3])polynors, mesh->totpoly, clnors); - } - - if (free_polynors) { - MEM_freeN(polynors); + BKE_mesh_set_custom_normals(mesh, custom_loopnors); } } diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c index 4f6276492ea..94910fbe80e 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.c +++ b/source/blender/modifiers/intern/MOD_triangulate.c @@ -66,42 +66,23 @@ static Mesh *triangulate_mesh(Mesh *mesh, const int quad_method, const int ngon_ if (keep_clnors) { - bool free_pnors = false; - float (*pnors)[3] = CustomData_get_layer(&result->pdata, CD_NORMAL); - if (pnors == NULL) { - pnors = MEM_mallocN(sizeof(*pnors) * result->totpoly, __func__); - BKE_mesh_calc_normals_poly( - result->mvert, NULL, result->totvert, - result->mloop, result->mpoly, result->totloop, result->totpoly, pnors, false); - free_pnors = true; - } - float (*lnors)[3] = CustomData_get_layer(&result->ldata, CD_NORMAL); - short (*clnors)[2] = CustomData_get_layer(&result->ldata, CD_CUSTOMLOOPNORMAL); - if (clnors == NULL) { - clnors = CustomData_add_layer(&result->ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, result->totloop); - } + BLI_assert(lnors != NULL); - BKE_mesh_normals_loop_custom_set( - result->mvert, result->totvert, - result->medge, result->totedge, - result->mloop, lnors, result->totloop, - result->mpoly, pnors, result->totpoly, clnors); + BKE_mesh_set_custom_normals(result, lnors); /* Do some cleanup, we do not want those temp data to stay around. */ CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); - if (free_pnors) { - MEM_freeN(pnors); - } } total_edges = result->totedge; me = result->medge; /* force drawing of all edges (seems to be omitted in CDDM_from_bmesh) */ - for (i = 0; i < total_edges; i++, me++) + for (i = 0; i < total_edges; i++, me++) { me->flag |= ME_EDGEDRAW | ME_EDGERENDER; + } result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; |