diff options
m--------- | release/scripts/addons | 0 | ||||
m--------- | release/scripts/addons_contrib | 0 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_opdefines.c | 1 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_bevel.c | 3 | ||||
-rw-r--r-- | source/blender/bmesh/tools/bmesh_bevel.c | 47 | ||||
-rw-r--r-- | source/blender/bmesh/tools/bmesh_bevel.h | 2 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_bevel.c | 16 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_bevel.c | 9 | ||||
m--------- | source/tools | 0 |
9 files changed, 70 insertions, 8 deletions
diff --git a/release/scripts/addons b/release/scripts/addons -Subproject 25ae9e134472c5bca62add0a1db3cdfc2d86aaa +Subproject 40340832e3992f46034b470aef1af6f7a3a4410 diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib -Subproject 4c5ddaeb2d1953ea9db10b2fdde2f93e19b1d6d +Subproject 272b1a4ef07717beb3d0bfcb7380c2164fd008a diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 2cae6fb3823..db4985c62f6 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -1765,6 +1765,7 @@ static BMOpDefine bmo_bevel_def = { {"harden_normals", BMO_OP_SLOT_BOOL}, /* harden normals */ {"face_strength_mode", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_bevel_face_strength_type}, /* whether to set face strength, and which faces to set if so */ + {"smoothresh", BMO_OP_SLOT_FLT}, /* for passing mesh's smoothresh, used in hardening */ {{'\0'}}, }, /* slots_out */ diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index 1ef8531397f..3277824b890 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -47,6 +47,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) const bool mark_sharp = BMO_slot_bool_get(op->slots_in, "mark_sharp"); const bool harden_normals = BMO_slot_bool_get(op->slots_in, "harden_normals"); const int face_strength_mode = BMO_slot_int_get(op->slots_in, "face_strength_mode"); + const float smoothresh = BMO_slot_float_get(op->slots_in, "smoothresh"); if (offset > 0) { BMOIter siter; @@ -72,7 +73,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) BM_mesh_bevel( bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, - loop_slide, mark_seam, mark_sharp, harden_normals, face_strength_mode); + loop_slide, mark_seam, mark_sharp, harden_normals, face_strength_mode, smoothresh); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG); diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 7149df7dc4e..452dfa22993 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -222,6 +222,7 @@ typedef struct BevelParams { int vertex_group; /* vertex group index, maybe set if vertex_only */ int mat_nr; /* if >= 0, material number for bevel; else material comes from adjacent faces */ int face_strength_mode; /* setting face strength if > 0 */ + float smoothresh; /* mesh's smoothresh, used if hardening */ } BevelParams; // #pragma GCC diagnostic ignored "-Wpadded" @@ -1703,6 +1704,33 @@ static void bevel_extend_edge_data(BevVert *bv) } while (bcur != start); } +/* Mark edges as sharp if they are between a smooth recon face and a new face. */ +static void bevel_edges_sharp_boundary(BMesh *bm, BevelParams *bp) +{ + BMIter fiter, liter; + BMFace *f, *fother; + BMLoop *l, *lother; + FKind fkind; + + BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { + if (!BM_elem_flag_test(f, BM_ELEM_SMOOTH)) + continue; + if (get_face_kind(bp, f) != F_RECON) + continue; + BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) { + /* cases we care about will have exactly one adjacent face */ + lother = l->radial_next; + fother = lother->f; + if (lother != l && fother) { + fkind = get_face_kind(bp, lother->f); + if (ELEM(fkind, F_EDGE, F_VERT)) { + BM_elem_flag_disable(l->e, BM_ELEM_SMOOTH); + } + } + } + } +} + /* * Harden normals for bevel. * The desired effect is that the newly created F_EDGE and F_VERT faces appear smoothly shaded @@ -1725,11 +1753,25 @@ static void bevel_harden_normals(BMesh *bm, BevelParams *bp) return; /* recalculate all face and vertex normals; side effect: ensures vertex, edge, face indices */ + /* I suspect this is not necessary: TODO: test that guess */ BM_mesh_normals_update(bm); + cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + + /* If there is not already a custom split normal layer then making one (with BM_lnorspace_update) + * will not respect the autosmooth angle between smooth faces. To get that to happen, we have + * to mark the sharpen the edges that are only sharp because of the angle test -- otherwise would be smooth. + */ + if (cd_clnors_offset == -1) { + BM_edges_sharp_from_angle_set(bm, bp->smoothresh); + bevel_edges_sharp_boundary(bm, bp); + } + /* ensure that bm->lnor_spacearr has properly stored loop normals; side effect: ensures loop indices */ BM_lnorspace_update(bm); - cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); + + if (cd_clnors_offset == -1) + cd_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL); BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) { fkind = get_face_kind(bp, f); @@ -5677,7 +5719,7 @@ void BM_mesh_bevel( const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group, const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp, - const bool harden_normals, const int face_strength_mode) + const bool harden_normals, const int face_strength_mode, const float smoothresh) { BMIter iter, liter; BMVert *v, *v_next; @@ -5704,6 +5746,7 @@ void BM_mesh_bevel( bp.mark_sharp = mark_sharp; bp.harden_normals = harden_normals; bp.face_strength_mode = face_strength_mode; + bp.smoothresh = smoothresh; bp.face_hash = NULL; if (profile >= 0.950f) { /* r ~ 692, so PRO_SQUARE_R is 1e4 */ diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h index 2bfa2be8f1c..36a80ee5e25 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.h +++ b/source/blender/bmesh/tools/bmesh_bevel.h @@ -34,6 +34,6 @@ void BM_mesh_bevel( const float profile, const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group, const int mat, const bool loop_slide, const bool mark_seam, const bool mark_sharp, - const bool harden_normals, const int face_strength_mode); + const bool harden_normals, const int face_strength_mode, const float smoothresh); #endif /* __BMESH_BEVEL_H__ */ diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index ff259f01f64..0d99c433c11 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -41,6 +41,8 @@ #include "BKE_layer.h" #include "BKE_mesh.h" +#include "DNA_mesh_types.h" + #include "RNA_define.h" #include "RNA_access.h" @@ -231,6 +233,7 @@ static bool edbm_bevel_calc(wmOperator *op) const bool harden_normals = RNA_boolean_get(op->ptr, "harden_normals"); const int face_strength_mode = RNA_enum_get(op->ptr, "face_strength_mode"); + for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) { em = opdata->ob_store[ob_index].em; @@ -243,12 +246,21 @@ static bool edbm_bevel_calc(wmOperator *op) material = CLAMPIS(material, -1, em->ob->totcol - 1); } + Mesh *me = em->ob->data; + + if (harden_normals && !(me->flag & ME_AUTOSMOOTH)) { + /* harden_normals only has a visible effect if autosmooth is on, so turn it on */ + me->flag |= ME_AUTOSMOOTH; + } + EDBM_op_init( em, &bmop, op, "bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f clamp_overlap=%b " - "material=%i loop_slide=%b mark_seam=%b mark_sharp=%b harden_normals=%b face_strength_mode=%i", + "material=%i loop_slide=%b mark_seam=%b mark_sharp=%b harden_normals=%b face_strength_mode=%i " + "smoothresh=%f", BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile, - clamp_overlap, material, loop_slide, mark_seam, mark_sharp, harden_normals, face_strength_mode); + clamp_overlap, material, loop_slide, mark_seam, mark_sharp, harden_normals, face_strength_mode, + me->smoothresh); BMO_op_exec(em->bm, &bmop); diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index e63b5407a74..363cdb083d4 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -116,7 +116,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes const bool loop_slide = (bmd->flags & MOD_BEVEL_EVEN_WIDTHS) == 0; const bool mark_seam = (bmd->edge_flags & MOD_BEVEL_MARK_SEAM); const bool mark_sharp = (bmd->edge_flags & MOD_BEVEL_MARK_SHARP); - const bool harden_normals = (bmd->flags & MOD_BEVEL_HARDEN_NORMALS); + bool harden_normals = (bmd->flags & MOD_BEVEL_HARDEN_NORMALS); const int face_strength_mode = bmd->face_str_mode; bm = BKE_mesh_to_bmesh_ex( @@ -187,10 +187,15 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes } } + if (harden_normals && !(((Mesh *)ctx->object->data)->flag & ME_AUTOSMOOTH)) { + modifier_setError(md, "Enable 'Auto Smooth' option in mesh settings for hardening"); + harden_normals = false; + } + BM_mesh_bevel(bm, bmd->value, offset_type, bmd->res, bmd->profile, vertex_only, bmd->lim_flags & MOD_BEVEL_WEIGHT, do_clamp, dvert, vgroup, mat, loop_slide, mark_seam, mark_sharp, - harden_normals, face_strength_mode); + harden_normals, face_strength_mode, mesh->smoothresh); result = BKE_mesh_from_bmesh_for_eval_nomain(bm, 0); diff --git a/source/tools b/source/tools -Subproject 279c373280e54388ede50abea9d11d5cdaa1d56 +Subproject aef8f32086b9393d286c49cbe5a51ae465fe058 |