Add 'loop slide' option to bevel. See T45260

Current behavior of bevel is to 'loop slide' along unbeveled edges
when possible, but this produces uneven bevel widths sometimes,
so this option lets user choose between having the loop slide effect
or having more even bevel widths. Trying it out with default being
'no loop slide', so different from current behavior. May reverse this
choice later, depending on user reactions.
This commit is contained in:
Howard Trickey 2015-07-05 09:53:17 -04:00
parent 51e9a814c9
commit 12aff8d783
Notes: blender-bot 2023-02-14 08:56:51 +01:00
Referenced by issue #45260, Uneven bevel widths when trying to loop slide
9 changed files with 24 additions and 12 deletions

View File

@ -132,6 +132,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col = split.column()
col.prop(md, "use_only_vertices")
col.prop(md, "use_clamp_overlap")
col.prop(md, "loop_slide")
layout.label(text="Limit Method:")
layout.row().prop(md, "limit_method", expand=True)

View File

@ -1727,6 +1727,7 @@ static BMOpDefine bmo_bevel_def = {
{"vertex_only", BMO_OP_SLOT_BOOL}, /* only bevel vertices, not edges */
{"clamp_overlap", BMO_OP_SLOT_BOOL}, /* do not allow beveled edges/vertices to overlap each other */
{"material", BMO_OP_SLOT_INT}, /* material for bevel faces, -1 means get from adjacent faces */
{"loop_slide", BMO_OP_SLOT_BOOL}, /* prefer to slide along edges to having even widths */
{{'\0'}},
},
/* slots_out */

View File

@ -42,6 +42,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
const float profile = BMO_slot_float_get(op->slots_in, "profile");
const bool clamp_overlap = BMO_slot_bool_get(op->slots_in, "clamp_overlap");
const int material = BMO_slot_int_get(op->slots_in, "material");
const bool loop_slide = BMO_slot_bool_get(op->slots_in, "loop_slide");
if (offset > 0) {
BMOIter siter;
@ -62,7 +63,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);
BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide);
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG);
}

View File

@ -186,7 +186,7 @@ typedef struct BevelParams {
float pro_super_r; /* superellipse parameter for edge profile */
bool vertex_only; /* bevel vertices only */
bool use_weights; /* bevel amount affected by weights on edges or verts */
bool preserve_widths; /* should bevel prefer widths over angles, if forced to choose? */
bool loop_slide; /* should bevel prefer to slide along edges rather than keep widths spec? */
bool limit_offset; /* should offsets be limited by collisions? */
const struct MDeformVert *dvert; /* vertex group array, maybe set if vertex_only */
int vertex_group; /* vertex group index, maybe set if vertex_only */
@ -1787,7 +1787,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
offset_meet(e, e2, bv->v, e->fnext, false, co);
}
else if (nnip > 0) {
if (nnip == 1 && good_offset_on_edge_between(e, e2, enip, bv->v)) {
if (bp->loop_slide && nnip == 1 && good_offset_on_edge_between(e, e2, enip, bv->v)) {
offset_on_edge_between(bp, e, e2, enip, bv->v, co);
}
else {
@ -1796,7 +1796,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
}
else {
/* nip > 0 and nnip == 0 */
if (nip == 1 && good_offset_on_edge_between(e, e2, eip, bv->v)) {
if (bp->loop_slide && nip == 1 && good_offset_on_edge_between(e, e2, eip, bv->v)) {
offset_on_edge_between(bp, e, e2, eip, bv->v, co);
}
else {
@ -1954,7 +1954,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
if (e->prev->prev->is_bev) {
BLI_assert(e->prev->prev != e); /* see: edgecount 2, selcount 1 case */
/* find meet point between e->prev->prev and e and attach e->prev there */
if (bp->preserve_widths)
if (!bp->loop_slide)
offset_in_two_planes(bp, e->prev->prev, e, e->prev, bv->v, co);
else
offset_on_edge_between(bp, e->prev->prev, e, e->prev, bv->v, co);
@ -4193,7 +4193,8 @@ void BM_mesh_bevel(
BMesh *bm, const float offset, const int offset_type,
const float segments, 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 struct MDeformVert *dvert, const int vertex_group, const int mat,
const bool loop_slide)
{
BMIter iter;
BMVert *v, *v_next;
@ -4207,7 +4208,7 @@ void BM_mesh_bevel(
bp.pro_super_r = 4.0f * profile; /* convert to superellipse exponent */
bp.vertex_only = vertex_only;
bp.use_weights = use_weights;
bp.preserve_widths = false;
bp.loop_slide = loop_slide;
bp.limit_offset = limit_offset;
bp.dvert = dvert;
bp.vertex_group = vertex_group;

View File

@ -33,6 +33,6 @@ void BM_mesh_bevel(
BMesh *bm, const float offset, const int offset_type, const float segments,
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 int mat, const bool loop_slide);
#endif /* __BMESH_BEVEL_H__ */

View File

@ -156,6 +156,7 @@ static bool edbm_bevel_calc(wmOperator *op)
const bool vertex_only = RNA_boolean_get(op->ptr, "vertex_only");
const bool clamp_overlap = RNA_boolean_get(op->ptr, "clamp_overlap");
int material = RNA_int_get(op->ptr, "material");
const bool loop_slide = RNA_boolean_get(op->ptr, "loop_slide");
/* revert to original mesh */
if (opdata->is_modal) {
@ -167,8 +168,8 @@ static bool edbm_bevel_calc(wmOperator *op)
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",
BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile, clamp_overlap, material);
"material=%i loop_slide=%b",
BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile, clamp_overlap, material, loop_slide);
BMO_op_exec(em->bm, &bmop);
@ -501,5 +502,6 @@ void MESH_OT_bevel(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "vertex_only", false, "Vertex Only", "Bevel only vertices");
RNA_def_boolean(ot->srna, "clamp_overlap", false, "Clamp Overlap",
"Do not allow beveled edges/vertices to overlap each other");
RNA_def_boolean(ot->srna, "loop_slide", false, "Loop Slide", "Prefer slide along edge to even widths");
RNA_def_int(ot->srna, "material", -1, -1, INT_MAX, "Material", "Material for bevel faces (-1 means use adjacent faces)", -1, 100);
}

View File

@ -338,6 +338,7 @@ enum {
/* MOD_BEVEL_EVEN = (1 << 11), */
/* MOD_BEVEL_DIST = (1 << 12), */ /* same as above */
MOD_BEVEL_OVERLAP_OK = (1 << 13),
MOD_BEVEL_LOOP_SLIDE = (1 << 14),
};
/* BevelModifierData->val_flags (not used as flags any more) */

View File

@ -2824,7 +2824,11 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
RNA_def_property_range(prop, -1, SHRT_MAX);
RNA_def_property_ui_text(prop, "Material", "Material index of generated faces, -1 for automatic");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "loop_slide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_BEVEL_LOOP_SLIDE);
RNA_def_property_ui_text(prop, "Loop Slide", "Prefer sliding along edges to having even widths");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
static void rna_def_modifier_shrinkwrap(BlenderRNA *brna)

View File

@ -112,6 +112,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob,
const bool do_clamp = !(bmd->flags & MOD_BEVEL_OVERLAP_OK);
const int offset_type = bmd->val_flags;
const int mat = CLAMPIS(bmd->mat, -1, ob->totcol - 1);
const bool loop_slide = (bmd->flags & MOD_BEVEL_LOOP_SLIDE) != 0;
bm = DM_to_bmesh(dm, true);
if ((bmd->lim_flags & MOD_BEVEL_VGROUP) && bmd->defgrp_name[0])
@ -173,7 +174,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob,
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);
dvert, vgroup, mat, loop_slide);
result = CDDM_from_bmesh(bm, true);