merge with trunk at r31523
[blender.git] / source / blender / editors / mesh / loopcut.c
index 488b59fa29ea1b43a990808f812d4aa6ec19a250..68ef56ad3ab87cb37c18412bbd955863af995660 100644 (file)
@@ -15,7 +15,7 @@
  *
  * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
  * The Original Code is Copyright (C) 2007 Blender Foundation.
  * All rights reserved.
@@ -27,6 +27,8 @@
  */
 
 #include <float.h>
+#define _USE_MATH_DEFINES
+#include <math.h>
 #include <string.h>
 #include <ctype.h>
 #include <stdio.h>
 #include "BLI_blenlib.h"
 #include "BLI_dynstr.h" /*for WM_operator_pystring */
 #include "BLI_editVert.h"
-#include "BLI_math.h"
+#include "BLI_array.h"
 
 #include "BKE_blender.h"
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
 #include "BKE_scene.h"
 #include "BKE_mesh.h"
+#include "BKE_tessmesh.h"
+#include "BKE_depsgraph.h"
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h" /* for paint cursor */
@@ -86,8 +90,8 @@ typedef struct tringselOpData {
        ViewContext vc;
 
        Object *ob;
-       EditMesh *em;
-       EditEdge *eed;
+       BMEditMesh *em;
+       BMEdge *eed;
 
        int extend;
        int do_cut;
@@ -118,17 +122,60 @@ static void ringsel_draw(const bContext *C, ARegion *ar, void *arg)
        }
 }
 
+/*given two opposite edges in a face, finds the ordering of their vertices so
+  that cut preview lines won't cross each other*/
+static void edgering_find_order(BMEditMesh *em, BMEdge *lasteed, BMEdge *eed, 
+                                BMVert *lastv1, BMVert *v[2][2])
+{
+       BMIter liter;
+       BMLoop *l, *l2;
+       int rev;
+
+       l = eed->l;
+
+       /*find correct order for v[1]*/
+       if (!(BM_Edge_In_Face(l->f, eed) && BM_Edge_In_Face(l->f, lasteed))) {
+               BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_LOOP, l) {
+                       if (BM_Edge_In_Face(l->f, eed) && BM_Edge_In_Face(l->f, lasteed))
+                               break;
+               }
+       }
+       
+       /*this should never happen*/
+       if (!l) {
+               v[0][0] = eed->v1;
+               v[0][1] = eed->v2;
+               v[1][0] = lasteed->v1;
+               v[1][1] = lasteed->v2;
+               return;
+       }
+       
+       l2 = BM_OtherFaceLoop(l->e, l->f, eed->v1);
+       rev = (l2 == (BMLoop*)l->prev);
+       while (l2->v != lasteed->v1 && l2->v != lasteed->v2) {
+               l2 = rev ? (BMLoop*)l2->prev : (BMLoop*)l2->next;
+       }
+
+       if (l2->v == lastv1) {
+               v[0][0] = eed->v1;
+               v[0][1] = eed->v2;
+       } else {
+               v[0][0] = eed->v2;
+               v[0][1] = eed->v1;
+       }
+}
+
 static void edgering_sel(tringselOpData *lcd, int previewlines, int select)
 {
-       EditMesh *em = lcd->em;
-       EditEdge *startedge = lcd->eed;
-       EditEdge *eed;
-       EditFace *efa;
-       EditVert *v[2][2];
+       BMEditMesh *em = lcd->em;
+       BMEdge *startedge = lcd->eed;
+       BMEdge *eed, *lasteed;
+       BMVert *v[2][2], *lastv1;
+       BMWalker walker;
        float (*edges)[2][3] = NULL;
-       V_DYNDECLARE(edges);
+       BLI_array_declare(edges);
        float co[2][3];
-       int looking=1, i, tot=0;
+       int i, tot=0;
        
        if (!startedge)
                return;
@@ -140,110 +187,75 @@ static void edgering_sel(tringselOpData *lcd, int previewlines, int select)
        }
 
        if (!lcd->extend) {
-               EM_clear_flag_all(lcd->em, SELECT);
+               EDBM_clear_flag_all(lcd->em, BM_SELECT);
        }
 
-       /* in eed->f1 we put the valence (amount of faces in edge) */
-       /* in eed->f2 we put tagged flag as correct loop */
-       /* in efa->f1 we put tagged flag as correct to select */
+       if (select) {
+               BMW_Init(&walker, em->bm, BMW_EDGERING, 0, 0);
+               eed = BMW_Begin(&walker, startedge);
+               for (; eed; eed=BMW_Step(&walker)) {
+                       BM_Select(em->bm, eed, 1);
+               }
+               BMW_End(&walker);
 
-       for(eed= em->edges.first; eed; eed= eed->next) {
-               eed->f1= 0;
-               eed->f2= 0;
+               return;
        }
 
-       for(efa= em->faces.first; efa; efa= efa->next) {
-               efa->f1= 0;
-               if(efa->h==0) {
-                       efa->e1->f1++;
-                       efa->e2->f1++;
-                       efa->e3->f1++;
-                       if(efa->e4) efa->e4->f1++;
-               }
-       }
-       
-       // tag startedge OK
-       startedge->f2= 1;
-       
-       while(looking) {
-               looking= 0;
-               
-               for(efa= em->faces.first; efa; efa= efa->next) {
-                       if(efa->e4 && efa->f1==0 && efa->h == 0) {      // not done quad
-                               if(efa->e1->f1<=2 && efa->e2->f1<=2 && efa->e3->f1<=2 && efa->e4->f1<=2) { // valence ok
-
-                                       // if edge tagged, select opposing edge and mark face ok
-                                       if(efa->e1->f2) {
-                                               efa->e3->f2= 1;
-                                               efa->f1= 1;
-                                               looking= 1;
-                                       }
-                                       else if(efa->e2->f2) {
-                                               efa->e4->f2= 1;
-                                               efa->f1= 1;
-                                               looking= 1;
-                                       }
-                                       if(efa->e3->f2) {
-                                               efa->e1->f2= 1;
-                                               efa->f1= 1;
-                                               looking= 1;
-                                       }
-                                       if(efa->e4->f2) {
-                                               efa->e2->f2= 1;
-                                               efa->f1= 1;
-                                               looking= 1;
-                                       }
-                               }
+       BMW_Init(&walker, em->bm, BMW_EDGERING, 0, 0);
+       eed = startedge = BMW_Begin(&walker, startedge);
+       lastv1 = NULL;
+       for (lasteed=NULL; eed; eed=BMW_Step(&walker)) {
+               if (lasteed) {
+                       if (lastv1) {
+                               v[1][0] = v[0][0];
+                               v[1][1] = v[0][1];
+                       } else {
+                               v[1][0] = lasteed->v1;
+                               v[1][1] = lasteed->v2;
+                               lastv1 = lasteed->v1;
+                       }
+
+                       edgering_find_order(em, lasteed, eed, lastv1, v);
+                       lastv1 = v[0][0];
+
+                       for(i=1;i<=previewlines;i++){
+                               co[0][0] = (v[0][1]->co[0] - v[0][0]->co[0])*(i/((float)previewlines+1))+v[0][0]->co[0];
+                               co[0][1] = (v[0][1]->co[1] - v[0][0]->co[1])*(i/((float)previewlines+1))+v[0][0]->co[1];
+                               co[0][2] = (v[0][1]->co[2] - v[0][0]->co[2])*(i/((float)previewlines+1))+v[0][0]->co[2];
+
+                               co[1][0] = (v[1][1]->co[0] - v[1][0]->co[0])*(i/((float)previewlines+1))+v[1][0]->co[0];
+                               co[1][1] = (v[1][1]->co[1] - v[1][0]->co[1])*(i/((float)previewlines+1))+v[1][0]->co[1];
+                               co[1][2] = (v[1][1]->co[2] - v[1][0]->co[2])*(i/((float)previewlines+1))+v[1][0]->co[2];                                        
+                               
+                               BLI_array_growone(edges);
+                               VECCOPY(edges[tot][0], co[0]);
+                               VECCOPY(edges[tot][1], co[1]);
+                               tot++;
                        }
                }
+               lasteed = eed;
        }
        
-       if(previewlines > 0 && !select){
-                       for(efa= em->faces.first; efa; efa= efa->next) {
-                               if(efa->v4 == NULL) {  continue; }
-                               if(efa->h == 0){
-                                       if(efa->e1->f2 == 1){
-                                               if(efa->e1->h == 1 || efa->e3->h == 1 )
-                                                       continue;
-                                               
-                                               v[0][0] = efa->v1;
-                                               v[0][1] = efa->v2;
-                                               v[1][0] = efa->v4;
-                                               v[1][1] = efa->v3;
-                                       } else if(efa->e2->f2 == 1){
-                                               if(efa->e2->h == 1 || efa->e4->h == 1)
-                                                       continue;
-                                               v[0][0] = efa->v2;
-                                               v[0][1] = efa->v3;
-                                               v[1][0] = efa->v1;
-                                               v[1][1] = efa->v4;                                      
-                                       } else { continue; }
-                                                                                 
-                                       for(i=1;i<=previewlines;i++){
-                                               co[0][0] = (v[0][1]->co[0] - v[0][0]->co[0])*(i/((float)previewlines+1))+v[0][0]->co[0];
-                                               co[0][1] = (v[0][1]->co[1] - v[0][0]->co[1])*(i/((float)previewlines+1))+v[0][0]->co[1];
-                                               co[0][2] = (v[0][1]->co[2] - v[0][0]->co[2])*(i/((float)previewlines+1))+v[0][0]->co[2];
-
-                                               co[1][0] = (v[1][1]->co[0] - v[1][0]->co[0])*(i/((float)previewlines+1))+v[1][0]->co[0];
-                                               co[1][1] = (v[1][1]->co[1] - v[1][0]->co[1])*(i/((float)previewlines+1))+v[1][0]->co[1];
-                                               co[1][2] = (v[1][1]->co[2] - v[1][0]->co[2])*(i/((float)previewlines+1))+v[1][0]->co[2];                                        
-                                               
-                                               V_GROW(edges);
-                                               VECCOPY(edges[tot][0], co[0]);
-                                               VECCOPY(edges[tot][1], co[1]);
-                                               tot++;
-                                       }
-                               }
-                       }
-       } else {
-               select = (startedge->f & SELECT) == 0;
+       if (BM_Edge_Share_Faces(lasteed, startedge)) {
+               edgering_find_order(em, lasteed, startedge, lastv1, v);
+
+               for(i=1;i<=previewlines;i++){
+                       co[0][0] = (v[0][1]->co[0] - v[0][0]->co[0])*(i/((float)previewlines+1))+v[0][0]->co[0];
+                       co[0][1] = (v[0][1]->co[1] - v[0][0]->co[1])*(i/((float)previewlines+1))+v[0][0]->co[1];
+                       co[0][2] = (v[0][1]->co[2] - v[0][0]->co[2])*(i/((float)previewlines+1))+v[0][0]->co[2];
 
-               /* select the edges */
-               for(eed= em->edges.first; eed; eed= eed->next) {
-                       if(eed->f2) EM_select_edge(eed, select);
+                       co[1][0] = (v[1][1]->co[0] - v[1][0]->co[0])*(i/((float)previewlines+1))+v[1][0]->co[0];
+                       co[1][1] = (v[1][1]->co[1] - v[1][0]->co[1])*(i/((float)previewlines+1))+v[1][0]->co[1];
+                       co[1][2] = (v[1][1]->co[2] - v[1][0]->co[2])*(i/((float)previewlines+1))+v[1][0]->co[2];                                        
+                       
+                       BLI_array_growone(edges);
+                       VECCOPY(edges[tot][0], co[0]);
+                       VECCOPY(edges[tot][1], co[1]);
+                       tot++;
                }
        }
 
+       BMW_End(&walker);
        lcd->edges = edges;
        lcd->totedge = tot;
 }
@@ -262,14 +274,16 @@ static void ringsel_find_edge(tringselOpData *lcd, const bContext *C, ARegion *a
 static void ringsel_finish(bContext *C, wmOperator *op)
 {
        tringselOpData *lcd= op->customdata;
-       int cuts= (lcd->do_cut)? RNA_int_get(op->ptr,"number_cuts"): 0;
+       int cuts= RNA_int_get(op->ptr, "number_cuts");
 
        if (lcd->eed) {
                edgering_sel(lcd, cuts, 1);
                if (lcd->do_cut) {
-                       EditMesh *em = BKE_mesh_get_editmesh(lcd->ob->data);
-                       esubdivideflag(lcd->ob, em, SELECT, 0.0f, 0.0f, 0, cuts, 0, SUBDIV_SELECT_LOOPCUT);
+                       BMEditMesh *em = lcd->em;
 
+                       BM_esubdivideflag(lcd->ob, em->bm, BM_SELECT, 0.0f, 
+                                         0.0f, 0, cuts, SUBDIV_SELECT_LOOPCUT, 
+                                         SUBD_PATH, 0, 0);
                        /* force edge slide to edge select mode in in face select mode */
                        if (em->selectmode & SCE_SELECT_FACE) {
                                if (em->selectmode == SCE_SELECT_FACE)
@@ -277,16 +291,13 @@ static void ringsel_finish(bContext *C, wmOperator *op)
                                else
                                        em->selectmode &= ~SCE_SELECT_FACE;
                                CTX_data_tool_settings(C)->selectmode= em->selectmode;
-                               EM_selectmode_set(em);
+                               EDBM_selectmode_set(em);
                        }
-                       
+
+                       WM_event_add_notifier(C, NC_GEOM|ND_SELECT|ND_DATA, lcd->ob->data);
                        DAG_id_flush_update(lcd->ob->data, OB_RECALC_DATA);
-                       WM_event_add_notifier(C, NC_GEOM|ND_DATA, lcd->ob->data);
-               }
-               else {
-                       EM_selectmode_flush(lcd->em);
-                       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, lcd->ob->data);
                }
+               WM_event_add_notifier(C, NC_GEOM|ND_DATA, lcd->ob->data);
        }
 }
 
@@ -320,7 +331,7 @@ static int ringsel_init (bContext *C, wmOperator *op, int do_cut)
        lcd->ar= CTX_wm_region(C);
        lcd->draw_handle= ED_region_draw_cb_activate(lcd->ar->type, ringsel_draw, lcd, REGION_DRAW_POST_VIEW);
        lcd->ob = CTX_data_edit_object(C);
-       lcd->em= BKE_mesh_get_editmesh((Mesh *)lcd->ob->data);
+       lcd->em= ((Mesh *)lcd->ob->data)->edit_btmesh;
        lcd->extend = do_cut ? 0 : RNA_boolean_get(op->ptr, "extend");
        lcd->do_cut = do_cut;
        em_setup_viewcontext(C, &lcd->vc);
@@ -330,7 +341,7 @@ static int ringsel_init (bContext *C, wmOperator *op, int do_cut)
        return 1;
 }
 
-static int ringcut_cancel (bContext *C, wmOperator *op)
+static int ringsel_cancel (bContext *C, wmOperator *op)
 {
        /* this is just a wrapper around exit() */
        ringsel_exit(C, op);
@@ -340,44 +351,35 @@ static int ringcut_cancel (bContext *C, wmOperator *op)
 static int ringsel_invoke (bContext *C, wmOperator *op, wmEvent *evt)
 {
        tringselOpData *lcd;
-       EditEdge *edge;
+       BMEdge *edge;
        int dist = 75;
-       
+
        view3d_operator_needs_opengl(C);
 
        if (!ringsel_init(C, op, 0))
                return OPERATOR_CANCELLED;
        
-       lcd = op->customdata;
-       
-       if (lcd->em->selectmode == SCE_SELECT_FACE) {
-               ringsel_exit(C, op);
-               WM_operator_name_call(C, "MESH_OT_loop_select", WM_OP_INVOKE_REGION_WIN, NULL);
-               return OPERATOR_CANCELLED;
-       }
+       /* add a modal handler for this operator - handles loop selection */
+       WM_event_add_modal_handler(C, op);
 
+       lcd = op->customdata;
        lcd->vc.mval[0] = evt->mval[0];
        lcd->vc.mval[1] = evt->mval[1];
        
-       edge = findnearestedge(&lcd->vc, &dist);
-       if(!edge) {
-               ringsel_exit(C, op);
-               return OPERATOR_CANCELLED;
+       edge = EDBM_findnearestedge(&lcd->vc, &dist);
+       if (edge != lcd->eed) {
+               lcd->eed = edge;
+               ringsel_find_edge(lcd, C, lcd->ar, 1);
        }
 
-       lcd->eed = edge;
-       ringsel_find_edge(lcd, C, lcd->ar, 1);
-
-       ringsel_finish(C, op);
-       ringsel_exit(C, op);
-
-       return OPERATOR_FINISHED;
+       return OPERATOR_RUNNING_MODAL;
 }
 
+
 static int ringcut_invoke (bContext *C, wmOperator *op, wmEvent *evt)
 {
        tringselOpData *lcd;
-       EditEdge *edge;
+       BMEdge *edge;
        int dist = 75;
 
        view3d_operator_needs_opengl(C);
@@ -392,7 +394,7 @@ static int ringcut_invoke (bContext *C, wmOperator *op, wmEvent *evt)
        lcd->vc.mval[0] = evt->mval[0];
        lcd->vc.mval[1] = evt->mval[1];
        
-       edge = findnearestedge(&lcd->vc, &dist);
+       edge = EDBM_findnearestedge(&lcd->vc, &dist);
        if (edge != lcd->eed) {
                lcd->eed = edge;
                ringsel_find_edge(lcd, C, lcd->ar, 1);
@@ -401,7 +403,7 @@ static int ringcut_invoke (bContext *C, wmOperator *op, wmEvent *evt)
        return OPERATOR_RUNNING_MODAL;
 }
 
-static int ringcut_modal (bContext *C, wmOperator *op, wmEvent *event)
+static int ringsel_modal (bContext *C, wmOperator *op, wmEvent *event)
 {
        int cuts= RNA_int_get(op->ptr,"number_cuts");
        tringselOpData *lcd= op->customdata;
@@ -410,7 +412,12 @@ static int ringcut_modal (bContext *C, wmOperator *op, wmEvent *event)
 
 
        switch (event->type) {
-               case LEFTMOUSE: /* confirm */ // XXX hardcoded
+               case LEFTMOUSE: /* abort */ // XXX hardcoded
+                       ED_region_tag_redraw(lcd->ar);
+                       ringsel_exit(C, op);
+
+                       return OPERATOR_FINISHED;
+               case RIGHTMOUSE: /* confirm */ // XXX hardcoded
                        if (event->val == KM_PRESS) {
                                /* finish */
                                ED_region_tag_redraw(lcd->ar);
@@ -423,44 +430,104 @@ static int ringcut_modal (bContext *C, wmOperator *op, wmEvent *event)
                        
                        ED_region_tag_redraw(lcd->ar);
                        break;
-               case RIGHTMOUSE: /* abort */ // XXX hardcoded
                case ESCKEY:
                        if (event->val == KM_RELEASE) {
                                /* cancel */
                                ED_region_tag_redraw(lcd->ar);
                                
-                               return ringcut_cancel(C, op);
+                               return ringsel_cancel(C, op);
                        }
                        
                        ED_region_tag_redraw(lcd->ar);
                        break;
-               case WHEELUPMOUSE:  /* change number of cuts */
-               case PAGEUPKEY:
-                       if (event->val == KM_PRESS) {
-                               cuts++;
-                               RNA_int_set(op->ptr, "number_cuts",cuts);
+               case MOUSEMOVE: { /* mouse moved somewhere to select another loop */
+                       int dist = 75;
+                       BMEdge *edge;
+
+                       lcd->vc.mval[0] = event->mval[0];
+                       lcd->vc.mval[1] = event->mval[1];
+                       edge = EDBM_findnearestedge(&lcd->vc, &dist);
+
+                       if (edge != lcd->eed) {
+                               lcd->eed = edge;
                                ringsel_find_edge(lcd, C, lcd->ar, cuts);
-                               
-                               ED_region_tag_redraw(lcd->ar);
                        }
+
+                       ED_region_tag_redraw(lcd->ar);
                        break;
-               case WHEELDOWNMOUSE:  /* change number of cuts */
-               case PAGEDOWNKEY:
-                       if (event->val == KM_PRESS) {
-                               cuts=MAX2(cuts-1,1);
-                               RNA_int_set(op->ptr,"number_cuts",cuts);
-                               ringsel_find_edge(lcd, C, lcd->ar,cuts);
+               }                       
+       }
+       
+       /* keep going until the user confirms */
+       return OPERATOR_RUNNING_MODAL;
+}
+
+static int loopcut_modal (bContext *C, wmOperator *op, wmEvent *event)
+{
+       int cuts= RNA_int_get(op->ptr,"number_cuts");
+       tringselOpData *lcd= op->customdata;
+
+       view3d_operator_needs_opengl(C);
+
+
+       switch (event->type) {
+               case LEFTMOUSE: /* confirm */ // XXX hardcoded
+                       if (event->val == KM_RELEASE) {
+                               /* finish */
+                               ED_region_tag_redraw(lcd->ar);
                                
+                               ringsel_finish(C, op);
+                               ringsel_exit(C, op);
+                               
+                               return OPERATOR_FINISHED;
+                       }
+                       
+                       ED_region_tag_redraw(lcd->ar);
+                       break;
+               case RIGHTMOUSE: /* abort */ // XXX hardcoded
+                       ED_region_tag_redraw(lcd->ar);
+                       ringsel_exit(C, op);
+
+                       return OPERATOR_FINISHED;
+               case ESCKEY:
+                       if (event->val == KM_RELEASE) {
+                               /* cancel */
                                ED_region_tag_redraw(lcd->ar);
+                               
+                               return ringsel_cancel(C, op);
                        }
+                       
+                       ED_region_tag_redraw(lcd->ar);
+                       break;
+               case PAGEUPKEY:
+               case WHEELUPMOUSE:  /* change number of cuts */
+                       if (event->val == KM_RELEASE)
+                               break;
+
+                       cuts++;
+                       RNA_int_set(op->ptr,"number_cuts",cuts);
+                       ringsel_find_edge(lcd, C, lcd->ar, cuts);
+                       
+                       ED_region_tag_redraw(lcd->ar);
+                       break;
+               case PAGEDOWNKEY:
+               case WHEELDOWNMOUSE:  /* change number of cuts */
+                       if (event->val == KM_RELEASE)
+                               break;
+
+                       cuts=MAX2(cuts-1,1);
+                       RNA_int_set(op->ptr,"number_cuts",cuts);
+                       ringsel_find_edge(lcd, C, lcd->ar,cuts);
+                       
+                       ED_region_tag_redraw(lcd->ar);
                        break;
                case MOUSEMOVE: { /* mouse moved somewhere to select another loop */
                        int dist = 75;
-                       EditEdge *edge;
+                       BMEdge *edge;
 
                        lcd->vc.mval[0] = event->mval[0];
                        lcd->vc.mval[1] = event->mval[1];
-                       edge = findnearestedge(&lcd->vc, &dist);
+                       edge = EDBM_findnearestedge(&lcd->vc, &dist);
 
                        if (edge != lcd->eed) {
                                lcd->eed = edge;
@@ -485,10 +552,12 @@ void MESH_OT_edgering_select (wmOperatorType *ot)
        
        /* callbacks */
        ot->invoke= ringsel_invoke;
+       ot->modal= ringsel_modal;
+       ot->cancel= ringsel_cancel;
        ot->poll= ED_operator_editmesh_view3d;
        
        /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
 
        RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection");
 }
@@ -498,12 +567,12 @@ void MESH_OT_loopcut (wmOperatorType *ot)
        /* description */
        ot->name= "Loop Cut";
        ot->idname= "MESH_OT_loopcut";
-       ot->description= "Add a new loop between existing loops";
+       ot->description= "Add a new loop between existing loops.";
        
        /* callbacks */
        ot->invoke= ringcut_invoke;
-       ot->modal= ringcut_modal;
-       ot->cancel= ringcut_cancel;
+       ot->modal= loopcut_modal;
+       ot->cancel= ringsel_cancel;
        ot->poll= ED_operator_editmesh_view3d;
        
        /* flags */