=bmesh=
authorJoseph Eagar <joeedh@gmail.com>
Thu, 17 Mar 2011 22:59:54 +0000 (22:59 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Thu, 17 Mar 2011 22:59:54 +0000 (22:59 +0000)
Bevel! Implemented bevel (from scratch).  Man is
this tool way cooler then I thought it was.  Note that
uv/vcol interpolation is working (loop level data) but
vert/edge data (like vgroups) likely still needs
work.

16 files changed:
source/blender/blenkernel/intern/BME_tools.c
source/blender/blenlib/BLI_smallhash.h
source/blender/blenlib/intern/math_geom.c
source/blender/bmesh/CMakeLists.txt
source/blender/bmesh/bmesh.h
source/blender/bmesh/intern/bmesh_interp.c
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/intern/bmesh_operators_private.h
source/blender/bmesh/operators/bevel.c [new file with mode: 0644]
source/blender/editors/mesh/bmesh_tools.c
source/blender/editors/mesh/loopcut.c
source/blender/editors/mesh/mesh_intern.h
source/blender/editors/mesh/mesh_ops.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/uvedit/uvedit_ops.c
source/blender/modifiers/intern/MOD_util.c

index 9dd4669ba1f9102eaf915a309c51203bbb1b60eb..8efc2d0e955e1303bb3e8bfdc06b78d7ef477f15 100644 (file)
 #include "DNA_object_types.h"
 
 #include "BLI_math.h"
 #include "DNA_object_types.h"
 
 #include "BLI_math.h"
-<<<<<<< .working
 #include "BLI_cellalloc.h"
 #include "BLI_cellalloc.h"
-=======
 #include "BLI_utildefines.h"
 #include "BLI_utildefines.h"
->>>>>>> .merge-right.r35190
 
 #include "BKE_bmesh.h"
 
 
 #include "BKE_bmesh.h"
 
index 2ab365eea0e6b7aef15758abd44682c09a962c7f..a9b0e34bf89b3dcbab5daa0b2bdaa52873cfffab 100755 (executable)
@@ -59,7 +59,7 @@ typedef struct SmallHash {
 #define CELL_FREE      ((void*)0x7FFFFFFD)
 
 #define NONZERO(n) ((n) + !(n))
 #define CELL_FREE      ((void*)0x7FFFFFFD)
 
 #define NONZERO(n) ((n) + !(n))
-#define HASHNEXT(h, hoff) ((h) + ((hoff=NONZERO(hoff*2)+1), hoff))
+#define HASHNEXT(h, hoff) ABS(((h) + ((hoff=NONZERO(hoff*2)+1), hoff)))
 
 BM_INLINE void BLI_smallhash_init(SmallHash *hash)
 {
 
 BM_INLINE void BLI_smallhash_init(SmallHash *hash)
 {
@@ -92,7 +92,9 @@ BM_INLINE void BLI_smallhash_release(SmallHash *hash)
 BM_INLINE void BLI_smallhash_insert(SmallHash *hash, intptr_t key, void *item) 
 {
        int h, hoff=1;
 BM_INLINE void BLI_smallhash_insert(SmallHash *hash, intptr_t key, void *item) 
 {
        int h, hoff=1;
-       
+
+       key = ABS(key);
+
        if (hash->size < hash->used*3) {
                int newsize = hashsizes[++hash->curhash];
                entry *tmp;
        if (hash->size < hash->used*3) {
                int newsize = hashsizes[++hash->curhash];
                entry *tmp;
@@ -145,7 +147,10 @@ BM_INLINE void BLI_smallhash_insert(SmallHash *hash, intptr_t key, void *item)
 
 BM_INLINE void BLI_smallhash_remove(SmallHash *hash, intptr_t key)
 {
 
 BM_INLINE void BLI_smallhash_remove(SmallHash *hash, intptr_t key)
 {
-       int h = key, hoff=1;
+       int h, hoff=1;
+
+       key = ABS(key);
+       h = key;
        
        while (hash->table[h % hash->size].key != key 
              || hash->table[h % hash->size].val == CELL_UNUSED)
        
        while (hash->table[h % hash->size].key != key 
              || hash->table[h % hash->size].val == CELL_UNUSED)
@@ -162,7 +167,10 @@ BM_INLINE void BLI_smallhash_remove(SmallHash *hash, intptr_t key)
 
 BM_INLINE void *BLI_smallhash_lookup(SmallHash *hash, intptr_t key)
 {
 
 BM_INLINE void *BLI_smallhash_lookup(SmallHash *hash, intptr_t key)
 {
-       int h = key, hoff=1;
+       int h, hoff=1;
+
+       key = ABS(key);
+       h = key;
        
        if (!hash->table)
                return NULL;
        
        if (!hash->table)
                return NULL;
@@ -181,7 +189,8 @@ BM_INLINE void *BLI_smallhash_lookup(SmallHash *hash, intptr_t key)
 
 BM_INLINE int BLI_smallhash_haskey(SmallHash *hash, intptr_t key)
 {
 
 BM_INLINE int BLI_smallhash_haskey(SmallHash *hash, intptr_t key)
 {
-       int h = key, hoff=1;
+       int h = ABS(key), hoff=1;
+       key = ABS(key);
        
        if (!hash->table)
                return 0;
        
        if (!hash->table)
                return 0;
index 2d4935ed4a68a541022be97593e162b96f8330d9..4f0e7d10dd51abb1063aff68ef65a3470badb3da 100644 (file)
@@ -905,7 +905,7 @@ int isect_line_line_v3(float v1[3], float v2[3], float v3[3], float v4[3], float
        normalize_v3_v3(dir1, a);
        normalize_v3_v3(dir2, b);
        d = dot_v3v3(dir1, dir2);
        normalize_v3_v3(dir1, a);
        normalize_v3_v3(dir2, b);
        d = dot_v3v3(dir1, dir2);
-       if (d == 1.0f || d == -1.0f) {
+       if (d >= 1.0-FLT_EPSILON*10 || d <= -1.0 + FLT_EPSILON*10) {
                /* colinear */
                return 0;
        }
                /* colinear */
                return 0;
        }
index 870cfa66a61a43e722e2d550e7f19c31ffd27986..c16b1206222d580a65c79b595403baf23bd00dcf 100644 (file)
@@ -58,6 +58,7 @@ set(INC
 )
 
 set(SRC
 )
 
 set(SRC
+       operators/bevel.c
        operators/bmesh_dupeops.c
        operators/utils.c
        operators/subdivideop.c
        operators/bmesh_dupeops.c
        operators/utils.c
        operators/subdivideop.c
index 01f714000f0f8f28e219ba80600165a0c55ff592..3cb938dad7129c0199654d46849de7729fbb20ed 100644 (file)
@@ -216,16 +216,23 @@ int BM_Dissolve_Vert ( BMesh *bm, BMVert *v );
 
 
 /*Interpolation*/
 
 
 /*Interpolation*/
+
+/*projects target onto source for customdata interpolation.  note: only
+  does loop customdata.*/
+void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source);
+
+/*same as BM_face_interp_from_face, but only interpolates one loop, instead
+  of all loops in a face*/
+void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source);
+
 void BM_Data_Interp_From_Verts ( struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, float fac );
 void BM_Data_Facevert_Edgeinterp ( struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, struct BMEdge *e1, float fac );
 void BM_Data_Interp_From_Verts ( struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, float fac );
 void BM_Data_Facevert_Edgeinterp ( struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, struct BMEdge *e1, float fac );
-//void bmesh_data_interp_from_face(struct BMesh *bm, struct BMFace *source, struct BMFace *target);
 void BM_add_data_layer ( BMesh *em, CustomData *data, int type );
 void BM_add_data_layer_named ( BMesh *bm, CustomData *data, int type, char *name );
 void BM_free_data_layer ( BMesh *em, CustomData *data, int type );
 float BM_GetCDf(struct CustomData *cd, void *element, int type);
 void BM_SetCDf(struct CustomData *cd, void *element, int type, float val);
 
 void BM_add_data_layer ( BMesh *em, CustomData *data, int type );
 void BM_add_data_layer_named ( BMesh *bm, CustomData *data, int type, char *name );
 void BM_free_data_layer ( BMesh *em, CustomData *data, int type );
 float BM_GetCDf(struct CustomData *cd, void *element, int type);
 void BM_SetCDf(struct CustomData *cd, void *element, int type, float val);
 
-
 /*computes the centroid of a face, using the center of the bounding box*/
 int BM_Compute_Face_Center ( BMesh *bm, BMFace *f, float center[3] );
 
 /*computes the centroid of a face, using the center of the bounding box*/
 int BM_Compute_Face_Center ( BMesh *bm, BMFace *f, float center[3] );
 
index 9dfe3c63be933b044d560009c94f7bf6242e4311..57318f8433e3deca89e4e02b4499e4b98843d02e 100644 (file)
@@ -39,6 +39,7 @@
 #include "BKE_utildefines.h"
 
 #include "BLI_array.h"
 #include "BKE_utildefines.h"
 
 #include "BLI_array.h"
+#include "BLI_math.h"
 
 #include "bmesh.h"
 #include "bmesh_private.h"
 
 #include "bmesh.h"
 #include "bmesh_private.h"
@@ -78,7 +79,6 @@ void BM_Data_Interp_From_Verts(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v, flo
     to the average of the face regions surrounding it.
 */
 
     to the average of the face regions surrounding it.
 */
 
-//CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, vloop->head.data);                               
 
 void BM_Data_Vert_Average(BMesh *bm, BMFace *f)
 {
 
 void BM_Data_Vert_Average(BMesh *bm, BMFace *f)
 {
@@ -175,13 +175,91 @@ void BM_loops_to_corners(BMesh *bm, Mesh *me, int findex,
        }
 }
 
        }
 }
 
-//static void bmesh_data_interp_from_face(BME_Mesh *bm, BMFace *source, BMFace *target)
-//{
-//
-//}
-/*insert BM_data_interp_from_face here for mean value coordinates...*/
 
 
 
 
+/**
+ *                     BM_data_interp_from_face
+ *
+ *  projects target onto source, and pulls interpolated customdata from
+ *  source.
+ * 
+ *  Returns -
+ *     Nothing
+*/
+void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source)
+{
+       BMLoop *l1, *l2;
+       void **blocks=NULL;
+       float (*cos)[3]=NULL, *w=NULL;
+       BLI_array_staticdeclare(cos, 64);
+       BLI_array_staticdeclare(w, 64);
+       BLI_array_staticdeclare(blocks, 64);
+       
+       BM_Copy_Attributes(bm, bm, source, target);
+       
+       l2 = bm_firstfaceloop(source);
+       do {
+               BLI_array_growone(cos);
+               copy_v3_v3(cos[BLI_array_count(cos)-1], l2->v->co);
+               BLI_array_growone(w);
+               BLI_array_append(blocks, l2->head.data);
+               l2 = l2->next;
+       } while (l2 != bm_firstfaceloop(source));
+
+       l1 = bm_firstfaceloop(target);
+       do {
+               interp_weights_poly_v3(w, cos, source->len, l1->v->co);
+               CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, BLI_array_count(blocks), l1->head.data);
+               l1 = l1->next;
+       } while (l1 != bm_firstfaceloop(target));
+
+       BLI_array_free(cos);
+       BLI_array_free(w);
+       BLI_array_free(blocks);
+}
+
+void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source)
+{
+       BMLoop *l;
+       void **blocks=NULL;
+       float (*cos)[3]=NULL, *w=NULL, cent[3] = {0.0f, 0.0f, 0.0f};
+       BLI_array_staticdeclare(cos, 64);
+       BLI_array_staticdeclare(w, 64);
+       BLI_array_staticdeclare(blocks, 64);
+       int i;
+       
+       BM_Copy_Attributes(bm, bm, source, target->f);
+       
+       l = bm_firstfaceloop(source);
+       do {
+               BLI_array_growone(cos);
+               copy_v3_v3(cos[BLI_array_count(cos)-1], l->v->co);
+               add_v3_v3(cent, cos[BLI_array_count(cos)-1]);
+               
+               BLI_array_append(w, 0.0f);
+               BLI_array_append(blocks, l->head.data);
+               l = l->next;
+       } while (l != bm_firstfaceloop(source));
+
+       /*scale source face coordinates a bit, so points sitting directonly on an
+      edge will work.*/
+       mul_v3_fl(cent, 1.0/source->len);
+       for (i=0; i<source->len; i++) {
+               float vec[3];
+               sub_v3_v3v3(vec, cent, cos[i]);
+               mul_v3_fl(vec, 0.01);
+               add_v3_v3(cos[i], vec);
+       }
+       
+       /*interpolate*/
+       interp_weights_poly_v3(w, cos, source->len, target->v->co);
+       CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, target->head.data);
+       
+       BLI_array_free(cos);
+       BLI_array_free(w);
+       BLI_array_free(blocks);
+}
+
 static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
 {
        BMIter iter;
 static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
 {
        BMIter iter;
index 957a97b61faec3707a8e8fe4ad3497588627df6b..c949d730d8c5640c68d50592a292a5d664d2d6bd 100644 (file)
@@ -938,6 +938,22 @@ BMOpDefine def_create_cube = {
        0,
 };
 
        0,
 };
 
+/*
+  Bevel
+
+  Bevels edges and vertices
+ */
+BMOpDefine def_bevel = {
+       "bevel",
+       {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */
+        {BMOP_OPSLOT_ELEMENT_BUF, "face_spans"}, /* new geometry */
+        {BMOP_OPSLOT_ELEMENT_BUF, "face_holes"}, /* new geometry */
+        {BMOP_OPSLOT_FLT, "percent"}, /* percentage to expand bevelled edges*/
+        {0} /*null-terminating sentinel*/},
+       bmesh_bevel_exec,
+       0
+};
+
 BMOpDefine *opdefines[] = {
        &def_splitop,
        &def_dupeop,
 BMOpDefine *opdefines[] = {
        &def_splitop,
        &def_dupeop,
@@ -997,6 +1013,7 @@ BMOpDefine *opdefines[] = {
        &def_create_cone,
        &def_create_cube,
        &def_join_triangles,
        &def_create_cone,
        &def_create_cube,
        &def_join_triangles,
+       &def_bevel,
 };
 
 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));
 };
 
 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));
index e60d40efb2466b6d891c3d9f315842347450e322..b81475d314f4034a08ee6a5578ace5bb7bdeb57f 100644 (file)
@@ -68,5 +68,6 @@ void bmesh_create_uvsphere_exec(BMesh *bm, BMOperator *op);
 void bmesh_create_grid_exec(BMesh *bm, BMOperator *op);
 void bmesh_create_cube_exec(BMesh *bm, BMOperator *op);
 void bmesh_jointriangles_exec(BMesh *bm, BMOperator *op);
 void bmesh_create_grid_exec(BMesh *bm, BMOperator *op);
 void bmesh_create_cube_exec(BMesh *bm, BMOperator *op);
 void bmesh_jointriangles_exec(BMesh *bm, BMOperator *op);
+void bmesh_bevel_exec(BMesh *bm, BMOperator *op);
 
 #endif
 
 #endif
diff --git a/source/blender/bmesh/operators/bevel.c b/source/blender/bmesh/operators/bevel.c
new file mode 100644 (file)
index 0000000..315b252
--- /dev/null
@@ -0,0 +1,704 @@
+#include "MEM_guardedalloc.h"
+
+#include "BKE_utildefines.h"
+
+#include "BLI_ghash.h"
+#include "BLI_memarena.h"
+#include "BLI_blenlib.h"
+#include "BLI_array.h"
+#include "BLI_math.h"
+#include "BLI_array.h"
+#include "BLI_utildefines.h"
+#include "BLI_smallhash.h"
+
+#include "bmesh.h"
+#include "bmesh_operators_private.h"
+
+#define BEVEL_FLAG     1
+#define BEVEL_DEL      2
+#define FACE_NEW       4
+#define EDGE_OLD       8
+#define FACE_OLD       16
+#define FACE_DONE      32
+#define VERT_OLD       64
+#define FACE_SPAN      128
+#define FACE_HOLE      256
+
+typedef struct LoopTag {
+       BMVert *newv;
+} LoopTag;
+
+typedef struct EdgeTag {
+       BMVert *newv1, *newv2;
+} EdgeTag;
+
+
+/* "Projects" a vector perpendicular to vec2 against vec1, such that
+ * the projected vec1 + vec2 has a min distance of 1 from the "edge" defined by vec2.
+ * note: the direction, is_forward, is used in conjunction with up_vec to determine
+ * whether this is a convex or concave corner. If it is a concave corner, it will
+ * be projected "backwards." If vec1 is before vec2, is_forward should be 0 (we are projecting backwards).
+ * vec1 is the vector to project onto (expected to be normalized)
+ * vec2 is the direction of projection (pointing away from vec1)
+ * up_vec is used for orientation (expected to be normalized)
+ * returns the length of the projected vector that lies along vec1 */
+static float BM_bevel_project_vec(float *vec1, float *vec2, float *up_vec, int is_forward) {
+       float factor, vec3[3], tmp[3],c1,c2;
+
+       cross_v3_v3v3(tmp,vec1,vec2);
+       normalize_v3(tmp);
+       factor = dot_v3v3(up_vec,tmp);
+       if ((factor > 0 && is_forward) || (factor < 0 && !is_forward)) {
+               cross_v3_v3v3(vec3,vec2,tmp); /* hmm, maybe up_vec should be used instead of tmp */
+       }
+       else {
+               cross_v3_v3v3(vec3,tmp,vec2); /* hmm, maybe up_vec should be used instead of tmp */
+       }
+       normalize_v3(vec3);
+       c1 = dot_v3v3(vec3,vec1);
+       c2 = dot_v3v3(vec1,vec1);
+       if (fabs(c1) < 0.000001f || fabs(c2) < 0.000001f) {
+               factor = 0.0f;
+       }
+       else {
+               factor = c2/c1;
+       }
+
+       return factor;
+}
+
+void calc_corner_co(BMesh *bm, BMLoop *l, float *co, float fac)
+{
+       float no[3], tan[3], vec1[3], vec2[3], v1[3], v2[3], v3[3], v4[3];
+       float p1[3], p2[3], w[3];
+       float l1, l2;
+       int ret;
+
+       copy_v3_v3(v1, l->prev->v->co);
+       copy_v3_v3(v2, l->v->co);
+       copy_v3_v3(v3, l->v->co);
+       copy_v3_v3(v4, l->next->v->co);
+       
+       /*calculate normal*/
+       sub_v3_v3v3(vec1, v1, v2);
+       sub_v3_v3v3(vec2, v4, v3);
+#if 0
+       cross_v3_v3v3(no, vec2, vec1);
+       normalize_v3(no);
+       
+       if (dot_v3v3(no, no) < DBL_EPSILON*10) {
+               copy_v3_v3(no, l->f->no);
+       }
+       
+       /*compute offsets*/
+       l1 = len_v3(vec1)*fac;
+       l2 = len_v3(vec2)*fac;
+       if (dot_v3v3(no, l->f->no) < 0.0) {
+               l1 = -l1;
+               l2 = -l2;
+       }       
+       
+       /*compute tangent and offset first edge*/
+       cross_v3_v3v3(tan, vec1, no);
+       normalize_v3(tan);
+
+       mul_v3_fl(tan, l1);
+       
+       add_v3_v3(v1, tan);
+       add_v3_v3(v2, tan);
+       
+       /*compute tangent and offset second edge*/
+       cross_v3_v3v3(tan, no, vec2);
+       normalize_v3(tan);
+       
+       mul_v3_fl(tan, l2);
+
+       add_v3_v3(v3, tan);
+       add_v3_v3(v4, tan);
+       
+       /*compute intersection*/
+       ret = isect_line_line_v3(v1, v2, v3, v4, p1, p2);
+       if (ret==1) {
+               copy_v3_v3(co, p1);
+       } else if (ret==2) {
+               add_v3_v3v3(co, p1, p2);
+               mul_v3_fl(co, 0.5);
+       } else { /*colinear case*/
+               add_v3_v3v3(co, v2, v3);
+               mul_v3_fl(co, 0.5);
+       }
+#endif
+       /*oddly, this simplistic method seems to work the best*/
+       mul_v3_fl(vec1, fac);
+       mul_v3_fl(vec2, fac);
+       add_v3_v3(vec1, vec2);
+       mul_v3_fl(vec1, 0.5);
+       
+       add_v3_v3v3(co, vec1, l->v->co);
+}
+
+#define ETAG_SET(e, v, nv) (v) == (e)->v1 ? (etags[BMINDEX_GET((e))].newv1 = (nv)) : (etags[BMINDEX_GET((e))].newv2 = (nv))
+#define ETAG_GET(e, v) ((v) == (e)->v1 ? (etags[BMINDEX_GET((e))].newv1) : (etags[BMINDEX_GET((e))].newv2))
+
+void bmesh_bevel_exec(BMesh *bm, BMOperator *op)
+{
+       BMOIter siter;
+       BMIter iter;
+       BMEdge *e;
+       BMVert *v;
+       BMFace **faces = NULL;
+       LoopTag *tags=NULL, *tag;
+       EdgeTag *etags = NULL, *etag;
+       BMVert **verts = NULL;
+       BMEdge **edges = NULL;
+       BLI_array_declare(faces);
+       BLI_array_declare(tags);
+       BLI_array_declare(etags);
+       BLI_array_declare(verts);
+       BLI_array_declare(edges);
+       SmallHash hash;
+       float fac = BMO_Get_Float(op, "percent");
+       int i;
+       
+       BLI_smallhash_init(&hash);
+       
+       BMO_ITER(e, &siter, bm, op, "geom", BM_EDGE) {
+               BMO_SetFlag(bm, e, BEVEL_FLAG|BEVEL_DEL);
+               BMO_SetFlag(bm, e->v1, BEVEL_FLAG|BEVEL_DEL);
+               BMO_SetFlag(bm, e->v2, BEVEL_FLAG|BEVEL_DEL);
+               
+               if (BM_Edge_FaceCount(e) < 2) {
+                       BMO_ClearFlag(bm, e, BEVEL_DEL);
+                       BMO_ClearFlag(bm, e->v1, BEVEL_DEL);
+                       BMO_ClearFlag(bm, e->v2, BEVEL_DEL);
+               }
+       }
+       
+       BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
+               BMO_SetFlag(bm, v, VERT_OLD);
+       }
+
+#if 0
+       //a bit of cleaner code that, alas, doens't work.
+       /*build edge tags*/
+       BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
+               if (BMO_TestFlag(bm, e->v1, BEVEL_FLAG) || BMO_TestFlag(bm, e->v2, BEVEL_FLAG)) {
+                       BMIter liter;
+                       BMLoop *l;
+                       
+                       if (!BMO_TestFlag(bm, e, EDGE_OLD)) {
+                               BMINDEX_SET(e, BLI_array_count(etags));
+                               BLI_array_growone(etags);
+                               
+                               BMO_SetFlag(bm, e, EDGE_OLD);
+                       }
+                       
+                       BM_ITER(l, &liter, bm, BM_LOOPS_OF_EDGE, e) {
+                               BMLoop *l2;
+                               BMIter liter2;
+                               
+                               if (BMO_TestFlag(bm, l->f, BEVEL_FLAG))
+                                       continue;
+                       
+                               BM_ITER(l2, &liter2, bm, BM_LOOPS_OF_FACE, l->f) {
+                                       BMINDEX_SET(l2, BLI_array_count(tags));
+                                       BLI_array_growone(tags);
+
+                                       if (!BMO_TestFlag(bm, l2->e, EDGE_OLD)) {
+                                               BMINDEX_SET(l2->e, BLI_array_count(etags));
+                                               BLI_array_growone(etags);
+                                               
+                                               BMO_SetFlag(bm, l2->e, EDGE_OLD);
+                                       }
+                               }
+
+                               BMO_SetFlag(bm, l->f, BEVEL_FLAG);
+                               BLI_array_append(faces, l->f);
+                       }
+               } else {
+                       BMINDEX_SET(e, -1);
+               }
+       }
+#endif
+       
+       /*create and assign looptag structures*/
+       BMO_ITER(e, &siter, bm, op, "geom", BM_EDGE) {
+               BMLoop *l;
+               BMIter liter;
+
+               BMO_SetFlag(bm, e->v1, BEVEL_FLAG|BEVEL_DEL);
+               BMO_SetFlag(bm, e->v2, BEVEL_FLAG|BEVEL_DEL);
+               
+               if (BM_Edge_FaceCount(e) < 2) {
+                       BMO_ClearFlag(bm, e, BEVEL_DEL);
+                       BMO_ClearFlag(bm, e->v1, BEVEL_DEL);
+                       BMO_ClearFlag(bm, e->v2, BEVEL_DEL);
+                       //continue;     
+               }
+               
+               if (!BLI_smallhash_haskey(&hash, (intptr_t)e)) {
+                       BLI_array_growone(etags);
+                       BMINDEX_SET(e, BLI_array_count(etags)-1);
+                       BLI_smallhash_insert(&hash, (intptr_t)e, NULL);
+                       BMO_SetFlag(bm, e, EDGE_OLD);
+               }
+               
+               /*find all faces surrounding e->v1 and, e->v2*/
+               for (i=0; i<2; i++) {
+                       BM_ITER(l, &liter, bm, BM_LOOPS_OF_VERT, i?e->v2:e->v1) {
+                               BMLoop *l2;
+                               BMIter liter2;
+                               
+                               /*see if we've already processed this loop's face*/
+                               if (BLI_smallhash_haskey(&hash, (intptr_t)l->f))
+                                       continue;
+                               
+                               /*create tags for all loops in l->f*/
+                               BM_ITER(l2, &liter2, bm, BM_LOOPS_OF_FACE, l->f) {
+                                       BLI_array_growone(tags);
+                                       BMINDEX_SET(l2, BLI_array_count(tags)-1);
+                                       
+                                       if (!BLI_smallhash_haskey(&hash, (intptr_t)l2->e)) {
+                                               BLI_array_growone(etags);
+                                               BMINDEX_SET(l2->e, BLI_array_count(etags)-1);
+                                               BLI_smallhash_insert(&hash, (intptr_t)l2->e, NULL);                                             
+                                               BMO_SetFlag(bm, l2->e, EDGE_OLD);
+                                       }
+                               }
+       
+                               BLI_smallhash_insert(&hash, (intptr_t)l->f, NULL);
+                               BMO_SetFlag(bm, l->f, BEVEL_FLAG);
+                               BLI_array_append(faces, l->f);
+                       }
+               }
+       }
+
+       BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
+               BMIter eiter;
+               
+               if (!BMO_TestFlag(bm, v, BEVEL_FLAG))
+                       continue;
+               
+               BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
+                       if (!BMO_TestFlag(bm, e, BEVEL_FLAG) && !ETAG_GET(e, v)) {
+                               BMVert *v2;
+                               float co[3];
+                               
+                               v2 = BM_OtherEdgeVert(e, v);
+                               sub_v3_v3v3(co, v2->co, v->co);
+                               mul_v3_fl(co, fac);
+                               add_v3_v3(co, v->co);
+                               
+                               v2 = BM_Make_Vert(bm, co, v);
+                               ETAG_SET(e, v, v2);
+                       }
+               }
+       }
+       
+       for (i=0; i<BLI_array_count(faces); i++) {
+               BMLoop *l;
+               BMIter liter;
+               
+               BMO_SetFlag(bm, faces[i], FACE_OLD);
+               
+               BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, faces[i]) {
+                       float co[3];
+
+                       if (BMO_TestFlag(bm, l->e, BEVEL_FLAG)) {
+                               if (BMO_TestFlag(bm, l->prev->e, BEVEL_FLAG))
+                               {
+                                       tag = tags + BMINDEX_GET(l);
+                                       calc_corner_co(bm, l, co, fac);
+                                       tag->newv = BM_Make_Vert(bm, co, l->v);
+                               } else {
+                                       tag = tags + BMINDEX_GET(l);
+                                       tag->newv = ETAG_GET(l->prev->e, l->v);
+                                       
+                                       if (!tag->newv) {
+                                               sub_v3_v3v3(co, l->prev->v->co, l->v->co);
+                                               mul_v3_fl(co, fac);
+                                               add_v3_v3(co, l->v->co);
+                                       
+                                               tag->newv = BM_Make_Vert(bm, co, l->v);
+                                               
+                                               ETAG_SET(l->prev->e, l->v, tag->newv);
+                                       }
+                               }
+                       } else if (BMO_TestFlag(bm, l->v, BEVEL_FLAG)) {
+                               tag = tags + BMINDEX_GET(l);
+                               tag->newv = ETAG_GET(l->e, l->v);                               
+               
+                               if (!tag->newv) {
+                                       sub_v3_v3v3(co, l->next->v->co, l->v->co);
+                                       mul_v3_fl(co, fac);
+                                       add_v3_v3(co, l->v->co);
+                       
+                                       tag = tags + BMINDEX_GET(l);
+                                       tag->newv = BM_Make_Vert(bm, co, l->v);
+                                       
+                                       ETAG_SET(l->e, l->v, tag->newv);
+                               }                                       
+                       } else {
+                               tag = tags + BMINDEX_GET(l);
+                               tag->newv = l->v;
+                               BMO_ClearFlag(bm, l->v, BEVEL_DEL);
+                       }
+               }
+       }
+       
+       /*create new faces*/
+       for (i=0; i<BLI_array_count(faces); i++) {
+               BMLoop *l;
+               BMIter liter;
+               BMFace *f;
+               int j;
+               
+               BMO_SetFlag(bm, faces[i], BEVEL_DEL);
+               
+               BLI_array_empty(verts);
+               BLI_array_empty(edges);
+               
+               BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, faces[i]) {
+                       BMVert *v2;
+                       
+                       tag = tags + BMINDEX_GET(l);
+                       BLI_array_append(verts, tag->newv);
+                       
+                       etag = etags + BMINDEX_GET(l->e);
+                       v2 = l->next->v == l->e->v1 ? etag->newv1 : etag->newv2;
+                       
+                       tag = tags + BMINDEX_GET(l->next);
+                       if (!BMO_TestFlag(bm, l->e, BEVEL_FLAG) && v2 && v2 != tag->newv) {
+                               BLI_array_append(verts, v2);
+                       }
+               }
+               
+               for (j=0; j<BLI_array_count(verts); j++) {
+                       BMVert *next = verts[(j+1)%BLI_array_count(verts)];
+
+                       e = BM_Make_Edge(bm, next, verts[j], NULL, 1);
+                       BLI_array_append(edges, e);
+               }
+               
+               f = BM_Make_Face(bm, verts, edges, BLI_array_count(verts));
+               if (!f) {
+                       printf("eck!!\n");
+                       continue;
+               }
+                       
+               BMO_SetFlag(bm, f, FACE_NEW);
+               
+               /*create quad spans between split edges*/
+               BMO_SetFlag(bm, f, FACE_NEW);
+               BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, faces[i]) {
+                       BMVert *v1=NULL, *v2=NULL, *v3=NULL, *v4=NULL;
+                       
+                       if (!BMO_TestFlag(bm, l->e, BEVEL_FLAG))
+                               continue;
+                       
+                       v1 = tags[BMINDEX_GET(l)].newv;
+                       v2 = tags[BMINDEX_GET(l->next)].newv;
+                       if (l->radial_next != l) {
+                               v3 = tags[BMINDEX_GET(l->radial_next)].newv;
+                               if (l->radial_next->next->v == l->next->v) {
+                                       v4 = v3;
+                                       v3 = tags[BMINDEX_GET(l->radial_next->next)].newv;
+                               } else {
+                                       v4 = tags[BMINDEX_GET(l->radial_next->next)].newv;
+                               }
+                       } else {
+                               v3 = l->next->v;
+                               v4 = l->v;
+                               
+                               for (j=0; j<2; j++) {
+                                       BMIter eiter;
+                                       BMVert *v = j ? v4 : v3;
+
+                                       BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
+                                               if (!BM_Vert_In_Edge(e, v3) || !BM_Vert_In_Edge(e, v4))
+                                                       continue;
+                                               
+                                               if (!BMO_TestFlag(bm, e, BEVEL_FLAG) && BMO_TestFlag(bm, e, EDGE_OLD)) {
+                                                       BMVert *vv;
+                                                       
+                                                       vv = ETAG_GET(e, v);
+                                                       if (!vv || BMO_TestFlag(bm, vv, BEVEL_FLAG))
+                                                               continue;
+                                                       
+                                                       if (j)
+                                                               v1 = vv;
+                                                       else
+                                                               v2 = vv;
+                                                       break;
+                                               }
+                                       }
+                               }
+
+                               BMO_ClearFlag(bm, v3, BEVEL_DEL);
+                               BMO_ClearFlag(bm, v4, BEVEL_DEL);
+                       }
+                       
+                       if (v1 != v2 && v2 != v3 && v3 != v4) {
+                               BMIter liter2;
+                               BMLoop *l2;
+                               
+                               f = BM_Make_QuadTri(bm, v4, v3, v2, v1, l->f, 1);
+                               if (!f) {
+                                       printf("eek!\n");
+                                       continue;
+                               }
+                               
+                               BMO_SetFlag(bm, f, FACE_NEW|FACE_SPAN);
+                               
+                               /*un-tag edges in f for deletion*/
+                               BM_ITER(l2, &liter2, bm, BM_LOOPS_OF_FACE, f) {
+                                       BMO_ClearFlag(bm, l2->e, BEVEL_DEL);
+                               }
+                       } else {
+                               f = NULL;
+                       }
+               }       
+       }
+       
+       /*fill in holes at vertices*/
+       BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
+               BMIter eiter;
+               BMVert *vv, *vstart=NULL, *lastv=NULL;
+               SmallHash tmphash;
+               int rad, insorig=0, err=0;
+               
+               BLI_smallhash_init(&tmphash);
+               
+               if (!BMO_TestFlag(bm, v, BEVEL_FLAG))
+                       continue;
+               
+               BLI_array_empty(verts);
+               BLI_array_empty(edges);
+               
+               BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
+                       BMIter liter;
+                       BMVert *v1=NULL, *v2=NULL;
+                       BMLoop *l;
+                       
+                       if (BM_Edge_FaceCount(e) < 2)
+                               insorig = 1;
+                       
+                       rad = 0;
+                       BM_ITER(l, &liter, bm, BM_LOOPS_OF_EDGE, e) {
+                               if (!BMO_TestFlag(bm, l->f, FACE_OLD))
+                                       continue;
+                               
+                               rad++;
+                               
+                               if (l->v == v)
+                                       tag = tags + BMINDEX_GET(l);
+                               else
+                                       tag = tags + BMINDEX_GET(l->next);
+                               
+                               if (!v1)
+                                       v1 = tag->newv;
+                               else if (!v2);
+                                       v2 = tag->newv;
+                       }
+                       
+                       if (rad < 2)
+                               insorig = 1;
+                       
+                       if (!v1)
+                               v1 = ETAG_GET(e, v);
+                       if (!v2 || v1 == v2)
+                               v2 = ETAG_GET(e, v);
+                       
+                       if (v1) {
+                               if (!BLI_smallhash_haskey(&tmphash, (intptr_t)v1)) {
+                                       BLI_array_append(verts, v1);
+                                       BLI_smallhash_insert(&tmphash, (intptr_t)v1, NULL);
+                               }
+                               
+                               if (v2 && v1 != v2 && !BLI_smallhash_haskey(&tmphash, (intptr_t)v2)) {
+                                       BLI_array_append(verts, v2);
+                                       BLI_smallhash_insert(&tmphash, (intptr_t)v2, NULL);
+                               }
+                       }
+               }
+               
+               if (!BLI_array_count(verts))
+                       continue;
+               
+               if (insorig) {
+                       BLI_array_append(verts, v);
+                       BLI_smallhash_insert(&tmphash, (intptr_t)v, NULL);
+               }
+               
+               /*find edges that exist between vertices in verts.  this is basically
+          a topological walk of the edges connecting them.*/
+               vstart = vstart ? vstart : verts[0];
+               vv = vstart;
+               do {
+                       BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, vv) {
+                               BMVert *vv2 = BM_OtherEdgeVert(e, vv);
+                               
+                               if (vv2 != lastv && BLI_smallhash_haskey(&tmphash, (intptr_t)vv2)) {
+                                       /*if we've go over the same vert twice, break out of outer loop*/
+                                       if (BLI_smallhash_lookup(&tmphash, (intptr_t)vv2) != NULL) {
+                                               e = NULL;
+                                               err = 1;
+                                               break;
+                                       }
+                                       
+                                       /*use self pointer as tag*/
+                                       BLI_smallhash_remove(&tmphash, (intptr_t)vv2);
+                                       BLI_smallhash_insert(&tmphash, (intptr_t)vv2, vv2);
+                                       
+                                       lastv = vv;
+                                       BLI_array_append(edges, e);
+                                       vv = vv2;
+                                       break;
+                               }
+                       }
+                       if (e == NULL)
+                               break;
+               } while (vv != vstart);
+               
+               if (err)
+                       continue;
+               
+               /*there may not be a complete loop of edges, so start again and make
+          final edge afterwards.  in this case, the previous loop worked to
+          find one of the two edges at the extremes.*/
+               if (vv != vstart) {
+                       /*undo previous tagging*/
+                       for (i=0; i<BLI_array_count(verts); i++) {
+                               BLI_smallhash_remove(&tmphash, (intptr_t)verts[i]);
+                               BLI_smallhash_insert(&tmphash, (intptr_t)verts[i], NULL);
+                       }
+
+                       vstart = vv;
+                       lastv = NULL;
+                       BLI_array_empty(edges);
+                       do {
+                               BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, vv) {
+                                       BMVert *vv2 = BM_OtherEdgeVert(e, vv);
+                                       
+                                       if (vv2 != lastv && BLI_smallhash_haskey(&tmphash, (intptr_t)vv2)) {
+                                               /*if we've go over the same vert twice, break out of outer loop*/
+                                               if (BLI_smallhash_lookup(&tmphash, (intptr_t)vv2) != NULL) {
+                                                       e = NULL;
+                                                       err = 1;
+                                                       break;
+                                               }
+                                               
+                                               /*use self pointer as tag*/
+                                               BLI_smallhash_remove(&tmphash, (intptr_t)vv2);
+                                               BLI_smallhash_insert(&tmphash, (intptr_t)vv2, vv2);
+                                               
+                                               lastv = vv;
+                                               BLI_array_append(edges, e);
+                                               vv = vv2;
+                                               break;
+                                       }
+                               }
+                               if (e == NULL)
+                                       break;
+                       } while (vv != vstart);
+                       
+                       if (!err) {
+                               e = BM_Make_Edge(bm, vv, vstart, NULL, 1);
+                               BLI_array_append(edges, e);
+                       }
+               }
+               
+               if (err)
+                       continue;
+               
+               if (BLI_array_count(edges) >= 3) {
+                       BMFace *f;
+                       
+                       f = BM_Make_Ngon(bm, lastv, vstart, edges, BLI_array_count(edges), 0);
+                       if (!f) {
+                               printf("eek! in bevel vert fill!\n");
+                       } else 
+                               BMO_SetFlag(bm, f, FACE_NEW|FACE_HOLE);
+               }
+               BLI_smallhash_release(&tmphash);
+       }
+       
+       /*copy over customdata*/
+       for (i=0; i<BLI_array_count(faces); i++) {
+               BMLoop *l;
+               BMIter liter;
+               BMFace *f = faces[i];
+               
+               BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
+                       BMLoop *l2;
+                       BMIter liter2;
+                       
+                       tag = tags + BMINDEX_GET(l);
+                       if (!tag->newv)
+                               continue;
+                       
+                       BM_ITER(l2, &liter2, bm, BM_LOOPS_OF_VERT, tag->newv) {
+                               if (!BMO_TestFlag(bm, l2->f, FACE_NEW) || (l2->v != tag->newv && l2->v != l->v))
+                                       continue;
+                               
+                               if (tag->newv != l->v) {
+                                       BM_Copy_Attributes(bm, bm, l->f, l2->f);
+                                       BM_loop_interp_from_face(bm, l2, f);
+                               } else {
+                                       BM_Copy_Attributes(bm, bm, l->f, l2->f);
+                                       BM_Copy_Attributes(bm, bm, l, l2);
+                               }
+                       }
+               }
+       }
+       
+       /*handle vertices along boundary edges*/
+       BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {
+               if (BMO_TestFlag(bm, v, VERT_OLD) && BMO_TestFlag(bm, v, BEVEL_FLAG) && !BMO_TestFlag(bm, v, BEVEL_DEL)) {
+                       BMLoop *l;
+                       BMLoop *lorig=NULL;
+                       BMIter liter;
+                       
+                       BM_ITER(l, &liter, bm, BM_LOOPS_OF_VERT, v) {
+                               BMIter liter2;
+                               BMLoop *l2 = l->v == v ? l : l->next, *l3;
+                               
+                               if (BMO_TestFlag(bm, l->f, FACE_OLD)) {
+                                       lorig = l;
+                                       break;
+                               }
+                       }
+                       
+                       if (!lorig)
+                               continue;
+                       
+                       BM_ITER(l, &liter, bm, BM_LOOPS_OF_VERT, v) {
+                               BMLoop *l2 = l->v == v ? l : l->next, *l3;
+                               
+                               BM_Copy_Attributes(bm, bm, lorig->f, l2->f);
+                               BM_Copy_Attributes(bm, bm, lorig, l2);
+                       }
+               }
+       }
+
+       BMO_CallOpf(bm, "del geom=%fv context=%i", BEVEL_DEL, DEL_VERTS);
+
+       /*clean up any edges that might not get properly deleted*/
+       BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
+               if (BMO_TestFlag(bm, e, EDGE_OLD) && !e->l)
+                       BMO_SetFlag(bm, e, BEVEL_DEL);
+       }
+
+       BMO_CallOpf(bm, "del geom=%fe context=%i", BEVEL_DEL, DEL_EDGES);
+       BMO_CallOpf(bm, "del geom=%ff context=%i", BEVEL_DEL, DEL_FACES);
+       
+       BLI_smallhash_release(&hash);
+       BLI_array_free(tags);
+       BLI_array_free(etags);
+       BLI_array_free(verts);
+       BLI_array_free(edges);
+       BLI_array_free(faces);
+       
+       BMO_Flag_To_Slot(bm, op, "face_spans", FACE_SPAN, BM_FACE);
+       BMO_Flag_To_Slot(bm, op, "face_holes", FACE_HOLE, BM_FACE);
+}
index 7f15056d6bd6b053916b661c465216c0675544eb..5964a91b9b79b758eb94f5ad66d0a44715e11a5e 100644 (file)
@@ -4793,3 +4793,56 @@ void MESH_OT_noise(wmOperatorType *ot)
 
        RNA_def_float(ot->srna, "factor", 0.1f, -FLT_MAX, FLT_MAX, "Factor", "", 0.0f, 1.0f);
 }
 
        RNA_def_float(ot->srna, "factor", 0.1f, -FLT_MAX, FLT_MAX, "Factor", "", 0.0f, 1.0f);
 }
+
+/*bevel! yay!!*/
+static int mesh_bevel_exec(bContext *C, wmOperator *op)
+{
+       Object *obedit= CTX_data_edit_object(C);
+       BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
+       Material *ma;
+       Tex *tex;
+       BMVert *eve;
+       BMIter iter;
+       BMOperator bmop;
+       float factor= RNA_float_get(op->ptr, "percent"), fac=factor;
+       int i, recursion = RNA_int_get(op->ptr, "recursion");
+       
+       if(em==NULL) return OPERATOR_CANCELLED;
+       
+       while (recursion-- > 0) {
+               if (!EDBM_InitOpf(em, &bmop, op, "bevel geom=%hev percent=%f", BM_SELECT, fac))
+                       return OPERATOR_CANCELLED;
+               
+               BMO_Exec_Op(em->bm, &bmop);
+               BMO_HeaderFlag_Buffer(em->bm, &bmop, "face_spans", BM_SELECT, BM_FACE);
+               BMO_HeaderFlag_Buffer(em->bm, &bmop, "face_holes", BM_SELECT, BM_FACE);
+               BMO_Finish_Op(em->bm, &bmop);
+               
+               fac = fac + (sqrt(fac) - fac)*0.25;
+       }
+       
+       EDBM_RecalcNormals(em);
+
+       DAG_id_tag_update(obedit->data, 0);
+       WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
+
+       return OPERATOR_FINISHED;
+}
+
+void MESH_OT_bevel(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Bevel";
+       ot->description= "Edge/Vertex Bevel";
+       ot->idname= "MESH_OT_bevel";
+
+       /* api callbacks */
+       ot->exec= mesh_bevel_exec;
+       ot->poll= ED_operator_editmesh;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       RNA_def_float(ot->srna, "percent", 0.16f, -FLT_MAX, FLT_MAX, "Percentage", "", -0.07f, 0.5f);
+       RNA_def_int(ot->srna, "recursion", 1, 1, 50, "Recursion Level", "Recursion Level", 1, 6);
+}
index 0c9f9d8d68db2f028c4a53a5696a58f87b66c004..711177e817bb6442b52a611b878eac3aea3c7cbc 100644 (file)
@@ -247,6 +247,9 @@ static void edgering_sel(tringselOpData *lcd, int previewlines, int select)
                edgering_find_order(em, lasteed, startedge, lastv1, v);
 
                for(i=1;i<=previewlines;i++){
                edgering_find_order(em, lasteed, startedge, lastv1, v);
 
                for(i=1;i<=previewlines;i++){
+                       if (!v[0][0] || !v[0][1] || !v[1][0] || !v[1][1])
+                               continue;
+                       
                        co[0][0] = (v[0][1]->co[0] - v[0][0]->co[0])*(i/((float)previewlines+1))+v[0][0]->co[0];
                        co[0][1] = (v[0][1]->co[1] - v[0][0]->co[1])*(i/((float)previewlines+1))+v[0][0]->co[1];
                        co[0][2] = (v[0][1]->co[2] - v[0][0]->co[2])*(i/((float)previewlines+1))+v[0][0]->co[2];
                        co[0][0] = (v[0][1]->co[0] - v[0][0]->co[0])*(i/((float)previewlines+1))+v[0][0]->co[0];
                        co[0][1] = (v[0][1]->co[1] - v[0][0]->co[1])*(i/((float)previewlines+1))+v[0][0]->co[1];
                        co[0][2] = (v[0][1]->co[2] - v[0][0]->co[2])*(i/((float)previewlines+1))+v[0][0]->co[2];
@@ -451,6 +454,7 @@ static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event)
                        ringsel_exit(C, op);
 
                        return OPERATOR_FINISHED;
                        ringsel_exit(C, op);
 
                        return OPERATOR_FINISHED;
+               case RETKEY:
                case RIGHTMOUSE: /* confirm */ // XXX hardcoded
                        if (event->val == KM_PRESS) {
                                /* finish */
                case RIGHTMOUSE: /* confirm */ // XXX hardcoded
                        if (event->val == KM_PRESS) {
                                /* finish */
@@ -507,6 +511,7 @@ static int loopcut_modal (bContext *C, wmOperator *op, wmEvent *event)
 
 
        switch (event->type) {
 
 
        switch (event->type) {
+               case RETKEY:
                case LEFTMOUSE: /* confirm */ // XXX hardcoded
                        if (event->val == KM_RELEASE) {
                                /* finish */
                case LEFTMOUSE: /* confirm */ // XXX hardcoded
                        if (event->val == KM_RELEASE) {
                                /* finish */
index ba5f87f47a2e7174d18ddf4ed3068165a51b13e8..aa6b586b194ba1327ed8b1a56c3cf55c41b48dc1 100644 (file)
@@ -301,6 +301,7 @@ void MESH_OT_edgering_select(struct wmOperatorType *ot);
 void MESH_OT_loopcut(struct wmOperatorType *ot);
 
 void MESH_OT_knifetool(struct wmOperatorType *ot);
 void MESH_OT_loopcut(struct wmOperatorType *ot);
 
 void MESH_OT_knifetool(struct wmOperatorType *ot);
+void MESH_OT_bevel(struct wmOperatorType *ot);
 
 #endif // MESH_INTERN_H
 
 
 #endif // MESH_INTERN_H
 
index 519a77fa4aadc2f62dd471ac202934c776d799bd..d0c9f06eb4601f5003898b8db6550ab2c9161813 100644 (file)
@@ -148,6 +148,8 @@ void ED_operatortypes_mesh(void)
        WM_operatortype_append(MESH_OT_select_nth);
        WM_operatortype_append(MESH_OT_vert_connect);
        WM_operatortype_append(MESH_OT_knifetool);
        WM_operatortype_append(MESH_OT_select_nth);
        WM_operatortype_append(MESH_OT_vert_connect);
        WM_operatortype_append(MESH_OT_knifetool);
+
+       WM_operatortype_append(MESH_OT_bevel);
 }
 
 #if 0 /* UNUSED, remove? */
 }
 
 #if 0 /* UNUSED, remove? */
index 86957ecb86c4487d5ff5b7be05d36ccef2346475..7e93f8999f46d75e85663c943801abdbf58694fd 100644 (file)
@@ -1439,7 +1439,7 @@ static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) /* like a loca
        INIT_MINMAX(min, max);
 
        if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
        INIT_MINMAX(min, max);
 
        if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
-               /* hardcoded exception, we look for the one selected armature */
+               /* hardcoded exception, we look for the one selectedW armature */
                /* this is weak code this way, we should make a generic active/selection callback interface once... */
                Base *base;
                for(base=scene->base.first; base; base= base->next) {
                /* this is weak code this way, we should make a generic active/selection callback interface once... */
                Base *base;
                for(base=scene->base.first; base; base= base->next) {
index a5d11d6796a55361b37d5a7b73243d9b05be5595..a882e8f7d9280e0c6a68a37e5bf2c832fa531042 100644 (file)
@@ -1609,7 +1609,7 @@ static int select_all_exec(bContext *C, wmOperator *op)
                                        luv->flag |= MLOOPUV_VERTSEL;
                                        break;
                                case SEL_DESELECT:
                                        luv->flag |= MLOOPUV_VERTSEL;
                                        break;
                                case SEL_DESELECT:
-                                       luv->flag &= MLOOPUV_VERTSEL;
+                                       luv->flag &= ~MLOOPUV_VERTSEL;
                                        break;
                                case SEL_INVERT:
                                        luv->flag ^= MLOOPUV_VERTSEL;
                                        break;
                                case SEL_INVERT:
                                        luv->flag ^= MLOOPUV_VERTSEL;
index d5235736368e0dd3ca2fded4ea9fabbce21646ed..35571cd8e767664c3a03a9a9214d42d38fe96065 100644 (file)
@@ -132,7 +132,7 @@ DerivedMesh *get_dm(Object *ob, struct EditMesh *em, DerivedMesh *dm, float (*ve
                return dm;
 
        if(ob->type==OB_MESH) {
                return dm;
 
        if(ob->type==OB_MESH) {
-               if(em) dm= CDDM_from_editmesh(em, ob->data);
+               if(em) dm= CDDM_from_BMEditMesh(em, ob->data);
                else dm = CDDM_from_mesh((struct Mesh *)(ob->data), ob);
 
                if(vertexCos) {
                else dm = CDDM_from_mesh((struct Mesh *)(ob->data), ob);
 
                if(vertexCos) {