Add 'loop slide' option to bevel. See T45260
authorHoward Trickey <howard.trickey@gmail.com>
Sun, 5 Jul 2015 13:53:17 +0000 (09:53 -0400)
committerHoward Trickey <howard.trickey@gmail.com>
Sun, 5 Jul 2015 13:53:17 +0000 (09:53 -0400)
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.

release/scripts/startup/bl_ui/properties_data_modifier.py
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/operators/bmo_bevel.c
source/blender/bmesh/tools/bmesh_bevel.c
source/blender/bmesh/tools/bmesh_bevel.h
source/blender/editors/mesh/editmesh_bevel.c
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesrna/intern/rna_modifier.c
source/blender/modifiers/intern/MOD_bevel.c

index 381c9add34fbf25d506da9f6d331649f068ad251..549c75d6fdaf16a51f8adbc63bd36945761aec96 100644 (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)
index 687fb62795f62eb9e5da155fb9e3bb3e44f8beb7..3e814948ade662e47e3ecce1bf72e0373b0b2e1f 100644 (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 */
index 864c4dada6d868517144a0f6923e05e924e592e8..d5afb39d7b79f40903e4b7cd43e600b4e4f95d11 100644 (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);
        }
index 3348afa3bfad7f1345394c44c8f77417c7f75879..791669fa0fc6e06b56fc518164453c3fb67a3d2b 100644 (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;
index b4bb6c56b7dc796b8aebad2f64071b9ae07b358f..386dc8a1fcec86abc365ce5280186e1fca847ef7 100644 (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__ */
index 1abb7a308898ad38cbe8b4624b7e516d9c693a85..709977629096715cda0cf8ef52ca64a1d928d650 100644 (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);
 }
index 1fc66b9b016ea3cb42b036103af42e98ec4fd11b..8319dc3a874c211a32a136d05ba7ffbf4ffc3279 100644 (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) */
index 087db2bedcde05014ffd0dc00e05c0456653ab47..7bbf975ac85ead4af4d5d716dc56db6dcf9ca057 100644 (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)
index c2b5a29939f187fe07e49c5971c411db7fff4a58..63e4b15d52e70ad13098ac6c69f2b286c20aac21 100644 (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);