Part one of editmesh.c refactoring. The huge file has been split in
authorTon Roosendaal <ton@blender.org>
Sun, 19 Sep 2004 11:47:49 +0000 (11:47 +0000)
committerTon Roosendaal <ton@blender.org>
Sun, 19 Sep 2004 11:47:49 +0000 (11:47 +0000)
logical parts, and include files altered to denote internal and external
functions.

include/editmesh.h: internal calls for editmesh_xxx.c files
include/BIF_editmesh.h: external calls for these files

src/editmesh.c: basic alloc/lists and in/out editmode, undo, separate
src/editmesh_lib.c: basic utility calls for all editmesh_xxx.c (no UI)
src/editmesh_add.c: add prim, add duplicate, add vertex/edge/face (UI)
src/editmesh_mods.c: selecting, transforming (UI)
src/editmesh_loop.c: loop tools like knife, loop select, loop subdiv (UI)
src/editmesh_tools.c: other tools (extrude, spin, etc) (UI)

And a new file:

src/meshtools.c: tools for Mesh outside of editmode (normals, draw flags)

15 files changed:
source/blender/include/BIF_editmesh.h
source/blender/include/BIF_meshtools.h [new file with mode: 0644]
source/blender/include/editmesh.h [new file with mode: 0644]
source/blender/src/booleanops.c
source/blender/src/buttons_editing.c
source/blender/src/editmesh.c
source/blender/src/editmesh_add.c [new file with mode: 0644]
source/blender/src/editmesh_lib.c [new file with mode: 0644]
source/blender/src/editmesh_loop.c [new file with mode: 0644]
source/blender/src/editmesh_mods.c [new file with mode: 0644]
source/blender/src/editmesh_tools.c [new file with mode: 0644]
source/blender/src/header_view3d.c
source/blender/src/meshtools.c [new file with mode: 0644]
source/blender/src/space.c
source/blender/src/usiblender.c

index 176cef6c99c83bf256b7c31f144e56cde2422903..a40c09f4bfeb3223922b86df7f2720fa998cdada 100644 (file)
@@ -30,6 +30,8 @@
  * ***** END GPL/BL DUAL LICENSE BLOCK *****
  */
 
+/* External for editmesh_xxxx.c functions */
+
 #ifndef BIF_EDITMESH_H
 #define BIF_EDITMESH_H
 
@@ -40,139 +42,104 @@ struct Mesh;
 struct bDeformGroup;
 struct View3D;
 
-void free_hashedgetab(void);
-void fasterdraw(void);
-void slowerdraw(void);
-void vertexnoise(void);
-void vertexsmooth(void);
-void make_sticky(void);
-void deselectall_mesh(void);
-
-/* For Knife subdivide */
-typedef struct CutCurve {
-       short  x; 
-       short  y;
-} CutCurve;
-
-void KnifeSubdivide(char mode);
-#define KNIFE_PROMPT 0
-#define KNIFE_EXACT 1
-#define KNIFE_MIDPOINT 2
+/* ******************* editmesh.c */
+extern void make_editMesh(void);
+extern void load_editMesh(void);
+extern void free_editMesh(void);
+extern void remake_editMesh(void);
 
-CutCurve *get_mouse_trail(int * length, char mode);
-#define TRAIL_POLYLINE 1 /* For future use, They don't do anything yet */
-#define TRAIL_FREEHAND 2
-#define TRAIL_MIXED    3 /* (1|2) */
-#define TRAIL_AUTO     4 
-#define        TRAIL_MIDPOINTS 8
+       /* Editmesh Undo code */
+void undo_free_mesh(struct Mesh *me);
+void undo_push_mesh(char *name);
+void undo_pop_mesh(int steps);
+void undo_redo_mesh(void);
+void undo_clear_mesh(void);
+void undo_menu_mesh(void);
+
+extern void separatemenu(void);
+extern void separate_mesh(void);
+extern void separate_mesh_loose(void);
+
+/* ******************* editmesh_add.c */
+extern void add_primitiveMesh(int type);
+extern void adduplicate_mesh(void);
+extern void addvert_mesh(void);
+extern void addedgeface_mesh(void);
+
+/* ******************* editmesh_lib.c */
+extern int faceselectedAND(struct EditFace *efa, int flag);
+extern void recalc_editnormals(void);
+extern void flip_editnormals(void);
+extern void vertexnormals(int testflip);
 
-short seg_intersect(struct EditEdge * e, CutCurve *c, int len);
+/* ******************* editmesh_mods.c */
+extern void vertexnoise(void);
+extern void vertexsmooth(void);
+extern void righthandfaces(int select);
+extern void mouse_mesh(void);
 
-void LoopMenu(void);
-/* End Knife Subdiv */
+extern void deselectall_mesh(void);
+extern void selectconnected_mesh(int qual);
+extern void selectswap_mesh(void);
+
+extern void hide_mesh(int swap);
+extern void reveal_mesh(void);
+
+extern void vertices_to_sphere(void);
 
        /** Aligns the selected TFace's of @a me to the @a v3d,
         * using the given axis (0-2). Can give a user error.
         */
-void faceselect_align_view_to_selected(struct View3D *v3d, struct Mesh *me, int axis);
+extern void faceselect_align_view_to_selected(struct View3D *v3d, struct Mesh *me, int axis);
        /** Aligns the selected faces or vertices of @a me to the @a v3d,
         * using the given axis (0-2). Can give a user error.
         */
-void editmesh_align_view_to_selected(struct View3D *v3d, int axis);
-
-struct EditVert *addvertlist(float *vec);
-struct EditEdge *addedgelist(struct EditVert *v1, struct EditVert *v2, struct EditEdge *example);
-struct EditFace *addfacelist(struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example);
-struct EditEdge *findedgelist(struct EditVert *v1, struct EditVert *v2);
-
-void remedge(struct EditEdge *eed);
+extern void editmesh_align_view_to_selected(struct View3D *v3d, int axis);
 
-int faceselectedAND(struct EditFace *efa, int flag);
+       /* Selection */
+extern void select_non_manifold(void);
+extern void select_more(void);
+extern void select_less(void);
+extern void selectrandom_mesh(void);
+extern void editmesh_select_by_material(int index);
+extern void editmesh_deselect_by_material(int index);
 
-void recalc_editnormals(void);
-void flip_editnormals(void);
-void vertexnormals(int testflip);
-/* this is currently only used by the python NMesh module: */
-void vertexnormals_mesh(struct Mesh *me, float *extverts);
+extern void Edge_Menu(void);
+extern void editmesh_mark_seam(int clear);
 
-void make_editMesh(void);
-void load_editMesh(void);
-void free_editMesh(void);
-void remake_editMesh(void);
+/* ******************* editmesh_loop.c */
 
-void convert_to_triface(int all);
-
-void righthandfaces(int select);
-
-void mouse_mesh(void);
-
-void selectconnected_mesh(int qual);
-short extrudeflag(short flag,short type);
-void rotateflag(short flag, float *cent, float rotmat[][3]);
-void translateflag(short flag, float *vec);
-short removedoublesflag(short flag, float limit);
-void xsortvert_flag(int flag);
-void hashvert_flag(int flag);
-void subdivideflag(int flag, float rad, int beauty);
-void adduplicateflag(int flag);
-void extrude_mesh(void);
-void adduplicate_mesh(void);
-void split_mesh(void);
+#define KNIFE_PROMPT 0
+#define KNIFE_EXACT 1
+#define KNIFE_MIDPOINT 2
 
-void separatemenu(void);
-void separate_mesh(void);
-void separate_mesh_loose(void);
+extern void KnifeSubdivide(char mode);
+extern void LoopMenu(void);
 
-void loopoperations(char mode);
 #define LOOP_SELECT    1
 #define LOOP_CUT       2
 
-void vertex_loop_select(void); 
-void edge_select(void);
-
-void extrude_repeat_mesh(int steps, float offs);
-void spin_mesh(int steps,int degr,float *dvec, int mode);
-void screw_mesh(int steps,int turns);
-void selectswap_mesh(void);
-void addvert_mesh(void);
-void addedgeface_mesh(void);
-void delete_mesh(void);
-void add_primitiveMesh(int type);
-void hide_mesh(int swap);
-void reveal_mesh(void);
-void beauty_fill(void);
-void join_triangles(void);
-void edge_flip(void);
-void join_mesh(void);
-void sort_faces(void);
-void vertices_to_sphere(void);
-void fill_mesh(void);
-
-void bevel_menu();
-
-/* Editmesh Undo code */
-void undo_free_mesh(struct Mesh *me);
-void undo_push_mesh(char *name);
-void undo_pop_mesh(int steps);
-void undo_redo_mesh(void);
-void undo_clear_mesh(void);
-void undo_menu_mesh(void);
-
-/* Selection */
-void select_non_manifold(void);
-void select_more(void);
-void select_less(void);
-void selectrandom_mesh(void);
-
-void Edge_Menu(void);
-
-void editmesh_select_by_material(int index);
-void editmesh_deselect_by_material(int index);
-
-void editmesh_mark_seam(int clear);
-
+extern void loopoperations(char mode);
+extern void vertex_loop_select(void); 
+
+/* ******************* editmesh_tools.c */
+extern void convert_to_triface(int all);
+extern short removedoublesflag(short flag, float limit);
+extern void xsortvert_flag(int flag);
+extern void hashvert_flag(int flag);
+extern void subdivideflag(int flag, float rad, int beauty);
+extern void extrude_mesh(void);
+extern void split_mesh(void);
+extern void extrude_repeat_mesh(int steps, float offs);
+extern void spin_mesh(int steps,int degr,float *dvec, int mode);
+extern void screw_mesh(int steps,int turns);
+extern void delete_mesh(void);
+extern void beauty_fill(void);
+extern void join_triangles(void);
+extern void edge_flip(void);
+extern void fill_mesh(void);
+extern void bevel_menu();
 void edge_rotate_selected(void);
-void edge_rotate(struct EditEdge *eed);
  
 #endif
 
diff --git a/source/blender/include/BIF_meshtools.h b/source/blender/include/BIF_meshtools.h
new file mode 100644 (file)
index 0000000..facfecb
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * $Id: 
+ *
+ * ***** BEGIN GPL/BL DUAL 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BIF_MESHTOOLS_H
+#define BIF_MESHTOOLS_H
+
+extern void join_mesh(void);
+extern void make_sticky(void);
+
+extern void fasterdraw(void);
+extern void slowerdraw(void);
+
+extern void vertexnormals_mesh(Mesh *me, float *extverts);
+extern void sort_faces(void);
+
+
+#endif
+
diff --git a/source/blender/include/editmesh.h b/source/blender/include/editmesh.h
new file mode 100644 (file)
index 0000000..d7cd459
--- /dev/null
@@ -0,0 +1,89 @@
+/**
+ * $Id: 
+ *
+ * ***** BEGIN GPL/BL DUAL 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/* Internal for editmesh_xxxx.c functions */
+
+#ifndef EDITMESH_H
+#define EDITMESH_H
+
+#define TEST_EDITMESH  if(G.obedit==0) return; \
+                                               if( (G.vd->lay & G.obedit->lay)==0 ) return;
+
+#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
+
+
+/* ******************* editmesh.c */
+extern void free_editvert(EditVert *eve);
+extern void free_editedge(EditEdge *eed);
+extern void free_editface(EditFace *efa);
+
+extern void free_vertlist(ListBase *edve);
+extern void free_edgelist(ListBase *lb);
+extern void free_facelist(ListBase *lb);
+
+extern void remedge(EditEdge *eed);
+
+extern struct EditVert *addvertlist(float *vec);
+extern struct EditEdge *addedgelist(struct EditVert *v1, struct EditVert *v2, struct EditEdge *example);
+extern struct EditFace *addfacelist(struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example);
+extern struct EditEdge *findedgelist(struct EditVert *v1, struct EditVert *v2);
+
+/* ******************* editmesh_add.c */
+extern void adduplicateflag(int flag);
+
+
+/* ******************* editmesh_lib.c */
+extern int editmesh_nfaces_selected(void);
+extern int editmesh_nvertices_selected(void);
+
+extern int faceselectedOR(EditFace *efa, int flag);
+extern int faceselectedAND(EditFace *efa, int flag);
+
+extern int exist_face(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4);
+extern void flipface(EditFace *efa); // flips for normal direction
+extern int compareface(EditFace *vl1, EditFace *vl2);
+
+extern void delfaceflag(int flag);
+extern short extrudeflag(short flag,short type);
+extern void rotateflag(short flag, float *cent, float rotmat[][3]);
+extern void translateflag(short flag, float *vec);
+
+extern float convex(float *v1, float *v2, float *v3, float *v4);
+
+/* ******************* editmesh_mods.c */
+extern EditEdge *findnearestedge();
+
+/* ******************* editmesh_tools.c */
+
+
+#endif
+
index 0ced994fd569748ab2f1a9938b1e7e518c15de17..644813c0e01fd86812094cb5f7cf294b329ed643 100644 (file)
 // TODO check to see how many of these includes are necessary
 
 #include "BLI_blenlib.h"
-#include "BLI_editVert.h"
 #include "BLI_arithb.h"
 #include "BLI_linklist.h"
 #include "BLI_memarena.h"
 
-#include "BIF_editmesh.h"
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
index ed5e86a270b4bc3f9e6e9b1ae5c9d09169a7bb45..cb04b9d3faf4f760cb0412e214edf0f1cf735209 100644 (file)
@@ -98,6 +98,7 @@
 #include "BIF_editmesh.h"
 #include "BIF_editsound.h"
 #include "BIF_interface.h"
+#include "BIF_meshtools.h"
 #include "BIF_mywindow.h"
 #include "BIF_renderwin.h"
 #include "BIF_resources.h"
index ad1acb139fa56769c25db177d457cc95fed2ad85..8b088a9f0bc195670ed7f6a021d5a5d8b701ccb0 100644 (file)
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 #include "BLI_editVert.h"
-#include "BLI_rand.h"
-
 
 #include "BKE_utildefines.h"
 #include "BKE_key.h"
 #include "BKE_object.h"
-#include "BKE_texture.h"
 #include "BKE_displist.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_material.h"
 #include "BKE_mesh.h"
+#include "BKE_texture.h"
 
-#include "BIF_gl.h"
-#include "BIF_graphics.h"
 #include "BIF_editkey.h"
-#include "BIF_space.h"
-#include "BIF_toolbox.h"
-#include "BIF_screen.h"
-#include "BIF_interface.h"
 #include "BIF_editmesh.h"
+#include "BIF_interface.h"
 #include "BIF_mywindow.h"
-#include "BIF_resources.h"
-#include "BIF_glutil.h"
-#include "BIF_cursors.h"
+#include "BIF_space.h"
+#include "BIF_screen.h"
+#include "BIF_toolbox.h"
 
 #include "BSE_view.h"
 #include "BSE_edit.h"
 
 #include "mydevice.h"
 #include "blendef.h"
-#include "nla.h"               /* For __NLA : Important - Do not remove! */
 #include "render.h"
 
-#include "GHOST_C-api.h"
-#include "winlay.h"
-
-#ifdef WIN32
-       #ifndef snprintf
-               #define snprintf  _snprintf
-       #endif
-#endif
-
-/****/
-
-static float convex(float *v1, float *v2, float *v3, float *v4);
-
-/* EditMesh Undo */
-void make_editMesh_real(Mesh *me);
-void load_editMesh_real(Mesh *me, int);
-/****/
 
+/* own include */
+#include "editmesh.h"
 
-/* extern ListBase fillvertbase, filledgebase; */ /* scanfill.c, in
-    the lib... already in BLI_blenlib.h */
-
-
-extern short editbutflag;
-
-static float icovert[12][3] = {
-       {0,0,-200}, 
-       {144.72, -105.144,-89.443},
-       {-55.277, -170.128,-89.443}, 
-       {-178.885,0,-89.443},
-       {-55.277,170.128,-89.443}, 
-       {144.72,105.144,-89.443},
-       {55.277,-170.128,89.443},
-       {-144.72,-105.144,89.443},
-       {-144.72,105.144,89.443},
-       {55.277,170.128,89.443},
-       {178.885,0,89.443},
-       {0,0,200}
-};
-static short icoface[20][3] = {
-       {1,0,2},
-       {1,0,5},
-       {2,0,3},
-       {3,0,4},
-       {4,0,5},
-       {1,5,10},
-       {2,1,6},
-       {3,2,7},
-       {4,3,8},
-       {5,4,9},
-       {10,1,6},
-       {6,2,7},
-       {7,3,8},
-       {8,4,9},
-       {9,5,10},
-       {6,10,11},
-       {7,6,11},
-       {8,7,11},
-       {9,8,11},
-       {10,9,11}
-};
+/* 
 
-/* DEFINES */
-#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
+editmesh.c:
+- add/alloc/free data
+- hashtables
+- enter/exit editmode
 
-#define TEST_EDITMESH  if(G.obedit==0) return; \
-                                               if( (G.vd->lay & G.obedit->lay)==0 ) return;
+*/
 
-#define FACE_MARKCLEAR(f) (f->f1 = 1)
 
 /* ***************** HASH ********************* */
 
@@ -183,39 +119,6 @@ struct HashEdge {
 
 struct HashEdge *hashedgetab=NULL;
 
-/********* qsort routines *********/
-
-
-struct xvertsort {
-       float x;
-       EditVert *v1;
-};
-
-/* Functions */
-static int vergxco(const void *v1, const void *v2)
-{
-       const struct xvertsort *x1=v1, *x2=v2;
-
-       if( x1->x > x2->x ) return 1;
-       else if( x1->x < x2->x) return -1;
-       return 0;
-}
-
-struct facesort {
-       long x;
-       struct EditFace *efa;
-};
-
-
-static int vergface(const void *v1, const void *v2)
-{
-       const struct facesort *x1=v1, *x2=v2;
-       
-       if( x1->x > x2->x ) return 1;
-       else if( x1->x < x2->x) return -1;
-       return 0;
-}
-
 
 /* ************ ADD / REMOVE / FIND ****************** */
 
@@ -381,7 +284,7 @@ EditEdge *addedgelist(EditVert *v1, EditVert *v2, EditEdge *example)
        return eed;
 }
 
-static void free_editvert (EditVert *eve)
+void free_editvert (EditVert *eve)
 {
        if (eve->dw) MEM_freeN (eve->dw);
        free (eve);
@@ -395,17 +298,17 @@ void remedge(EditEdge *eed)
        remove_hashedge(eed);
 }
 
-static void free_editedge(EditEdge *eed)
+void free_editedge(EditEdge *eed)
 {
        free(eed);
 }
 
-static void free_editface(EditFace *efa)
+void free_editface(EditFace *efa)
 {
        free(efa);
 }
 
-static void free_vertlist(ListBase *edve) 
+void free_vertlist(ListBase *edve) 
 {
        EditVert *eve, *next;
 
@@ -420,7 +323,7 @@ static void free_vertlist(ListBase *edve)
        edve->first= edve->last= NULL;
 }
 
-static void free_edgelist(ListBase *lb)
+void free_edgelist(ListBase *lb)
 {
        EditEdge *eed, *next;
        
@@ -433,7 +336,7 @@ static void free_edgelist(ListBase *lb)
        lb->first= lb->last= NULL;
 }
 
-static void free_facelist(ListBase *lb)
+void free_facelist(ListBase *lb)
 {
        EditFace *efa, *next;
        
@@ -497,138 +400,10 @@ EditFace *addfacelist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, Ed
 
 /* ********* end add / new / find */
 
-static int compareface(EditFace *vl1, EditFace *vl2)
-{
-       EditVert *v1, *v2, *v3, *v4;
-       
-       if(vl1->v4 && vl2->v4) {
-               v1= vl2->v1;
-               v2= vl2->v2;
-               v3= vl2->v3;
-               v4= vl2->v4;
-               
-               if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1 || vl1->v4==v1) {
-                       if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2 || vl1->v4==v2) {
-                               if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3 || vl1->v4==v3) {
-                                       if(vl1->v1==v4 || vl1->v2==v4 || vl1->v3==v4 || vl1->v4==v4) {
-                                               return 1;
-                                       }
-                               }
-                       }
-               }
-       }
-       else if(vl1->v4==0 && vl2->v4==0) {
-               v1= vl2->v1;
-               v2= vl2->v2;
-               v3= vl2->v3;
-
-               if(vl1->v1==v1 || vl1->v2==v1 || vl1->v3==v1) {
-                       if(vl1->v1==v2 || vl1->v2==v2 || vl1->v3==v2) {
-                               if(vl1->v1==v3 || vl1->v2==v3 || vl1->v3==v3) {
-                                       return 1;
-                               }
-                       }
-               }
-       }
-
-       return 0;
-}
-
-static int exist_face(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4)
-{
-       EditMesh *em = G.editMesh;
-       EditFace *efa, efatest;
-       
-       efatest.v1= v1;
-       efatest.v2= v2;
-       efatest.v3= v3;
-       efatest.v4= v4;
-       
-       efa= em->faces.first;
-       while(efa) {
-               if(compareface(&efatest, efa)) return 1;
-               efa= efa->next;
-       }
-       return 0;
-}
-
-
-static int faceselectedOR(EditFace *efa, int flag)
-{
-       
-       if(efa->v1->f & flag) return 1;
-       if(efa->v2->f & flag) return 1;
-       if(efa->v3->f & flag) return 1;
-       if(efa->v4 && (efa->v4->f & 1)) return 1;
-       return 0;
-}
-
-int faceselectedAND(EditFace *efa, int flag)
-{
-       if(efa->v1->f & flag) {
-               if(efa->v2->f & flag) {
-                       if(efa->v3->f & flag) {
-                               if(efa->v4) {
-                                       if(efa->v4->f & flag) return 1;
-                               }
-                               else return 1;
-                       }
-               }
-       }
-       return 0;
-}
-
-void recalc_editnormals(void)
-{
-       EditMesh *em = G.editMesh;
-       EditFace *efa;
-
-       efa= em->faces.first;
-       while(efa) {
-               if(efa->v4) CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
-               else CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
-               efa= efa->next;
-       }
-}
-
-static void flipface(EditFace *efa)
-{
-       if(efa->v4) {
-               SWAP(EditVert *, efa->v2, efa->v4);
-               SWAP(EditEdge *, efa->e1, efa->e4);
-               SWAP(EditEdge *, efa->e2, efa->e3);
-               SWAP(unsigned int, efa->tf.col[1], efa->tf.col[3]);
-               SWAP(float, efa->tf.uv[1][0], efa->tf.uv[3][0]);
-               SWAP(float, efa->tf.uv[1][1], efa->tf.uv[3][1]);
-       }
-       else {
-               SWAP(EditVert *, efa->v2, efa->v3);
-               SWAP(EditEdge *, efa->e1, efa->e3);
-               SWAP(unsigned int, efa->tf.col[1], efa->tf.col[2]);
-               efa->e2->dir= 1-efa->e2->dir;
-               SWAP(float, efa->tf.uv[1][0], efa->tf.uv[2][0]);
-               SWAP(float, efa->tf.uv[1][1], efa->tf.uv[2][1]);
-       }
-       if(efa->v4) CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n);
-       else CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n);
-}
 
 
-void flip_editnormals(void)
-{
-       EditMesh *em = G.editMesh;
-       EditFace *efa;
-       
-       efa= em->faces.first;
-       while(efa) {
-               if( faceselectedAND(efa, 1) ) {
-                       flipface(efa);
-               }
-               efa= efa->next;
-       }
-}
 
-/* ************************ IN & OUT ***************************** */
+/* ************************ IN & OUT EDITMODE ***************************** */
 
 static void edge_normal_compare(EditEdge *eed, EditFace *efa1)
 {
@@ -749,164 +524,6 @@ static void edge_drawflags(void)
        }
 }
 
-static int contrpuntnorm(float *n, float *puno)  /* dutch: check vertex normal */
-{
-       float inp;
-
-       inp= n[0]*puno[0]+n[1]*puno[1]+n[2]*puno[2];
-
-       /* angles 90 degrees: dont flip */
-       if(inp> -0.000001) return 0;
-
-       return 1;
-}
-
-void vertexnormals(int testflip)
-{
-       EditMesh *em = G.editMesh;
-       Mesh *me;
-       EditVert *eve;
-       EditFace *efa;  
-       float n1[3], n2[3], n3[3], n4[3], co[4], fac1, fac2, fac3, fac4, *temp;
-       float *f1, *f2, *f3, *f4, xn, yn, zn;
-       float len;
-       
-       if(G.obedit && G.obedit->type==OB_MESH) {
-               me= G.obedit->data;
-               if((me->flag & ME_TWOSIDED)==0) testflip= 0;
-       }
-
-       if(G.totvert==0) return;
-
-       if(G.totface==0) {
-               /* fake vertex normals for 'halo puno'! */
-               eve= em->verts.first;
-               while(eve) {
-                       VECCOPY(eve->no, eve->co);
-                       Normalise( (float *)eve->no);
-                       eve= eve->next;
-               }
-               return;
-       }
-
-       /* clear normals */     
-       eve= em->verts.first;
-       while(eve) {
-               eve->no[0]= eve->no[1]= eve->no[2]= 0.0;
-               eve= eve->next;
-       }
-       
-       /* calculate cosine angles and add to vertex normal */
-       efa= em->faces.first;
-       while(efa) {
-               VecSubf(n1, efa->v2->co, efa->v1->co);
-               VecSubf(n2, efa->v3->co, efa->v2->co);
-               Normalise(n1);
-               Normalise(n2);
-
-               if(efa->v4==0) {
-                       VecSubf(n3, efa->v1->co, efa->v3->co);
-                       Normalise(n3);
-                       
-                       co[0]= saacos(-n3[0]*n1[0]-n3[1]*n1[1]-n3[2]*n1[2]);
-                       co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
-                       co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
-                       
-               }
-               else {
-                       VecSubf(n3, efa->v4->co, efa->v3->co);
-                       VecSubf(n4, efa->v1->co, efa->v4->co);
-                       Normalise(n3);
-                       Normalise(n4);
-                       
-                       co[0]= saacos(-n4[0]*n1[0]-n4[1]*n1[1]-n4[2]*n1[2]);
-                       co[1]= saacos(-n1[0]*n2[0]-n1[1]*n2[1]-n1[2]*n2[2]);
-                       co[2]= saacos(-n2[0]*n3[0]-n2[1]*n3[1]-n2[2]*n3[2]);
-                       co[3]= saacos(-n3[0]*n4[0]-n3[1]*n4[1]-n3[2]*n4[2]);
-               }
-               
-               temp= efa->v1->no;
-               if(testflip && contrpuntnorm(efa->n, temp) ) co[0]= -co[0];
-               temp[0]+= co[0]*efa->n[0];
-               temp[1]+= co[0]*efa->n[1];
-               temp[2]+= co[0]*efa->n[2];
-               
-               temp= efa->v2->no;
-               if(testflip && contrpuntnorm(efa->n, temp) ) co[1]= -co[1];
-               temp[0]+= co[1]*efa->n[0];
-               temp[1]+= co[1]*efa->n[1];
-               temp[2]+= co[1]*efa->n[2];
-               
-               temp= efa->v3->no;
-               if(testflip && contrpuntnorm(efa->n, temp) ) co[2]= -co[2];
-               temp[0]+= co[2]*efa->n[0];
-               temp[1]+= co[2]*efa->n[1];
-               temp[2]+= co[2]*efa->n[2];
-               
-               if(efa->v4) {
-                       temp= efa->v4->no;
-                       if(testflip && contrpuntnorm(efa->n, temp) ) co[3]= -co[3];
-                       temp[0]+= co[3]*efa->n[0];
-                       temp[1]+= co[3]*efa->n[1];
-                       temp[2]+= co[3]*efa->n[2];
-               }
-               
-               efa= efa->next;
-       }
-
-       /* normalise vertex normals */
-       eve= em->verts.first;
-       while(eve) {
-               len= Normalise(eve->no);
-               if(len==0.0) {
-                       VECCOPY(eve->no, eve->co);
-                       Normalise( eve->no);
-               }
-               eve= eve->next;
-       }
-       
-       /* vertex normal flip-flags for shade (render) */
-       efa= em->faces.first;
-       while(efa) {
-               efa->f=0;                       
-
-               if(testflip) {
-                       f1= efa->v1->no;
-                       f2= efa->v2->no;
-                       f3= efa->v3->no;
-                       
-                       fac1= efa->n[0]*f1[0] + efa->n[1]*f1[1] + efa->n[2]*f1[2];
-                       if(fac1<0.0) {
-                               efa->f = ME_FLIPV1;
-                       }
-                       fac2= efa->n[0]*f2[0] + efa->n[1]*f2[1] + efa->n[2]*f2[2];
-                       if(fac2<0.0) {
-                               efa->f += ME_FLIPV2;
-                       }
-                       fac3= efa->n[0]*f3[0] + efa->n[1]*f3[1] + efa->n[2]*f3[2];
-                       if(fac3<0.0) {
-                               efa->f += ME_FLIPV3;
-                       }
-                       if(efa->v4) {
-                               f4= efa->v4->no;
-                               fac4= efa->n[0]*f4[0] + efa->n[1]*f4[1] + efa->n[2]*f4[2];
-                               if(fac4<0.0) {
-                                       efa->f += ME_FLIPV4;
-                               }
-                       }
-               }
-               /* projection for cubemap! */
-               xn= fabs(efa->n[0]);
-               yn= fabs(efa->n[1]);
-               zn= fabs(efa->n[2]);
-               
-               if(zn>xn && zn>yn) efa->f += ME_PROJXY;
-               else if(yn>xn && yn>zn) efa->f += ME_PROJXZ;
-               else efa->f += ME_PROJYZ;
-               
-               efa= efa->next;
-       }
-}
 
 void free_editMesh(void)
 {
@@ -919,21 +536,6 @@ void free_editMesh(void)
        G.totvert= G.totface= 0;
 }
 
-void make_editMesh(void)
-{
-       Mesh *me;       
-
-       me= get_mesh(G.obedit);
-       if (me != G.undo_last_data) {
-               G.undo_edit_level= -1;
-               G.undo_edit_highest= -1;
-               if (G.undo_clear) G.undo_clear();
-               G.undo_last_data= me;
-               G.undo_clear= undo_clear_mesh;
-       }
-       make_editMesh_real(me);
-}
-
 void make_editMesh_real(Mesh *me)
 {
        EditMesh *em = G.editMesh;
@@ -997,8 +599,6 @@ void make_editMesh_real(Mesh *me)
                 */
                eve->keyindex = a;
 
-#ifdef __NLA
-
                if (me->dvert){
                        eve->totweight = me->dvert[a].totweight;
                        if (me->dvert[a].dw){
@@ -1007,7 +607,6 @@ void make_editMesh_real(Mesh *me)
                        }
                }
 
-#endif
        }
 
        if(actkey && actkey->totelem!=me->totvert);
@@ -1084,6 +683,23 @@ void make_editMesh_real(Mesh *me)
        waitcursor(0);
 }
 
+void make_editMesh(void)
+{
+       Mesh *me;       
+
+       me= get_mesh(G.obedit);
+       if (me != G.undo_last_data) {
+               G.undo_edit_level= -1;
+               G.undo_edit_highest= -1;
+               if (G.undo_clear) G.undo_clear();
+               G.undo_last_data= me;
+               G.undo_clear= undo_clear_mesh;
+       }
+       make_editMesh_real(me);
+}
+
+
+
 /** Rotates MFace and UVFace vertices in case the last
   * vertex index is = 0. 
   * This function is a hack and may only be called in the
@@ -1094,7 +710,6 @@ void make_editMesh_real(Mesh *me)
   * calls/structures, this function resides here.
   */
 
-
 static void fix_faceindices(MFace *mface, EditFace *efa, int nr)
 {
        int a;
@@ -1191,21 +806,6 @@ static void fix_faceindices(MFace *mface, EditFace *efa, int nr)
 }
 
 
-
-/* load from EditMode to Mesh */
-
-void load_editMesh()
-{
-       Mesh *me;
-
-       waitcursor(1);
-       countall();
-       me= get_mesh(G.obedit);
-       
-       load_editMesh_real(me, 0);
-}
-
-
 void load_editMesh_real(Mesh *me, int undo)
 {
        EditMesh *em = G.editMesh;
@@ -1219,10 +819,8 @@ void load_editMesh_real(Mesh *me, int undo)
        EditEdge *eed;
        float *fp, *newkey, *oldkey, nor[3];
        int i, a, ototvert, totedge=0;
-#ifdef __NLA
        MDeformVert *dvert;
        int     usedDvert = 0;
-#endif
 
        /* this one also tests of edges are not in faces: */
        /* eed->f==0: not in face, f==1: draw it */
@@ -1256,14 +854,11 @@ void load_editMesh_real(Mesh *me, int undo)
        else mface= MEM_callocN(G.totface*sizeof(MFace), "loadeditMesh face");
        
 
-#ifdef __NLA
        if (G.totvert==0) dvert= NULL;
        else dvert = MEM_callocN(G.totvert*sizeof(MDeformVert), "loadeditMesh3");
 
        if (me->dvert) free_dverts(me->dvert, me->totvert);
        me->dvert=dvert;
-#endif         
-
 
        /* lets save the old verts just in case we are actually working on
         * a key ... we now do processing of the keys at the end */
@@ -1294,7 +889,7 @@ void load_editMesh_real(Mesh *me, int undo)
                VECCOPY(nor, eve->no);
                VecMulf(nor, 32767.0);
                VECCOPY(mvert->no, nor);
-#ifdef __NLA
+
                /* NEW VERSION */
                if (dvert){
                        dvert->totweight=eve->totweight;
@@ -1306,7 +901,6 @@ void load_editMesh_real(Mesh *me, int undo)
                                usedDvert++;
                        }
                }
-#endif
 
                eve->vn= (EditVert *)(long)(a++);  /* counter */
                        
@@ -1319,18 +913,14 @@ void load_editMesh_real(Mesh *me, int undo)
                        
                eve= eve->next;
                mvert++;
-#ifdef __NLA
                dvert++;
-#endif
        }
        
-#ifdef __NLA
        /* If we didn't actually need the dverts, get rid of them */
        if (!usedDvert){
                free_dverts(me->dvert, G.totvert);
                me->dvert=NULL;
        }
-#endif
 
        /* the edges */
        if(medge) {
@@ -1570,8650 +1160,533 @@ void remake_editMesh(void)
        makeDispList(G.obedit);
 }
 
+/* load from EditMode to Mesh */
+
+void load_editMesh()
+{
+       Mesh *me;
+
+       waitcursor(1);
+       countall();
+       me= get_mesh(G.obedit);
+       
+       load_editMesh_real(me, 0);
+}
+
+
+
 /* *********************  TOOLS  ********************* */
 
 
+                                                                                                                       
+
+
+/*********************** EDITMESH UNDO ********************************/
+/* Mesh Edit undo by Alexander Ewring,                                */
+/* ported by Robert Wenzlaff                                          */
+/*                                                                    */
+/* Any meshedit function wishing to create an undo step, calls        */
+/*     undo_push_mesh("menu_name_of_step");                           */
 
-void make_sticky(void)
+Mesh *undo_new_mesh(void)
 {
-       Object *ob;
-       Base *base;
-       MVert *mvert;
-       Mesh *me;
-       MSticky *ms;
-       float ho[4], mat[4][4];
-       int a;
-       
-       if(G.scene->camera==0) return;
-       
-       if(G.obedit) {
-               error("Unable to make sticky in Edit Mode");
-               return;
-       }
-       base= FIRSTBASE;
-       while(base) {
-               if TESTBASELIB(base) {
-                       if(base->object->type==OB_MESH) {
-                               ob= base->object;
-                               
-                               me= ob->data;
-                               mvert= me->mvert;
-                               if(me->msticky) MEM_freeN(me->msticky);
-                               me->msticky= MEM_mallocN(me->totvert*sizeof(MSticky), "sticky");
-                               
-                               /* like convert to render data */               
-                               R.r= G.scene->r;
-                               R.r.xsch= (R.r.size*R.r.xsch)/100;
-                               R.r.ysch= (R.r.size*R.r.ysch)/100;
-                               
-                               R.afmx= R.r.xsch/2;
-                               R.afmy= R.r.ysch/2;
-                               
-                               R.ycor= ( (float)R.r.yasp)/( (float)R.r.xasp);
-               
-                               R.rectx= R.r.xsch; 
-                               R.recty= R.r.ysch;
-                               R.xstart= -R.afmx; 
-                               R.ystart= -R.afmy;
-                               R.xend= R.xstart+R.rectx-1;
-                               R.yend= R.ystart+R.recty-1;
-               
-                               where_is_object(G.scene->camera);
-                               Mat4CpyMat4(R.viewinv, G.scene->camera->obmat);
-                               Mat4Ortho(R.viewinv);
-                               Mat4Invert(R.viewmat, R.viewinv);
-                               
-                               RE_setwindowclip(1, -1);
-               
-                               where_is_object(ob);
-                               Mat4MulMat4(mat, ob->obmat, R.viewmat);
-               
-                               ms= me->msticky;
-                               for(a=0; a<me->totvert; a++, ms++, mvert++) {
-                                       VECCOPY(ho, mvert->co);
-                                       Mat4MulVecfl(mat, ho);
-                                       RE_projectverto(ho, ho);
-                                       ms->co[0]= ho[0]/ho[3];
-                                       ms->co[1]= ho[1]/ho[3];
-                               }
-                       }
-               }
-               base= base->next;
-       }
-       allqueue(REDRAWBUTSEDIT, 0);
+       return(MEM_callocN(sizeof(Mesh), "undo_mesh"));
+}
+
+void undo_free_mesh(Mesh *me)
+{
+       if(me->mat) MEM_freeN(me->mat);
+       if(me->orco) MEM_freeN(me->orco);
+       if(me->mvert) MEM_freeN(me->mvert);
+       if(me->medge) MEM_freeN(me->medge);
+       if(me->mface) MEM_freeN(me->mface);
+       if(me->tface) MEM_freeN(me->tface);
+       if(me->dvert) free_dverts(me->dvert, me->totvert);
+       if(me->mcol) MEM_freeN(me->mcol);
+       if(me->msticky) MEM_freeN(me->msticky);
+       if(me->bb) MEM_freeN(me->bb);
+       if(me->disp.first) freedisplist(&me->disp);
+       MEM_freeN(me);
 }
 
-void fasterdraw(void)
+
+void undo_push_mesh(char *name)
 {
-       Base *base;
        Mesh *me;
-       MFace *mface;
-       int toggle, a;
+       int i;
+
+       countall();
 
-       if(G.obedit) return;
+       G.undo_edit_level++;
 
-       /* reset flags */
-       me= G.main->mesh.first;
-       while(me) {
-               me->flag &= ~ME_ISDONE;
-               me= me->id.next;
+       if (G.undo_edit_level<0) {
+               printf("undo: ERROR: G.undo_edit_level negative\n");
+               return;
        }
 
-       base= FIRSTBASE;
-       while(base) {
-               if( TESTBASELIB(base) && (base->object->type==OB_MESH)) {
-                       me= base->object->data;
-                       if(me->id.lib==0 && (me->flag & ME_ISDONE)==0) {
-                               me->flag |= ME_ISDONE;
-                               mface= me->mface;
-                               toggle= 0;
-                               for(a=0; a<me->totface; a++) {
-                                       if( (mface->edcode & ME_V1V2) && ( (toggle++) & 1) ) {
-                                               mface->edcode-= ME_V1V2;
-                                       }
-                                       if( (mface->edcode & ME_V2V3) && ( (toggle++) & 1)) {
-                                               mface->edcode-= ME_V2V3;
-                                       }
-                                       if( (mface->edcode & ME_V3V1) && ( (toggle++) & 1)) {
-                                               mface->edcode-= ME_V3V1;
-                                       }
-                                       if( (mface->edcode & ME_V4V1) && ( (toggle++) & 1)) {
-                                               mface->edcode-= ME_V4V1;
-                                       }
-                                       if( (mface->edcode & ME_V3V4) && ( (toggle++) & 1)) {
-                                               mface->edcode-= ME_V3V4;
-                                       }
-                                       mface++;
-                               }
+
+       if (G.undo_edit[G.undo_edit_level].datablock != 0) {
+               undo_free_mesh(G.undo_edit[G.undo_edit_level].datablock);
+       }
+       if (strcmp(name, "U")!=0) {
+               for (i=G.undo_edit_level+1; i<(U.undosteps-1); i++) {
+                       if (G.undo_edit[i].datablock != 0) {
+                               undo_free_mesh(G.undo_edit[i].datablock);
+                               G.undo_edit[i].datablock= 0;
                        }
                }
-               base= base->next;
+               G.undo_edit_highest= G.undo_edit_level;
        }
 
-       /* important?: reset flags again */
-       me= G.main->mesh.first;
-       while(me) {
-               me->flag &= ~ME_ISDONE;
-               me= me->id.next;
+       me= undo_new_mesh();
+
+       if (G.undo_edit_level>=U.undosteps) {
+               G.undo_edit_level--;
+               undo_free_mesh((Mesh*)G.undo_edit[0].datablock);
+               G.undo_edit[0].datablock= 0;
+               for (i=0; i<(U.undosteps-1); i++) {
+                       G.undo_edit[i]= G.undo_edit[i+1];
+               }
        }
 
-       allqueue(REDRAWVIEW3D, 0);
+       if (strcmp(name, "U")!=0) strcpy(G.undo_edit[G.undo_edit_level].name, name);
+       //printf("undo: saving block: %d [%s]\n", G.undo_edit_level, G.undo_edit[G.undo_edit_level].name);
+
+       G.undo_edit[G.undo_edit_level].datablock= (void*)me;
+       load_editMesh_real(me, 1);
 }
 
-void slowerdraw(void)          /* reset fasterdraw */
+void undo_pop_mesh(int steps)  /* steps == 1 is one step */
 {
-       Base *base;
-       Mesh *me;
-       MFace *mface;
-       int a;
-
-       if(G.obedit) return;
-
-       base= FIRSTBASE;
-       while(base) {
-               if( TESTBASELIB(base) && (base->object->type==OB_MESH)) {
-                       me= base->object->data;
-                       if(me->id.lib==0) {
-                               
-                               mface= me->mface;
-                               
-                               for(a=0; a<me->totface; a++) {
-                               
-                                       mface->edcode |= ME_V1V2|ME_V2V3;
-                                       mface++;
-                               }
-                       }
-               }
-               base= base->next;
-       }
+       if (G.undo_edit_level > (steps-2)) {
+               undo_push_mesh("U");
+               G.undo_edit_level-= steps;
 
-       allqueue(REDRAWVIEW3D, 0);
+               //printf("undo: restoring block: %d [%s]\n", G.undo_edit_level, G.undo_edit[G.undo_edit_level].name);    -
+               make_editMesh_real((Mesh*)G.undo_edit[G.undo_edit_level].datablock);
+               allqueue(REDRAWVIEW3D, 0);
+               makeDispList(G.obedit);
+               G.undo_edit_level--;
+       } else error("No more steps to undo");
 }
 
 
-void convert_to_triface(int all)
+void undo_redo_mesh(void)
 {
-       EditMesh *em = G.editMesh;
-       EditFace *efa, *efan, *next;
-       
-       undo_push_mesh("Convert Quads to Triangles");
-       
-       efa= em->faces.first;
-       while(efa) {
-               next= efa->next;
-               if(efa->v4) {
-                       if(all || faceselectedAND(efa, 1) ) {
-                               
-                               efan= addfacelist(efa->v1, efa->v2, efa->v3, 0, efa);
-                               efan= addfacelist(efa->v1, efa->v3, efa->v4, 0, efa);
+       if ( (G.undo_edit[G.undo_edit_level+2].datablock) &&
+               ( (G.undo_edit_level+1) <= G.undo_edit_highest ) ) {
+               G.undo_edit_level++;
 
-                               efan->tf.uv[1][0]= efan->tf.uv[2][0];
-                               efan->tf.uv[1][1]= efan->tf.uv[2][1];
-                               efan->tf.uv[2][0]= efan->tf.uv[3][0];
-                               efan->tf.uv[2][1]= efan->tf.uv[3][1];
-                               
-                               efan->tf.col[1]= efan->tf.col[2];
-                               efan->tf.col[2]= efan->tf.col[3];
-                               
-                               BLI_remlink(&em->faces, efa);
-                               free_editface(efa);
-                       }
-               }
-               efa= next;
-       }
-       
+               //printf("redo: restoring block: %d [%s]\n", G.undo_edit_level+1, G.undo_edit[G.undo_edit_level+1].name);-
+               make_editMesh_real((Mesh*)G.undo_edit[G.undo_edit_level+1].datablock);
+               allqueue(REDRAWVIEW3D, 0);
+               makeDispList(G.obedit);
+       } else error("No more steps to redo");
 }
 
-
-void deselectall_mesh(void)    /* toggle */
+void undo_clear_mesh(void)
 {
-       EditMesh *em = G.editMesh;
-       EditVert *eve;
-       int a;
-       
-       if(G.obedit->lay & G.vd->lay) {
-               a= 0;
-               eve= em->verts.first;
-               while(eve) {
-                       if(eve->f & 1) {
-                               a= 1;
-                               break;
-                       }
-                       eve= eve->next;
-               }
-               
-               if (a) undo_push_mesh("Deselect All");
-               else undo_push_mesh("Select All");
-               
-               eve= em->verts.first;
-               while(eve) {
-                       if(eve->h==0) {
-                               if(a) eve->f&= -2;
-                               else eve->f|= 1;
-                       }
-                       eve= eve->next;
+       int i;
+       Mesh *me;
+
+       for (i=0; i<=UNDO_EDIT_MAX; i++) {
+               me= (Mesh*) G.undo_edit[i].datablock;
+               if (me) {
+                       //printf("undo: freeing %d\n", i);
+                       undo_free_mesh(me);
+                       G.undo_edit[i].datablock= 0;
                }
        }
-       countall();
-       allqueue(REDRAWVIEW3D, 0);
 }
 
+#ifdef WIN32
+       #ifndef snprintf
+               #define snprintf  _snprintf
+       #endif
+#endif
 
-void righthandfaces(int select)        /* makes faces righthand turning */
+void undo_menu_mesh(void)
 {
-       EditMesh *em = G.editMesh;
-       EditEdge *eed, *ed1, *ed2, *ed3, *ed4;
-       EditFace *efa, *startvl;
-       float maxx, nor[3], cent[3];
-       int totsel, found, foundone, direct, turn, tria_nr;
-
-   /* based at a select-connected to witness loose objects */
-
-       /* count per edge the amount of faces */
-
-       /* find the ultimate left, front, upper face (not manhattan dist!!) */
-       /* also evaluate both triangle cases in quad, since these can be non-flat */
-
-       /* put normal to the outside, and set the first direction flags in edges */
+       short event=66;
+       int i;
+       char menu[2080], temp[64];
 
-       /* then check the object, and set directions / direction-flags: but only for edges with 1 or 2 faces */
-       /* this is in fact the 'select connected' */
-       
-       /* in case (selected) faces were not done: start over with 'find the ultimate ...' */
+       TEST_EDITMESH
 
-       waitcursor(1);
+       strcpy(menu, "Undo %t|%l");
+       strcat(menu, "|All changes%x1|%l");
        
-       eed= em->edges.first;
-       while(eed) {
-               eed->f= 0;
-               eed->f1= 0;
-               eed= eed->next;
-       }
-
-       /* count faces and edges */
-       totsel= 0;
-       efa= em->faces.first;
-       while(efa) {
-               if(select==0 || faceselectedAND(efa, 1) ) {
-                       efa->f= 1;
-                       totsel++;
-                       efa->e1->f1++;
-                       efa->e2->f1++;
-                       efa->e3->f1++;
-                       if(efa->v4) efa->e4->f1++;
-               }
-               else efa->f= 0;
-
-               efa= efa->next;
+       for (i=G.undo_edit_level; i>=0; i--) {
+               snprintf(temp, 64, "|%s%%x%d", G.undo_edit[i].name, i+2);
+               strcat(menu, temp);
        }
 
-       while(totsel>0) {
-               /* from the outside to the inside */
-
-               efa= em->faces.first;
-               startvl= NULL;
-               maxx= -1.0e10;
-               tria_nr= 0;
+       event=pupmenu_col(menu, 20);
 
-               while(efa) {
-                       if(efa->f) {
-                               CalcCent3f(cent, efa->v1->co, efa->v2->co, efa->v3->co);
-                               cent[0]= cent[0]*cent[0] + cent[1]*cent[1] + cent[2]*cent[2];
-                               
-                               if(cent[0]>maxx) {
-                                       maxx= cent[0];
-                                       startvl= efa;
-                                       tria_nr= 0;
-                               }
-                               if(efa->v4) {
-                                       CalcCent3f(cent, efa->v1->co, efa->v3->co, efa->v4->co);
-                                       cent[0]= cent[0]*cent[0] + cent[1]*cent[1] + cent[2]*cent[2];
-                                       
-                                       if(cent[0]>maxx) {
-                                               maxx= cent[0];
-                                               startvl= efa;
-                                               tria_nr= 1;
-                                       }
-                               }
-                       }
-                       efa= efa->next;
-               }
-               
-               /* set first face correct: calc normal */
-               
-               if(tria_nr==1) {
-                       CalcNormFloat(startvl->v1->co, startvl->v3->co, startvl->v4->co, nor);
-                       CalcCent3f(cent, startvl->v1->co, startvl->v3->co, startvl->v4->co);
-               } else {
-                       CalcNormFloat(startvl->v1->co, startvl->v2->co, startvl->v3->co, nor);
-                       CalcCent3f(cent, startvl->v1->co, startvl->v2->co, startvl->v3->co);
-               }
-               /* first normal is oriented this way or the other */
-               if(select) {
-                       if(select==2) {
-                               if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] > 0.0) flipface(startvl);
-                       }
-                       else {
-                               if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipface(startvl);
-                       }
-               }
-               else if(cent[0]*nor[0]+cent[1]*nor[1]+cent[2]*nor[2] < 0.0) flipface(startvl);
+       if(event<1) return;
 
+       if (event==1) remake_editMesh();
+       else undo_pop_mesh(G.undo_edit_level-event+3);
+}
 
-               eed= startvl->e1;
-               if(eed->v1==startvl->v1) eed->f= 1; 
-               else eed->f= 2;
-               
-               eed= startvl->e2;
-               if(eed->v1==startvl->v2) eed->f= 1; 
-               else eed->f= 2;
-               
-               eed= startvl->e3;
-               if(eed->v1==startvl->v3) eed->f= 1; 
-               else eed->f= 2;
-               
-               eed= startvl->e4;
-               if(eed) {
-                       if(eed->v1==startvl->v4) eed->f= 1; 
-                       else eed->f= 2;
-               }
-               
-               startvl->f= 0;
-               totsel--;
-
-               /* test normals */
-               found= 1;
-               direct= 1;
-               while(found) {
-                       found= 0;
-                       if(direct) efa= em->faces.first;
-                       else efa= em->faces.last;
-                       while(efa) {
-                               if(efa->f) {
-                                       turn= 0;
-                                       foundone= 0;
-
-                                       ed1= efa->e1;
-                                       ed2= efa->e2;
-                                       ed3= efa->e3;
-                                       ed4= efa->e4;
-
-                                       if(ed1->f) {
-                                               if(ed1->v1==efa->v1 && ed1->f==1) turn= 1;
-                                               if(ed1->v2==efa->v1 && ed1->f==2) turn= 1;
-                                               foundone= 1;
-                                       }
-                                       else if(ed2->f) {
-                                               if(ed2->v1==efa->v2 && ed2->f==1) turn= 1;
-                                               if(ed2->v2==efa->v2 && ed2->f==2) turn= 1;
-                                               foundone= 1;
-                                       }
-                                       else if(ed3->f) {
-                                               if(ed3->v1==efa->v3 && ed3->f==1) turn= 1;
-                                               if(ed3->v2==efa->v3 && ed3->f==2) turn= 1;
-                                               foundone= 1;
-                                       }
-                                       else if(ed4 && ed4->f) {
-                                               if(ed4->v1==efa->v4 && ed4->f==1) turn= 1;
-                                               if(ed4->v2==efa->v4 && ed4->f==2) turn= 1;
-                                               foundone= 1;
-                                       }
+/* *************** END UNDO *************/
 
-                                       if(foundone) {
-                                               found= 1;
-                                               totsel--;
-                                               efa->f= 0;
-
-                                               if(turn) {
-                                                       if(ed1->v1==efa->v1) ed1->f= 2; 
-                                                       else ed1->f= 1;
-                                                       if(ed2->v1==efa->v2) ed2->f= 2; 
-                                                       else ed2->f= 1;
-                                                       if(ed3->v1==efa->v3) ed3->f= 2; 
-                                                       else ed3->f= 1;
-                                                       if(ed4) {
-                                                               if(ed4->v1==efa->v4) ed4->f= 2; 
-                                                               else ed4->f= 1;
-                                                       }
+/* *************** SEPARATE (partial exit editmode) *************/
 
-                                                       flipface(efa);
 
-                                               }
-                                               else {
-                                                       if(ed1->v1== efa->v1) ed1->f= 1; 
-                                                       else ed1->f= 2;
-                                                       if(ed2->v1==efa->v2) ed2->f= 1; 
-                                                       else ed2->f= 2;
-                                                       if(ed3->v1==efa->v3) ed3->f= 1; 
-                                                       else ed3->f= 2;
-                                                       if(ed4) {
-                                                               if(ed4->v1==efa->v4) ed4->f= 1; 
-                                                               else ed4->f= 2;
-                                                       }
-                                               }
-                                       }
-                               }
-                               if(direct) efa= efa->next;
-                               else efa= efa->prev;
-                       }
-                       direct= 1-direct;
-               }
-       }
+void separatemenu(void)
+{
+       short event;
 
-       recalc_editnormals();
+       event = pupmenu("Separate (No undo!) %t|Selected%x1|All Loose Parts%x2");
        
-       makeDispList(G.obedit);
+       if (event==0) return;
+       waitcursor(1);
        
+       switch (event) {
+
+               case 1: 
+                       separate_mesh();                    
+                       break;
+               case 2:                     
+                       separate_mesh_loose();              
+                       break;
+       }
        waitcursor(0);
 }
 
-static EditVert *findnearestvert(short sel)
+
+void separate_mesh(void)
 {
        EditMesh *em = G.editMesh;
-       /* if sel==1 the vertices with flag==1 get a disadvantage */
-       EditVert *eve,*act=0;
-       static EditVert *acto=0;
-       short dist=100,temp,mval[2];
-
-       if(em->verts.first==0) return 0;
+       EditVert *eve, *v1;
+       EditEdge *eed, *e1;
+       EditFace *efa, *vl1;
+       Object *oldob;
+       Mesh *me, *men;
+       Base *base, *oldbase;
+       ListBase edve, eded, edvl;
+       float trans[9];
+       int ok, flag;
+       
+       TEST_EDITMESH   
 
-       /* do projection */
-       calc_meshverts_ext();   /* drawobject.c */
+       waitcursor(1);
+       
+       me= get_mesh(G.obedit);
+       if(me->key) {
+               error("Can't separate with vertex keys");
+               return;
+       }
+       
+       /* we are going to abuse the system as follows:
+        * 1. add a duplicate object: this will be the new one, we remember old pointer
+        * 2: then do a split if needed.
+        * 3. put apart: all NOT selected verts, edges, faces
+        * 4. call loadobeditdata(): this will be the new object
+        * 5. freelist and get back old verts, edges, facs
+        */
+       
+       /* make only obedit selected */
+       base= FIRSTBASE;
+       while(base) {
+               if(base->lay & G.vd->lay) {
+                       if(base->object==G.obedit) base->flag |= SELECT;
+                       else base->flag &= ~SELECT;
+               }
+               base= base->next;
+       }
+       
+       /* testen for split */
+       ok= 0;
+       eed= em->edges.first;
+       while(eed) {
+               flag= (eed->v1->f & 1)+(eed->v2->f & 1);
+               if(flag==1) {
+                       ok= 1;
+                       break;
+               }
+               eed= eed->next;
+       }
+       if(ok) {
+               /* SPLIT: first make duplicate */
+               adduplicateflag(1);
+               /* SPLIT: old faces have 3x flag 128 set, delete these ones */
+               delfaceflag(128);
+       }
        
-       /* we count from acto->next to last, and from first to acto */
-       /* does acto exist? */
+       /* set apart: everything that is not selected */
+       edve.first= edve.last= eded.first= eded.last= edvl.first= edvl.last= 0;
        eve= em->verts.first;
        while(eve) {
-               if(eve==acto) break;
-               eve= eve->next;
+               v1= eve->next;
+               if((eve->f & 1)==0) {
+                       BLI_remlink(&em->verts, eve);
+                       BLI_addtail(&edve, eve);
+               }
+               eve= v1;
        }
-       if(eve==0) acto= em->verts.first;
-
-       if(acto==0) return 0;
-
-       /* is there an indicated vertex? part 1 */
-       getmouseco_areawin(mval);
-       eve= acto->next;
-       while(eve) {
-               if(eve->h==0) {
-                       temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys);
-                       if( (eve->f & 1)==sel ) temp+=5;
-                       if(temp<dist) {
-                               act= eve;
-                               dist= temp;
-                               if(dist<4) break;
-                       }
+       eed= em->edges.first;
+       while(eed) {
+               e1= eed->next;
+               if( (eed->v1->f & 1)==0 || (eed->v2->f & 1)==0 ) {
+                       BLI_remlink(&em->edges, eed);
+                       BLI_addtail(&eded, eed);
                }
-               eve= eve->next;
+               eed= e1;
        }
-       /* is there an indicated vertex? part 2 */
-       if(dist>3) {
-               eve= em->verts.first;
-               while(eve) {
-                       if(eve->h==0) {
-                               temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys);
-                               if( (eve->f & 1)==sel ) temp+=5;
-                               if(temp<dist) {
-                                       act= eve;
-                                       if(temp<4) break;
-                                       dist= temp;
-                               }
-                               if(eve== acto) break;
-                       }
-                       eve= eve->next;
+       efa= em->faces.first;
+       while(efa) {
+               vl1= efa->next;
+               if( (efa->v1->f & 1)==0 || (efa->v2->f & 1)==0 || (efa->v3->f & 1)==0 ) {
+                       BLI_remlink(&em->faces, efa);
+                       BLI_addtail(&edvl, efa);
                }
+               efa= vl1;
        }
+       
+       oldob= G.obedit;
+       oldbase= BASACT;
+       
+       trans[0]=trans[1]=trans[2]=trans[3]=trans[4]=trans[5]= 0.0;
+       trans[6]=trans[7]=trans[8]= 1.0;
+       G.qual |= LR_ALTKEY;    /* patch to make sure we get a linked duplicate */
+       adduplicate(trans);
+       G.qual &= ~LR_ALTKEY;
+       
+       G.obedit= BASACT->object;       /* basact was set in adduplicate()  */
 
-       acto= act;
-       return act;
-}
-
-
-static EditEdge *findnearestedge()
-{
-       EditMesh *em = G.editMesh;
-       EditEdge *closest, *eed;
-       EditVert *eve;
-       short found=0, mval[2];
-       float distance[2], v1[2], v2[2], mval2[2];
+       men= copy_mesh(me);
+       set_mesh(G.obedit, men);
+       /* because new mesh is a copy: reduce user count */
+       men->id.us--;
        
-       if(em->edges.first==0) return NULL;
-       else eed=em->edges.first;       
+       load_editMesh();
        
-       /* reset flags */       
-       for(eve=em->verts.first; eve; eve=eve->next){
-               eve->f &= ~2;
-       }       
-               
-       calc_meshverts_ext_f2();        /*sets (eve->f & 2) for vertices that aren't visible*/
-       getmouseco_areawin(mval);
-       closest=NULL;
+       BASACT->flag &= ~SELECT;
+       
+       makeDispList(G.obedit);
+       free_editMesh();
        
-       mval2[0] = (float)mval[0];
-       mval2[1] = (float)mval[1];
+       em->verts= edve;
+       em->edges= eded;
+       em->faces= edvl;
        
-       eed=em->edges.first;
-       /*compare the distance to the rest of the edges and find the closest one*/
+       /* hashedges are freed now, make new! */
+       eed= em->edges.first;
        while(eed) {
-               /* Are both vertices of the edge ofscreen or either of them hidden? then don't select the edge*/
-               if( !((eed->v1->f & 2) && (eed->v2->f & 2)) && (eed->v1->h==0 && eed->v2->h==0)){
-                       v1[0] = eed->v1->xs;
-                       v1[1] = eed->v1->ys;
-                       v2[0] = eed->v2->xs;
-                       v2[1] = eed->v2->ys;
-                       
-                       distance[1] = PdistVL2Dfl(mval2, v1, v2);
-                       
-                       if(distance[1]<50){
-                               /*do we have to compare it to other distances? */                       
-                               if(found) {
-                                       if (distance[1]<distance[0]){
-                                               distance[0]=distance[1];
-                                               /*save the current closest edge*/
-                                               closest=eed;    
-                                       }
-                               } else {
-                                       distance[0]=distance[1];
-                                       closest=eed;
-                                       found=1;
-                               }
-                       }
-               }
+               if( findedgelist(eed->v1, eed->v2)==NULL )
+                       insert_hashedge(eed);
                eed= eed->next;
        }
        
-       /* reset flags */       
-       for(eve=em->verts.first; eve; eve=eve->next){
-               eve->f &= ~2;
-       }
+       G.obedit= oldob;
+       BASACT= oldbase;
+       BASACT->flag |= SELECT;
        
-       if(found) return closest;
-       else return 0;
+       waitcursor(0);
+
+       countall();
+       allqueue(REDRAWVIEW3D, 0);
+       makeDispList(G.obedit);
+
 }
 
-/* does the same as findnearestedge but both vertices of the edge should be on screen*/
-static EditEdge *findnearestvisibleedge()
+void separate_mesh_loose(void)
 {
        EditMesh *em = G.editMesh;
-       EditEdge *closest, *eed;
-       EditVert *eve;
-       short found=0, mval[2];
-       float distance[2], v1[2], v2[2], mval2[2];
+       EditVert *eve, *v1;
+       EditEdge *eed, *e1;
+       EditFace *efa, *vl1;
+       Object *oldob;
+       Mesh *me, *men;
+       Base *base, *oldbase;
+       ListBase edve, eded, edvl;
+       float trans[9];
+       int ok, vertsep=0, flag;        
+       short done=0, check=1;
                
-       if(em->edges.first==0) return NULL;
-       else eed=em->edges.first;       
-       
-       /* reset flags */       
-       for(eve=em->verts.first; eve; eve=eve->next){
-               eve->f &= ~2;
-       }       
-       calc_meshverts_ext_f2();        /*sets (eve->f & 2) for vertices that aren't visible*/
-       
-       closest=NULL;
-       getmouseco_areawin(mval);
-       
-       mval2[0] = (float)mval[0];      /* cast to float because of the pdist function only taking floats...*/
-       mval2[1] = (float)mval[1];
+       TEST_EDITMESH
+       waitcursor(1);  
        
-       eed=em->edges.first;
-       while(eed) {                                            /* compare the distance to the rest of the edges and find the closest one*/
-               if( !((eed->v1->f | eed->v2->f) & 2) && (eed->v1->h==0 && eed->v2->h==0) ){     /* only return edges with both vertices on screen */
-                       v1[0] = eed->v1->xs;                    
-                       v1[1] = eed->v1->ys;
-                       v2[0] = eed->v2->xs;
-                       v2[1] = eed->v2->ys;
-                       
-                       distance[1] = PdistVL2Dfl(mval2, v1, v2);
+       /* we are going to abuse the system as follows:
+        * 1. add a duplicate object: this will be the new one, we remember old pointer
+        * 2: then do a split if needed.
+        * 3. put apart: all NOT selected verts, edges, faces
+        * 4. call loadobeditdata(): this will be the new object
+        * 5. freelist and get back old verts, edges, facs
+        */
                        
-                       if(distance[1]<50){                     /* TODO: make this maximum selecting distance selectable (the same with vertice select?) */
-                               if(found) {                     /*do we have to compare it to other distances? */
-                                       if (distance[1]<distance[0]){
-                                               distance[0]=distance[1];
-                                               closest=eed;    /*save the current closest edge*/
-                                       }
-                               } else {
-                                       distance[0]=distance[1];
-                                       closest=eed;
-                                       found=1;
-                               }
-                       }
-               }
-               eed= eed->next;
-       }
-       
-       /* reset flags */       
-       for(eve=em->verts.first; eve; eve=eve->next){
-               eve->f &= ~2;
-       }
        
-       if(found) return closest;
-       else return 0;
-}
-
-#if 0
-/* this is a template function to demonstrate a loop with drawing...
-   it is a temporal mode, so use with wisdom! if you can avoid, always better. (ton)
-*/
-void loop(int mode)
-{
-       EditEdge *eed;
-       int mousemove= 1;
-
-       while(mousemove) {
-               /* uses callback mechanism to draw it all in current area */
-               scrarea_do_windraw(curarea); 
-               
-               /* do your stuff */
-               eed= findnearestedge();
-               
-               /* set window matrix to perspective, default an area returns with buttons transform */
-               persp(PERSP_VIEW);
-               /* make a copy, for safety */
-               glPushMatrix();
-               /* multiply with the object transformation */
-               mymultmatrix(G.obedit->obmat);
-               
-               /* draw */
-               if(eed) {
-                       glColor3ub(255, 255, 0);
-                       glBegin(GL_LINES);
-                       glVertex3fv(eed->v1->co);
-                       glVertex3fv(eed->v2->co);
-                       glEnd();
-               }
-               
-               /* restore matrix transform */
-               glPopMatrix();
+                       
+       while(!done){           
+               vertsep=check=1;
                
-               headerprint("We are now in evil edge select mode. Press any key to exit");
+               countall();
                
-               /* this also verifies other area/windows for clean swap */
-               screen_swapbuffers();
+               me= get_mesh(G.obedit);
+               if(me->key) {
+                       error("Can't separate a mesh with vertex keys");
+                       return;
+               }               
                
-               /* testing for user input... */
-               while(qtest()) {
-                       unsigned short val;
-                       short event= extern_qread(&val);        // extern_qread stores important events for the mainloop to handle 
-
-                       /* val==0 on key-release event */
-                       if(val && event!=MOUSEY && event!=MOUSEX) {
-                               mousemove= 0;
+               /* make only obedit selected */
+               base= FIRSTBASE;
+               while(base) {
+                       if(base->lay & G.vd->lay) {
+                               if(base->object==G.obedit) base->flag |= SELECT;
+                               else base->flag &= ~SELECT;
                        }
+                       base= base->next;
+               }               
+               
+               /*--------- Select connected-----------*/               
+               //sel= 3;
+               /* clear test flags */
+               eve= em->verts.first;
+               while(eve) {
+                       eve->f&= ~1;                    
+                       eve= eve->next;
                }
-               /* sleep 0.01 second to prevent overload in this poor loop */
-               PIL_sleep_ms(10);       
                
-       }
-       
-       /* send event to redraw this window, does header too */
-       addqueue(curarea->win, REDRAW, 1); 
-}
-#endif
-
-/* 
-functionality: various loop functions
-parameters: mode tells the function what it should do with the loop:
-               LOOP_SELECT = select
-               LOOP_CUT = cut in half
-*/     
-
-void loopoperations(char mode)
-{
-       EditMesh *em = G.editMesh;
-       EditVert* look = NULL;
-
-       EditEdge *start, *eed, *opposite,*currente, *oldstart;
-       EditEdge **tagged = NULL,**taggedsrch = NULL,*close;
-
-       EditFace *efa,**percentfacesloop = NULL, *currentvl,  *formervl;        
-
-       short lastface=0, foundedge=0, c=0, tri=0, side=1, totface=0, searching=1, event=0, noface=1;
-       short skip,nextpos,percentfaces;
-
-       int i=0,ect=0,j=0,k=0,cut,smooth,timesthrough=0,inset = 0;
-
-       float percentcut, outcut;
-
-       char mesg[100];
-
-       if ((G.obedit==0) || (em->faces.first==0)) return;
-       
-       if(mode==LOOP_CUT)undo_push_mesh("Face Loop Subdivide");
-       else if(mode==LOOP_SELECT)undo_push_mesh("Select Face Loop");   
-
-       SetBlenderCursor(BC_VLOOPCURSOR);
-
-       start=NULL;
-       oldstart=NULL;
-
-       while(searching){
+               /* Select a random vert to start with */
+               eve= em->verts.first;
+               eve->f |= 1;
                
-               /* reset variables */
-               start=eed=opposite=currente=0;
-               efa=currentvl=formervl=0;
-               side=noface=1;
-               lastface=foundedge=c=tri=totface=0;             
-                               
-               start=findnearestvisibleedge();
-                               
-               /* If the edge doesn't belong to a face, it's not a valid starting edge */
-               /* and only accept starting edge if it is part of at least one visible face */
-               if(start){
-                       start->f |= 16;
-                       efa=em->faces.first;
-                       while(efa){
-                               if(efa->e1->f & 16){
-                                       /* since this edge is on the face, check if the face has any hidden verts */
-                                       if( !efa->v1->h && !efa->v2->h &&  !efa->v3->h && (efa->v4 && !efa->v4->h)  ){
-                                               noface=0;
-                                               efa->e1->f &= ~16;
-                                       }
-                               }
-                               else if(efa->e2->f & 16){                                       
-                                       if( !efa->v1->h && !efa->v2->h &&  !efa->v3->h && (efa->v4 && !efa->v4->h)  ){
-                                               noface=0;
-                                               efa->e2->f &= ~16;
-                                       }
-                               }
-                               else if(efa->e3->f & 16){                                       
-                                       if( !efa->v1->h && !efa->v2->h &&  !efa->v3->h && (efa->v4 && !efa->v4->h)  ){
-                                               noface=0;
-                                               efa->e3->f &= ~16;
+               while(check==1) {
+                       check= 0;                       
+                       eed= em->edges.first;                   
+                       while(eed) {                            
+                               if(eed->h==0) {
+                                       if(eed->v1->f & 1) {
+                                               if( (eed->v2->f & 1)==0 ) {
+                                                       eed->v2->f |= 1;
+                                                       vertsep++;
+                                                       check= 1;
+                                               }
                                        }
-                               }
-                               else if(efa->e4 && (efa->e4->f & 16)){                                  
-                                       if( !efa->v1->h && !efa->v2->h &&  !efa->v3->h && (efa->v4 && !efa->v4->h)  ){
-                                               noface=0;
-                                               efa->e4->f &= ~16;
+                                       else if(eed->v2->f & 1) {
+                                               if( (eed->v1->f & 1)==0 ) {
+                                                       eed->v1->f |= 1;
+                                                       vertsep++;
+                                                       check= 1;
+                                               }
                                        }
                                }
-                               
-                               efa=efa->next;
-                       }                       
-               }                               
-                               
-               /* Did we find anything that is selectable? */
-               if(start && !noface && (oldstart==NULL || start!=oldstart)){
-                                       
-                       /* If we stay in the neighbourhood of this edge, we don't have to recalculate the loop everytime*/
-                       oldstart=start; 
-                       
-                       /* Clear flags */
-                       for(eed=em->edges.first; eed; eed=eed->next){                   
-                               eed->f &= ~(2|4|8|32|64);
-                               eed->v1->f &= ~(2|8|16);
-                               eed->v2->f &= ~(2|8|16);                                
-                       }
-                       
-                       for(efa= em->faces.first; efa; efa=efa->next){                  
-                               efa->f &= ~(4|8);
-                               totface++;                              
+                               eed= eed->next;                         
                        }
-                                       
-                       /* Tag the starting edge */
-                       start->f |= (2|4|8|64);                         
-                       start->v1->f |= 2;
-                       start->v2->f |= 2;              
-                       
-                       currente=start;                                         
-                       
-                       /*-----Limit the Search----- */
-                       while(!lastface && c<totface+1){
-                               
-                               /*----------Get Loop------------------------*/
-                               tri=foundedge=lastface=0;                                                                                                       
-                               efa= em->faces.first;           
-                               while(efa && !foundedge && !tri){
-                                                                       
-                                       if(!(efa->v4)){ /* Exception for triangular faces */
-                                               
-                                               if((efa->e1->f | efa->e2->f | efa->e3->f) & 2){
-                                                       if(!(efa->f & 4)){                                                              
-                                                               tri=1;
-                                                               currentvl=efa;
-                                                               if(side==1) efa->f |= 4;
-                                                       }
-                                               }                                               
-                                       }
-                                       else{
-                                               
-                                               if((efa->e1->f | efa->e2->f | efa->e3->f | efa->e4->f) & 2){
-                                                       
-                                                       if(c==0){       /* just pick a face, doesn't matter wich side of the edge we go to */
-                                                               if(!(efa->f & 4)){
-                                                                       
-                                                                       if(!(efa->e1->v1->f & 2) && !(efa->e1->v2->f & 2)){
-                                                                               if(efa->e1->v1->h==0 && efa->e1->v2->h==0){
-                                                                                       opposite=efa->e1;                                                                                                               
-                                                                                       foundedge=1;
-                                                                               }
-                                                                       }
-                                                                       else if(!(efa->e2->v1->f & 2) && !(efa->e2->v2->f & 2)){
-                                                                               if(efa->e2->v1->h==0 && efa->e2->v2->h==0){
-                                                                                       opposite=efa->e2;
-                                                                                       foundedge=1;
-                                                                               }
-                                                                       }
-                                                                       else if(!(efa->e3->v1->f & 2) && !(efa->e3->v2->f & 2)){
-                                                                               if(efa->e3->v1->h==0 && efa->e3->v2->h==0){
-                                                                                       opposite=efa->e3;
-                                                                                       foundedge=1;
-                                                                               }
-                                                                       }
-                                                                       else if(!(efa->e4->v1->f & 2) && !(efa->e4->v2->f & 2)){
-                                                                               if(efa->e4->v1->h==0 && efa->e4->v2->h==0){
-                                                                                       opposite=efa->e4;
-                                                                                       foundedge=1;
-                                                                               }
-                                                                       }
-                                                                       
-                                                                       if(foundedge){
-                                                                               currentvl=efa;
-                                                                               formervl=efa;
-                                                                       
-                                                                               /* mark this side of the edge so we know in which direction we went */
-                                                                               if(side==1) efa->f |= 4;
-                                                                       }
-                                                               }
-                                                       }
-                                                       else {  
-                                                               if(efa!=formervl){      /* prevent going backwards in the loop */
-                                                               
-                                                                       if(!(efa->e1->v1->f & 2) && !(efa->e1->v2->f & 2)){
-                                                                               if(efa->e1->v1->h==0 && efa->e1->v2->h==0){
-                                                                                       opposite=efa->e1;                                                                                                               
-                                                                                       foundedge=1;
-                                                                               }
-                                                                       }
-                                                                       else if(!(efa->e2->v1->f & 2) && !(efa->e2->v2->f & 2)){
-                                                                               if(efa->e2->v1->h==0 && efa->e2->v2->h==0){
-                                                                                       opposite=efa->e2;
-                                                                                       foundedge=1;
-                                                                               }
-                                                                       }
-                                                                       else if(!(efa->e3->v1->f & 2) && !(efa->e3->v2->f & 2)){
-                                                                               if(efa->e3->v1->h==0 && efa->e3->v2->h==0){
-                                                                                       opposite=efa->e3;
-                                                                                       foundedge=1;
-                                                                               }
-                                                                       }
-                                                                       else if(!(efa->e4->v1->f & 2) && !(efa->e4->v2->f & 2)){
-                                                                               if(efa->e4->v1->h==0 && efa->e4->v2->h==0){
-                                                                                       opposite=efa->e4;
-                                                                                       foundedge=1;
-                                                                               }
-                                                                       }
-                                                                       
-                                                                       currentvl=efa;
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               efa=efa->next;
-                               }
-                               /*----------END Get Loop------------------------*/
-                               
-                       
-                               /*----------Decisions-----------------------------*/
-                               if(foundedge){
-                                       /* mark the edge and face as done */                                    
-                                       currente->f |= 8;
-                                       currentvl->f |= 8;
-
-                                       if(opposite->f & 4) lastface=1; /* found the starting edge! close loop */                                                               
-                                       else{
-                                               /* un-set the testflags */
-                                               currente->f &= ~2;
-                                               currente->v1->f &= ~2;
-                                               currente->v2->f &= ~2;                                                  
-                                               
-                                               /* set the opposite edge to be the current edge */                              
-                                               currente=opposite;                                                      
-                                               
-                                               /* set the current face to be the FORMER face (to prevent going backwards in the loop) */
-                                               formervl=currentvl;
-                                               
-                                               /* set the testflags */
-                                               currente->f |= 2;
-                                               currente->v1->f |= 2;
-                                               currente->v2->f |= 2;                   
-                                       }
-                                       c++;
+               }               
+               /*----------End of select connected--------*/
+               
+               
+               /* If the amount of vertices that is about to be split == the total amount 
+                  of verts in the mesh, it means that there is only 1 unconnected object, so we don't have to separate
+               */
+               if(G.totvert==vertsep)done=1;                           
+               else{                   
+                       /* Test for splitting: Separate selected */
+                       ok= 0;
+                       eed= em->edges.first;
+                       while(eed) {
+                               flag= (eed->v1->f & 1)+(eed->v2->f & 1);
+                               if(flag==1) {
+                                       ok= 1;
+                                       break;
                                }
-                               else{   
-                                       /* un-set the testflags */
-                                       currente->f &= ~2;
-                                       currente->v1->f &= ~2;
-                                       currente->v2->f &= ~2;
-                                       
-                                       /* mark the edge and face as done */
-                                       currente->f |= 8;
-                                       currentvl->f |= 8;
-                                       
-                                       
-                                                                                               
-                                       /* is the the first time we've ran out of possible faces?
-                                       *  try to start from the beginning but in the opposite direction go as far as possible
-                                       */                              
-                                       if(side==1){                                            
-                                               if(tri)tri=0;
-                                               currente=start;
-                                               currente->f |= 2;
-                                               currente->v1->f |= 2;
-                                               currente->v2->f |= 2;                                   
-                                               side++;
-                                               c=0;
-                                       }
-                                       else lastface=1;
-                               }                               
-                               /*----------END Decisions-----------------------------*/
-                               
+                               eed= eed->next;
                        }
-                       /*-----END Limit the Search----- */
-                       
-                       
-                       /*------------- Preview lines--------------- */
-                       
-                       /* uses callback mechanism to draw it all in current area */
-                       scrarea_do_windraw(curarea);                    
+                       if(ok) {
+                               /* SPLIT: first make duplicate */
+                               adduplicateflag(1);
+                               /* SPLIT: old faces have 3x flag 128 set, delete these ones */
+                               delfaceflag(128);
+                       }       
                        
-                       /* set window matrix to perspective, default an area returns with buttons transform */
-                       persp(PERSP_VIEW);
-                       /* make a copy, for safety */
-                       glPushMatrix();
-                       /* multiply with the object transformation */
-                       mymultmatrix(G.obedit->obmat);
                        
-                       glColor3ub(255, 255, 0);
                        
-                       if(mode==LOOP_SELECT){
-                               efa= em->faces.first;
-                               while(efa){
-                                       if(efa->f & 8){
-                                               
-                                               if(!(efa->e1->f & 8)){
-                                                       glBegin(GL_LINES);                                                      
-                                                       glVertex3fv(efa->e1->v1->co);
-                                                       glVertex3fv(efa->e1->v2->co);
-                                                       glEnd();        
-                                               }
-                                               
-                                               if(!(efa->e2->f & 8)){
-                                                       glBegin(GL_LINES);                                                      
-                                                       glVertex3fv(efa->e2->v1->co);
-                                                       glVertex3fv(efa->e2->v2->co);
-                                                       glEnd();        
-                                               }
-                                               
-                                               if(!(efa->e3->f & 8)){
-                                                       glBegin(GL_LINES);                                                      
-                                                       glVertex3fv(efa->e3->v1->co);
-                                                       glVertex3fv(efa->e3->v2->co);
-                                                       glEnd();        
-                                               }
-                                               
-                                               if(efa->e4){
-                                                       if(!(efa->e4->f & 8)){
-                                                               glBegin(GL_LINES);                                                      
-                                                               glVertex3fv(efa->e4->v1->co);
-                                                               glVertex3fv(efa->e4->v2->co);
-                                                               glEnd();        
-                                                       }
-                                               }
-                                       }
-                                       efa=efa->next;
-                               }
-                       }
-                               
-                       if(mode==LOOP_CUT){
-                               efa= em->faces.first;
-                               while(efa){
-                                       if(efa->f & 8){
-                                               float cen[2][3];
-                                               int a=0;                                                
-                                               
-                                               efa->v1->f &= ~8;
-                                               efa->v2->f &= ~8;
-                                               efa->v3->f &= ~8;
-                                               if(efa->v4)efa->v4->f &= ~8;
-                                       
-                                               if(efa->e1->f & 8){
-                                                       cen[a][0]= (efa->e1->v1->co[0] + efa->e1->v2->co[0])/2.0;
-                                                       cen[a][1]= (efa->e1->v1->co[1] + efa->e1->v2->co[1])/2.0;
-                                                       cen[a][2]= (efa->e1->v1->co[2] + efa->e1->v2->co[2])/2.0;
-                                                       
-                                                       efa->e1->v1->f |= 8;
-                                                       efa->e1->v2->f |= 8;
-                                                       
-                                                       a++;
-                                               }
-                                               if((efa->e2->f & 8) && a!=2){
-                                                       cen[a][0]= (efa->e2->v1->co[0] + efa->e2->v2->co[0])/2.0;
-                                                       cen[a][1]= (efa->e2->v1->co[1] + efa->e2->v2->co[1])/2.0;
-                                                       cen[a][2]= (efa->e2->v1->co[2] + efa->e2->v2->co[2])/2.0;
-                                                       
-                                                       efa->e2->v1->f |= 8;
-                                                       efa->e2->v2->f |= 8;
-                                                       
-                                                       a++;
-                                               }
-                                               if((efa->e3->f & 8) && a!=2){
-                                                       cen[a][0]= (efa->e3->v1->co[0] + efa->e3->v2->co[0])/2.0;
-                                                       cen[a][1]= (efa->e3->v1->co[1] + efa->e3->v2->co[1])/2.0;
-                                                       cen[a][2]= (efa->e3->v1->co[2] + efa->e3->v2->co[2])/2.0;
-                                                       
-                                                       efa->e3->v1->f |= 8;
-                                                       efa->e3->v2->f |= 8;
-                                                       
-                                                       a++;
-                                               }
-                                               
-                                               if(efa->e4){
-                                                       if((efa->e4->f & 8) && a!=2){
-                                                               cen[a][0]= (efa->e4->v1->co[0] + efa->e4->v2->co[0])/2.0;
-                                                               cen[a][1]= (efa->e4->v1->co[1] + efa->e4->v2->co[1])/2.0;
-                                                               cen[a][2]= (efa->e4->v1->co[2] + efa->e4->v2->co[2])/2.0;
-                                                               
-                                                               efa->e4->v1->f |= 8;
-                                                               efa->e4->v2->f |= 8;
-                                                       
-                                                               a++;
-                                                       }
-                                               }
-                                               else{   /* if it's a triangular face, set the remaining vertex as the cutcurve coordinate */                                                                                                            
-                                                               if(!(efa->v1->f & 8) && efa->v1->h==0){
-                                                                       cen[a][0]= efa->v1->co[0];
-                                                                       cen[a][1]= efa->v1->co[1];
-                                                                       cen[a][2]= efa->v1->co[2];
-                                                                       a++;                                                            
-                                                               }
-                                                               else if(!(efa->v2->f & 8) && efa->v2->h==0){
-                                                                       cen[a][0]= efa->v2->co[0];
-                                                                       cen[a][1]= efa->v2->co[1];
-                                                                       cen[a][2]= efa->v2->co[2];      
-                                                                       a++;
-                                                               }
-                                                               else if(!(efa->v3->f & 8) && efa->v3->h==0){
-                                                                       cen[a][0]= efa->v3->co[0];
-                                                                       cen[a][1]= efa->v3->co[1];
-                                                                       cen[a][2]= efa->v3->co[2];
-                                                                       a++;                                                                    
-                                                               }                                                       
-                                               }
-                                               
-                                               if(a==2){
-                                                       glBegin(GL_LINES);
-                                                       
-                                                       glVertex3fv(cen[0]);
-                                                       glVertex3fv(cen[1]);    
-                                                                                               
-                                                       glEnd();
-                                               }                                               
-                                       }
-                                       efa=efa->next;
+                       /* set apart: everything that is not selected */
+                       edve.first= edve.last= eded.first= eded.last= edvl.first= edvl.last= 0;
+                       eve= em->verts.first;
+                       while(eve) {
+                               v1= eve->next;
+                               if((eve->f & 1)==0) {
+                                       BLI_remlink(&em->verts, eve);
+                                       BLI_addtail(&edve, eve);
                                }
-                               
-                               eed=em->edges.first; 
-                               while(eed){
-                                       if(eed->f & 64){
-                                               glBegin(GL_LINES);
-                                               glColor3ub(200, 255, 200);
-                                               glVertex3fv(eed->v1->co);
-                                               glVertex3fv(eed->v2->co);
-                                               glEnd();
-                                               eed=0;
-                                       }else{
-                                               eed = eed->next;
-                                       }
-                               }               
-                       }
-                       
-                       /* restore matrix transform */
-                       glPopMatrix();
-                       
-                       headerprint("LMB to confirm, RMB to cancel");
-                       
-                       /* this also verifies other area/windows for clean swap */
-                       screen_swapbuffers();
-                       
-                       /*--------- END Preview Lines------------*/
-                               
-               }/*if(start!=NULL){ */
-               
-               while(qtest()) {
-                       unsigned short val=0;                   
-                       event= extern_qread(&val);      /* extern_qread stores important events for the mainloop to handle */
-
-                       /* val==0 on key-release event */
-                       if(val && (event==ESCKEY || event==RIGHTMOUSE || event==LEFTMOUSE || event==RETKEY || event == MIDDLEMOUSE)){
-                               searching=0;
-                       }
-               }       
-               
-       }/*while(event!=ESCKEY && event!=RIGHTMOUSE && event!=LEFTMOUSE && event!=RETKEY){*/
-       
-       /*----------Select Loop------------*/
-       if(mode==LOOP_SELECT && start!=NULL && ((event==LEFTMOUSE || event==RETKEY) || event == MIDDLEMOUSE || event == BKEY)){
-                               
-               /* If this is a unmodified select, clear the selection */
-               if(!(G.qual & LR_SHIFTKEY) && !(G.qual & LR_ALTKEY)){
-                       for(efa= em->faces.first;efa;efa=efa->next){
-                               efa->v1->f &= !1;
-                               efa->v2->f &= !1;
-                               efa->v3->f &= !1;
-                               if(efa->v4)efa->v4->f &= !1;                    
+                               eve= v1;
                        }
-               }
-               /* Alt was not pressed, so add to the selection */
-               if(!(G.qual & LR_ALTKEY)){
-                       for(efa= em->faces.first;efa;efa=efa->next){
-                               if(efa->f & 8){
-                                       efa->v1->f |= 1;
-                                       efa->v2->f |= 1;
-                                       efa->v3->f |= 1;
-                                       if(efa->v4)efa->v4->f |= 1;
+                       eed= em->edges.first;
+                       while(eed) {
+                               e1= eed->next;
+                               if( (eed->v1->f & 1)==0 || (eed->v2->f & 1)==0 ) {
+                                       BLI_remlink(&em->edges, eed);
+                                       BLI_addtail(&eded, eed);
                                }
+                               eed= e1;
                        }
-               }
-               /* alt was pressed, so subtract from the selection */
-               else
-               {
-                       for(efa= em->faces.first;efa;efa=efa->next){
-                               if(efa->f & 8){
-                                       efa->v1->f &= !1;
-                                       efa->v2->f &= !1;
-                                       efa->v3->f &= !1;
-                                       if(efa->v4)efa->v4->f &= !1;
+                       efa= em->faces.first;
+                       while(efa) {
+                               vl1= efa->next;
+                               if( (efa->v1->f & 1)==0 || (efa->v2->f & 1)==0 || (efa->v3->f & 1)==0 ) {
+                                       BLI_remlink(&em->faces, efa);
+                                       BLI_addtail(&edvl, efa);
                                }
+                               efa= vl1;
                        }
-               }
-       
-       }
-       /*----------END Select Loop------------*/
-       
-       /*----------Cut Loop---------------*/                   
-       if(mode==LOOP_CUT && start!=NULL && (event==LEFTMOUSE || event==RETKEY)){
-               
-               /* count the number of edges in the loop */             
-               for(eed=em->edges.first; eed; eed = eed->next){
-                       if(eed->f & 8)
-                               ect++;
-               }               
-               
-               tagged = MEM_mallocN(ect*sizeof(EditEdge*), "tagged");
-               taggedsrch = MEM_mallocN(ect*sizeof(EditEdge*), "taggedsrch");
-               for(i=0;i<ect;i++)
-               {
-                       tagged[i] = NULL;
-                       taggedsrch[i] = NULL;
-               }
-               ect = 0;
-               for(eed=em->edges.first; eed; eed = eed->next){
-                       if(eed->f & 8)
-                       {
-                               if(eed->h==0){
-                                       eed->v1->f |= 1;
-                                       eed->v2->f |= 1;
-                                       tagged[ect] = eed;
-                                       eed->f &= ~(32);
-                                       ect++;
-                               }
-                       }                       
-               }
-               taggedsrch[0] = tagged[0];
-
-               while(timesthrough < 2)
-               {
-                       i=0;
-                       while(i < ect){/*Look at the members of the search array to line up cuts*/
-                               if(taggedsrch[i]==NULL)break;
-                               for(j=0;j<ect;j++){                      /*Look through the list of tagged verts for connected edges*/
-                                       int addededge = 0;
-                                       if(taggedsrch[i]->f & 32)        /*If this edgee is marked as flipped, use vert 2*/
-                                               look = taggedsrch[i]->v2;
-                                       else                                                     /*else use vert 1*/
-                                               look = taggedsrch[i]->v1;
-
-                                       if(taggedsrch[i] == tagged[j])
-                                               continue;  /*If we are looking at the same edge, skip it*/
-       
-                                       skip = 0;
-                                       for(k=0;k<ect;k++)      {
-                                               if(taggedsrch[k] == NULL)       /*go to empty part of search list without finding*/
-                                                       break;                                                  
-                                               if(tagged[j] == taggedsrch[k]){         /*We found a match already in the list*/
-                                                       skip = 1;
-                                                       break;
-                                               }
-                                       }
-                                       if(skip)
-                                               continue;
-                                       nextpos = 0;
-                                       if(findedgelist(look,tagged[j]->v2)){
-                                               while(nextpos < ect){ /*Find the first open spot in the search array*/
-                                                       if(taggedsrch[nextpos] == NULL){
-                                                               taggedsrch[nextpos] = tagged[j]; /*put tagged[j] in it*/
-                                                               taggedsrch[nextpos]->f |= 32;
-                                                               addededge = 1;
-                                                               break;
-                                                       }
-                                                       else
-                                                               nextpos++;
-                                               }
-                                       } /* End else if connected to vert 2*/
-                                       else if(findedgelist(look,tagged[j]->v1)){   /*If our vert is connected to vert 1 */
-                                               while(nextpos < ect){ /*Find the first open spot in the search array */
-                                                       if(taggedsrch[nextpos] == NULL){
-                                                               taggedsrch[nextpos] = tagged[j]; /*put tagged[j] in it*/
-                                                               addededge = 1;
-                                                               break;
-                                                       }
-                                                       else 
-                                                               nextpos++;
-                                               }
-                                       }
-
-                                       if(addededge)
-                                       {
-                                               break;
-                                       }                                       
-                               }/* End Outer For (j)*/
-                               i++;
-                       } /* End while(j<ect)*/
-                       timesthrough++;
-               } /*end while timesthrough */
-               percentcut = 0.50;
-               searching = 1;
-               cut   = 1;
-               smooth = 0;
-               close = NULL;
-
-
-               /* Count the Number of Faces in the selected loop*/
-               percentfaces = 0;
-               for(efa= em->faces.first; efa ;efa=efa->next){
-                       if(efa->f & 8)
-                        {
-                               percentfaces++; 
-                        }
-               }
                        
-               /* create a dynamic array for those face pointers */
-               percentfacesloop = MEM_mallocN(percentfaces*sizeof(EditFace*), "percentage");
-
-               /* put those faces in the array */
-               i=0;
-               for(efa= em->faces.first; efa ;efa=efa->next){
-                        if(efa->f & 8)
-                        {
-                               percentfacesloop[i] = efa;      
-                               i++;
-                        }
-               }
-
-               while(searching){
+                       oldob= G.obedit;
+                       oldbase= BASACT;
                        
-                       /* For the % calculation */
-                       short mval[2];                  
-                       float labda, rc[2], len, slen=0.0;
-                       float v1[2], v2[2], v3[2];
-
-                       /*------------- Percent Cut Preview Lines--------------- */
-                       scrarea_do_windraw(curarea);                    
-                       persp(PERSP_VIEW);
-                       glPushMatrix();
-                       mymultmatrix(G.obedit->obmat);
-                       glColor3ub(0, 255, 255);
-                               
-                       /*Put the preview lines where they should be for the percentage selected.*/
-
-                       for(i=0;i<percentfaces;i++){
-                               efa = percentfacesloop[i];
-                               for(eed = em->edges.first; eed; eed=eed->next){
-                                       if(eed->f & 64){        /* color the starting edge */                   
-                                               glBegin(GL_LINES);
-                                                                                               
-                                               glColor3ub(200, 255, 200);
-                                               glVertex3fv(eed->v1->co);                                       
-                                               glVertex3fv(eed->v2->co);
-                                               
-                                               glEnd();
-
-                                               glPointSize(5);
-                                               glBegin(GL_POINTS);
-                                               glColor3ub(255,0,255);
-                                               
-                                               if(eed->f & 32)
-                                                       glVertex3fv(eed->v2->co);                       
-                                               else
-                                                       glVertex3fv(eed->v1->co);
-                                               glEnd();
-
-
-                                               /*Get Starting Edge Length*/
-                                               slen = sqrt((eed->v1->co[0]-eed->v2->co[0])*(eed->v1->co[0]-eed->v2->co[0])+
-                                                                       (eed->v1->co[1]-eed->v2->co[1])*(eed->v1->co[1]-eed->v2->co[1])+
-                                                                       (eed->v1->co[2]-eed->v2->co[2])*(eed->v1->co[2]-eed->v2->co[2]));
-                                       }
-                               }
-                               
-                               if(!inset){
-                                       glColor3ub(0,255,255);
-                                       if(efa->f & 8)
-                                       {
-                                               float cen[2][3];
-                                               int a=0;                                        
-                                               
-                                               efa->v1->f &= ~8;
-                                               efa->v2->f &= ~8;
-                                               efa->v3->f &= ~8;
-                                               if(efa->v4)efa->v4->f &= ~8;
-                                               
-                                               if(efa->e1->f & 8){
-                                                       float pct;
-                                                       if(efa->e1->f & 32)
-                                                               pct = 1-percentcut;
-                                                       else
-                                                               pct = percentcut;
-                                                       cen[a][0]= efa->e1->v1->co[0] - ((efa->e1->v1->co[0] - efa->e1->v2->co[0]) * (pct));
-                                                       cen[a][1]= efa->e1->v1->co[1] - ((efa->e1->v1->co[1] - efa->e1->v2->co[1]) * (pct));
-                                                       cen[a][2]= efa->e1->v1->co[2] - ((efa->e1->v1->co[2] - efa->e1->v2->co[2]) * (pct));
-                                                       efa->e1->v1->f |= 8;
-                                                       efa->e1->v2->f |= 8;
-                                                       a++;
-                                               }
-                                               if((efa->e2->f & 8) && a!=2)
-                                               {
-                                                       float pct;
-                                                       if(efa->e2->f & 32)
-                                                               pct = 1-percentcut;
-                                                       else
-                                                               pct = percentcut;
-                                                       cen[a][0]= efa->e2->v1->co[0] - ((efa->e2->v1->co[0] - efa->e2->v2->co[0]) * (pct));
-                                                       cen[a][1]= efa->e2->v1->co[1] - ((efa->e2->v1->co[1] - efa->e2->v2->co[1]) * (pct));
-                                                       cen[a][2]= efa->e2->v1->co[2] - ((efa->e2->v1->co[2] - efa->e2->v2->co[2]) * (pct));
-
-                                                       efa->e2->v1->f |= 8;
-                                                       efa->e2->v2->f |= 8;
-                                                       
-                                                       a++;
-                                               }
-                                               if((efa->e3->f & 8) && a!=2){
-                                                       float pct;
-                                                       if(efa->e3->f & 32)
-                                                               pct = 1-percentcut;
-                                                       else
-                                                               pct = percentcut;
-                                                       cen[a][0]= efa->e3->v1->co[0] - ((efa->e3->v1->co[0] - efa->e3->v2->co[0]) * (pct));
-                                                       cen[a][1]= efa->e3->v1->co[1] - ((efa->e3->v1->co[1] - efa->e3->v2->co[1]) * (pct));
-                                                       cen[a][2]= efa->e3->v1->co[2] - ((efa->e3->v1->co[2] - efa->e3->v2->co[2]) * (pct));
-
-                                                       efa->e3->v1->f |= 8;
-                                                       efa->e3->v2->f |= 8;
-                                                       
-                                                       a++;
-                                               }
-                                                       
-                                               if(efa->e4){
-                                                       if((efa->e4->f & 8) && a!=2){
-                                                               float pct;
-                                                               if(efa->e4->f & 32)
-                                                                       pct = 1-percentcut;
-                                                               else
-                                                                       pct = percentcut;
-                                                               cen[a][0]= efa->e4->v1->co[0] - ((efa->e4->v1->co[0] - efa->e4->v2->co[0]) * (pct));
-                                                               cen[a][1]= efa->e4->v1->co[1] - ((efa->e4->v1->co[1] - efa->e4->v2->co[1]) * (pct));
-                                                               cen[a][2]= efa->e4->v1->co[2] - ((efa->e4->v1->co[2] - efa->e4->v2->co[2]) * (pct));
-
-                                                               efa->e4->v1->f |= 8;
-                                                               efa->e4->v2->f |= 8;
-                                                       
-                                                               a++;
-                                                       }
-                                               }
-                                               else {  /* if it's a triangular face, set the remaining vertex as the cutcurve coordinate */
-                                                       if(!(efa->v1->f & 8) && efa->v1->h==0){
-                                                               cen[a][0]= efa->v1->co[0];
-                                                               cen[a][1]= efa->v1->co[1];
-                                                               cen[a][2]= efa->v1->co[2];
-                                                               a++;                                                            
-                                                       }
-                                                       else if(!(efa->v2->f & 8) && efa->v2->h==0){
-                                                               cen[a][0]= efa->v2->co[0];
-                                                               cen[a][1]= efa->v2->co[1];
-                                                               cen[a][2]= efa->v2->co[2];
-                                                               a++;                                                            
-                                                       }
-                                                       else if(!(efa->v3->f & 8) && efa->v3->h==0){
-                                                               cen[a][0]= efa->v3->co[0];
-                                                               cen[a][1]= efa->v3->co[1];
-                                                               cen[a][2]= efa->v3->co[2];
-                                                               a++;                                                                                                    
-                                                       }
-                                               }
-                                               
-                                               if(a==2){
-                                                       glBegin(GL_LINES);
-                                                       
-                                                       glVertex3fv(cen[0]);
-                                                       glVertex3fv(cen[1]);    
-                                                                                               
-                                                       glEnd();
-                                               }       
-                                       }
-                               }/* end preview line drawing */                 
-                               else{
-                                       glColor3ub(0,128,255);
-                                       if(efa->f & 8)
-                                       {
-                                               float cen[2][3];
-                                               int a=0;                                        
-                                               
-                                               efa->v1->f &= ~8;
-                                               efa->v2->f &= ~8;
-                                               efa->v3->f &= ~8;
-                                               if(efa->v4)efa->v4->f &= ~8;
-                                               
-                                               if(efa->e1->f & 8){                                                     
-                                                       float nlen,npct;
-                                                       
-                                                       nlen = sqrt((efa->e1->v1->co[0] - efa->e1->v2->co[0])*(efa->e1->v1->co[0] - efa->e1->v2->co[0])+
-                                                                               (efa->e1->v1->co[1] - efa->e1->v2->co[1])*(efa->e1->v1->co[1] - efa->e1->v2->co[1])+
-                                                                               (efa->e1->v1->co[2] - efa->e1->v2->co[2])*(efa->e1->v1->co[2] - efa->e1->v2->co[2]));
-                                                       npct = (percentcut*slen)/nlen;
-                                                       if(npct >= 1) npct = 1;
-                                                       if(efa->e1->f & 32)     npct = 1-npct;
-
-                                                       cen[a][0]= efa->e1->v1->co[0] - ((efa->e1->v1->co[0] - efa->e1->v2->co[0]) * (npct));
-                                                       cen[a][1]= efa->e1->v1->co[1] - ((efa->e1->v1->co[1] - efa->e1->v2->co[1]) * (npct));
-                                                       cen[a][2]= efa->e1->v1->co[2] - ((efa->e1->v1->co[2] - efa->e1->v2->co[2]) * (npct));
-
-                                                       efa->e1->f1 = 32768*(npct);
-                                                       efa->e1->v1->f |= 8;
-                                                       efa->e1->v2->f |= 8;
-                                                       a++;
-                                               }
-                                               if((efa->e2->f & 8) && a!=2)
-                                               {
-                                                       float nlen,npct;
-                                                       
-                                                       nlen = sqrt((efa->e2->v1->co[0] - efa->e2->v2->co[0])*(efa->e2->v1->co[0] - efa->e2->v2->co[0])+
-                                                                               (efa->e2->v1->co[1] - efa->e2->v2->co[1])*(efa->e2->v1->co[1] - efa->e2->v2->co[1])+
-                                                                               (efa->e2->v1->co[2] - efa->e2->v2->co[2])*(efa->e2->v1->co[2] - efa->e2->v2->co[2]));
-                                                       npct = (percentcut*slen)/nlen;
-                                                       if(npct >= 1) npct = 1;
-                                                       if(efa->e2->f & 32)     npct = 1-npct;
-
-                                                       cen[a][0]= efa->e2->v1->co[0] - ((efa->e2->v1->co[0] - efa->e2->v2->co[0]) * (npct));
-                                                       cen[a][1]= efa->e2->v1->co[1] - ((efa->e2->v1->co[1] - efa->e2->v2->co[1]) * (npct));
-                                                       cen[a][2]= efa->e2->v1->co[2] - ((efa->e2->v1->co[2] - efa->e2->v2->co[2]) * (npct));
-
-                                                       efa->e2->f1 = 32768*(npct);                                                             
-                                                       efa->e2->v1->f |= 8;
-                                                       efa->e2->v2->f |= 8;
-                                                       a++;
-                                               }
-                                               if((efa->e3->f & 8) && a!=2){
-                                                       float nlen,npct;
-                                                       
-                                                       nlen = sqrt((efa->e3->v1->co[0] - efa->e3->v2->co[0])*(efa->e3->v1->co[0] - efa->e3->v2->co[0])+
-                                                                               (efa->e3->v1->co[1] - efa->e3->v2->co[1])*(efa->e3->v1->co[1] - efa->e3->v2->co[1])+
-                                                                               (efa->e3->v1->co[2] - efa->e3->v2->co[2])*(efa->e3->v1->co[2] - efa->e3->v2->co[2]));
-                                                       npct = (percentcut*slen)/nlen;
-                                                       if(npct >= 1) npct = 1;
-                                                       if(efa->e3->f & 32)     npct = 1-npct;
-
-                                                       cen[a][0]= efa->e3->v1->co[0] - ((efa->e3->v1->co[0] - efa->e3->v2->co[0]) * (npct));
-                                                       cen[a][1]= efa->e3->v1->co[1] - ((efa->e3->v1->co[1] - efa->e3->v2->co[1]) * (npct));
-                                                       cen[a][2]= efa->e3->v1->co[2] - ((efa->e3->v1->co[2] - efa->e3->v2->co[2]) * (npct));
-
-                                                       efa->e3->f1 = 32768*(npct);                                                             
-                                                       efa->e3->v1->f |= 8;
-                                                       efa->e3->v2->f |= 8;
-                                                       a++;
-                                               }
-                                                       
-                                               if(efa->e4){
-                                                       if((efa->e4->f & 8) && a!=2){
-                                                               float nlen,npct;
-                                                               
-                                                               nlen = sqrt((efa->e4->v1->co[0] - efa->e4->v2->co[0])*(efa->e4->v1->co[0] - efa->e4->v2->co[0])+
-                                                                                       (efa->e4->v1->co[1] - efa->e4->v2->co[1])*(efa->e4->v1->co[1] - efa->e4->v2->co[1])+
-                                                                                       (efa->e4->v1->co[2] - efa->e4->v2->co[2])*(efa->e4->v1->co[2] - efa->e4->v2->co[2]));
-                                                       npct = (percentcut*slen)/nlen;
-                                                       if(npct >= 1) npct = 1;
-                                                       if(efa->e4->f & 32)     npct = 1-npct;
-
-                                                               cen[a][0]= efa->e4->v1->co[0] - ((efa->e4->v1->co[0] - efa->e4->v2->co[0]) * (npct));
-                                                               cen[a][1]= efa->e4->v1->co[1] - ((efa->e4->v1->co[1] - efa->e4->v2->co[1]) * (npct));
-                                                               cen[a][2]= efa->e4->v1->co[2] - ((efa->e4->v1->co[2] - efa->e4->v2->co[2]) * (npct));
-
-                                                               efa->e4->f1 = 32768*(npct);                                                                     
-                                                               efa->e4->v1->f |= 8;
-                                                               efa->e4->v2->f |= 8;
-                                                               a++;
-                                                       }
-                                               }
-                                               else {  /* if it's a triangular face, set the remaining vertex as the cutcurve coordinate */
-                                                       if(!(efa->v1->f & 8) && efa->v1->h==0){
-                                                               cen[a][0]= efa->v1->co[0];
-                                                               cen[a][1]= efa->v1->co[1];
-                                                               cen[a][2]= efa->v1->co[2];
-                                                               a++;                                                            
-                                                       }
-                                                       else if(!(efa->v2->f & 8) && efa->v2->h==0){
-                                                               cen[a][0]= efa->v2->co[0];
-                                                               cen[a][1]= efa->v2->co[1];
-                                                               cen[a][2]= efa->v2->co[2];
-                                                               a++;                                                            
-                                                       }
-                                                       else if(!(efa->v3->f & 8) && efa->v3->h==0){
-                                                               cen[a][0]= efa->v3->co[0];
-                                                               cen[a][1]= efa->v3->co[1];
-                                                               cen[a][2]= efa->v3->co[2];
-                                                               a++;                                                                                                    
-                                                       }
-                                               }
-                                               
-                                               if(a==2){
-                                                       glBegin(GL_LINES);
-                                                       
-                                                       glVertex3fv(cen[0]);
-                                                       glVertex3fv(cen[1]);    
-                                                                                               
-                                                       glEnd();
-                                               }       
-                                       }
-                               }
-                       }
-                       /* restore matrix transform */
-       
-                       glPopMatrix();
-
-                       /*--------- END Preview Lines------------*/
-                       while(qtest()) 
-                       {
-                               unsigned short val=0;                   
-                               event= extern_qread(&val);      /* extern_qread stores important events for the mainloop to handle */
-                               /* val==0 on key-release event */
+                       trans[0]=trans[1]=trans[2]=trans[3]=trans[4]=trans[5]= 0.0;
+                       trans[6]=trans[7]=trans[8]= 1.0;
+                       G.qual |= LR_ALTKEY;    /* patch to make sure we get a linked duplicate */
+                       adduplicate(trans);
+                       G.qual &= ~LR_ALTKEY;
+                       
+                       G.obedit= BASACT->object;       /* basact was set in adduplicate()  */
                
-                               if(val && (event==SKEY))
-                               {
-                                       if(smooth)smooth = 0;
-                                       else smooth = 1;
-                               }
-
-                               if(val && (event==PKEY))
-                               {
-                                       if(inset)inset = 0;
-                                       else inset = 1;
-                               }
-
-                               if(val && (event==FKEY))
-                               {
-                                               int ct;
-                                               for(ct = 0; ct < ect; ct++){
-                                                       if(tagged[ct]->f & 32) 
-                                                               tagged[ct]->f &= ~32;
-                                                       else
-                                                               tagged[ct]->f |= 32;
-                                               }
-                               }
-
-                               if(val && (event == MIDDLEMOUSE))
-                               {
-                                       cut = 2;
-                                       searching=0;
-                               }
-                               else if(val && (event==LEFTMOUSE || event==RETKEY))
-                               {
-                                       searching=0;
-                               }
-
-                               if(val && (event==ESCKEY || event==RIGHTMOUSE ))
-                               {
-                                       searching=0;
-                                       cut = 0;
-                               }
-                               
-                       }                       
+                       men= copy_mesh(me);
+                       set_mesh(G.obedit, men);
+                       /* because new mesh is a copy: reduce user count */
+                       men->id.us--;
                        
-
-                       /* Determine the % on wich the loop should be cut */
-                       getmouseco_areawin(mval);                       
-                       v1[0]=(float)mval[0];
-                       v1[1]=(float)mval[1];
+                       load_editMesh();
                        
-                       v2[0]=(float)start->v1->xs;
-                       v2[1]=(float)start->v1->ys;
+                       BASACT->flag &= ~SELECT;
                        
-                       v3[0]=(float)start->v2->xs;
-                       v3[1]=(float)start->v2->ys;
+                       makeDispList(G.obedit);
+                       free_editMesh();
                        
-                       rc[0]= v3[0]-v2[0];
-                       rc[1]= v3[1]-v2[1];
-                       len= rc[0]*rc[0]+ rc[1]*rc[1];
-                               
-                       labda= ( rc[0]*(v1[0]-v2[0]) + rc[1]*(v1[1]-v2[1]) )/len;
-
-
-                       if(labda<=0.0) labda=0.0;
-                       else if(labda>=1.0)labda=1.0;
-                                               
-                       percentcut=labda;               
+                       em->verts= edve;
+                       em->edges= eded;
+                       em->faces= edvl;
                        
-                       if(start->f & 32)
-                               percentcut = 1.0-percentcut;
-
-               if(cut == 2){
-                       percentcut = 0.5;
-               }
-
-               if (G.qual & LR_SHIFTKEY){
-
-                       percentcut = (int)(percentcut*100.0)/100.0;     
-               }
-               else if (G.qual & LR_CTRLKEY)
-                       percentcut = (int)(percentcut*10.0)/10.0;               
-       
-               outcut = (percentcut*100.0);
-
-               /* Build the Header Line */ 
-
-               if(inset)
-                       sprintf(mesg,"Cut: %0.2f%% ",slen*percentcut);
-               else
-                       sprintf(mesg,"Cut: %0.2f%% ",outcut);
-               
-
-               if(smooth)
-                       sprintf(mesg,"%s| (f)lip side | (s)mooth on  |",mesg);
-               else
-                       sprintf(mesg,"%s| (f)lip side | (s)mooth off |",mesg);
-
-               if(inset)
-                       sprintf(mesg,"%s (p)roportional on ",mesg);
-               else
-                       sprintf(mesg,"%s (p)roportional off",mesg);
-               
-               headerprint(mesg);
-
-               screen_swapbuffers();           
-       }                       
-       
-       if(cut){
-               /* Now that we have selected a cut %, mark the edges for cutting. */
-               if(!inset){
-                       for(eed = em->edges.first; eed; eed=eed->next){         
-                                       if(percentcut == 1.0)
-                                               percentcut = 0.9999;
-                                       else if(percentcut == 0.0)
-                                               percentcut = 0.0001;
-                                       if(eed->f & 8){
-                                               if(eed->f & 32)/* Need to offset by a const. (0.5/32768) for consistant roundoff */
-                                                       eed->f1 = 32768*(1.0-percentcut - 0.0000153);
-                                               else
-                                                       eed->f1 = 32768*(percentcut + 0.0000153);
-                                       }                               
+                       /* hashedges are freed now, make new! */
+                       eed= em->edges.first;
+                       while(eed) {
+                               if( findedgelist(eed->v1, eed->v2)==NULL )
+                                       insert_hashedge(eed);
+                               eed= eed->next;
                        }
-               }
-       /*-------------------------------------*/
-
-                       if(smooth)
-                               subdivideflag(8, 0, B_KNIFE | B_PERCENTSUBD | B_SMOOTH); /* B_KNIFE tells subdivide that edgeflags are already set */
-                       else
-                               subdivideflag(8, 0, B_KNIFE | B_PERCENTSUBD); /* B_KNIFE tells subdivide that edgeflags are already set */
                        
-                       for(eed = em->edges.first; eed; eed=eed->next){                                                 
-                               if(eed->v1->f & 16) eed->v1->f |= 1;
-                               else eed->v1->f &= ~1;
-                               
-                               if(eed->v2->f & 16) eed->v2->f |= 1;
-                               else eed->v2->f &= ~1;
-                       }                       
-               }
-       }
-       /*----------END Cut Loop-----------------------------*/
-
-       
-
-       /* Clear flags */               
-       for(eed = em->edges.first; eed; eed=eed->next){ 
-               eed->f &= ~(2|4|8|32|64);
-               eed->v1->f &= ~(2|16);
-               eed->v2->f &= ~(2|16);          
+                       G.obedit= oldob;
+                       BASACT= oldbase;
+                       BASACT->flag |= SELECT; 
+                                       
+               }               
        }
        
-       for(efa= em->faces.first; efa; efa=efa->next){
-               efa->f &= ~(4|8);
+       /* unselect the vertices that we (ab)used for the separation*/
+       eve= em->verts.first;
+       while(eve) {
+               eve->f&= ~1;                    
+               eve= eve->next;
        }
        
+       waitcursor(0);
        countall();
-
-       if(tagged)
-               MEM_freeN(tagged);
-       if(taggedsrch)
-               MEM_freeN(taggedsrch);
-       if(percentfacesloop)
-               MEM_freeN(percentfacesloop);
-       
-       /* send event to redraw this window, does header too */ 
-       SetBlenderCursor(SYSCURSOR);
-       addqueue(curarea->win, REDRAW, 1); 
-}
-
-void edge_select(void)
-{
-       EditMesh *em = G.editMesh;
-       EditEdge *closest=0;
-       
-       closest=findnearestedge();      
-       
-       if(closest){         /* Did we find anything that is selectable?*/
-
-               if( (G.qual & LR_SHIFTKEY)==0) {
-                       EditVert *eve;                  
-                       
-                       undo_push_mesh("Select Edge");
-                       /* deselectall */
-                       for(eve= em->verts.first; eve; eve= eve->next) eve->f&= ~1;
-
-                       /* select edge */
-                       closest->v1->f |= 1;
-                       closest->v2->f |= 1;
-               }
-               else {
-                       /*  both of the vertices are selected: deselect both*/
-                       if((closest->v1->f & 1) && (closest->v2->f & 1) ){  
-                               closest->v1->f &= ~1;
-                               closest->v2->f &= ~1;
-                       }
-                       else { 
-                               /* select both */
-                               closest->v1->f |= 1;
-                               closest->v2->f |= 1;
-                       }
-               }
-               countall();
-               allqueue(REDRAWVIEW3D, 0);
-       }
+       allqueue(REDRAWVIEW3D, 0);
+       makeDispList(G.obedit); 
 }
 
-static void draw_vertices_special(int mode, EditVert *act) /* teken = draw */
-{
-       /* (only this view, no other windows) */
-       /* hackish routine for visual speed:
-        * mode 0: deselect the selected ones, draw them, except act
-        * mode 1: only draw act
-        */
-       EditMesh *em = G.editMesh;
-       EditVert *eve;
-       float size= BIF_GetThemeValuef(TH_VERTEX_SIZE);
-       char col[3];
-       
-       glPointSize(size);
-
-       persp(PERSP_VIEW);
-       glPushMatrix();
-       mymultmatrix(G.obedit->obmat);
-
-       if(mode==0) {
-               BIF_ThemeColor(TH_VERTEX);
-               
-               /* set zbuffer on, its default off outside main drawloops */
-               if(G.vd->drawtype > OB_WIRE) {
-                       G.zbuf= 1;
-                       glEnable(GL_DEPTH_TEST);
-               }
-
-               glBegin(GL_POINTS);
-               eve= (EditVert *)em->verts.first;
-               while(eve) {
-                       if(eve->h==0) {
-                               if(eve!=act && (eve->f & 1)) {
-                                       eve->f -= 1;
-                                       glVertex3fv(eve->co);
-                               }
-                       }
-                       eve= eve->next;
-               }
-               glEnd();
-               
-               glDisable(GL_DEPTH_TEST);
-               G.zbuf= 0;
-       }
-       
-       /* draw active vertex */
-       if(act->f & 1) BIF_GetThemeColor3ubv(TH_VERTEX_SELECT, col);
-       else BIF_GetThemeColor3ubv(TH_VERTEX, col);
-       
-       glColor3ub(col[0], col[1], col[2]);
-
-       glBegin(GL_POINTS);
-       glVertex3fv(act->co);
-       glEnd();
-       
-       glPointSize(1.0);
-       glPopMatrix();
-
-       
-}
-
-void mouse_mesh(void)
-{
-       EditVert *act=0;
-
-       if(G.qual & LR_ALTKEY) {
-               if (G.qual & LR_CTRLKEY) edge_select();
-       }
-       else {
-       
-               act= findnearestvert(1);
-               if(act) {
-                       
-                       glDrawBuffer(GL_FRONT);
-
-                       undo_push_mesh("Select Vertex");
-
-                       if( (act->f & 1)==0) act->f+= 1;
-                       else if(G.qual & LR_SHIFTKEY) act->f-= 1;
-
-                       if((G.qual & LR_SHIFTKEY)==0) {
-                               draw_vertices_special(0, act);
-                       }
-                       else draw_vertices_special(1, act);
-
-                       countall();
-
-                       glFlush();
-                       glDrawBuffer(GL_BACK);
-                       
-                       /* signal that frontbuf differs from back */
-                       curarea->win_swap= WIN_FRONT_OK;
-                       
-                       if(G.f & (G_FACESELECT|G_DRAWFACES|G_DRAWEDGES)) {
-                               /* update full view later on */
-                               allqueue(REDRAWVIEW3D, 0);
-                       }
-                       else allqueue(REDRAWVIEW3D, curarea->win);      // all windows except this one
-               }
-       
-               rightmouse_transform();
-       }
-}
-
-static void selectconnectedAll(void)
-{
-       EditMesh *em = G.editMesh;
-       EditVert *v1,*v2;
-       EditEdge *eed;
-       short flag=1,toggle=0;
-
-       if(em->edges.first==0) return;
-       
-       undo_push_mesh("Select Connected (All)");
-
-       while(flag==1) {
-               flag= 0;
-               toggle++;
-               if(toggle & 1) eed= em->edges.first;
-               else eed= em->edges.last;
-               while(eed) {
-                       v1= eed->v1;
-                       v2= eed->v2;
-                       if(eed->h==0) {
-                               if(v1->f & 1) {
-                                       if( (v2->f & 1)==0 ) {
-                                               v2->f |= 1;
-                                               flag= 1;
-                                       }
-                               }
-                               else if(v2->f & 1) {
-                                       if( (v1->f & 1)==0 ) {
-                                               v1->f |= 1;
-                                               flag= 1;
-                                       }
-                               }
-                       }
-                       if(toggle & 1) eed= eed->next;
-                       else eed= eed->prev;
-               }
-       }
-       countall();
-
-       allqueue(REDRAWVIEW3D, 0);
-
-}
-
-void selectconnected_mesh(int qual)
-{
-       EditMesh *em = G.editMesh;
-       EditVert *eve,*v1,*v2,*act= 0;
-       EditEdge *eed;
-       short flag=1,sel,toggle=0;
-
-       if(em->edges.first==0) return;
-
-       if(qual & LR_CTRLKEY) {
-               selectconnectedAll();
-               return;
-       }
-
-       sel= 3;
-       if(qual & LR_SHIFTKEY) sel=2;
-       
-       act= findnearestvert(sel-2);
-       if(act==0) {
-               error("Nothing indicated ");
-               return;
-       }
-       
-       undo_push_mesh("Select Linked");
-       /* clear test flags */
-       eve= em->verts.first;
-       while(eve) {
-               eve->f&= ~2;
-               eve= eve->next;
-       }
-       act->f= (act->f & ~3) | sel;
-
-       while(flag==1) {
-               flag= 0;
-               toggle++;
-               if(toggle & 1) eed= em->edges.first;
-               else eed= em->edges.last;
-               while(eed) {
-                       v1= eed->v1;
-                       v2= eed->v2;
-                       if(eed->h==0) {
-                               if(v1->f & 2) {
-                                       if( (v2->f & 2)==0 ) {
-                                               v2->f= (v2->f & ~3) | sel;
-                                               flag= 1;
-                                       }
-                               }
-                               else if(v2->f & 2) {
-                                       if( (v1->f & 2)==0 ) {
-                                               v1->f= (v1->f & ~3) | sel;
-                                               flag= 1;
-                                       }
-                               }
-                       }
-                       if(toggle & 1) eed= eed->next;
-                       else eed= eed->prev;
-               }
-       }
-       countall();
-       
-       allqueue(REDRAWVIEW3D, 0);
-}
-
-
-short extrudeflag(short flag,short type)
-{
-       /* when type=1 old extrusion faces are removed (for spin etc) */
-       /* all verts with (flag & 'flag'): extrude */
-       /* from old verts, 'flag' is cleared, in new ones it is set */
-       EditMesh *em = G.editMesh;
-       EditVert *eve, *v1, *v2, *v3, *v4, *nextve;
-       EditEdge *eed, *e1, *e2, *e3, *e4, *nexted;
-       EditFace *efa, *efa2, *nextvl;
-       short sel=0, deloud= 0, smooth= 0;
-
-       if(G.obedit==0 || get_mesh(G.obedit)==0) return 0;
-
-       /* clear vert flag f1, we use this to detext a loose selected vertice */
-       eve= em->verts.first;
-       while(eve) {
-               if(eve->f & flag) eve->f1= 1;
-               else eve->f1= 0;
-               eve= eve->next;
-       }
-       /* clear edges counter flag, if selected we set it at 1 */
-       eed= em->edges.first;
-       while(eed) {
-               if( (eed->v1->f & flag) && (eed->v2->f & flag) ) {
-                       eed->f= 1;
-                       eed->v1->f1= 0;
-                       eed->v2->f1= 0;
-               }
-               else eed->f= 0;
-               
-               eed->f1= 1;             /* this indicates it is an 'old' edge (in this routine we make new ones) */
-               
-               eed= eed->next;
-       }
-
-       /* we set a flag in all selected faces, and increase the associated edge counters */
-
-       efa= em->faces.first;
-       while(efa) {
-               efa->f= 0;
-
-               if (efa->flag & ME_SMOOTH) {
-                       if (faceselectedOR(efa, 1)) smooth= 1;
-               }
-               
-               if(faceselectedAND(efa, flag)) {
-                       e1= efa->e1;
-                       e2= efa->e2;
-                       e3= efa->e3;
-                       e4= efa->e4;
-
-                       if(e1->f < 3) e1->f++;
-                       if(e2->f < 3) e2->f++;
-                       if(e3->f < 3) e3->f++;
-                       if(e4 && e4->f < 3) e4->f++;
-                       efa->f= 1;
-               }
-               else if(faceselectedOR(efa, flag)) {
-                       e1= efa->e1;
-                       e2= efa->e2;
-                       e3= efa->e3;
-                       e4= efa->e4;
-                       
-                       if( (e1->v1->f & flag) && (e1->v2->f & flag) ) e1->f1= 2;
-                       if( (e2->v1->f & flag) && (e2->v2->f & flag) ) e2->f1= 2;
-                       if( (e3->v1->f & flag) && (e3->v2->f & flag) ) e3->f1= 2;
-                       if( e4 && (e4->v1->f & flag) && (e4->v2->f & flag) ) e4->f1= 2;
-               }
-               
-               efa= efa->next;
-       }
-
-       /* set direction of edges */
-       efa= em->faces.first;
-       while(efa) {
-               if(efa->f== 0) {
-                       if(efa->e1->f==2) {
-                               if(efa->e1->v1 == efa->v1) efa->e1->dir= 0;
-                               else efa->e1->dir= 1;
-                       }
-                       if(efa->e2->f==2) {
-                               if(efa->e2->v1 == efa->v2) efa->e2->dir= 0;
-                               else efa->e2->dir= 1;
-                       }
-                       if(efa->e3->f==2) {
-                               if(efa->e3->v1 == efa->v3) efa->e3->dir= 0;
-                               else efa->e3->dir= 1;
-                       }
-                       if(efa->e4 && efa->e4->f==2) {
-                               if(efa->e4->v1 == efa->v4) efa->e4->dir= 0;
-                               else efa->e4->dir= 1;
-                       }
-               }
-               efa= efa->next;
-       }       
-
-
-       /* the current state now is:
-               eve->f1==1: loose selected vertex 
-
-               eed->f==0 : edge is not selected, no extrude
-               eed->f==1 : edge selected, is not part of a face, extrude
-               eed->f==2 : edge selected, is part of 1 face, extrude
-               eed->f==3 : edge selected, is part of more faces, no extrude
-               
-               eed->f1==0: new edge
-               eed->f1==1: edge selected, is part of selected face, when eed->f==3: remove
-               eed->f1==2: edge selected, is not part of a selected face
-                                       
-               efa->f==1 : duplicate this face
-       */
-
-       /* copy all selected vertices, */
-       /* write pointer to new vert in old struct at eve->vn */
-       eve= em->verts.last;
-       while(eve) {
-               eve->f&= ~128;  /* clear, for later test for loose verts */
-               if(eve->f & flag) {
-                       sel= 1;
-                       v1= addvertlist(0);
-                       
-                       VECCOPY(v1->co, eve->co);
-                       v1->f= eve->f;
-                       eve->f-= flag;
-                       eve->vn= v1;
-               }
-               else eve->vn= 0;
-               eve= eve->prev;
-       }
-
-       if(sel==0) return 0;
-
-       /* all edges with eed->f==1 or eed->f==2 become faces */
-       /* if deloud==1 then edges with eed->f>2 are removed */
-       eed= em->edges.last;
-       while(eed) {
-               nexted= eed->prev;
-               if( eed->f<3) {
-                       eed->v1->f|=128;  /* = no loose vert! */
-                       eed->v2->f|=128;
-               }
-               if( (eed->f==1 || eed->f==2) ) {
-                       if(eed->f1==2) deloud=1;
-                       
-                       if(eed->dir==1) efa2= addfacelist(eed->v1, eed->v2, eed->v2->vn, eed->v1->vn, NULL);
-                       else efa2= addfacelist(eed->v2, eed->v1, eed->v1->vn, eed->v2->vn, NULL);
-                       if (smooth) efa2->flag |= ME_SMOOTH;
-
-                       /* Needs smarter adaption of existing creases.
-                        * If addedgelist is used, make sure seams are set to 0 on these
-                        * new edges, since we do not want to add any seams on extrusion.
-                        */
-                       efa2->e1->crease= eed->crease;
-                       efa2->e2->crease= eed->crease;
-                       efa2->e3->crease= eed->crease;
-                       if(efa2->e4) efa2->e4->crease= eed->crease;
-               }
-
-               eed= nexted;
-       }
-       if(deloud) {
-               eed= em->edges.first;
-               while(eed) {
-                       nexted= eed->next;
-                       if(eed->f==3 && eed->f1==1) {
-                               remedge(eed);
-                               free_editedge(eed);
-                       }
-                       eed= nexted;
-               }
-       }
-       /* duplicate faces, if necessart remove old ones  */
-       efa= em->faces.first;
-       while(efa) {
-               nextvl= efa->next;
-               if(efa->f & 1) {
-               
-                       v1= efa->v1->vn;
-                       v2= efa->v2->vn;
-                       v3= efa->v3->vn;
-                       if(efa->v4) v4= efa->v4->vn; else v4= 0;
-                       
-                       efa2= addfacelist(v1, v2, v3, v4, efa);
-                       
-                       if(deloud) {
-                               BLI_remlink(&em->faces, efa);
-                               free_editface(efa);
-                       }
-                       if (smooth) efa2->flag |= ME_SMOOTH;                    
-               }
-               efa= nextvl;
-       }
-       /* for all vertices with eve->vn!=0 
-               if eve->f1==1: make edge
-               if flag!=128 : if deloud==1: remove
-       */
-       eve= em->verts.last;
-       while(eve) {
-               nextve= eve->prev;
-               if(eve->vn) {
-                       if(eve->f1==1) addedgelist(eve, eve->vn, NULL);
-                       else if( (eve->f & 128)==0) {
-                               if(deloud) {
-                                       BLI_remlink(&em->verts,eve);
-                                       free_editvert(eve);
-                                       eve= NULL;
-                               }
-                       }
-               }
-               if(eve) eve->f&= ~128;
-               
-               eve= nextve;
-       }
-
-       return 1;
-}
-
-void rotateflag(short flag, float *cent, float rotmat[][3])
-{
-       /* all verts with (flag & 'flag') rotate */
-       EditMesh *em = G.editMesh;
-       EditVert *eve;
-
-       eve= em->verts.first;
-       while(eve) {
-               if(eve->f & flag) {
-                       eve->co[0]-=cent[0];
-                       eve->co[1]-=cent[1];
-                       eve->co[2]-=cent[2];
-                       Mat3MulVecfl(rotmat,eve->co);
-                       eve->co[0]+=cent[0];
-                       eve->co[1]+=cent[1];
-                       eve->co[2]+=cent[2];
-               }
-               eve= eve->next;
-       }
-}
-
-void translateflag(short flag, float *vec)
-{
-       /* all verts with (flag & 'flag') translate */
-       EditMesh *em = G.editMesh;
-       EditVert *eve;
-
-       eve= em->verts.first;
-       while(eve) {
-               if(eve->f & flag) {
-                       eve->co[0]+=vec[0];
-                       eve->co[1]+=vec[1];
-                       eve->co[2]+=vec[2];
-               }
-               eve= eve->next;
-       }
-}
-
-short removedoublesflag(short flag, float limit)               /* return amount */
-{
-       EditMesh *em = G.editMesh;
-       /* all verts with (flag & 'flag') are being evaluated */
-       EditVert *eve, *v1, *nextve;
-       EditEdge *eed, *e1, *nexted;
-       EditFace *efa, *nextvl;
-       struct xvertsort *sortblock, *sb, *sb1;
-       struct facesort *vlsortblock, *vsb, *vsb1;
-       float dist;
-       int a, b, test, aantal;
-
-       /* flag 128 is cleared, count */
-       eve= em->verts.first;
-       aantal= 0;
-       while(eve) {
-               eve->f&= ~128;
-               if(eve->f & flag) aantal++;
-               eve= eve->next;
-       }
-       if(aantal==0) return 0;
-
-       /* allocate memory and qsort */
-       sb= sortblock= (struct xvertsort *)MEM_mallocN(sizeof(struct xvertsort)*aantal,"sortremovedoub");
-       eve= em->verts.first;
-       while(eve) {
-               if(eve->f & flag) {
-                       sb->x= eve->co[0]+eve->co[1]+eve->co[2];
-                       sb->v1= eve;
-                       sb++;
-               }
-               eve= eve->next;
-       }
-       qsort(sortblock, aantal, sizeof(struct xvertsort), vergxco);
-
-       /* test for doubles */
-       sb= sortblock;
-       for(a=0; a<aantal; a++) {
-               eve= sb->v1;
-               if( (eve->f & 128)==0 ) {
-                       sb1= sb+1;
-                       for(b=a+1; b<aantal; b++) {
-                               /* first test: simpel dist */
-                               dist= sb1->x - sb->x;
-                               if(dist > limit) break;
-                               
-                               /* second test: is vertex allowed */
-                               v1= sb1->v1;
-                               if( (v1->f & 128)==0 ) {
-                                       
-                                       dist= fabs(v1->co[0]-eve->co[0]);
-                                       if(dist<=limit) {
-                                               dist= fabs(v1->co[1]-eve->co[1]);
-                                               if(dist<=limit) {
-                                                       dist= fabs(v1->co[2]-eve->co[2]);
-                                                       if(dist<=limit) {
-                                                               v1->f|= 128;
-                                                               v1->vn= eve;
-                                                       }
-                                               }
-                                       }
-                               }
-                               sb1++;
-                       }
-               }
-               sb++;
-       }
-       MEM_freeN(sortblock);
-
-       /* test edges and insert again */
-       eed= em->edges.first;
-       while(eed) {
-               eed->f= 0;
-               eed= eed->next;
-       }
-       eed= em->edges.last;
-       while(eed) {
-               nexted= eed->prev;
-
-               if(eed->f==0) {
-                       if( (eed->v1->f & 128) || (eed->v2->f & 128) ) {
-                               remedge(eed);
-
-                               if(eed->v1->f & 128) eed->v1= eed->v1->vn;
-                               if(eed->v2->f & 128) eed->v2= eed->v2->vn;
-                               e1= addedgelist(eed->v1, eed->v2, eed);
-                               
-                               if(e1) e1->f= 1;
-                               if(e1!=eed) free_editedge(eed);
-                       }
-               }
-               eed= nexted;
-       }
-
-       /* first count amount of test faces */
-       efa= (struct EditFace *)em->faces.first;
-       aantal= 0;
-       while(efa) {
-               efa->f= 0;
-               if(efa->v1->f & 128) efa->f= 1;
-               else if(efa->v2->f & 128) efa->f= 1;
-               else if(efa->v3->f & 128) efa->f= 1;
-               else if(efa->v4 && (efa->v4->f & 128)) efa->f= 1;
-               
-               if(efa->f==1) aantal++;
-               efa= efa->next;
-       }
-
-       /* test faces for double vertices, and if needed remove them */
-       efa= (struct EditFace *)em->faces.first;
-       while(efa) {
-               nextvl= efa->next;
-               if(efa->f==1) {
-                       
-                       if(efa->v1->f & 128) efa->v1= efa->v1->vn;
-                       if(efa->v2->f & 128) efa->v2= efa->v2->vn;
-                       if(efa->v3->f & 128) efa->v3= efa->v3->vn;
-                       if(efa->v4 && (efa->v4->f & 128)) efa->v4= efa->v4->vn;
-               
-                       test= 0;
-                       if(efa->v1==efa->v2) test+=1;
-                       if(efa->v2==efa->v3) test+=2;
-                       if(efa->v3==efa->v1) test+=4;
-                       if(efa->v4==efa->v1) test+=8;
-                       if(efa->v3==efa->v4) test+=16;
-                       if(efa->v2==efa->v4) test+=32;
-                       
-                       if(test) {
-                               if(efa->v4) {
-                                       if(test==1 || test==2) {
-                                               efa->v2= efa->v3;
-                                               efa->v3= efa->v4;
-                                               efa->v4= 0;
-                                               test= 0;
-                                       }
-                                       else if(test==8 || test==16) {
-                                               efa->v4= 0;
-                                               test= 0;
-                                       }
-                                       else {
-                                               BLI_remlink(&em->faces, efa);
-                                               free_editface(efa);
-                                               aantal--;
-                                       }
-                               }
-                               else {
-                                       BLI_remlink(&em->faces, efa);
-                                       free_editface(efa);
-                                       aantal--;
-                               }
-                       }
-                       
-                       if(test==0) {
-                               /* set edge pointers */
-                               efa->e1= findedgelist(efa->v1, efa->v2);
-                               efa->e2= findedgelist(efa->v2, efa->v3);
-                               if(efa->v4==0) {
-                                       efa->e3= findedgelist(efa->v3, efa->v1);
-                                       efa->e4= 0;
-                               }
-                               else {
-                                       efa->e3= findedgelist(efa->v3, efa->v4);
-                                       efa->e4= findedgelist(efa->v4, efa->v1);
-                               }
-                       }
-               }
-               efa= nextvl;
-       }
-
-       /* double faces: sort block */
-       /* count again, now all selected faces */
-       aantal= 0;
-       efa= em->faces.first;
-       while(efa) {
-               efa->f= 0;
-               if(faceselectedAND(efa, 1)) {
-                       efa->f= 1;
-                       aantal++;
-               }
-               efa= efa->next;
-       }
-
-       if(aantal) {
-               /* double faces: sort block */
-               vsb= vlsortblock= MEM_mallocN(sizeof(struct facesort)*aantal, "sortremovedoub");
-               efa= em->faces.first;
-               while(efa) {
-                       if(efa->f & 1) {
-                               if(efa->v4) vsb->x= (long) MIN4( (long)efa->v1, (long)efa->v2, (long)efa->v3, (long)efa->v4);
-                               else vsb->x= (long) MIN3( (long)efa->v1, (long)efa->v2, (long)efa->v3);
-
-                               vsb->efa= efa;
-                               vsb++;
-                       }
-                       efa= efa->next;
-               }
-               
-               qsort(vlsortblock, aantal, sizeof(struct facesort), vergface);
-                       
-               vsb= vlsortblock;
-               for(a=0; a<aantal; a++) {
-                       efa= vsb->efa;
-                       if( (efa->f & 128)==0 ) {
-                               vsb1= vsb+1;
-
-                               for(b=a+1; b<aantal; b++) {
-                               
-                                       /* first test: same pointer? */
-                                       if(vsb->x != vsb1->x) break;
-                                       
-                                       /* second test: is test permitted? */
-                                       efa= vsb1->efa;
-                                       if( (efa->f & 128)==0 ) {
-                                               if( compareface(efa, vsb->efa)) efa->f |= 128;
-                                               
-                                       }
-                                       vsb1++;
-                               }
-                       }
-                       vsb++;
-               }
-               
-               MEM_freeN(vlsortblock);
-               
-               /* remove double faces */
-               efa= (struct EditFace *)em->faces.first;
-               while(efa) {
-                       nextvl= efa->next;
-                       if(efa->f & 128) {
-                               BLI_remlink(&em->faces, efa);
-                               free_editface(efa);
-                       }
-                       efa= nextvl;
-               }
-       }
-       
-       /* remove double vertices */
-       a= 0;
-       eve= (struct EditVert *)em->verts.first;
-       while(eve) {
-               nextve= eve->next;
-               if(eve->f & flag) {
-                       if(eve->f & 128) {
-                               a++;
-                               BLI_remlink(&em->verts, eve);
-                               free_editvert(eve);
-                       }
-               }
-               eve= nextve;
-       }
-       return a;       /* amount */
-}
-
-void xsortvert_flag(int flag)
-{
-       EditMesh *em = G.editMesh;
-       /* all verts with (flag & 'flag') are sorted */
-       EditVert *eve;
-       struct xvertsort *sortblock, *sb;
-       ListBase tbase;
-       int aantal;
-       
-       /* count */
-       eve= em->verts.first;
-       aantal= 0;
-       while(eve) {
-               if(eve->f & flag) aantal++;
-               eve= eve->next;
-       }
-       if(aantal==0) return;
-
-       undo_push_mesh("Xsort");
-       
-       /* allocate memory and sort */
-       sb= sortblock= (struct xvertsort *)MEM_mallocN(sizeof(struct xvertsort)*aantal,"sortremovedoub");
-       eve= em->verts.first;
-       while(eve) {
-               if(eve->f & flag) {
-                       sb->x= eve->xs;
-                       sb->v1= eve;
-                       sb++;
-               }
-               eve= eve->next;
-       }
-       qsort(sortblock, aantal, sizeof(struct xvertsort), vergxco);
-       
-       /* make temporal listbase */
-       tbase.first= tbase.last= 0;
-       sb= sortblock;
-       while(aantal--) {
-               eve= sb->v1;
-               BLI_remlink(&em->verts, eve);
-               BLI_addtail(&tbase, eve);
-               sb++;
-       }
-       
-       addlisttolist(&em->verts, &tbase);
-       
-       MEM_freeN(sortblock);
-}
-
-
-void hashvert_flag(int flag)
-{
-       /* switch vertex order using hash table */
-       EditMesh *em = G.editMesh;
-       EditVert *eve;
-       struct xvertsort *sortblock, *sb, onth, *newsort;
-       ListBase tbase;
-       int aantal, a, b;
-       
-       /* count */
-       eve= em->verts.first;
-       aantal= 0;
-       while(eve) {
-               if(eve->f & flag) aantal++;
-               eve= eve->next;
-       }
-       if(aantal==0) return;
-       
-       undo_push_mesh("Hash");
-
-       /* allocate memory */
-       sb= sortblock= (struct xvertsort *)MEM_mallocN(sizeof(struct xvertsort)*aantal,"sortremovedoub");
-       eve= em->verts.first;
-       while(eve) {
-               if(eve->f & flag) {
-                       sb->v1= eve;
-                       sb++;
-               }
-               eve= eve->next;
-       }
-
-       BLI_srand(1);
-       
-       sb= sortblock;
-       for(a=0; a<aantal; a++, sb++) {
-               b= aantal*BLI_drand();
-               if(b>=0 && b<aantal) {
-                       newsort= sortblock+b;
-                       onth= *sb;
-                       *sb= *newsort;
-                       *newsort= onth;
-               }
-       }
-
-       /* make temporal listbase */
-       tbase.first= tbase.last= 0;
-       sb= sortblock;
-       while(aantal--) {
-               eve= sb->v1;
-               BLI_remlink(&em->verts, eve);
-               BLI_addtail(&tbase, eve);
-               sb++;
-       }
-       
-       addlisttolist(&em->verts, &tbase);
-       
-       MEM_freeN(sortblock);
-}
-
-static unsigned int cpack_fact(unsigned int col1, unsigned int col2, float fact)
-{
-       char *cp1, *cp2, *cp;
-       unsigned int col=0;
-       float fact1;
-       
-       fact1=1-fact; /*result is fact% col1 and (1-fact) % col2 */
-               
-       cp1= (char *)&col1;
-       cp2= (char *)&col2;
-       cp=  (char *)&col;
-       
-       cp[0]= fact*cp1[0]+fact1*cp2[0];
-       cp[1]= fact*cp1[1]+fact1*cp2[1];
-       cp[2]= fact*cp1[2]+fact1*cp2[2];
-       cp[3]= fact*cp1[3]+fact1*cp2[3];
-       
-       return col;
-}
-
-
-static void uv_half(float *uv, float *uv1, float *uv2)
-{
-       uv[0]= (uv1[0]+uv2[0])/2.0;
-       uv[1]= (uv1[1]+uv2[1])/2.0;
-       
-}
-
-static void uv_quart(float *uv, float *uv1)
-{
-       uv[0]= (uv1[0]+uv1[2]+uv1[4]+uv1[6])/4.0;
-       uv[1]= (uv1[1]+uv1[3]+uv1[5]+uv1[7])/4.0;
-}
-
-static void face_pin_vertex(EditFace *efa, EditVert *vertex)
-{
-       if(efa->v1 == vertex) efa->tf.unwrap |= TF_PIN1;
-       else if(efa->v2 == vertex) efa->tf.unwrap |= TF_PIN2;
-       else if(efa->v3 == vertex) efa->tf.unwrap |= TF_PIN3;
-       else if(efa->v4 && vertex && efa->v4 == vertex) efa->tf.unwrap |= TF_PIN4;
-}
-
-static void set_wuv(int tot, EditFace *efa, int v1, int v2, int v3, int v4, EditFace *efapin)
-{
-       /* this weird function only to be used for subdivide, the 'w' in the name has no meaning! */
-       float *uv, uvo[4][2];
-       unsigned int *col, colo[4], col1, col2;
-       int a, v;
-
-       /* recover pinning */
-       if(efapin){
-               efa->tf.unwrap= 0;
-               if(efapin->tf.unwrap & TF_PIN1) face_pin_vertex(efa, efapin->v1);
-               if(efapin->tf.unwrap & TF_PIN2) face_pin_vertex(efa, efapin->v2);
-               if(efapin->tf.unwrap & TF_PIN3) face_pin_vertex(efa, efapin->v3);
-               if(efapin->tf.unwrap & TF_PIN4) face_pin_vertex(efa, efapin->v4);
-       }
-
-                                               /* Numbers corespond to verts (corner points),  */
-                                               /* edge->vn's (center edges), the Center        */
-       memcpy(uvo, efa->tf.uv, sizeof(uvo));   /* And the quincunx points of a face            */
-       uv= efa->tf.uv[0];                            /* as shown here:                                 */
-                                                     /*           2         5          1   */
-       memcpy(colo, efa->tf.col, sizeof(colo));      /*               10         13        */
-       col= efa->tf.col;                             /*           6         9          8   */
-                                                  /*               11         12        */
-       if(tot==4) {                                  /*           3         7          4   */
-               for(a=0; a<4; a++, uv+=2, col++) {
-                       if(a==0) v= v1;
-                       else if(a==1) v= v2;
-                       else if(a==2) v= v3;
-                       else v= v4;
-                       
-                       if(a==3 && v4==0) break;
-                       
-                       if(v<=4) {
-                               uv[0]= uvo[v-1][0];
-                               uv[1]= uvo[v-1][1];
-                               *col= colo[v-1];
-                       }
-                       else if(v==8) {
-                               uv_half(uv, uvo[3], uvo[0]);
-                               *col= cpack_fact(colo[3], colo[0], 0.5);
-                       }
-                       else if(v==9) {
-                               uv_quart(uv, uvo[0]);
-                               col1= cpack_fact(colo[1], colo[0], 0.5);
-                               col2= cpack_fact(colo[2], colo[3], 0.5);
-                               *col= cpack_fact(col1, col2, 0.5);
-                       }
-                       /* Cases for adjacent edge square subdivide  Real voodoo */
-                       /* 1/2 closest corner + 1/4 adjacent corners */
-                       else if (v==10){ /* case test==3 in subdivideflag() */  
-                               uv[0]=(2*uvo[1][0]+uvo[0][0]+uvo[2][0])/4;
-                               uv[1]=(2*uvo[1][1]+uvo[0][1]+uvo[2][1])/4;
-                               col1= cpack_fact(colo[1], colo[0], 0.75);
-                               col2= cpack_fact(colo[2], colo[3], 0.75);
-                               *col= cpack_fact(col1, col2, 0.75);     
-                       }
-                       else if (v==11) { /* case of test==6 */
-                               uv[0]=(2*uvo[2][0]+uvo[1][0]+uvo[3][0])/4;
-                               uv[1]=(2*uvo[2][1]+uvo[1][1]+uvo[3][1])/4;
-                               col1= cpack_fact(colo[1], colo[0], 0.75);
-                               col2= cpack_fact(colo[2], colo[3], 0.75);
-                               *col= cpack_fact(col1, col2, 0.25);     
-                       }
-                       else if (v==12) { /* case of test==12 */
-                               uv[0]=(2*uvo[3][0]+uvo[2][0]+uvo[0][0])/4;
-                               uv[1]=(2*uvo[3][1]+uvo[2][1]+uvo[0][1])/4;
-                               col1= cpack_fact(colo[1], colo[0], 0.25);
-                               col2= cpack_fact(colo[2], colo[3], 0.25);
-                               *col= cpack_fact(col1, col2, 0.25);
-                       }
-                       else if (v==13) { /* case of test==9 */
-                               uv[0]=(2*uvo[0][0]+uvo[1][0]+uvo[3][0])/4;
-                               uv[1]=(2*uvo[0][1]+uvo[1][1]+uvo[3][1])/4;
-                               col1= cpack_fact(colo[1], colo[0], 0.25);
-                               col2= cpack_fact(colo[2], colo[3], 0.25);
-                               *col= cpack_fact(col1, col2, 0.75);
-                       }
-                       /* default for consecutive verts*/
-                       else { 
-                               uv_half(uv, uvo[v-5], uvo[v-4]);
-                               *col= cpack_fact(colo[v-5], colo[v-4], 0.5);
-                       }
-               }
-       }
-       else {
-               for(a=0; a<3; a++, uv+=2, col++) {
-                       if(a==0) v= v1;
-                       else if(a==1) v= v2;
-                       else v= v3;
-               
-                       if(v<=4) {
-                               uv[0]= uvo[v-1][0];
-                               uv[1]= uvo[v-1][1];
-                               *col= colo[v-1];
-                       }
-                       else if(v==7) {
-                               uv_half(uv, uvo[2], uvo[0]);
-                               *col= cpack_fact(colo[2], colo[0], 0.5);
-                       }
-                       else {
-                               uv_half(uv, uvo[v-5], uvo[v-4]);
-                               *col= cpack_fact(colo[v-5], colo[v-4], 0.5);
-                       }
-               }
-       }
-}
-
-static EditVert *vert_from_number(EditFace *efa, int nr)
-{
-       switch(nr) {
-       case 0:
-               return 0;
-       case 1:
-               return efa->v1;
-       case 2:
-               return efa->v2;
-       case 3:
-               return efa->v3;
-       case 4:
-               return efa->v4;
-       case 5:
-               return efa->e1->vn;
-       case 6:
-               return efa->e2->vn;
-       case 7:
-               return efa->e3->vn;
-       case 8:
-               return efa->e4->vn;
-       }
-       
-       return NULL;
-}
-
-static void addface_subdiv(EditFace *efa, int val1, int val2, int val3, int val4, EditVert *eve, EditFace *efapin)
-{
-       EditFace *w;
-       EditVert *v1, *v2, *v3, *v4;
-       
-       if(val1>=9) v1= eve;
-       else v1= vert_from_number(efa, val1);
-       
-       if(val2>=9) v2= eve;
-       else v2= vert_from_number(efa, val2);
-
-       if(val3>=9) v3= eve;
-       else v3= vert_from_number(efa, val3);
-
-       if(val4>=9) v4= eve;
-       else v4= vert_from_number(efa, val4);
-       
-       w= addfacelist(v1, v2, v3, v4, efa);
-       if(w) {
-               if(efa->v4) set_wuv(4, w, val1, val2, val3, val4, efapin);
-               else set_wuv(3, w, val1, val2, val3, val4, efapin);
-       }
-}
-
-static float smoothperc= 0.0;
-
-static void smooth_subdiv_vec(float *v1, float *v2, float *n1, float *n2, float *vec)
-{
-       float len, fac, nor[3], nor1[3], nor2[3];
-       
-       VecSubf(nor, v1, v2);
-       len= 0.5*Normalise(nor);
-
-       VECCOPY(nor1, n1);
-       VECCOPY(nor2, n2);
-
-       /* cosine angle */
-       fac= nor[0]*nor1[0] + nor[1]*nor1[1] + nor[2]*nor1[2] ;
-       
-       vec[0]= fac*nor1[0];
-       vec[1]= fac*nor1[1];
-       vec[2]= fac*nor1[2];
-
-       /* cosine angle */
-       fac= -nor[0]*nor2[0] - nor[1]*nor2[1] - nor[2]*nor2[2] ;
-       
-       vec[0]+= fac*nor2[0];
-       vec[1]+= fac*nor2[1];
-       vec[2]+= fac*nor2[2];
-
-       vec[0]*= smoothperc*len;
-       vec[1]*= smoothperc*len;
-       vec[2]*= smoothperc*len;
-}
-
-static void smooth_subdiv_quad(EditFace *efa, float *vec)
-{
-       
-       float nor1[3], nor2[3];
-       float vec1[3], vec2[3];
-       float cent[3];
-       
-       /* vlr->e1->vn is new vertex inbetween v1 / v2 */
-       
-       VecMidf(nor1, efa->v1->no, efa->v2->no);
-       Normalise(nor1);
-       VecMidf(nor2, efa->v3->no, efa->v4->no);
-       Normalise(nor2);
-
-       smooth_subdiv_vec( efa->e1->vn->co, efa->e3->vn->co, nor1, nor2, vec1);
-
-       VecMidf(nor1, efa->v2->no, efa->v3->no);
-       Normalise(nor1);
-       VecMidf(nor2, efa->v4->no, efa->v1->no);
-       Normalise(nor2);
-
-       smooth_subdiv_vec( efa->e2->vn->co, efa->e4->vn->co, nor1, nor2, vec2);
-
-       VecAddf(vec1, vec1, vec2);
-
-       CalcCent4f(cent, efa->v1->co,  efa->v2->co,  efa->v3->co,  efa->v4->co);
-       VecAddf(vec, cent, vec1);
-}
-
-void subdivideflag(int flag, float rad, int beauty)
-{
-       EditMesh *em = G.editMesh;
-       /* subdivide all with (vertflag & flag) */
-       /* if rad>0.0 it's a 'sphere' subdivide */
-       /* if rad<0.0 it's a fractal subdivide */
-       extern float doublimit;
-       EditVert *eve;
-       EditEdge *eed, *e1, *e2, *e3, *e4, *nexted;
-       EditFace *efa, efapin;
-       float fac, vec[3], vec1[3], len1, len2, len3, percent;
-       short test;
-       
-       if(beauty & B_SMOOTH) {
-               short perc= 100;
-
-               if(button(&perc, 10, 500, "Percentage:")==0) return;
-               
-               smoothperc= 0.292*perc/100.0;
-       }
-
-       /* edgeflags */
-       eed= em->edges.first;
-       while((eed) && !(beauty & B_KNIFE)) {   
-               if( (eed->v1->f & flag) && (eed->v2->f & flag) ) eed->f= flag;
-               else eed->f= 0; 
-               eed= eed->next;
-       }
-       
-       /* if beauty: test for area and clear edge flags of 'ugly' edges */
-       if(beauty & B_BEAUTY) {
-               efa= em->faces.first;
-               while(efa) {
-                       if( faceselectedAND(efa, flag) ) {
-                               if(efa->v4) {
-                               
-                                       /* area */
-                                       len1= AreaQ3Dfl(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
-                                       if(len1 <= doublimit) {
-                                               efa->e1->f = 0;
-                                               efa->e2->f = 0;
-                                               efa->e3->f = 0;
-                                               efa->e4->f = 0;
-                                       }
-                                       else {
-                                               len1= VecLenf(efa->v1->co, efa->v2->co) + VecLenf(efa->v3->co, efa->v4->co);
-                                               len2= VecLenf(efa->v2->co, efa->v3->co) + VecLenf(efa->v1->co, efa->v4->co);
-                                               
-                                               if(len1 < len2) {
-                                                       efa->e1->f = 0;
-                                                       efa->e3->f = 0;
-                                               }
-                                               else if(len1 > len2) {
-                                                       efa->e2->f = 0;
-                                                       efa->e4->f = 0;
-                                               }
-                                       }
-                               }
-                               else {
-                                       /* area */
-                                       len1= AreaT3Dfl(efa->v1->co, efa->v2->co, efa->v3->co);
-                                       if(len1 <= doublimit) {
-                                               efa->e1->f = 0;
-                                               efa->e2->f = 0;
-                                               efa->e3->f = 0;
-                                       }
-                                       else {
-                                               len1= VecLenf(efa->v1->co, efa->v2->co) ;
-                                               len2= VecLenf(efa->v2->co, efa->v3->co) ;
-                                               len3= VecLenf(efa->v3->co, efa->v1->co) ;
-                                               
-                                               if(len1<len2 && len1<len3) {
-                                                       efa->e1->f = 0;
-                                               }
-                                               else if(len2<len3 && len2<len1) {
-                                                       efa->e2->f = 0;
-                                               }
-                                               else if(len3<len2 && len3<len1) {
-                                                       efa->e3->f = 0;
-                                               }
-                                       }
-                               }
-                       }
-                       efa= efa->next;
-               }
-       }
-
-       if(beauty & B_SMOOTH) {
-               
-               vertexnormals(0);               /* no1*/
-                       
-       }
-       
-       /* make new normal and put in edge, clear flag! needed for face creation part below */
-       eed= em->edges.first;
-       while(eed) {
-               if(eed->f & flag) {
-                       /* Subdivide percentage is stored in 1/32768ths in eed->f1 */
-                       if (beauty & B_PERCENTSUBD) percent=(float)(eed->f1)/32768.0;
-                       else percent=0.5;
-                       
-                       vec[0]= (1-percent)*eed->v1->co[0] + percent*eed->v2->co[0];
-                       vec[1]= (1-percent)*eed->v1->co[1] + percent*eed->v2->co[1];
-                       vec[2]= (1-percent)*eed->v1->co[2] + percent*eed->v2->co[2];
-
-                       if(rad > 0.0) {   /* subdivide sphere */
-                               Normalise(vec);
-                               vec[0]*= rad;
-                               vec[1]*= rad;
-                               vec[2]*= rad;
-                       }
-                       else if(rad< 0.0) {  /* fractal subdivide */
-                               fac= rad* VecLenf(eed->v1->co, eed->v2->co);
-                               vec1[0]= fac*BLI_drand();
-                               vec1[1]= fac*BLI_drand();
-                               vec1[2]= fac*BLI_drand();
-                               VecAddf(vec, vec, vec1);
-                       }
-                       
-                       if(beauty & B_SMOOTH) {
-                               smooth_subdiv_vec(eed->v1->co, eed->v2->co, eed->v1->no, eed->v2->no, vec1);
-                               VecAddf(vec, vec, vec1);
-                       }
-                       
-                       eed->vn= addvertlist(vec);
-                       eed->vn->f= eed->v1->f;
-
-               }
-               else eed->vn= 0;
-               
-               eed->f= 0; /* needed! */
-               
-               eed= eed->next;
-       }
-
-       /* test all faces for subdivide edges, there are 8 or 16 cases (ugh)! */
-
-       efa= em->faces.last;
-       while(efa) {
-
-               efapin= *efa; /* make a copy of efa to recover uv pinning later */
-
-               if( faceselectedOR(efa, flag) ) {
-                       e1= efa->e1;
-                       e2= efa->e2;
-                       e3= efa->e3;
-                       e4= efa->e4;
-
-                       test= 0;
-                       if(e1 && e1->vn) { 
-                               test+= 1;
-                               e1->f= 1;
-                               /* add edges here, to copy correct edge data */
-                               eed= addedgelist(e1->v1, e1->vn, e1);
-                               eed= addedgelist(e1->vn, e1->v2, e1);
-                       }
-                       if(e2 && e2->vn) {
-                               test+= 2;
-                               e2->f= 1;
-                               /* add edges here, to copy correct edge data */
-                               eed= addedgelist(e2->v1, e2->vn, e2);
-                               eed= addedgelist(e2->vn, e2->v2, e2);
-                       }
-                       if(e3 && e3->vn) {
-                               test+= 4;
-                               e3->f= 1;
-                               /* add edges here, to copy correct edge data */
-                               eed= addedgelist(e3->v1, e3->vn, e3);
-                               eed= addedgelist(e3->vn, e3->v2, e3);
-                       }
-                       if(e4 && e4->vn) {
-                               test+= 8;
-                               e4->f= 1;
-                               /* add edges here, to copy correct edge data */
-                               eed= addedgelist(e4->v1, e4->vn, e4);
-                               eed= addedgelist(e4->vn, e4->v2, e4);
-                       }
-                       if(test) {
-                               if(efa->v4==0) {  /* All the permutations of 3 edges*/
-                                       if((test & 3)==3) addface_subdiv(efa, 2, 2+4, 1+4, 0, 0, &efapin);
-                                       if((test & 6)==6) addface_subdiv(efa, 3, 3+4, 2+4, 0, 0, &efapin);
-                                       if((test & 5)==5) addface_subdiv(efa, 1, 1+4, 3+4, 0, 0, &efapin);
-
-                                       if(test==7) {  /* four new faces, old face renews */
-                                               efa->v1= e1->vn;
-                                               efa->v2= e2->vn;
-                                               efa->v3= e3->vn;
-                                               set_wuv(3, efa, 1+4, 2+4, 3+4, 0, &efapin);
-                                       }
-                                       else if(test==3) {
-                                               addface_subdiv(efa, 1+4, 2+4, 3, 0, 0, &efapin);
-                                               efa->v2= e1->vn;
-                                               set_wuv(3, efa, 1, 1+4, 3, 0, &efapin);
-                                       }
-                                       else if(test==6) {
-                                               addface_subdiv(efa, 2+4, 3+4, 1, 0, 0, &efapin);
-                                               efa->v3= e2->vn;
-                                               set_wuv(3, efa, 1, 2, 2+4, 0, &efapin);
-                                       }
-                                       else if(test==5) {
-                                               addface_subdiv(efa, 3+4, 1+4, 2, 0, 0, &efapin);
-                                               efa->v1= e3->vn;
-                                               set_wuv(3, efa, 3+4, 2, 3, 0, &efapin);
-                                       }
-                                       else if(test==1) {
-                                               addface_subdiv(efa, 1+4, 2, 3, 0, 0, &efapin);
-                                               efa->v2= e1->vn;
-                                               set_wuv(3, efa, 1, 1+4, 3, 0, &efapin);
-                                       }
-                                       else if(test==2) {
-                                               addface_subdiv(efa, 2+4, 3, 1, 0, 0, &efapin);
-                                               efa->v3= e2->vn;
-                                               set_wuv(3, efa, 1, 2, 2+4, 0, &efapin);
-                                       }
-                                       else if(test==4) {
-                                               addface_subdiv(efa, 3+4, 1, 2, 0, 0, &efapin);
-                                               efa->v1= e3->vn;
-                                               set_wuv(3, efa, 3+4, 2, 3, 0, &efapin);
-                                       }
-                                       efa->e1= addedgelist(efa->v1, efa->v2, NULL);
-                                       efa->e2= addedgelist(efa->v2, efa->v3, NULL);
-                                       efa->e3= addedgelist(efa->v3, efa->v1, NULL);
-
-                               }
-                               else {  /* All the permutations of 4 faces */
-                                       if(test==15) {
-                                               /* add a new point in center */
-                                               CalcCent4f(vec, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
-                                               
-                                               if(beauty & B_SMOOTH) {
-                                                       smooth_subdiv_quad(efa, vec);   /* adds */
-                                               }
-                                               eve= addvertlist(vec);
-                                               
-                                               eve->f |= flag;
-
-                                               addface_subdiv(efa, 2, 2+4, 9, 1+4, eve, &efapin);
-                                               addface_subdiv(efa, 3, 3+4, 9, 2+4, eve, &efapin);
-                                               addface_subdiv(efa, 4, 4+4, 9, 3+4, eve, &efapin);
-
-                                               efa->v2= e1->vn;
-                                               efa->v3= eve;
-                                               efa->v4= e4->vn;
-                                               set_wuv(4, efa, 1, 1+4, 9, 4+4, &efapin);
-                                       }
-                                       else {
-                                               if(((test & 3)==3)&&(test!=3)) addface_subdiv(efa, 1+4, 2, 2+4, 0, 0, &efapin);
-                                               if(((test & 6)==6)&&(test!=6)) addface_subdiv(efa, 2+4, 3, 3+4, 0, 0, &efapin);
-                                               if(((test & 12)==12)&&(test!=12)) addface_subdiv(efa, 3+4, 4, 4+4, 0, 0, &efapin);
-                                               if(((test & 9)==9)&&(test!=9)) addface_subdiv(efa, 4+4, 1, 1+4, 0, 0, &efapin);
-
-                                               if(test==1) { /* Edge 1 has new vert */
-                                                       addface_subdiv(efa, 1+4, 2, 3, 0, 0, &efapin);
-                                                       addface_subdiv(efa, 1+4, 3, 4, 0, 0, &efapin);
-                                                       efa->v2= e1->vn;
-                                                       efa->v3= efa->v4;
-                                                       efa->v4= 0;
-                                                       set_wuv(4, efa, 1, 1+4, 4, 0, &efapin);
-                                               }
-                                               else if(test==2) { /* Edge 2 has new vert */
-                                                       addface_subdiv(efa, 2+4, 3, 4, 0, 0, &efapin);
-                                                       addface_subdiv(efa, 2+4, 4, 1, 0, 0, &efapin);
-                                                       efa->v3= e2->vn;
-                                                       efa->v4= 0;
-                                                       set_wuv(4, efa, 1, 2, 2+4, 0, &efapin);
-                                               }
-                                               else if(test==4) { /* Edge 3 has new vert */
-                                                       addface_subdiv(efa, 3+4, 4, 1, 0, 0, &efapin);
-                                                       addface_subdiv(efa, 3+4, 1, 2, 0, 0, &efapin);
-                                                       efa->v1= efa->v2;
-                                                       efa->v2= efa->v3;
-                                                       efa->v3= e3->vn;
-                                                       efa->v4= 0;
-                                                       set_wuv(4, efa, 2, 3, 3+4, 0, &efapin);
-                                               }
-                                               else if(test==8) { /* Edge 4 has new vert */
-                                                       addface_subdiv(efa, 4+4, 1, 2, 0, 0, &efapin);
-                                                       addface_subdiv(efa, 4+4, 2, 3, 0, 0, &efapin);
-                                                       efa->v1= efa->v3;
-                                                       efa->v2= efa->v4;
-                                                       efa->v3= e4->vn;
-                                                       efa->v4= 0;
-                                                       set_wuv(4, efa, 3, 4, 4+4, 0, &efapin);
-                                               }
-                                               else if(test==3) { /*edge 1&2 */
-                                                       /* make new vert in center of new edge */
-                                                       vec[0]=(e1->vn->co[0]+e2->vn->co[0])/2;
-                                                       vec[1]=(e1->vn->co[1]+e2->vn->co[1])/2;
-                                                       vec[2]=(e1->vn->co[2]+e2->vn->co[2])/2;
-                                                       eve= addvertlist(vec);
-                                                       eve->f |= flag;
-                                                       /* Add new faces */
-                                                       addface_subdiv(efa, 4, 10, 2+4, 3, eve, &efapin);
-                                                       addface_subdiv(efa, 4, 1, 1+4, 10, eve, &efapin);
-                                                       /* orig face becomes small corner */
-                                                       efa->v1=e1->vn;
-                                                       //efa->v2=efa->v2;
-                                                       efa->v3=e2->vn;
-                                                       efa->v4=eve;
-
-                                                       set_wuv(4, efa, 1+4, 2, 2+4, 10, &efapin);
-                                               }
-                                               else if(test==6) { /* 2&3 */
-                                                       /* make new vert in center of new edge */
-                                                       vec[0]=(e2->vn->co[0]+e3->vn->co[0])/2;
-                                                       vec[1]=(e2->vn->co[1]+e3->vn->co[1])/2;
-                                                       vec[2]=(e2->vn->co[2]+e3->vn->co[2])/2;
-                                                       eve= addvertlist(vec);
-                                                       eve->f |= flag;
-                                                       /*New faces*/
-                                                       addface_subdiv(efa, 1, 11, 3+4, 4, eve, &efapin);
-                                                       addface_subdiv(efa, 1, 2, 2+4, 11, eve, &efapin);
-                                                       /* orig face becomes small corner */
-                                                       efa->v1=e2->vn;
-                                                       efa->v2=efa->v3;
-                                                       efa->v3=e3->vn;
-                                                       efa->v4=eve;
-
-                                                       set_wuv(4, efa, 2+4, 3, 3+4, 11, &efapin);
-                                               }
-                                               else if(test==12) { /* 3&4 */
-                                                       /* make new vert in center of new edge */
-                                                       vec[0]=(e3->vn->co[0]+e4->vn->co[0])/2;
-                                                       vec[1]=(e3->vn->co[1]+e4->vn->co[1])/2;
-                                                       vec[2]=(e3->vn->co[2]+e4->vn->co[2])/2;
-                                                       eve= addvertlist(vec);
-                                                       eve->f |= flag;
-                                                       /*New Faces*/
-                                                       addface_subdiv(efa, 2, 12, 4+4, 1, eve, &efapin);
-                                                       addface_subdiv(efa, 2, 3, 3+4, 12, eve, &efapin);
-                                                       /* orig face becomes small corner */
-                                                       efa->v1=e3->vn;
-                                                       efa->v2=efa->v4;
-                                                       efa->v3=e4->vn;
-                                                       efa->v4=eve;
-
-                                                       set_wuv(4, efa, 3+4, 4, 4+4, 12, &efapin);
-                                               }
-                                               else if(test==9) { /* 4&1 */
-                                                       /* make new vert in center of new edge */
-                                                       vec[0]=(e1->vn->co[0]+e4->vn->co[0])/2;
-                                                       vec[1]=(e1->vn->co[1]+e4->vn->co[1])/2;
-                                                       vec[2]=(e1->vn->co[2]+e4->vn->co[2])/2;
-                                                       eve= addvertlist(vec);
-                                                       eve->f |= flag;
-                                                       /*New Faces*/
-                                                       addface_subdiv(efa, 3, 13, 1+4, 2, eve, &efapin);
-                                                       addface_subdiv(efa, 3, 4,  4+4,13, eve, &efapin);
-                                                       /* orig face becomes small corner */
-                                                       efa->v2=efa->v1;
-                                                       efa->v1=e4->vn;
-                                                       efa->v3=e1->vn;
-                                                       efa->v4=eve;
-
-                                                       set_wuv(4, efa, 4+4, 1, 1+4, 13, &efapin);
-                                               }
-                                               else if(test==5) { /* 1&3 */
-                                                       addface_subdiv(efa, 1+4, 2, 3, 3+4, 0, &efapin);
-                                                       efa->v2= e1->vn;
-                                                       efa->v3= e3->vn;
-                                                       set_wuv(4, efa, 1, 1+4, 3+4, 4, &efapin);
-                                               }
-                                               else if(test==10) { /* 2&4 */
-                                                       addface_subdiv(efa, 2+4, 3, 4, 4+4, 0, &efapin);
-                                                       efa->v3= e2->vn;
-                                                       efa->v4= e4->vn;
-                                                       set_wuv(4, efa, 1, 2, 2+4, 4+4, &efapin);
-                                               }/* Unfortunately, there is no way to avoid tris on 1 or 3 edges*/
-                                               else if(test==7) { /*1,2&3 */
-                                                       addface_subdiv(efa, 1+4, 2+4, 3+4, 0, 0, &efapin);
-                                                       efa->v2= e1->vn;
-                                                       efa->v3= e3->vn;
-                                                       set_wuv(4, efa, 1, 1+4, 3+4, 4, &efapin);
-                                               }
-                                               
-                                               else if(test==14) { /* 2,3&4 */
-                                                       addface_subdiv(efa, 2+4, 3+4, 4+4, 0, 0, &efapin);
-                                                       efa->v3= e2->vn;
-                                                       efa->v4= e4->vn;
-                                                       set_wuv(4, efa, 1, 2, 2+4, 4+4, &efapin);
-                                               }
-                                               else if(test==13) {/* 1,3&4 */
-                                                       addface_subdiv(efa, 3+4, 4+4, 1+4, 0, 0, &efapin);
-                                                       efa->v4= e3->vn;
-                                                       efa->v1= e1->vn;
-                                                       set_wuv(4, efa, 1+4, 3, 3, 3+4, &efapin);
-                                               }
-                                               else if(test==11) { /* 1,2,&4 */
-                                                       addface_subdiv(efa, 4+4, 1+4, 2+4, 0, 0, &efapin);
-                                                       efa->v1= e4->vn;
-                                                       efa->v2= e2->vn;
-                                                       set_wuv(4, efa, 4+4, 2+4, 3, 4, &efapin);
-                                               }
-                                       }
-                                       efa->e1= addedgelist(efa->v1, efa->v2, NULL);
-                                       efa->e2= addedgelist(efa->v2, efa->v3, NULL);
-                                       if(efa->v4) efa->e3= addedgelist(efa->v3, efa->v4, NULL);
-                                       else efa->e3= addedgelist(efa->v3, efa->v1, NULL);
-                                       if(efa->v4) efa->e4= addedgelist(efa->v4, efa->v1, NULL);
-                                       else efa->e4= NULL;
-                               }
-                       }
-               }
-               efa= efa->prev;
-       }
-
-       /* remove all old edges, if needed make new ones */
-       eed= em->edges.first;
-       while(eed) {
-               nexted= eed->next;
-               if( eed->vn ) {
-                       eed->vn->f |= 16;                       
-                       if(eed->f==0) {  /* not used in face */                         
-                               addedgelist(eed->v1, eed->vn, eed);
-                               addedgelist(eed->vn, eed->v2, eed);
-                       }                                               
-                       remedge(eed);
-                       free_editedge(eed);
-               }
-               eed= nexted;
-       }
-       countall();
-       allqueue(REDRAWVIEW3D, 0);
-       makeDispList(G.obedit);
-}
-
-void adduplicateflag(int flag)
-{
-       EditMesh *em = G.editMesh;
-       /* old verts have flag 128 set, and flag 'flag' cleared
-          new verts have flag 'flag' set */
-       EditVert *eve, *v1, *v2, *v3, *v4;
-       EditEdge *eed;
-       EditFace *efa;
-
-       /* vertices first */
-       eve= em->verts.last;
-       while(eve) {
-               eve->f&= ~128;
-               if(eve->f & flag) {
-                       v1= addvertlist(eve->co);
-                       v1->f= eve->f;
-                       eve->f-= flag;
-                       eve->f|= 128;
-                       eve->vn= v1;
-#ifdef __NLA
-                       /* >>>>> FIXME: Copy deformation weight ? */
-                       v1->totweight = eve->totweight;
-                       if (eve->totweight){
-                               v1->dw = MEM_mallocN (eve->totweight * sizeof(MDeformWeight), "deformWeight");
-                               memcpy (v1->dw, eve->dw, eve->totweight * sizeof(MDeformWeight));
-                       }
-                       else
-                               v1->dw=NULL;
-#endif
-               }
-               eve= eve->prev;
-       }
-       eed= em->edges.first;
-       while(eed) {
-               if( (eed->v1->f & 128) && (eed->v2->f & 128) ) {
-                       v1= eed->v1->vn;
-                       v2= eed->v2->vn;
-                       addedgelist(v1, v2, eed);
-               }
-               eed= eed->next;
-       }
-
-       /* then dupicate faces */
-       efa= em->faces.first;
-       while(efa) {
-               if( (efa->v1->f & 128) && (efa->v2->f & 128) && (efa->v3->f & 128) ) {
-                       if(efa->v4) {
-                               if(efa->v4->f & 128) {
-                                       v1= efa->v1->vn;
-                                       v2= efa->v2->vn;
-                                       v3= efa->v3->vn;
-                                       v4= efa->v4->vn;
-                                       addfacelist(v1, v2, v3, v4, efa);
-                               }
-                       }
-                       else {
-                               v1= efa->v1->vn;
-                               v2= efa->v2->vn;
-                               v3= efa->v3->vn;
-                               addfacelist(v1, v2, v3, 0, efa);
-                       }
-               }
-               efa= efa->next;
-       }
-}
-
-static void delfaceflag(int flag)
-{
-       EditMesh *em = G.editMesh;
-       /* delete all faces with 'flag', including edges and loose vertices */
-       /* in vertices the 'flag' is cleared */
-       EditVert *eve,*nextve;
-       EditEdge *eed, *nexted;
-       EditFace *efa,*nextvl;
-
-       eed= em->edges.first;
-       while(eed) {
-               eed->f= 0;
-               eed= eed->next;
-       }
-
-       efa= em->faces.first;
-       while(efa) {
-               nextvl= efa->next;
-               if(faceselectedAND(efa, flag)) {
-                       
-                       efa->e1->f= 1;
-                       efa->e2->f= 1;
-                       efa->e3->f= 1;
-                       if(efa->e4) {
-                               efa->e4->f= 1;
-                       }
-                                                               
-                       BLI_remlink(&em->faces, efa);
-                       free_editface(efa);
-               }
-               efa= nextvl;
-       }
-       /* all faces with 1, 2 (3) vertices selected: make sure we keep the edges */
-       efa= em->faces.first;
-       while(efa) {
-               efa->e1->f= 0;
-               efa->e2->f= 0;
-               efa->e3->f= 0;
-               if(efa->e4) {
-                       efa->e4->f= 0;
-               }
-
-               efa= efa->next;
-       }
-       
-       /* test all edges for vertices with 'flag', and clear */
-       eed= em->edges.first;
-       while(eed) {
-               nexted= eed->next;
-               if(eed->f==1) {
-                       remedge(eed);
-                       free_editedge(eed);
-               }
-               else if( (eed->v1->f & flag) || (eed->v2->f & flag) ) {
-                       eed->v1->f&= ~flag;
-                       eed->v2->f&= ~flag;
-               }
-               eed= nexted;
-       }
-       /* vertices with 'flag' now are the loose ones, and will be removed */
-       eve= em->verts.first;
-       while(eve) {
-               nextve= eve->next;
-               if(eve->f & flag) {
-                       BLI_remlink(&em->verts, eve);
-                       free_editvert(eve);
-               }
-               eve= nextve;
-       }
-
-}
-
-void extrude_mesh(void)
-{
-       short a;
-
-       TEST_EDITMESH
-
-       if(okee("Extrude")==0) return;
-       
-       waitcursor(1);
-       undo_push_mesh("Extrude");
-       
-       a= extrudeflag(1,1);
-       waitcursor(0);
-       if(a==0) {
-               error("No valid vertices are selected");
-       }
-       else {
-               countall();  /* for G.totvert in calc_meshverts() */
-               calc_meshverts();
-               transform('d');
-               G.undo_edit_level--;    /* to hide the transform from undo */
-       }
-
-}
-
-void adduplicate_mesh(void)
-{
-
-       TEST_EDITMESH
-
-       waitcursor(1);
-       undo_push_mesh("Duplicate");
-       adduplicateflag(1);
-       waitcursor(0);
-       countall();  /* for G.totvert in calc_meshverts() */
-       transform('d');
-}
-
-void split_mesh(void)
-{
-
-       TEST_EDITMESH
-
-       if(okee(" Split ")==0) return;
-
-       waitcursor(1);
-       undo_push_mesh("Split");
-       /* make duplicate first */
-       adduplicateflag(1);
-       /* old faces have 3x flag 128 set, delete them */
-       delfaceflag(128);
-
-       waitcursor(0);
-
-       countall();
-       allqueue(REDRAWVIEW3D, 0);
-       makeDispList(G.obedit);
-}
-
-
-void separatemenu(void)
-{
-       short event;
-
-       event = pupmenu("Separate (No undo!) %t|Selected%x1|All Loose Parts%x2");
-       
-       if (event==0) return;
-       waitcursor(1);
-       
-       switch (event) {
-
-               case 1: 
-                       separate_mesh();                    
-                       break;
-               case 2:                     
-                       separate_mesh_loose();              
-                       break;
-       }
-       waitcursor(0);
-}
-
-
-void separate_mesh(void)
-{
-       EditMesh *em = G.editMesh;
-       EditVert *eve, *v1;
-       EditEdge *eed, *e1;
-       EditFace *efa, *vl1;
-       Object *oldob;
-       Mesh *me, *men;
-       Base *base, *oldbase;
-       ListBase edve, eded, edvl;
-       float trans[9];
-       int ok, flag;
-       
-       TEST_EDITMESH   
-
-       waitcursor(1);
-       
-       me= get_mesh(G.obedit);
-       if(me->key) {
-               error("Can't separate with vertex keys");
-               return;
-       }
-       
-       /* we are going to abuse the system as follows:
-        * 1. add a duplicate object: this will be the new one, we remember old pointer
-        * 2: then do a split if needed.
-        * 3. put apart: all NOT selected verts, edges, faces
-        * 4. call loadobeditdata(): this will be the new object
-        * 5. freelist and get back old verts, edges, facs
-        */
-       
-       /* make only obedit selected */
-       base= FIRSTBASE;
-       while(base) {
-               if(base->lay & G.vd->lay) {
-                       if(base->object==G.obedit) base->flag |= SELECT;
-                       else base->flag &= ~SELECT;
-               }
-               base= base->next;
-       }
-       
-       /* testen for split */
-       ok= 0;
-       eed= em->edges.first;
-       while(eed) {
-               flag= (eed->v1->f & 1)+(eed->v2->f & 1);
-               if(flag==1) {
-                       ok= 1;
-                       break;
-               }
-               eed= eed->next;
-       }
-       if(ok) {
-               /* SPLIT: first make duplicate */
-               adduplicateflag(1);
-               /* SPLIT: old faces have 3x flag 128 set, delete these ones */
-               delfaceflag(128);
-       }
-       
-       /* set apart: everything that is not selected */
-       edve.first= edve.last= eded.first= eded.last= edvl.first= edvl.last= 0;
-       eve= em->verts.first;
-       while(eve) {
-               v1= eve->next;
-               if((eve->f & 1)==0) {
-                       BLI_remlink(&em->verts, eve);
-                       BLI_addtail(&edve, eve);
-               }
-               eve= v1;
-       }
-       eed= em->edges.first;
-       while(eed) {
-               e1= eed->next;
-               if( (eed->v1->f & 1)==0 || (eed->v2->f & 1)==0 ) {
-                       BLI_remlink(&em->edges, eed);
-                       BLI_addtail(&eded, eed);
-               }
-               eed= e1;
-       }
-       efa= em->faces.first;
-       while(efa) {
-               vl1= efa->next;
-               if( (efa->v1->f & 1)==0 || (efa->v2->f & 1)==0 || (efa->v3->f & 1)==0 ) {
-                       BLI_remlink(&em->faces, efa);
-                       BLI_addtail(&edvl, efa);
-               }
-               efa= vl1;
-       }
-       
-       oldob= G.obedit;
-       oldbase= BASACT;
-       
-       trans[0]=trans[1]=trans[2]=trans[3]=trans[4]=trans[5]= 0.0;
-       trans[6]=trans[7]=trans[8]= 1.0;
-       G.qual |= LR_ALTKEY;    /* patch to make sure we get a linked duplicate */
-       adduplicate(trans);
-       G.qual &= ~LR_ALTKEY;
-       
-       G.obedit= BASACT->object;       /* basact was set in adduplicate()  */
-
-       men= copy_mesh(me);
-       set_mesh(G.obedit, men);
-       /* because new mesh is a copy: reduce user count */
-       men->id.us--;
-       
-       load_editMesh();
-       
-       BASACT->flag &= ~SELECT;
-       
-       makeDispList(G.obedit);
-       free_editMesh();
-       
-       em->verts= edve;
-       em->edges= eded;
-       em->faces= edvl;
-       
-       /* hashedges are freed now, make new! */
-       eed= em->edges.first;
-       while(eed) {
-               if( findedgelist(eed->v1, eed->v2)==NULL )
-                       insert_hashedge(eed);
-               eed= eed->next;
-       }
-       
-       G.obedit= oldob;
-       BASACT= oldbase;
-       BASACT->flag |= SELECT;
-       
-       waitcursor(0);
-
-       countall();
-       allqueue(REDRAWVIEW3D, 0);
-       makeDispList(G.obedit);
-
-}
-
-void separate_mesh_loose(void)
-{
-       EditMesh *em = G.editMesh;
-       EditVert *eve, *v1;
-       EditEdge *eed, *e1;
-       EditFace *efa, *vl1;
-       Object *oldob;
-       Mesh *me, *men;
-       Base *base, *oldbase;
-       ListBase edve, eded, edvl;
-       float trans[9];
-       int ok, vertsep=0, flag;        
-       short done=0, check=1;
-               
-       TEST_EDITMESH
-       waitcursor(1);  
-       
-       /* we are going to abuse the system as follows:
-        * 1. add a duplicate object: this will be the new one, we remember old pointer
-        * 2: then do a split if needed.
-        * 3. put apart: all NOT selected verts, edges, faces
-        * 4. call loadobeditdata(): this will be the new object
-        * 5. freelist and get back old verts, edges, facs
-        */
-                       
-       
-                       
-       while(!done){           
-               vertsep=check=1;
-               
-               countall();
-               
-               me= get_mesh(G.obedit);
-               if(me->key) {
-                       error("Can't separate a mesh with vertex keys");
-                       return;
-               }               
-               
-               /* make only obedit selected */
-               base= FIRSTBASE;
-               while(base) {
-                       if(base->lay & G.vd->lay) {
-                               if(base->object==G.obedit) base->flag |= SELECT;
-                               else base->flag &= ~SELECT;
-                       }
-                       base= base->next;
-               }               
-               
-               /*--------- Select connected-----------*/               
-               //sel= 3;
-               /* clear test flags */
-               eve= em->verts.first;
-               while(eve) {
-                       eve->f&= ~1;                    
-                       eve= eve->next;
-               }
-               
-               /* Select a random vert to start with */
-               eve= em->verts.first;
-               eve->f |= 1;
-               
-               while(check==1) {
-                       check= 0;                       
-                       eed= em->edges.first;                   
-                       while(eed) {                            
-                               if(eed->h==0) {
-                                       if(eed->v1->f & 1) {
-                                               if( (eed->v2->f & 1)==0 ) {
-                                                       eed->v2->f |= 1;
-                                                       vertsep++;
-                                                       check= 1;
-                                               }
-                                       }
-                                       else if(eed->v2->f & 1) {
-                                               if( (eed->v1->f & 1)==0 ) {
-                                                       eed->v1->f |= 1;
-                                                       vertsep++;
-                                                       check= 1;
-                                               }
-                                       }
-                               }
-                               eed= eed->next;                         
-                       }
-               }               
-               /*----------End of select connected--------*/
-               
-               
-               /* If the amount of vertices that is about to be split == the total amount 
-                  of verts in the mesh, it means that there is only 1 unconnected object, so we don't have to separate
-               */
-               if(G.totvert==vertsep)done=1;                           
-               else{                   
-                       /* Test for splitting: Separate selected */
-                       ok= 0;
-                       eed= em->edges.first;
-                       while(eed) {
-                               flag= (eed->v1->f & 1)+(eed->v2->f & 1);
-                               if(flag==1) {
-                                       ok= 1;
-                                       break;
-                               }
-                               eed= eed->next;
-                       }
-                       if(ok) {
-                               /* SPLIT: first make duplicate */
-                               adduplicateflag(1);
-                               /* SPLIT: old faces have 3x flag 128 set, delete these ones */
-                               delfaceflag(128);
-                       }       
-                       
-                       
-                       
-                       /* set apart: everything that is not selected */
-                       edve.first= edve.last= eded.first= eded.last= edvl.first= edvl.last= 0;
-                       eve= em->verts.first;
-                       while(eve) {
-                               v1= eve->next;
-                               if((eve->f & 1)==0) {
-                                       BLI_remlink(&em->verts, eve);
-                                       BLI_addtail(&edve, eve);
-                               }
-                               eve= v1;
-                       }
-                       eed= em->edges.first;
-                       while(eed) {
-                               e1= eed->next;
-                               if( (eed->v1->f & 1)==0 || (eed->v2->f & 1)==0 ) {
-                                       BLI_remlink(&em->edges, eed);
-                                       BLI_addtail(&eded, eed);
-                               }
-                               eed= e1;
-                       }
-                       efa= em->faces.first;
-                       while(efa) {
-                               vl1= efa->next;
-                               if( (efa->v1->f & 1)==0 || (efa->v2->f & 1)==0 || (efa->v3->f & 1)==0 ) {
-                                       BLI_remlink(&em->faces, efa);
-                                       BLI_addtail(&edvl, efa);
-                               }
-                               efa= vl1;
-                       }
-                       
-                       oldob= G.obedit;
-                       oldbase= BASACT;
-                       
-                       trans[0]=trans[1]=trans[2]=trans[3]=trans[4]=trans[5]= 0.0;
-                       trans[6]=trans[7]=trans[8]= 1.0;
-                       G.qual |= LR_ALTKEY;    /* patch to make sure we get a linked duplicate */
-                       adduplicate(trans);
-                       G.qual &= ~LR_ALTKEY;
-                       
-                       G.obedit= BASACT->object;       /* basact was set in adduplicate()  */
-               
-                       men= copy_mesh(me);
-                       set_mesh(G.obedit, men);
-                       /* because new mesh is a copy: reduce user count */
-                       men->id.us--;
-                       
-                       load_editMesh();
-                       
-                       BASACT->flag &= ~SELECT;
-                       
-                       makeDispList(G.obedit);
-                       free_editMesh();
-                       
-                       em->verts= edve;
-                       em->edges= eded;
-                       em->faces= edvl;
-                       
-                       /* hashedges are freed now, make new! */
-                       eed= em->edges.first;
-                       while(eed) {
-                               if( findedgelist(eed->v1, eed->v2)==NULL )
-                                       insert_hashedge(eed);
-                               eed= eed->next;
-                       }
-                       
-                       G.obedit= oldob;
-                       BASACT= oldbase;
-                       BASACT->flag |= SELECT; 
-                                       
-               }               
-       }
-       
-       /* unselect the vertices that we (ab)used for the separation*/
-       eve= em->verts.first;
-       while(eve) {
-               eve->f&= ~1;                    
-               eve= eve->next;
-       }
-       
-       waitcursor(0);
-       countall();
-       allqueue(REDRAWVIEW3D, 0);
-       makeDispList(G.obedit); 
-}
-
-
-void extrude_repeat_mesh(int steps, float offs)
-{
-       float dvec[3], tmat[3][3], bmat[3][3];
-       short a,ok;
-
-       TEST_EDITMESH
-       waitcursor(1);
-       
-       undo_push_mesh("Extrude Repeat");
-
-       /* dvec */
-       dvec[0]= G.vd->persinv[2][0];
-       dvec[1]= G.vd->persinv[2][1];
-       dvec[2]= G.vd->persinv[2][2];
-       Normalise(dvec);
-       dvec[0]*= offs;
-       dvec[1]*= offs;
-       dvec[2]*= offs;
-
-       /* base correction */
-       Mat3CpyMat4(bmat, G.obedit->obmat);
-       Mat3Inv(tmat, bmat);
-       Mat3MulVecfl(tmat, dvec);
-
-       for(a=0;a<steps;a++) {
-               ok= extrudeflag(1,1);
-               if(ok==0) {
-                       error("No valid vertices are selected");
-                       break;
-               }
-               translateflag(1, dvec);
-       }
-
-       countall();
-       allqueue(REDRAWVIEW3D, 0);
-       makeDispList(G.obedit);
-       waitcursor(0);
-}
-
-void spin_mesh(int steps,int degr,float *dvec, int mode)
-{
-       EditMesh *em = G.editMesh;
-       EditVert *eve,*nextve;
-       float *curs, si,n[3],q[4],cmat[3][3],imat[3][3], tmat[3][3];
-       float cent[3],bmat[3][3];
-       float phi;
-       short a,ok;
-
-       TEST_EDITMESH
-       
-       waitcursor(1);
-       
-       undo_push_mesh("Spin");
-
-       /* imat and centre and size */
-       Mat3CpyMat4(bmat, G.obedit->obmat);
-       Mat3Inv(imat,bmat);
-
-       curs= give_cursor();
-       VECCOPY(cent, curs);
-       cent[0]-= G.obedit->obmat[3][0];
-       cent[1]-= G.obedit->obmat[3][1];
-       cent[2]-= G.obedit->obmat[3][2];
-       Mat3MulVecfl(imat, cent);
-
-       phi= degr*M_PI/360.0;
-       phi/= steps;
-       if(editbutflag & B_CLOCKWISE) phi= -phi;
-
-       if(dvec) {
-               n[0]=n[1]= 0.0;
-               n[2]= 1.0;
-       } else {
-               n[0]= G.vd->viewinv[2][0];
-               n[1]= G.vd->viewinv[2][1];
-               n[2]= G.vd->viewinv[2][2];
-               Normalise(n);
-       }
-
-       q[0]= cos(phi);
-       si= sin(phi);
-       q[1]= n[0]*si;
-       q[2]= n[1]*si;
-       q[3]= n[2]*si;
-       QuatToMat3(q, cmat);
-
-       Mat3MulMat3(tmat,cmat,bmat);
-       Mat3MulMat3(bmat,imat,tmat);
-
-       if(mode==0) if(editbutflag & B_KEEPORIG) adduplicateflag(1);
-       ok= 1;
-
-       for(a=0;a<steps;a++) {
-               if(mode==0) ok= extrudeflag(1,1);
-               else adduplicateflag(1);
-               if(ok==0) {
-                       error("No valid vertices are selected");
-                       break;
-               }
-               rotateflag(1, cent, bmat);
-               if(dvec) {
-                       Mat3MulVecfl(bmat,dvec);
-                       translateflag(1,dvec);
-               }
-       }
-
-       waitcursor(0);
-       if(ok==0) {
-               /* no vertices or only loose ones selected, remove duplicates */
-               eve= em->verts.first;
-               while(eve) {
-                       nextve= eve->next;
-                       if(eve->f & 1) {
-                               BLI_remlink(&em->verts,eve);
-                               free_editvert(eve);
-                       }
-                       eve= nextve;
-               }
-       }
-       countall();
-       recalc_editnormals();
-       allqueue(REDRAWVIEW3D, 0);
-       makeDispList(G.obedit);
-}
-
-void screw_mesh(int steps,int turns)
-{
-       EditMesh *em = G.editMesh;
-       EditVert *eve,*v1=0,*v2=0;
-       EditEdge *eed;
-       float dvec[3], nor[3];
-
-       TEST_EDITMESH
-
-       /* first condition: we need frontview! */
-       if(G.vd->view!=1) {
-               error("Must be in Front View");
-               return;
-       }
-       
-       undo_push_mesh("Screw");
-       
-       /* clear flags */
-       eve= em->verts.first;
-       while(eve) {
-               eve->f1= 0;
-               eve= eve->next;
-       }
-       /* edges set flags in verts */
-       eed= em->edges.first;
-       while(eed) {
-               if(eed->v1->f & 1) {
-                       if(eed->v2->f & 1) {
-                               /* watch: f1 is a byte */
-                               if(eed->v1->f1<2) eed->v1->f1++;
-                               if(eed->v2->f1<2) eed->v2->f1++;
-                       }
-               }
-               eed= eed->next;
-       }
-       /* find two vertices with eve->f1==1, more or less is wrong */
-       eve= em->verts.first;
-       while(eve) {
-               if(eve->f1==1) {
-                       if(v1==0) v1= eve;
-                       else if(v2==0) v2= eve;
-                       else {
-                               v1=0;
-            &n