Enable new bevel tool code in bevel modifier.
authorHoward Trickey <howard.trickey@gmail.com>
Thu, 21 Feb 2013 17:29:35 +0000 (17:29 +0000)
committerHoward Trickey <howard.trickey@gmail.com>
Thu, 21 Feb 2013 17:29:35 +0000 (17:29 +0000)
Now modifier takes a segments parameter.
Bevel edge weights will multiply the overall amount.
For vertex-only, you can give a vertex group name,
and the weights in that will multiply the overall amount.

release/scripts/startup/bl_ui/properties_data_modifier.py
source/blender/blenkernel/BKE_bmesh.h
source/blender/bmesh/operators/bmo_bevel.c
source/blender/bmesh/tools/bmesh_bevel.c
source/blender/bmesh/tools/bmesh_bevel.h
source/blender/makesrna/intern/rna_modifier.c
source/blender/modifiers/intern/MOD_bevel.c

index 7be0019..05e189c 100644 (file)
@@ -124,20 +124,17 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         split.prop(md, "width")
         split.prop(md, "use_only_vertices")
 
-        # -- new modifier only, this may be reverted in favor of 2.62 mod.
-        '''
-        split = layout.split()
-        split.prop(md, "use_even_offset")
-        split.prop(md, "use_distance_offset")
-        '''
-        # -- end
+        layout.prop(md, "segments")
 
         layout.label(text="Limit Method:")
         layout.row().prop(md, "limit_method", expand=True)
         if md.limit_method == 'ANGLE':
             layout.prop(md, "angle_limit")
-        elif md.limit_method == 'WEIGHT':
-            layout.row().prop(md, "edge_weight_method", expand=True)
+        elif md.limit_method == 'VGROUP':
+            layout.label(text="Vertex Group:")
+            layout.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+        # elif md.limit_method == 'WEIGHT':
+        #    layout.row().prop(md, "edge_weight_method", expand=True)
 
     def BOOLEAN(self, layout, ob, md):
         split = layout.split()
index 8bfee83..4bc2162 100644 (file)
@@ -38,7 +38,7 @@
 /*NOTE: this is the bmesh 1.0 code.  it's completely outdated.*/
 
 /* uncomment to use the new bevel operator as a modifier */
-// #define USE_BM_BEVEL_OP_AS_MOD
+#define USE_BM_BEVEL_OP_AS_MOD
 
 /* bevel tool defines */
 /* element flags */
@@ -53,6 +53,7 @@
 #define BME_BEVEL_RADIUS        (1 << 2)
 #define BME_BEVEL_ANGLE         (1 << 3)
 #define BME_BEVEL_WEIGHT        (1 << 4)
+#define BME_BEVEL_VGROUP        (1 << 5)
 //~ #define BME_BEVEL_EWEIGHT          (1<<4)
 //~ #define BME_BEVEL_VWEIGHT          (1<<5)
 #define BME_BEVEL_PERCENT       (1 << 6)
index c56af82..795531d 100644 (file)
@@ -55,7 +55,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
                        }
                }
 
-               BM_mesh_bevel(bm, offset, seg, vonly);
+               BM_mesh_bevel(bm, offset, seg, vonly, false, NULL, -1);
 
                BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG);
        }
index 1e74354..5adef16 100644 (file)
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_object_types.h"
+#include "DNA_meshdata_types.h"
+
 #include "BLI_array.h"
 #include "BLI_math.h"
 #include "BLI_memarena.h"
 
 #include "BKE_customdata.h"
+#include "BKE_deform.h"
 
 #include "bmesh.h"
 #include "./intern/bmesh_private.h"
@@ -104,6 +108,7 @@ typedef struct BevVert {
        BMVert *v;          /* original mesh vertex */
        int edgecount;          /* total number of edges around the vertex */
        int selcount;           /* number of selected edges around the vertex */
+       float offset;           /* offset for this vertex, if vertex_only bevel */
        EdgeHalf *edges;        /* array of size edgecount; CCW order from vertex normal side */
        VMesh *vmesh;           /* mesh structure for replacing vertex */
 } BevVert;
@@ -117,7 +122,10 @@ typedef struct BevelParams {
 
        float offset;           /* blender units to offset each side of a beveled edge */
        int seg;                /* number of segments in beveled edge profile */
-       int vertex_only;        /* bevel vertices only */
+       bool vertex_only;       /* bevel vertices only */
+       bool use_weights;       /* bevel amount affected by weights on edges or verts */
+       const struct MDeformVert *dvert; /* vertex group array, maybe set if vertex_only */
+       int vertex_group;       /* vertex group index, maybe set if vertex_only */
 } BevelParams;
 
 // #pragma GCC diagnostic ignored "-Wpadded"
@@ -665,7 +673,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv)
                return;
        }
 
-       lastd = bp->vertex_only ? bp->offset : e->offset;
+       lastd = bp->vertex_only? bv->offset : e->offset;
        vm->boundstart = NULL;
        do {
                if (e->is_bev) {
@@ -1722,6 +1730,7 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
        BMFace *f;
        BMIter iter, iter2;
        EdgeHalf *e;
+       float weight;
        int i, found_shared_face, ccw_test_sum;
        int nsel = 0;
        int ntot = 0;
@@ -1760,11 +1769,24 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
        bv->v = v;
        bv->edgecount = ntot;
        bv->selcount = nsel;
+       bv->offset = bp->offset;
        bv->edges = (EdgeHalf *)BLI_memarena_alloc(bp->mem_arena, ntot * sizeof(EdgeHalf));
        bv->vmesh = (VMesh *)BLI_memarena_alloc(bp->mem_arena, sizeof(VMesh));
        bv->vmesh->seg = bp->seg;
        BLI_ghash_insert(bp->vert_hash, v, bv);
 
+       if (bp->vertex_only) {
+               /* if weighted, modify offset by weight */
+               if (bp->dvert != NULL && bp->vertex_group != -1) {
+                       weight = defvert_find_weight(bp->dvert + BM_elem_index_get(v), bp->vertex_group);
+                       if (weight <= 0.0f) {
+                               BM_elem_flag_disable(v, BM_ELEM_TAG);
+                               return;
+                       }
+                       bv->offset *= weight;
+               }
+       }
+
        /* add edges to bv->edges in order that keeps adjacent edges sharing
         * a face, if possible */
        i = 0;
@@ -1815,7 +1837,16 @@ static void bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
                        e->seg = 0;
                }
                e->is_rev = (bme->v2 == v);
-               e->offset = e->is_bev ? bp->offset : 0.0f;
+               if (e->is_bev) {
+                       e->offset = bp->offset;
+                       if (bp->use_weights) {
+                               weight = BM_elem_float_data_get(&bm->edata, bme, CD_BWEIGHT);
+                               e->offset *= weight;
+                       }
+               }
+               else {
+                       e->offset = 0.0f;
+               }
        }
        /* find wrap-around shared face */
        BM_ITER_ELEM (f, &iter2, bme, BM_FACES_OF_EDGE) {
@@ -2034,7 +2065,9 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
  *
  * \warning all tagged edges _must_ be manifold.
  */
-void BM_mesh_bevel(BMesh *bm, const float offset, const float segments, const int vertex_only)
+void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
+                   const bool vertex_only, const bool use_weights,
+                   const struct MDeformVert *dvert, const int vertex_group)
 {
        BMIter iter;
        BMVert *v;
@@ -2044,6 +2077,9 @@ void BM_mesh_bevel(BMesh *bm, const float offset, const float segments, const in
        bp.offset = offset;
        bp.seg    = segments;
        bp.vertex_only = vertex_only;
+       bp.use_weights = use_weights;
+       bp.dvert = dvert;
+       bp.vertex_group = vertex_group;
 
        if (bp.offset > 0) {
                /* primary alloc */
index d56aa13..f214125 100644 (file)
  *  \ingroup bmesh
  */
 
-void BM_mesh_bevel(BMesh *bm, const float offset, const float segments, const int vertex_only);
+struct MDeformVert;
+
+void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
+                   const bool vertex_only, const bool use_weights,
+                   const struct MDeformVert *dvert, const int vertex_group);
 
 #endif /* __BMESH_BEVEL_H__ */
index 21ab112..1eaf54a 100644 (file)
@@ -749,6 +749,12 @@ static void rna_BevelModifier_angle_limit_set(PointerRNA *ptr, float value)
        md->bevel_angle = (int)value;
 }
 
+static void rna_BevelModifier_defgrp_name_set(PointerRNA *ptr, const char *value)
+{
+       BevelModifierData *md = (BevelModifierData *)ptr->data;
+       rna_object_vgroup_name_set(ptr, value, md->defgrp_name, sizeof(md->defgrp_name));
+}
+
 static void rna_UVWarpModifier_vgroup_set(PointerRNA *ptr, const char *value)
 {
        UVWarpModifierData *umd = (UVWarpModifierData *)ptr->data;
@@ -2291,11 +2297,13 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
                {0, "NONE", 0, "None", "Bevel the entire mesh by a constant amount"},
                {BME_BEVEL_ANGLE, "ANGLE", 0, "Angle", "Only bevel edges with sharp enough angles between faces"},
                {BME_BEVEL_WEIGHT, "WEIGHT", 0, "Weight",
-                                  "Use bevel weights to determine how much bevel is applied; "
-                                  "apply them separately in vert/edge select mode"},
+                                  "Use bevel weights to determine how much bevel is applied in edge mode"},
+               {BME_BEVEL_VGROUP, "VGROUP", 0, "Vertex Group",
+                                  "Use vertex group weights to determine how much bevel is applied in vertex mode"},
                {0, NULL, 0, NULL, NULL}
        };
 
+       /* TO BE DEPRECATED */
        static EnumPropertyItem prop_edge_weight_method_items[] = {
                {0, "AVERAGE", 0, "Average", ""},
                {BME_BEVEL_EMIN, "SHARPEST", 0, "Sharpest", ""},
@@ -2315,6 +2323,12 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Width", "Bevel value/amount");
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
 
+       prop = RNA_def_property(srna, "segments", PROP_INT, PROP_NONE);
+       RNA_def_property_int_sdna(prop, NULL, "res");
+       RNA_def_property_range(prop, 1, 100);
+       RNA_def_property_ui_text(prop, "Segments", "Number of segments for round edges/verts");
+       RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
        prop = RNA_def_property(srna, "use_only_vertices", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flags", BME_BEVEL_VERT);
        RNA_def_property_ui_text(prop, "Only Vertices", "Bevel verts/corners, not edges");
@@ -2326,6 +2340,7 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Limit Method", "");
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
 
+       /* TO BE DEPRECATED */
        prop = RNA_def_property(srna, "edge_weight_method", PROP_ENUM, PROP_NONE);
        RNA_def_property_enum_sdna(prop, NULL, "e_flags");
        RNA_def_property_enum_items(prop, prop_edge_weight_method_items);
@@ -2348,15 +2363,10 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
 
 #ifdef USE_BM_BEVEL_OP_AS_MOD
-       prop = RNA_def_property(srna, "use_even_offset", PROP_BOOLEAN, PROP_NONE); /* name matches solidify */
-       RNA_def_property_boolean_sdna(prop, NULL, "flags", BME_BEVEL_EVEN);
-       RNA_def_property_ui_text(prop, "Even", "Use even bevel distance correction");
-       RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
-       prop = RNA_def_property(srna, "use_distance_offset", PROP_BOOLEAN, PROP_NONE);
-       RNA_def_property_boolean_sdna(prop, NULL, "flags", BME_BEVEL_DIST);
-       RNA_def_property_ui_text(prop, "Distance",
-                                "Use the width as a distance in rather then a factor of the face size");
+       prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+       RNA_def_property_string_sdna(prop, NULL, "defgrp_name");
+       RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name");
+       RNA_def_property_string_funcs(prop, NULL, NULL, "rna_BevelModifier_defgrp_name_set");
        RNA_def_property_update(prop, 0, "rna_Modifier_update");
 #endif
 
index 776adb5..1942fe1 100644 (file)
 /** \file blender/modifiers/intern/MOD_bevel.c
  *  \ingroup modifiers
  */
+#include "DNA_object_types.h"
 
 #include "BLI_utildefines.h"
 #include "BLI_math.h"
 #include "BLI_string.h"
 
 #include "BKE_cdderivedmesh.h"
+#include "BKE_deform.h"
 #include "BKE_modifier.h"
 #include "BKE_mesh.h"
 #include "BKE_bmesh.h" /* only for defines */
 
-#include "bmesh.h"
+#include "MOD_util.h"
 
-#include "DNA_object_types.h"
+#include "bmesh.h"
 
 #include "MEM_guardedalloc.h"
 
@@ -88,21 +91,12 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
        return dataMask;
 }
 
-// #define USE_BM_BEVEL_OP_AS_MOD
-
 #ifdef USE_BM_BEVEL_OP_AS_MOD
 
-/* BMESH_TODO
- *
- * this bevel calls the new bevel code (added since 2.64)
- * which is missing many of the options which the bevel modifier from 2.4x has.
- * - no vertex bevel
- * - no weight bevel
- *
- * These will need to be added to the bmesh operator.
- * - campbell
+/*
+ * This calls the new bevel code (added since 2.64)
  */
-static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob),
+static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob,
                                   DerivedMesh *dm,
                                   ModifierApplyFlag UNUSED(flag))
 {
@@ -110,13 +104,33 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob),
        BMesh *bm;
        BMIter iter;
        BMEdge *e;
+       BMVert *v;
+       float weight;
+       int vgroup = -1;
+       MDeformVert *dvert = NULL;
        BevelModifierData *bmd = (BevelModifierData *) md;
        const float threshold = cosf((bmd->bevel_angle + 0.00001f) * (float)M_PI / 180.0f);
-       const int segments = 16;  /* XXX */
+       const bool vertex_only = bmd->flags & BME_BEVEL_VERT;
 
        bm = DM_to_bmesh(dm);
 
-       if (bmd->lim_flags & BME_BEVEL_ANGLE) {
+       if (vertex_only) {
+               if ((bmd->lim_flags & BME_BEVEL_VGROUP) && bmd->defgrp_name[0]) {
+                       modifier_get_vgroup(ob, dm, bmd->defgrp_name, &dvert, &vgroup);
+               }
+               BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
+                       if (!BM_vert_is_manifold(v))
+                               continue;
+                       if (vgroup != -1) {
+                               /* Is it safe to assume bmesh indices and dvert array line up?? */
+                               weight = defvert_array_find_weight_safe(dvert, BM_elem_index_get(v), vgroup);
+                               if (weight <= 0.0f)
+                                       continue;
+                       }
+                       BM_elem_flag_enable(v, BM_ELEM_TAG);
+               }
+       }
+       else if (bmd->lim_flags & BME_BEVEL_ANGLE) {
                BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
                        /* check for 1 edge having 2 face users */
                        BMLoop *l_a, *l_b;
@@ -133,6 +147,11 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob),
                /* crummy, is there a way just to operator on all? - campbell */
                BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
                        if (BM_edge_is_manifold(e)) {
+                               if (bmd->lim_flags & BME_BEVEL_WEIGHT) {
+                                       weight = BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT);
+                                       if (weight == 0.0f)
+                                               continue;
+                               }
                                BM_elem_flag_enable(e, BM_ELEM_TAG);
                                BM_elem_flag_enable(e->v1, BM_ELEM_TAG);
                                BM_elem_flag_enable(e->v2, BM_ELEM_TAG);
@@ -140,11 +159,14 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob),
                }
        }
 
-       BM_mesh_bevel(bm, bmd->value, segments, bmd->flags & BME_BEVEL_VERT);
+       BM_mesh_bevel(bm, bmd->value, bmd->res,
+                     vertex_only, bmd->lim_flags & BME_BEVEL_WEIGHT, dvert, vgroup);
 
        result = CDDM_from_bmesh(bm, TRUE);
 
-       BLI_assert(bm->toolflagpool == NULL);  /* make sure we never alloc'd this */
+       BLI_assert(bm->vtoolflagpool == NULL &&
+                  bm->etoolflagpool == NULL &&
+                  bm->ftoolflagpool == NULL);  /* make sure we never alloc'd these */
        BM_mesh_free(bm);
 
        CDDM_calc_normals(result);