diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_solidify_extrude.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_solidify_extrude.c | 209 |
1 files changed, 97 insertions, 112 deletions
diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c index 47277577d3e..f1758b91a91 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.c +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c @@ -61,27 +61,16 @@ static void mesh_calc_hq_normal(Mesh *mesh, #endif ) { - int i, verts_num, edges_num, polys_num; - MPoly *mpoly, *mp; - MLoop *mloop, *ml; - MEdge *medge, *ed; + int i; - verts_num = mesh->totvert; - edges_num = mesh->totedge; - polys_num = mesh->totpoly; - mpoly = mesh->mpoly; - medge = mesh->medge; - mloop = mesh->mloop; + const int verts_num = mesh->totvert; + const int edges_num = mesh->totedge; + const int polys_num = mesh->totpoly; + const MPoly *mpoly = BKE_mesh_polys(mesh); + const MLoop *mloop = BKE_mesh_loops(mesh); + const MEdge *medge = BKE_mesh_edges(mesh); - /* we don't want to overwrite any referenced layers */ - - /* Doesn't work here! */ -#if 0 - mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, verts_num); - cddm->mvert = mv; -#endif - - mp = mpoly; + const MPoly *mp = mpoly; { EdgeFaceRef *edge_ref_array = MEM_calloc_arrayN( @@ -93,7 +82,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, for (i = 0; i < polys_num; i++, mp++) { int j; - ml = mloop + mp->loopstart; + const MLoop *ml = mloop + mp->loopstart; for (j = 0; j < mp->totloop; j++, ml++) { /* --- add edge ref to face --- */ @@ -116,6 +105,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, } } + const MEdge *ed; for (i = 0, ed = medge, edge_ref = edge_ref_array; i < edges_num; i++, ed++, edge_ref++) { /* Get the edge vert indices, and edge value (the face indices that use it) */ @@ -166,10 +156,6 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex Mesh *result; const SolidifyModifierData *smd = (SolidifyModifierData *)md; - MVert *mv, *mvert, *orig_mvert; - MEdge *ed, *medge, *orig_medge; - MLoop *ml, *mloop, *orig_mloop; - MPoly *mp, *mpoly, *orig_mpoly; const uint verts_num = (uint)mesh->totvert; const uint edges_num = (uint)mesh->totedge; const uint polys_num = (uint)mesh->totpoly; @@ -216,7 +202,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex const bool do_shell = !(do_rim && (smd->flag & MOD_SOLIDIFY_NOSHELL) != 0); /* weights */ - MDeformVert *dvert; + const MDeformVert *dvert; const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0; int defgrp_index; const int shell_defgrp_index = BKE_id_defgroup_name_index(&mesh->id, smd->shell_defgrp_name); @@ -229,10 +215,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index); - orig_mvert = mesh->mvert; - orig_medge = mesh->medge; - orig_mloop = mesh->mloop; - orig_mpoly = mesh->mpoly; + const MVert *orig_mvert = BKE_mesh_verts(mesh); + const MEdge *orig_medge = BKE_mesh_edges(mesh); + const MPoly *orig_mpoly = BKE_mesh_polys(mesh); + const MLoop *orig_mloop = BKE_mesh_loops(mesh); if (need_poly_normals) { /* calculate only face normals */ @@ -262,16 +248,17 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex copy_vn_i(edge_users, edges_num, INVALID_UNUSED); #endif + const MEdge *ed; for (eidx = 0, ed = orig_medge; eidx < edges_num; eidx++, ed++) { edge_users[eidx] = INVALID_UNUSED; } + const MPoly *mp; for (i = 0, mp = orig_mpoly; i < polys_num; i++, mp++) { - MLoop *ml_prev; int j; - ml = orig_mloop + mp->loopstart; - ml_prev = ml + (mp->totloop - 1); + const MLoop *ml = orig_mloop + mp->loopstart; + const MLoop *ml_prev = ml + (mp->totloop - 1); for (j = 0; j < mp->totloop; j++, ml++) { /* add edge user */ @@ -348,15 +335,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex (int)((loops_num * stride) + newLoops), (int)((polys_num * stride) + newPolys)); - mpoly = result->mpoly; - mloop = result->mloop; - medge = result->medge; - mvert = result->mvert; - - if (do_bevel_convex) { - /* Make sure bweight is enabled. */ - result->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT; - } + MVert *mvert = BKE_mesh_verts_for_write(result); + MEdge *medge = BKE_mesh_edges_for_write(result); + MPoly *mpoly = BKE_mesh_polys_for_write(result); + MLoop *mloop = BKE_mesh_loops_for_write(result); if (do_shell) { CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)verts_num); @@ -405,6 +387,12 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)polys_num); } + float *result_edge_bweight = NULL; + if (do_bevel_convex) { + result_edge_bweight = CustomData_add_layer( + &result->edata, CD_BWEIGHT, CD_SET_DEFAULT, NULL, result->totedge); + } + /* initializes: (i_end, do_shell_align, mv). */ #define INIT_VERT_ARRAY_OFFSETS(test) \ if (((ofs_new >= ofs_orig) == do_flip) == test) { \ @@ -425,12 +413,14 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } \ (void)0 + int *dst_material_index = BKE_mesh_material_indices_for_write(result); + /* flip normals */ if (do_shell) { uint i; - mp = mpoly + polys_num; + MPoly *mp = mpoly + polys_num; for (i = 0; i < mesh->totpoly; i++, mp++) { const int loop_end = mp->totloop - 1; MLoop *ml2; @@ -462,8 +452,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex #endif if (mat_ofs) { - mp->mat_nr += mat_ofs; - CLAMP(mp->mat_nr, 0, mat_nr_max); + dst_material_index[mp - mpoly] += mat_ofs; + CLAMP(dst_material_index[mp - mpoly], 0, mat_nr_max); } e = ml2[0].e; @@ -480,6 +470,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } } + MEdge *ed; for (i = 0, ed = medge + edges_num; i < edges_num; i++, ed++) { ed->v1 += verts_num; ed->v2 += verts_num; @@ -528,15 +519,15 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex edge_user_pairs[eidx][0] = INVALID_UNUSED; edge_user_pairs[eidx][1] = INVALID_UNUSED; } - mp = orig_mpoly; + const MPoly *mp = orig_mpoly; for (uint i = 0; i < polys_num; i++, mp++) { - ml = orig_mloop + mp->loopstart; - MLoop *ml_prev = ml + (mp->totloop - 1); + const MLoop *ml = orig_mloop + mp->loopstart; + const MLoop *ml_prev = ml + (mp->totloop - 1); for (uint j = 0; j < mp->totloop; j++, ml++) { /* add edge user */ eidx = ml_prev->e; - ed = orig_medge + eidx; + const MEdge *ed = orig_medge + eidx; BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) && ELEM(ml->v, ed->v1, ed->v2)); char flip = (char)((ml_prev->v > ml->v) == (ed->v1 < ed->v2)); if (edge_user_pairs[eidx][flip] == INVALID_UNUSED) { @@ -549,7 +540,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex ml_prev = ml; } } - ed = orig_medge; + const MEdge *ed = orig_medge; float e[3]; for (uint i = 0; i < edges_num; i++, ed++) { if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) && @@ -580,12 +571,13 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex ofs_new_vgroup = ofs_new; + MVert *mv; INIT_VERT_ARRAY_OFFSETS(false); for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { const uint i = do_shell_align ? i_orig : new_vert_arr[i_orig]; if (dvert) { - MDeformVert *dv = &dvert[i]; + const MDeformVert *dv = &dvert[i]; if (defgrp_invert) { ofs_new_vgroup = 1.0f - BKE_defvert_find_weight(dv, defgrp_index); } @@ -631,12 +623,13 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex ofs_new_vgroup = ofs_orig; /* as above but swapped */ + MVert *mv; INIT_VERT_ARRAY_OFFSETS(true); for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { const uint i = do_shell_align ? i_orig : new_vert_arr[i_orig]; if (dvert) { - MDeformVert *dv = &dvert[i]; + const MDeformVert *dv = &dvert[i]; if (defgrp_invert) { ofs_new_vgroup = 1.0f - BKE_defvert_find_weight(dv, defgrp_index); } @@ -679,20 +672,18 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex for (uint i = 0; i < edges_num; i++) { if (edge_users[i] == INVALID_PAIR) { float angle = edge_angs[i]; - medge[i].bweight = (char)clamp_i( - (int)medge[i].bweight + (int)((angle < M_PI ? clamp_f(bevel_convex, 0.0f, 1.0f) : - clamp_f(bevel_convex, -1.0f, 0.0f)) * - 255), - 0, - 255); + result_edge_bweight[i] = clamp_f(result_edge_bweight[i] + + (angle < M_PI ? clamp_f(bevel_convex, 0.0f, 1.0f) : + clamp_f(bevel_convex, -1.0f, 0.0f)), + 0.0f, + 1.0f); if (do_shell) { - medge[i + edges_num].bweight = (char)clamp_i( - (int)medge[i + edges_num].bweight + - (int)((angle > M_PI ? clamp_f(bevel_convex, 0.0f, 1.0f) : - clamp_f(bevel_convex, -1.0f, 0.0f)) * - 255), + result_edge_bweight[i + edges_num] = clamp_f( + result_edge_bweight[i + edges_num] + (angle > M_PI ? + clamp_f(bevel_convex, 0.0f, 1.0f) : + clamp_f(bevel_convex, -1.0f, 0.0f)), 0, - 255); + 1.0f); } } } @@ -722,11 +713,13 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (vert_nors == NULL) { vert_nors = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "mod_solid_vno"); + const MVert *mv; for (i = 0, mv = mvert; i < verts_num; i++, mv++) { copy_v3_v3(vert_nors[i], mesh_vert_normals[i]); } } + const MPoly *mp; for (i = 0, mp = mpoly; i < polys_num; i++, mp++) { /* #BKE_mesh_calc_poly_angles logic is inlined here */ float nor_prev[3]; @@ -735,7 +728,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex int i_curr = mp->totloop - 1; int i_next = 0; - ml = &mloop[mp->loopstart]; + const MLoop *ml = &mloop[mp->loopstart]; sub_v3_v3v3(nor_prev, mvert[ml[i_curr - 1].v].co, mvert[ml[i_curr].v].co); normalize_v3(nor_prev); @@ -779,7 +772,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex /* vertex group support */ if (dvert) { - MDeformVert *dv = dvert; + const MDeformVert *dv = dvert; float scalar; if (defgrp_invert) { @@ -822,13 +815,13 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex edge_user_pairs[eidx][1] = INVALID_UNUSED; } for (i = 0, mp = orig_mpoly; i < polys_num; i++, mp++) { - ml = orig_mloop + mp->loopstart; - MLoop *ml_prev = ml + (mp->totloop - 1); + const MLoop *ml = orig_mloop + mp->loopstart; + const MLoop *ml_prev = ml + (mp->totloop - 1); for (int j = 0; j < mp->totloop; j++, ml++) { /* add edge user */ eidx = ml_prev->e; - ed = orig_medge + eidx; + const MEdge *ed = orig_medge + eidx; BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) && ELEM(ml->v, ed->v1, ed->v2)); char flip = (char)((ml_prev->v > ml->v) == (ed->v1 < ed->v2)); if (edge_user_pairs[eidx][flip] == INVALID_UNUSED) { @@ -841,7 +834,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex ml_prev = ml; } } - ed = orig_medge; + const MEdge *ed = orig_medge; float e[3]; for (i = 0; i < edges_num; i++, ed++) { if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) && @@ -906,20 +899,17 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex for (i = 0; i < edges_num; i++) { if (edge_users[i] == INVALID_PAIR) { float angle = edge_angs[i]; - medge[i].bweight = (char)clamp_i( - (int)medge[i].bweight + (int)((angle < M_PI ? clamp_f(bevel_convex, 0, 1) : - clamp_f(bevel_convex, -1, 0)) * - 255), - 0, - 255); + result_edge_bweight[i] = clamp_f(result_edge_bweight[i] + + (angle < M_PI ? clamp_f(bevel_convex, 0.0f, 1.0f) : + clamp_f(bevel_convex, -1.0f, 0.0f)), + 0.0f, + 1.0f); if (do_shell) { - medge[i + edges_num].bweight = (char)clamp_i( - (int)medge[i + edges_num].bweight + - (int)((angle > M_PI ? clamp_f(bevel_convex, 0, 1) : - clamp_f(bevel_convex, -1, 0)) * - 255), - 0, - 255); + result_edge_bweight[i + edges_num] = clamp_f( + result_edge_bweight[i + edges_num] + + (angle > M_PI ? clamp_f(bevel_convex, 0, 1) : clamp_f(bevel_convex, -1, 0)), + 0.0f, + 1.0f); } } } @@ -936,6 +926,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex uint i_orig, i_end; bool do_shell_align; + MVert *mv; INIT_VERT_ARRAY_OFFSETS(false); for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { @@ -952,6 +943,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex bool do_shell_align; /* same as above but swapped, intentional use of 'ofs_new' */ + MVert *mv; INIT_VERT_ARRAY_OFFSETS(true); for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { @@ -981,7 +973,6 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex else if (do_shell) { uint i; /* flip vertex normals for copied verts */ - mv = mvert + verts_num; for (i = 0; i < verts_num; i++) { negate_v3((float *)mesh_vert_normals[i]); } @@ -989,22 +980,15 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex /* Add vertex weights for rim and shell vgroups. */ if (shell_defgrp_index != -1 || rim_defgrp_index != -1) { - dvert = CustomData_duplicate_referenced_layer(&result->vdata, CD_MDEFORMVERT, result->totvert); - /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ - if (dvert == NULL) { - /* Add a valid data layer! */ - dvert = CustomData_add_layer( - &result->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, result->totvert); - } + MDeformVert *dst_dvert = BKE_mesh_deform_verts_for_write(result); + /* Ultimate security check. */ - if (dvert != NULL) { - result->dvert = dvert; + if (dst_dvert != NULL) { if (rim_defgrp_index != -1) { for (uint i = 0; i < rimVerts; i++) { - BKE_defvert_ensure_index(&result->dvert[new_vert_arr[i]], rim_defgrp_index)->weight = - 1.0f; - BKE_defvert_ensure_index(&result->dvert[(do_shell ? new_vert_arr[i] : i) + verts_num], + BKE_defvert_ensure_index(&dst_dvert[new_vert_arr[i]], rim_defgrp_index)->weight = 1.0f; + BKE_defvert_ensure_index(&dst_dvert[(do_shell ? new_vert_arr[i] : i) + verts_num], rim_defgrp_index) ->weight = 1.0f; } @@ -1012,7 +996,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (shell_defgrp_index != -1) { for (uint i = verts_num; i < result->totvert; i++) { - BKE_defvert_ensure_index(&result->dvert[i], shell_defgrp_index)->weight = 1.0f; + BKE_defvert_ensure_index(&dst_dvert[i], shell_defgrp_index)->weight = 1.0f; } } } @@ -1040,22 +1024,23 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex NULL; float nor[3]; #endif - const uchar crease_rim = smd->crease_rim * 255.0f; - const uchar crease_outer = smd->crease_outer * 255.0f; - const uchar crease_inner = smd->crease_inner * 255.0f; + const float crease_rim = smd->crease_rim; + const float crease_outer = smd->crease_outer; + const float crease_inner = smd->crease_inner; int *origindex_edge; int *orig_ed; uint j; + float *result_edge_crease = NULL; if (crease_rim || crease_outer || crease_inner) { - result->cd_flag |= ME_CDFLAG_EDGE_CREASE; + result_edge_crease = (float *)CustomData_get_layer(&result->edata, CD_CREASE); } /* add faces & edges */ origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX); orig_ed = (origindex_edge) ? &origindex_edge[(edges_num * stride) + newEdges] : NULL; - ed = &medge[(edges_num * stride) + newEdges]; /* start after copied edges */ + MEdge *ed = &medge[(edges_num * stride) + newEdges]; /* start after copied edges */ for (i = 0; i < rimVerts; i++, ed++) { ed->v1 = new_vert_arr[i]; ed->v2 = (do_shell ? new_vert_arr[i] : i) + verts_num; @@ -1067,13 +1052,13 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } if (crease_rim) { - ed->crease = crease_rim; + result_edge_crease[ed - medge] = crease_rim; } } /* faces */ - mp = mpoly + (polys_num * stride); - ml = mloop + (loops_num * stride); + MPoly *mp = mpoly + (polys_num * stride); + MLoop *ml = mloop + (loops_num * stride); j = 0; for (i = 0; i < newPolys; i++, mp++) { uint eidx = new_edge_arr[i]; @@ -1151,21 +1136,21 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex /* use the next material index if option enabled */ if (mat_ofs_rim) { - mp->mat_nr += mat_ofs_rim; - CLAMP(mp->mat_nr, 0, mat_nr_max); + dst_material_index[mp - mpoly] += mat_ofs_rim; + CLAMP(dst_material_index[mp - mpoly], 0, mat_nr_max); } if (crease_outer) { /* crease += crease_outer; without wrapping */ - char *cr = &(ed->crease); - int tcr = *cr + crease_outer; - *cr = tcr > 255 ? 255 : tcr; + float *cr = &(result_edge_crease[ed - medge]); + float tcr = *cr + crease_outer; + *cr = tcr > 1.0f ? 1.0f : tcr; } if (crease_inner) { /* crease += crease_inner; without wrapping */ - char *cr = &(medge[edges_num + (do_shell ? eidx : i)].crease); - int tcr = *cr + crease_inner; - *cr = tcr > 255 ? 255 : tcr; + float *cr = &(result_edge_crease[edges_num + (do_shell ? eidx : i)]); + float tcr = *cr + crease_inner; + *cr = tcr > 1.0f ? 1.0f : tcr; } #ifdef SOLIDIFY_SIDE_NORMALS |