Merged 15170:15635 from trunk (no conflicts or even merges)
[blender.git] / source / blender / blenkernel / intern / BME_tools.c
index 2b3ff3812e417ce0d797b95fed2c49f233b91e7c..90259031e5caa3e42e22ba9ef9ed75a64e5d336e 100644 (file)
@@ -5,15 +5,12 @@
  *
  * $Id: BME_eulers.c,v 1.00 2007/01/17 17:42:01 Briggs Exp $
  *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -31,7 +28,7 @@
  *
  * Contributor(s): Geoffrey Bantle and Levi Schooley.
  *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
  */
 
 #include <math.h>
 
 #include "blendef.h"
 
-/**
- *                     BME_dissolve_edge
- *
- *     Edge Dissolve Function:
- *
- *     Dissolves a 2-manifold edge by joining it's two faces. if
- *     they have opposite windings it first makes them consistent
- *     by calling BME_loop_reverse()
- *
- *     Returns -
-*/
-
-/**
- *                     BME_inset_edge
- *
- *     Edge Inset Function:
- *
- *     Splits a face in two along an edge and returns the next loop
- *
- *     Returns -
- *     A BME_Poly pointer.
- */
-
-BME_Loop *BME_inset_edge(BME_Mesh *bm, BME_Loop *l, BME_Poly *f){
-       BME_Loop *nloop;
-       BME_SFME(bm, f, l->v, l->next->v, &nloop);
-       return nloop->next;
-}
-
-/**
- *                     BME_inset_poly
- *
- *     Face Inset Tool:
- *
- *     Insets a single face and returns a pointer to the face at the
- *     center of the newly created region
- *
- *     Returns -
- *     A BME_Poly pointer.
- */
-
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#define MAX(a,b) (((a)>(b))?(a):(b))
-
-BME_Poly *BME_inset_poly(BME_Mesh *bm,BME_Poly *f){
-
-       BME_Vert *v;
-       BME_Loop *l,*nextloop, *killoop, *sloop;
-
-       int len,i;
-       float max[3],min[3],cent[3]; //center of original face
-
-       /*get bounding box for face*/
-       VECCOPY(max,f->loopbase->v->co);
-       VECCOPY(min,f->loopbase->v->co);
-       len = f->len;
-       for(i=0,l=f->loopbase;i<len;i++,l=l->next){
-               max[0] = MAX(max[0],l->v->co[0]);
-               max[1] = MAX(max[1],l->v->co[1]);
-               max[2] = MAX(max[2],l->v->co[2]);
-
-               min[0] = MIN(min[0],l->v->co[0]);
-               min[1] = MIN(min[1],l->v->co[1]);
-               min[2] = MIN(min[2],l->v->co[2]);
-       }
-
-       cent[0] = (min[0] + max[0]) / 2.0f;
-       cent[1] = (min[1] + max[1]) / 2.0f;
-       cent[2] = (min[2] + max[2]) / 2.0f;
-
-       /*inset each edge in the polygon.*/
-       len = f->len;
-       for(i=0,l=f->loopbase; i < len; i++){
-               nextloop = l->next;
-               f = BME_SFME(bm,l->f,l->v,l->next->v,NULL);
-               l=nextloop;
-       }
-
-       /*for each new edge, call SEMV on it*/
-       for(i=0,l=f->loopbase; i < len; i++, l=l->next){
-               l->tflag1 = 1; //going to store info that this loops edge still needs split
-               f = BME_SFME(bm,l->f,l->v,l->next->v,NULL);
-               l->tflag2 = l->v->tflag1 = l->v->tflag2 = 0;
-       }
-
-       len = f->len;
-       for(i=0,l=f->loopbase; i < len; i++){
-               if(l->tflag1){
-                       l->tflag1 = 0;
-                       v= BME_SEMV(bm,l->next->v,l->e,NULL);
-                       VECCOPY(v->co,l->v->co);
-                       v->tflag1 = 1;
-                       l = l->next->next;
-               }
-       }
-
-       len = f->len;
-       sloop = NULL;
-       for(i=0,l=f->loopbase; i < len; i++,l=l->next){
-               if(l->v->tflag1 && l->next->next->v->tflag1){
-                       sloop = l;
-                       break;
-               }
-       }
-       if(sloop){
-               for(i=0,l=sloop; i < len; i++){
-                       nextloop = l->next->next;
-                       f = BME_SFME(bm,f,l->v,l->next->next->v,&killoop);
-                       i+=1; //i+=2;
-                       BME_JFKE(bm,l->f,((BME_Loop*)l->radial.next->data)->f,l->e);
-                       l=nextloop;
-               }
-       }
-
-       len = f->len;
-       for(i=0,l=f->loopbase; i < len; i++,l=l->next){
-               l->v->co[0] = (l->v->co[0] + cent[0]) / 2.0f;
-               l->v->co[1] = (l->v->co[1] + cent[1]) / 2.0f;
-               l->v->co[2] = (l->v->co[2] + cent[2]) / 2.0f;
-       }
-       return NULL;
-}
+/*split this all into a seperate bevel.c file in src*/
 
 /* ------- Bevel code starts here -------- */
 
@@ -236,7 +112,7 @@ float *BME_new_transdata_float(BME_TransData_Head *td) {
        return BLI_memarena_alloc(td->ma, sizeof(float));
 }
 
-int BME_is_nonmanifold_vert(BME_Mesh *bm, BME_Vert *v) {
+static int BME_is_nonmanifold_vert(BME_Mesh *bm, BME_Vert *v) {
        BME_Edge *e, *oe;
        BME_Loop *l;
        int len, count, flag;
@@ -298,7 +174,7 @@ int BME_is_nonmanifold_vert(BME_Mesh *bm, BME_Vert *v) {
 
 /* a wrapper for BME_JFKE that [for now just] checks to
  * make sure loop directions are compatible */
-BME_Poly *BME_JFKE_safe(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e) {
+static BME_Poly *BME_JFKE_safe(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e) {
        BME_Loop *l1, *l2;
 
        l1 = e->loop;
@@ -311,7 +187,7 @@ BME_Poly *BME_JFKE_safe(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e) {
 }
 
 /* a wrapper for BME_SFME that transfers element flags */
-BME_Poly *BME_split_face(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Loop **nl, BME_Edge *example) {
+static BME_Poly *BME_split_face(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2, BME_Loop **nl, BME_Edge *example) {
        BME_Poly *nf;
        nf = BME_SFME(bm,f,v1,v2,nl);
        nf->flag = f->flag;
@@ -329,8 +205,54 @@ BME_Poly *BME_split_face(BME_Mesh *bm, BME_Poly *f, BME_Vert *v1, BME_Vert *v2,
        return nf;
 }
 
-/* a wrapper for BME_SEMV that transfers element flags */
-BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge **ne, float percent) {
+
+static void BME_data_interp_from_verts(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Vert *v, float fac)
+{
+       void *src[2];
+       float w[2];
+       if (v1->data && v2->data) {
+               src[0]= v1->data;
+               src[1]= v2->data;
+               w[0] = 1.0f-fac;
+               w[1] = fac;
+               CustomData_bmesh_interp(&bm->vdata, src, w, NULL, 2, v->data);
+       }
+}
+
+
+static void BME_data_facevert_edgesplit(BME_Mesh *bm, BME_Vert *v1, BME_Vert *v2, BME_Vert *v, BME_Edge *e1, float fac){
+       void *src[2];
+       float w[2];
+       BME_Loop *l=NULL, *v1loop = NULL, *vloop = NULL, *v2loop = NULL;
+       
+       w[0] = 1.0f - fac;
+       w[1] = fac;
+
+       if(!e1->loop) return;
+       l = e1->loop;
+       do{
+               if(l->v == v1){ 
+                       v1loop = l;
+                       vloop = v1loop->next;
+                       v2loop = vloop->next;
+               }else if(l->v == v){
+                       v1loop = l->next;
+                       vloop = l;
+                       v2loop = l->prev;
+                       
+               }
+
+               src[0] = v1loop->data;
+               src[1] = v2loop->data;                                  
+
+               CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, vloop->data);                               
+               l = l->radial.next->data;
+       }while(l!=e1->loop);
+}
+
+
+/* a wrapper for BME_SEMV that transfers element flags */ /*add custom data interpolation in here!*/
+static BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge **ne, float percent) {
        BME_Vert *nv, *v2;
        float len;
 
@@ -348,11 +270,40 @@ BME_Vert *BME_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Edge *e, BME_Edge **ne,
                (*ne)->crease = e->crease;
                (*ne)->bweight = e->bweight;
        }
-
+       /*v->nv->v2*/
+       BME_data_facevert_edgesplit(bm,v2, v, nv, e, 0.75);     
        return nv;
 }
 
-int BME_bevel_is_split_vert(BME_Loop *l) {
+static void BME_collapse_vert(BME_Mesh *bm, BME_Edge *ke, BME_Vert *kv, float fac){
+       void *src[2];
+       float w[2];
+       BME_Loop *l=NULL, *kvloop=NULL, *tvloop=NULL;
+       BME_Vert *tv = BME_edge_getothervert(ke,kv);
+
+       w[0] = 1.0f - fac;
+       w[1] = fac;
+
+       if(ke->loop){
+               l = ke->loop;
+               do{
+                       if(l->v == tv && l->next->v == kv){
+                               tvloop = l;
+                               kvloop = l->next;
+
+                               src[0] = kvloop->data;
+                               src[1] = tvloop->data;
+                               CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, kvloop->data);                                                              
+                       }
+                       l=l->radial.next->data;
+               }while(l!=ke->loop);
+       }
+       BME_JEKV(bm,ke,kv);
+}
+
+
+
+static int BME_bevel_is_split_vert(BME_Loop *l) {
        /* look for verts that have already been added to the edge when
         * beveling other polys; this can be determined by testing the
         * vert and the edges around it for originality
@@ -370,13 +321,13 @@ int BME_bevel_is_split_vert(BME_Loop *l) {
  * the bevel operation as a whole based on the relationship between v1 and v2
  * (won't necessarily be a vec from v1->co to v2->co, though it probably will be);
  * the return value is -1 for failure, 0 if we used vert co's, and 1 if we used transform origins */
-int BME_bevel_get_vec(float *vec, BME_Vert *v1, BME_Vert *v2, BME_TransData_Head *td) {
+static int BME_bevel_get_vec(float *vec, BME_Vert *v1, BME_Vert *v2, BME_TransData_Head *td) {
        BME_TransData *vtd1, *vtd2;
 
        vtd1 = BME_get_transdata(td,v1);
        vtd2 = BME_get_transdata(td,v2);
        if (!vtd1 || !vtd2) {
-               printf("BME_bevel_get_vec() got called without proper BME_TransData\n");
+               //printf("BME_bevel_get_vec() got called without proper BME_TransData\n");
                return -1;
        }
 
@@ -408,7 +359,7 @@ int BME_bevel_get_vec(float *vec, BME_Vert *v1, BME_Vert *v2, BME_TransData_Head
  * 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 */
-float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec, int is_forward, BME_TransData_Head *td) {
+static float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec, int is_forward, BME_TransData_Head *td) {
        float factor, vec3[3], tmp[3],c1,c2;
 
        Crossf(tmp,vec1,vec2);
@@ -437,9 +388,9 @@ float BME_bevel_project_vec(float *vec1, float *vec2, float *up_vec, int is_forw
  * using the vert and the loop passed, get or make the split vert, set its coordinates
  * and transform properties, and set the max limits.
  * Finally, return the split vert. */
-BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop *l, float *up_vec, float value, BME_TransData_Head *td) {
+static BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop *l, float *up_vec, float value, BME_TransData_Head *td) {
        BME_TransData *vtd, *vtd1, *vtd2;
-       BME_Vert *sv, *v2, *v3;
+       BME_Vert *sv, *v2, *v3, *ov;
        BME_Loop *lv1, *lv2;
        BME_Edge *ne, *e1, *e2;
        float maxfactor, scale, len, dis, vec1[3], vec2[3], t_up_vec[3];
@@ -452,19 +403,19 @@ BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop
                forward = 1;
                is_split_vert = 0;
                if (v->edge == NULL) {
-                       printf("We can't split a loose vert's edge!\n");
+                       //printf("We can't split a loose vert's edge!\n");
                        return NULL;
                }
                e1 = v->edge; /* we just use the first two edges */
                e2 = BME_disk_nextedge(v->edge, v);
                if (e1 == e2) {
-                       printf("You need at least two edges to use BME_bevel_split_edge()\n");
+                       //printf("You need at least two edges to use BME_bevel_split_edge()\n");
                        return NULL;
                }
                v2 = BME_edge_getothervert(e1, v);
                v3 = BME_edge_getothervert(e2, v);
                if (v1 != v2 && v1 != v3) {
-                       printf("Error: more than 2 edges in v's disk cycle, or v1 does not share an edge with v\n");
+                       //printf("Error: more than 2 edges in v's disk cycle, or v1 does not share an edge with v\n");
                        return NULL;
                }
                if (v1 == v2) {
@@ -473,7 +424,11 @@ BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop
                else {
                        e1 = e2;
                }
+               ov = BME_edge_getothervert(e1,v);
                sv = BME_split_edge(bm,v,e1,&ne,0);
+               //BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /*this is technically wrong...*/
+               //BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25);
+               //BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25);
                BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */
                sv->tflag1 |= BME_BEVEL_BEVEL;
                ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */
@@ -500,7 +455,7 @@ BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop
                        v2 = l->next->next->v;
                }
                else {
-                       printf("ERROR: BME_bevel_split_edge() - v must be adjacent to l\n");
+                       //printf("ERROR: BME_bevel_split_edge() - v must be adjacent to l\n");
                        return NULL;
                }
 
@@ -512,7 +467,11 @@ BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop
                }
                else {
                        is_split_vert = 0;
+                       ov = BME_edge_getothervert(l->e,v);
                        sv = BME_split_edge(bm,v,l->e,&ne,0);
+                       //BME_data_interp_from_verts(bm, v, ov, sv, 0.25); /*this is technically wrong...*/
+                       //BME_data_interp_from_faceverts(bm, v, ov, sv, 0.25);
+                       //BME_data_interp_from_faceverts(bm, ov, v, sv, 0.25);
                        BME_assign_transdata(td, bm, sv, sv->co, sv->co, NULL, sv->co, 0, -1, -1, NULL); /* quick default */
                        sv->tflag1 |= BME_BEVEL_BEVEL;
                        ne->tflag1 = BME_BEVEL_ORIG; /* mark edge as original, even though it isn't */
@@ -572,7 +531,7 @@ BME_Vert *BME_bevel_split_edge(BME_Mesh *bm, BME_Vert *v, BME_Vert *v1, BME_Loop
        return sv;
 }
 
-float BME_bevel_set_max(BME_Vert *v1, BME_Vert *v2, float value, BME_TransData_Head *td) {
+static float BME_bevel_set_max(BME_Vert *v1, BME_Vert *v2, float value, BME_TransData_Head *td) {
        BME_TransData *vtd1, *vtd2;
        float max, fac1, fac2, vec1[3], vec2[3], vec3[3];
 
@@ -626,7 +585,7 @@ float BME_bevel_set_max(BME_Vert *v1, BME_Vert *v2, float value, BME_TransData_H
        return max;
 }
 
-BME_Vert *BME_bevel_wire(BME_Mesh *bm, BME_Vert *v, float value, int res, int options, BME_TransData_Head *td) {
+static BME_Vert *BME_bevel_wire(BME_Mesh *bm, BME_Vert *v, float value, int res, int options, BME_TransData_Head *td) {
        BME_Vert *ov1, *ov2, *v1, *v2;
 
        ov1 = BME_edge_getothervert(v->edge, v);
@@ -651,12 +610,11 @@ BME_Vert *BME_bevel_wire(BME_Mesh *bm, BME_Vert *v, float value, int res, int op
        return v1;
 }
 
-BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int options, float *up_vec, BME_TransData_Head *td) {
+static BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int options, float *up_vec, BME_TransData_Head *td) {
        BME_Vert *v1, *v2, *kv;
-       BME_Loop *kl, *nl;
+       BME_Loop *kl=NULL, *nl;
        BME_Edge *e;
        BME_Poly *f;
-       float factor=1;
 
        f = l->f;
        e = l->e;
@@ -692,12 +650,15 @@ BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int options, fl
                if (kl->v == kv) {
                        BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e);
                        BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e);
-                       BME_JEKV(bm,kl->e,kv);
+                       BME_collapse_vert(bm, kl->e, kv, 1.0);
+                       //BME_JEKV(bm,kl->e,kv);
+                       
                }
                else {
                        BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e);
                        BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e);
-                       BME_JEKV(bm,kl->e,kv);
+                       BME_collapse_vert(bm, kl->e, kv, 1.0);
+                       //BME_JEKV(bm,kl->e,kv);
                }
                l = l->prev;
        }
@@ -726,12 +687,14 @@ BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int options, fl
                if (kl->v == kv) {
                        BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e);
                        BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e);
-                       BME_JEKV(bm,kl->e,kv);
+                       BME_collapse_vert(bm, kl->e, kv, 1.0);
+                       //BME_JEKV(bm,kl->e,kv);
                }
                else {
                        BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e);
                        BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e);
-                       BME_JEKV(bm,kl->e,kv);
+                       BME_collapse_vert(bm, kl->e, kv, 1.0);
+                       //BME_JEKV(bm,kl->e,kv);
                }
        }
 
@@ -741,12 +704,14 @@ BME_Loop *BME_bevel_edge(BME_Mesh *bm, BME_Loop *l, float value, int options, fl
                l = l->radial.next->data;
        }
 
-       if (l->f != f) printf("Whoops! You got something out of order in BME_bevel_edge()!\n");
+       if (l->f != f){
+               //printf("Whoops! You got something out of order in BME_bevel_edge()!\n");
+       }
 
        return l;
 }
 
-BME_Loop *BME_bevel_vert(BME_Mesh *bm, BME_Loop *l, float value, int options, float *up_vec, BME_TransData_Head *td) {
+static BME_Loop *BME_bevel_vert(BME_Mesh *bm, BME_Loop *l, float value, int options, float *up_vec, BME_TransData_Head *td) {
        BME_Vert *v1, *v2;
        BME_Poly *f;
 
@@ -779,7 +744,7 @@ BME_Loop *BME_bevel_vert(BME_Mesh *bm, BME_Loop *l, float value, int options, fl
  *     Returns -
  *  A BME_Poly pointer to the resulting inner face.
 */
-BME_Poly *BME_bevel_poly(BME_Mesh *bm, BME_Poly *f, float value, int options, BME_TransData_Head *td) {
+static BME_Poly *BME_bevel_poly(BME_Mesh *bm, BME_Poly *f, float value, int options, BME_TransData_Head *td) {
        BME_Loop *l, *ol;
        BME_TransData *vtd1, *vtd2;
        float up_vec[3], vec1[3], vec2[3], vec3[3], fac1, fac2, max = -1;
@@ -864,12 +829,12 @@ BME_Poly *BME_bevel_poly(BME_Mesh *bm, BME_Poly *f, float value, int options, BM
        return l->f;
 }
 
-void BME_bevel_add_vweight(BME_TransData_Head *td, BME_Mesh *bm, BME_Vert *v, float weight, float factor, int options) {
+static void BME_bevel_add_vweight(BME_TransData_Head *td, BME_Mesh *bm, BME_Vert *v, float weight, float factor, int options) {
        BME_TransData *vtd;
 
        if (v->tflag1 & BME_BEVEL_NONMAN) return;
        v->tflag1 |= BME_BEVEL_BEVEL;
-       if (vtd = BME_get_transdata(td, v)) {
+       if ( (vtd = BME_get_transdata(td, v)) ) {
                if (options & BME_BEVEL_EMIN) {
                        vtd->factor = 1.0;
                        if (vtd->weight < 0 || weight < vtd->weight) {
@@ -897,7 +862,7 @@ void BME_bevel_add_vweight(BME_TransData_Head *td, BME_Mesh *bm, BME_Vert *v, fl
        }
 }
 
-float BME_bevel_get_angle(BME_Mesh *bm, BME_Edge *e, BME_Vert *v) {
+static float BME_bevel_get_angle(BME_Mesh *bm, BME_Edge *e, BME_Vert *v) {
        BME_Vert *v1, *v2;
        BME_Loop *l1, *l2;
        float vec1[3], vec2[3], vec3[3], vec4[3];
@@ -934,7 +899,18 @@ float BME_bevel_get_angle(BME_Mesh *bm, BME_Edge *e, BME_Vert *v) {
 
        return Inpf(vec3,vec4);
 }
-
+static int BME_face_sharededges(BME_Poly *f1, BME_Poly *f2){
+       BME_Loop *l;
+       int count = 0;
+       
+       l = f1->loopbase;
+       do{
+               if(BME_radial_find_face(l->e,f2)) count++;
+               l = l->next;
+       }while(l != f1->loopbase);
+       
+       return count;
+}
 /**
  *                     BME_bevel_initialize
  *
@@ -945,14 +921,14 @@ float BME_bevel_get_angle(BME_Mesh *bm, BME_Edge *e, BME_Vert *v) {
  *     Returns -
  *  A BME_Mesh pointer to the BMesh passed as a parameter.
 */
-BME_Mesh *BME_bevel_initialize(BME_Mesh *bm, int options, int defgrp_index, float angle, BME_TransData_Head *td) {
+static BME_Mesh *BME_bevel_initialize(BME_Mesh *bm, int options, int defgrp_index, float angle, BME_TransData_Head *td) {
        BME_Vert *v;
        BME_Edge *e;
        BME_Poly *f;
        BME_TransData *vtd;
        MDeformVert *dvert;
        MDeformWeight *dw;
-       int i, len;
+       int len;
        float weight, threshold;
 
        /* vert pass */
@@ -1113,11 +1089,22 @@ BME_Mesh *BME_bevel_initialize(BME_Mesh *bm, int options, int defgrp_index, floa
        /* face pass */
        for (f=bm->polys.first; f; f=f->next) f->tflag1 = BME_BEVEL_ORIG;
 
+       /*clean up edges with 2 faces that share more than one edge*/
+       for (e=bm->edges.first; e; e=e->next){
+               if(e->tflag1 & BME_BEVEL_BEVEL){
+                       int count = 0;
+                       count = BME_face_sharededges(e->loop->f, ((BME_Loop*)e->loop->radial.next->data)->f);
+                       if(count > 1){
+                               e->tflag1 &= ~BME_BEVEL_BEVEL;
+                       }       
+               }
+       }
+
        return bm;
 }
 
 /* tags all elements as originals */
-BME_Mesh *BME_bevel_reinitialize(BME_Mesh *bm) {
+static BME_Mesh *BME_bevel_reinitialize(BME_Mesh *bm) {
        BME_Vert *v;
        BME_Edge *e;
        BME_Poly *f;
@@ -1150,12 +1137,40 @@ BME_Mesh *BME_bevel_reinitialize(BME_Mesh *bm) {
  *     Returns -
  *  A BME_Mesh pointer to the BMesh passed as a parameter.
 */
-BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int defgrp_index, BME_TransData_Head *td) {
-       BME_Vert *v, *nv, *kv;
-       BME_Edge *e, *oe, *ne;
+
+static void bmesh_dissolve_disk(BME_Mesh *bm, BME_Vert *v){
+       BME_Poly *f;
+       BME_Edge *e;
+       int done, len;
+       
+       if(v->edge){
+               done = 0;
+               while(!done){
+                       done = 1;
+                       e = v->edge; /*loop the edge looking for a edge to dissolve*/
+                       do{
+                               f = NULL;
+                               len = BME_cycle_length(&(e->loop->radial));
+                               if(len == 2){
+                                       f = BME_JFKE_safe(bm,e->loop->f, ((BME_Loop*)(e->loop->radial.next->data))->f, e);
+                               }
+                               if(f){ 
+                                       done = 0;
+                                       break;
+                               }
+                               e = BME_disk_nextedge(e,v);
+                       }while(e != v->edge);
+               }
+               BME_collapse_vert(bm, v->edge, v, 1.0);
+               //BME_JEKV(bm,v->edge,v);
+       }
+}
+static BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int defgrp_index, BME_TransData_Head *td) {
+       BME_Vert *v, *nv;
+       BME_Edge *e, *oe;
        BME_Loop *l, *l2;
-       BME_Poly *f, *nf;
-       unsigned int i, len, done;
+       BME_Poly *f;
+       unsigned int i, len;
 
        for (f=bm->polys.first; f; f=f->next) {
                if(f->tflag1 & BME_BEVEL_ORIG) {
@@ -1171,24 +1186,31 @@ BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int de
                        v = BME_bevel_wire(bm, v, value, res, options, td);
                }
                else if (res && ((v->tflag1 & BME_BEVEL_BEVEL) && (v->tflag1 & BME_BEVEL_ORIG))) {
+                       int count = 0;
                        /* first, make sure we're not sitting on an edge to be removed */
                        oe = v->edge;
                        e = BME_disk_nextedge(oe,v);
                        while ((e->tflag1 & BME_BEVEL_BEVEL) && (e->tflag1 & BME_BEVEL_ORIG)) {
                                e = BME_disk_nextedge(e,v);
                                if (e == oe) {
-                                       printf("Something's wrong! We can't remove every edge here!\n");
+                                       //printf("Something's wrong! We can't remove every edge here!\n");
                                        break;
                                }
                        }
                        /* look for original edges, and remove them */
                        oe = e;
-                       while (e = BME_disk_next_edgeflag(oe, v, 0, BME_BEVEL_ORIG | BME_BEVEL_BEVEL)) {
+                       while ( (e = BME_disk_next_edgeflag(oe, v, 0, BME_BEVEL_ORIG | BME_BEVEL_BEVEL)) ) {
+                               count++;
                                /* join the faces (we'll split them later) */
                                f = BME_JFKE_safe(bm,e->loop->f,((BME_Loop*)e->loop->radial.next->data)->f,e);
-                               if (!f) printf("Non-manifold geometry not getting tagged right?\n");
+                               if (!f){
+                                       //printf("Non-manifold geometry not getting tagged right?\n");
+                               }
                        }
 
+                       /*need to do double check *before* you bevel to make sure that manifold edges are for two faces that share only *one* edge to make sure it doesnt hang here!*/
+
+
                        /* all original edges marked to be beveled have been removed;
                         * now we need to link up the edges for this "corner" */
                        len = BME_cycle_length(BME_disk_getpointer(v->edge, v));
@@ -1211,56 +1233,15 @@ BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int de
                                        }
                                }
                        }
-
-                       done = 0;
-                       while(!done){
-                               done = 1;
-                               e = v->edge;
-                               do{
-                                       f = NULL;
-                                       len = BME_cycle_length(&(e->loop->radial));
-                                       if(len == 2){
-                                               f = BME_JFKE_safe(bm,e->loop->f, ((BME_Loop*)(e->loop->radial.next->data))->f, e);
-                                       }
-                                       if(f){ 
-                                               done = 0;
-                                               break;
-                                       }
-                                       e = BME_disk_nextedge(e,v);
-                               }while(e != v->edge);
-                       }
-                       BME_JEKV(bm,e,v);
+                       bmesh_dissolve_disk(bm, v);
                }
                v = nv;
        }
 
-       /*clean up two edged faces here*/
-               for(f=bm->polys.first; f;){
-                       nf = f->next;
-                       if(f->len == 2){
-                               e = NULL;
-                               l = f->loopbase;
-                               do{
-                                       if(BME_cycle_length(&l->radial) == 2){
-                                               e = l->e;
-                                               break;
-                                       }
-                                       l = l->next;
-                               }while(l!=f->loopbase);
-
-                               if(e) BME_JFKE_safe(bm,f, ((BME_Loop*)(e->loop->radial.next->data))->f, e);
-                               else{
-                                       /*We are still leaving a stray edge? This shouldnt even be possible!*/
-                                       BME_KF(bm, f);
-                               }
-                       }
-                       f = nf;
-               }
-
        return bm;
 }
 
-BME_Mesh *BME_tesselate(BME_Mesh *bm) {
+static BME_Mesh *BME_tesselate(BME_Mesh *bm) {
        BME_Loop *l, *nextloop;
        BME_Poly *f;
 
@@ -1276,6 +1257,12 @@ BME_Mesh *BME_tesselate(BME_Mesh *bm) {
        return bm;
 }
 
+
+/*Main bevel function:
+       Should be only one exported
+
+*/
+
 /* options that can be passed:
  * BME_BEVEL_VWEIGHT   <---- v, Look at vertex weights; use defgrp_index if option is present
  * BME_BEVEL_SELECT            <---- v,e, check selection for verts and edges
@@ -1305,7 +1292,9 @@ BME_Mesh *BME_bevel(BME_Mesh *bm, float value, int res, int options, int defgrp_
        /* crazy idea. if res == 0, don't remove original geometry */
        for (i=0; i<res || (res==0 && i==0); i++) {
                if (i != 0) BME_bevel_reinitialize(bm);
+               BME_model_begin(bm);
                BME_bevel_mesh(bm,d,res,options,defgrp_index,td);
+               BME_model_end(bm);
                if (i==0) d /= 3; else d /= 2;
        }
 
@@ -1318,7 +1307,7 @@ BME_Mesh *BME_bevel(BME_Mesh *bm, float value, int res, int options, int defgrp_
 
        /* transform pass */
        for (v = bm->verts.first; v; v=v->next) {
-               if (vtd = BME_get_transdata(td, v)) {
+               if ( (vtd = BME_get_transdata(td, v)) ) {
                        if (vtd->max && (*vtd->max > 0 && value > *vtd->max)) {
                                d = *vtd->max;
                        }