select more/less properly uses bmops now, and also made a little start on documenting...
authorJoseph Eagar <joeedh@gmail.com>
Thu, 6 Aug 2009 05:06:55 +0000 (05:06 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Thu, 6 Aug 2009 05:06:55 +0000 (05:06 +0000)
source/blender/bmesh/intern/bmesh_mods.c
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/intern/bmesh_operators_private.h
source/blender/bmesh/operators/utils.c
source/blender/editors/mesh/bmesh_select.c
source/blender/editors/mesh/bmesh_tools.c
source/blender/editors/mesh/bmeshutils.c

index 9ed868ce8a38206f697e7a6a4e747d4ce4c7ee5e..de63764db437280b5044d5027ce9b077f1f3305b 100644 (file)
@@ -344,18 +344,15 @@ BMVert *BM_Split_Edge(BMesh *bm, BMVert *v, BMEdge *e, BMEdge **ne, float percen
        v2 = bmesh_edge_getothervert(e,v);
        nv = bmesh_semv(bm,v,e,ne);
        if (nv == NULL) return NULL;
+
        VECSUB(nv->co,v2->co,v->co);
        VECADDFAC(nv->co,v->co,nv->co,percent);
+
        if (ne) {
-               if(bmesh_test_sysflag(&(e->head), BM_SELECT)) {
-                       bmesh_set_sysflag((BMHeader*)*ne, BM_SELECT);
-                       bmesh_set_sysflag((BMHeader*)nv, BM_SELECT);
-               }
-               if(bmesh_test_sysflag(&(e->head), BM_HIDDEN)) {
-                       bmesh_set_sysflag((BMHeader*)*ne, BM_HIDDEN);
-                       bmesh_set_sysflag((BMHeader*)nv, BM_HIDDEN);
-               }
+               (*ne)->head.flag = e->head.flag;
+               BM_Copy_Attributes(bm, bm, e, *ne);
        }
+
        /*v->nv->v2*/
        BM_Data_Facevert_Edgeinterp(bm,v2, v, nv, e, percent);  
        BM_Data_Interp_From_Verts(bm, v2, v, nv, percent);
index a6ccb8e4939106d16d0967a0ea73d5c686ed6d97..74c4785a4a29422ff1ee724267450c55b3df45ee 100644 (file)
@@ -2,11 +2,99 @@
 #include "bmesh_private.h"
 #include <stdio.h>
 
-/*do not rename any operator or slot names! otherwise you must go 
-  through the code and find all references to them!*/
+/*
+This file defines (and documents) all bmesh operators (bmops).
+
+Do not rename any operator or slot names! otherwise you must go 
+through the code and find all references to them!
+
+A word on slot names:
+
+For geometry input slots, the following are valid names:
+* verts
+* edges
+* faces
+* edgefacein
+* vertfacein
+* vertedgein
+* vertfacein
+* geom
+
+The basic rules are, for single-type geometry slots, use the plural of the
+type name (e.g. edges).  for double-type slots, use the two type names plus
+"in" (e.g. edgefacein).  for three-type slots, use geom.
+
+for output slots, for single-type geometry slots, use the type name plus "out",
+(e.g. vertout), for double-type slots, use the two type names plus "out",
+(e.g. vertfaceout), for three-type slots, use geom.  note that you can also
+use more esohteric names (e.g. skirtout) do long as the comment next to the
+slot definition tells you what types of elements are in it.
+
+*/
+
+/*
+ok, I'm going to write a little docgen script. so all
+bmop comments must conform to the following template/rules:
+
+template (py quotes used because nested comments don't work
+on all C compilers):
+
+"""
+Region Extend.
+
+paragraph1, Extends bleh bleh bleh.
+Bleh Bleh bleh.
+
+Another paragraph.
+
+Another paragraph.
+"""
+
+so the first line is the "title" of the bmop.
+subsequent line blocks seperated by blank lines
+are paragraphs.  individual descriptions of slots 
+would be extracted from comments
+next to them, e.g.
+
+{BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //output slot, boundary region
+
+the doc generator would automatically detect the presence of "output slot"
+and flag the slot as an output.  the same happens for "input slot".  also
+note that "edges", "faces", "verts", "loops", and "geometry" are valid 
+substitutions for "slot".
+*/
+
+/*
+  Region Extend
+  
+  used to implement the select more/less tools.
+  this puts some geometry surrounding regions of
+  geometry in geom into geomout.
+  
+  if usefaces is 0 then geomout spits out verts and edges, 
+  otherwise it spits out faces.
+  */
+BMOpDefine def_regionextend = {
+       "regionextend",
+       {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, //input geometry
+        {BMOP_OPSLOT_ELEMENT_BUF, "geomout"}, //output slot, computed boundary geometry.
+        {BMOP_OPSLOT_INT, "constrict"}, //find boundary inside the regions, not outside.
+        {BMOP_OPSLOT_INT, "usefaces"}, //extend from faces instead of edges
+       {0} /*null-terminating sentinel*/,
+       },
+       bmesh_regionextend_exec,
+       0
+};
+
+/*
+  Edge Rotate
+
+  Rotates edges topologically.  Also known as "spin edge" to some people.
+  Simple example: [/] becomes [|] then [\].
+*/
 BMOpDefine def_edgerotate = {
        "edgerotate",
-       {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
+       {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input edges
         {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, //newly spun edges
         {BMOP_OPSLOT_INT, "ccw"}, //rotate edge counter-clockwise if true, othewise clockwise
        {0} /*null-terminating sentinel*/,
@@ -15,38 +103,54 @@ BMOpDefine def_edgerotate = {
        0
 };
 
+/*
+  Reverse Faces
 
+  Reverses the winding (vertex order) of faces.  This has the effect of
+  flipping the normal.
+*/
 BMOpDefine def_reversefaces = {
        "reversefaces",
-       {{BMOP_OPSLOT_ELEMENT_BUF, "faces"},
+       {{BMOP_OPSLOT_ELEMENT_BUF, "faces"}, //input faces
        {0} /*null-terminating sentinel*/,
        },
        bmesh_reversefaces_exec,
        0
 };
 
+/*
+  Edge Split
+
+  Splits input edges (but doesn't do anything else).
+*/
 BMOpDefine def_edgesplit = {
        "edgesplit",
-       {{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
-       {BMOP_OPSLOT_INT, "numcuts"},
-       {BMOP_OPSLOT_ELEMENT_BUF, "outsplit"},
+       {{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input edges
+       {BMOP_OPSLOT_INT, "numcuts"}, //number of cuts
+       {BMOP_OPSLOT_ELEMENT_BUF, "outsplit"}, //newly created vertices and edges
        {0} /*null-terminating sentinel*/,
        },
        esplit_exec,
        0
 };
 
+/*
+  Mirror
+
+  Mirrors geometry along an axis.  The resulting geometry is welded on using
+  mergedist.  Pairs of original/mirrored vertices are welded using the mergedist
+  parameter (which defines the minimum distance for welding to happen).
+*/
+
 BMOpDefine def_mirror = {
        "mirror",
-       /*maps welded vertices to verts they should weld to.*/
-       {{BMOP_OPSLOT_ELEMENT_BUF, "geom"},
-        //list of verts to keep
+       {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, //input geometry
         {BMOP_OPSLOT_MAT, "mat"}, //matrix defining the mirror transformation
-        {BMOP_OPSLOT_FLT, "mergedist"}, //does no merging if mergedist is 0
-        {BMOP_OPSLOT_ELEMENT_BUF, "newout"},
-        {BMOP_OPSLOT_INT,         "axis"},
-        {BMOP_OPSLOT_INT,         "mirror_u"},
-        {BMOP_OPSLOT_INT,         "mirror_v"},
+        {BMOP_OPSLOT_FLT, "mergedist"}, //maximum distance for merging.  does no merging if 0.
+        {BMOP_OPSLOT_ELEMENT_BUF, "newout"}, //output geometry, mirrored
+        {BMOP_OPSLOT_INT,         "axis"}, //the axis to use, 0, 1, or 2 for x, y, z
+        {BMOP_OPSLOT_INT,         "mirror_u"}, //mirror UVs across the u axis
+        {BMOP_OPSLOT_INT,         "mirror_v"}, //mirror UVs across the v axis
         {0, /*null-terminating sentinel*/}},
        bmesh_mirror_exec,
        0,
@@ -369,6 +473,7 @@ BMOpDefine *opdefines[] = {
        &def_edgesplit,
        &def_reversefaces,
        &def_edgerotate,
+       &def_regionextend,
 };
 
 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));
index 484d4e08e18639e6b3cd86d90ee628d285df6647..4307e5069a7b2880ad84952062059c38bc491fc4 100644 (file)
@@ -38,5 +38,6 @@ void bmesh_mirror_exec(BMesh *bm, BMOperator *op);
 void esplit_exec(BMesh *bm, BMOperator *op);
 void bmesh_reversefaces_exec(BMesh *bm, BMOperator *op);
 void bmesh_edgerotate_exec(BMesh *bm, BMOperator *op);
+void bmesh_regionextend_exec(BMesh *bm, BMOperator *op);
 
 #endif
index 77d39204a84b52a685aa92a7ded50eed4ee74a00..2e8fb571d75ebeb669a51cd68e28157fb4c16725 100644 (file)
@@ -31,7 +31,8 @@
  *
 */
 
-void bmesh_makevert_exec(BMesh *bm, BMOperator *op) {
+void bmesh_makevert_exec(BMesh *bm, BMOperator *op)
+{
        float vec[3];
 
        BMO_Get_Vec(op, "co", vec);
@@ -40,7 +41,8 @@ void bmesh_makevert_exec(BMesh *bm, BMOperator *op) {
        BMO_Flag_To_Slot(bm, op, "newvertout", 1, BM_VERT);
 }
 
-void bmesh_transform_exec(BMesh *bm, BMOperator *op) {
+void bmesh_transform_exec(BMesh *bm, BMOperator *op)
+{
        BMOIter iter;
        BMVert *v;
        float mat[4][4];
@@ -56,7 +58,8 @@ void bmesh_transform_exec(BMesh *bm, BMOperator *op) {
   is a little complex, but makes it easier to make
   sure the transform op is working, since initially
   only this one will be used.*/
-void bmesh_translate_exec(BMesh *bm, BMOperator *op) {
+void bmesh_translate_exec(BMesh *bm, BMOperator *op)
+{
        float mat[4][4], vec[3];
        
        BMO_Get_Vec(op, "vec", vec);
@@ -67,7 +70,8 @@ void bmesh_translate_exec(BMesh *bm, BMOperator *op) {
        BMO_CallOpf(bm, "transform mat=%m4 verts=%s", mat, op, "verts");
 }
 
-void bmesh_rotate_exec(BMesh *bm, BMOperator *op) {
+void bmesh_rotate_exec(BMesh *bm, BMOperator *op)
+{
        float vec[3];
        
        BMO_Get_Vec(op, "cent", vec);
@@ -84,7 +88,8 @@ void bmesh_rotate_exec(BMesh *bm, BMOperator *op) {
        BMO_CallOpf(bm, "translate verts=%s vec=%v", op, "verts", vec);
 }
 
-void bmesh_reversefaces_exec(BMesh *bm, BMOperator *op) {
+void bmesh_reversefaces_exec(BMesh *bm, BMOperator *op)
+{
        BMOIter siter;
        BMFace *f;
 
@@ -93,7 +98,8 @@ void bmesh_reversefaces_exec(BMesh *bm, BMOperator *op) {
        }
 }
 
-void bmesh_edgerotate_exec(BMesh *bm, BMOperator *op) {
+void bmesh_edgerotate_exec(BMesh *bm, BMOperator *op)
+{
        BMOIter siter;
        BMEdge *e, *e2;
        int ccw = BMO_Get_Int(op, "ccw");
@@ -109,3 +115,98 @@ void bmesh_edgerotate_exec(BMesh *bm, BMOperator *op) {
 
        BMO_Flag_To_Slot(bm, op, "edgeout", 1, BM_EDGE);
 }
+
+#define SEL_FLAG       1
+#define SEL_ORIG       2
+
+static void bmesh_regionextend_extend(BMesh *bm, BMOperator *op, int usefaces)
+{
+       BMVert *v;
+       BMEdge *e;
+       BMIter eiter;
+       BMOIter siter;
+
+       if (!usefaces) {
+               BMO_ITER(v, &siter, bm, op, "geom", BM_VERT) {
+                       BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
+                               if (!BMO_TestFlag(bm, e, SEL_ORIG))
+                                       break;
+                       }
+
+                       if (e) {
+                               BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
+                                       BMO_SetFlag(bm, e, SEL_FLAG);
+                                       BMO_SetFlag(bm, BM_OtherEdgeVert(e, v), SEL_FLAG);
+                               }
+                       }
+               }
+       } else {
+               BMIter liter, fiter;
+               BMFace *f, *f2;
+               BMLoop *l;
+
+               BMO_ITER(f, &siter, bm, op, "geom", BM_FACE) {
+                       BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
+                               BM_ITER(f2, &fiter, bm, BM_FACES_OF_EDGE, l->e) {
+                                       if (!BMO_TestFlag(bm, f2, SEL_ORIG))
+                                               BMO_SetFlag(bm, f2, SEL_FLAG);
+                               }
+                       }
+               }
+       }
+}
+
+static void bmesh_regionextend_constrict(BMesh *bm, BMOperator *op, int usefaces)
+{
+       BMVert *v;
+       BMEdge *e;
+       BMIter eiter;
+       BMOIter siter;
+
+       if (!usefaces) {
+               BMO_ITER(v, &siter, bm, op, "geom", BM_VERT) {
+                       BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
+                               if (!BMO_TestFlag(bm, e, SEL_ORIG))
+                                       break;
+                       }
+
+                       if (e) {
+                               BMO_SetFlag(bm, v, SEL_FLAG);
+
+                               BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
+                                       BMO_SetFlag(bm, e, SEL_FLAG);
+                               }
+                       }
+               }
+       } else {
+               BMIter liter, fiter;
+               BMFace *f, *f2;
+               BMLoop *l;
+
+               BMO_ITER(f, &siter, bm, op, "geom", BM_FACE) {
+                       BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
+                               BM_ITER(f2, &fiter, bm, BM_FACES_OF_EDGE, l->e) {
+                                       if (!BMO_TestFlag(bm, f2, SEL_ORIG)) {
+                                               BMO_SetFlag(bm, f, SEL_FLAG);
+                                               break;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+void bmesh_regionextend_exec(BMesh *bm, BMOperator *op)
+{
+       int usefaces = BMO_Get_Int(op, "usefaces");
+       int constrict = BMO_Get_Int(op, "constrict");
+
+       BMO_Flag_Buffer(bm, op, "geom", SEL_ORIG);
+
+       if (constrict)
+               bmesh_regionextend_constrict(bm, op, usefaces);
+       else
+               bmesh_regionextend_extend(bm, op, usefaces);
+
+       BMO_Flag_To_Slot(bm, op, "geomout", SEL_FLAG, BM_ALL);
+}
\ No newline at end of file
index 616f22f814509815941db0941ebb4411c6c2961f..ec1e699d03e18a64de8b4a6f2b725d9d98a9d952 100644 (file)
@@ -1622,84 +1622,25 @@ void MESH_OT_select_linked(wmOperatorType *ot)
 
 /* ******************** **************** */
 
-void EDBM_select_more(BMEditMesh *em)
+static int select_more(bContext *C, wmOperator *op)
 {
-       BMIter iter;
-       
-       /*for now, bmops aren't supposed to mess with header flags
-         (might need to revisit that design decision later), so 
-         this function is slightly unconventional to avoid the use
-         of the BMO_[Set/Clear]Flag functions.  it accumulates lists
-         of elements to make selection changes to in pointer arrays.*/
-
-       if (em->selectmode <= SCE_SELECT_EDGE) {
-               BMVert *v;
-               BMEdge *e;
-               BMIter eiter;
-               BMVert **verts = NULL;
-               V_DECLARE(verts);
-               V_DECLARE(edges);
-               BMEdge **edges = NULL;
-               int vtot=0, etot=0, i;
-
-               BM_ITER_NOTSELECT(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL)
-                       BM_ITER(e, &eiter, em->bm, BM_EDGES_OF_VERT, v) {
-                               if (BM_TestHFlag(BM_OtherEdgeVert(e, v), BM_SELECT))
-                                       break;
-                       }
-
-                       if (e) {
-                               V_GROW(verts);
-                               verts[vtot++] = v;
-                       }
-
-               }
-
-               for (i=0; i<vtot; i++) {
-                       BM_Select(em->bm, verts[i], 1);
-               }
-
-               /*make sure we flush from vertices on up, not from edges*/
-               EDBM_select_flush(em, SCE_SELECT_VERTEX);
-
-               V_FREE(verts);
-       } else {
-               BMIter liter, fiter;
-               BMFace *f, *f2, **faces = NULL;
-               V_DECLARE(faces);
-               BMLoop *l;
-               int i, tot=0;
-
-               BM_ITER_SELECT(f, &iter, em->bm, BM_FACES_OF_MESH, NULL)
-                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, f) {
-                               BM_ITER(f2, &fiter, em->bm, BM_FACES_OF_EDGE, l->e) {
-                                       if (!BM_TestHFlag(f2, BM_SELECT)) {
-                                               V_GROW(faces);
-                                               faces[tot++] = f2;
-                                       }
-                               }
-                       }
-               }
+       Object *obedit= CTX_data_edit_object(C);
+       BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
+       BMOperator bmop;
+       int usefaces = em->selectmode > SCE_SELECT_EDGE;
 
-               for (i=0; i<tot; i++) {
-                       BM_Select(em->bm, faces[i], 1);
-               }
+       EDBM_InitOpf(em, &bmop, op, "regionextend geom=%hvef constrict=%d usefaces=%d", 
+                    BM_SELECT, 0, usefaces);
 
-               V_FREE(faces);
-       }
+       BMO_Exec_Op(em->bm, &bmop);
+       BMO_HeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT);
 
        EDBM_selectmode_flush(em);
-}
-
-static int select_more(bContext *C, wmOperator *op)
-{
-       Object *obedit= CTX_data_edit_object(C);
-       BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
 
-       EDBM_select_more(em);
+       if (!EDBM_FinishOp(em, &bmop, op, 1))
+               return OPERATOR_CANCELLED;
 
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
-
        return OPERATOR_FINISHED;
 }
 
@@ -1717,92 +1658,23 @@ void MESH_OT_select_more(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
-void EDBM_select_less(BMEditMesh *em)
+static int select_less(bContext *C, wmOperator *op)
 {
-       BMIter iter;
-       
-       /*for now, bmops aren't supposed to mess with header flags
-         (might need to revisit that design decision later), so 
-         this function is slightly unconventional to avoid the use
-         of the BMO_[Set/Clear]Flag functions.  it accumulates lists
-         of elements to make selection changes to in pointer arrays.*/
-
-       if (em->selectmode <= SCE_SELECT_EDGE) {
-               BMVert *v;
-               BMEdge *e;
-               BMIter eiter;
-               BMVert **verts = NULL;
-               V_DECLARE(verts);
-               V_DECLARE(edges);
-               BMEdge **edges = NULL;
-               int vtot=0, etot=0, i;
-
-               BM_ITER_SELECT(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL)
-                       BM_ITER(e, &eiter, em->bm, BM_EDGES_OF_VERT, v) {
-                               if (!BM_TestHFlag(e, BM_SELECT))
-                                       break;
-                       }
-
-                       if (e) {
-                               V_GROW(verts);
-                               verts[vtot++] = v;
-
-                               BM_ITER(e, &eiter, em->bm, BM_EDGES_OF_VERT, v) {
-                                       V_GROW(edges);
-                                       edges[etot++] = e;
-                               }
-                       }
-               }
-
-               for (i=0; i<vtot; i++) {
-                       BM_Select(em->bm, verts[i], 0);
-               }
-
-               for (i=0; i<etot; i++) {
-                       BM_Select(em->bm, edges[i], 0);
-               }
-
-               V_FREE(verts);
-               V_FREE(edges);
-       } else {
-               BMIter liter, fiter;
-               BMFace *f, *f2, **faces = NULL;
-               V_DECLARE(faces);
-               BMLoop *l;
-               int i, tot=0;
-
-               BM_ITER_SELECT(f, &iter, em->bm, BM_FACES_OF_MESH, NULL)
-                       BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, f) {
-                               BM_ITER(f2, &fiter, em->bm, BM_FACES_OF_EDGE, l->e) {
-                                       if (!BM_TestHFlag(f2, BM_SELECT))
-                                               break;
-                               }
-                               if (f2)
-                                       break;
-                       }
-
-                       if (l) {
-                               V_GROW(faces);
-                               faces[tot++] = f;
-                       }
-               }
+       Object *obedit= CTX_data_edit_object(C);
+       BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
+       BMOperator bmop;
+       int usefaces = em->selectmode > SCE_SELECT_EDGE;
 
-               for (i=0; i<tot; i++) {
-                       BM_Select(em->bm, faces[i], 0);
-               }
+       EDBM_InitOpf(em, &bmop, op, "regionextend geom=%hvef constrict=%d usefaces=%d", 
+                    BM_SELECT, 1, usefaces);
 
-               V_FREE(faces);
-       }
+       BMO_Exec_Op(em->bm, &bmop);
+       BMO_UnHeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT);
 
        EDBM_selectmode_flush(em);
-}
 
-static int select_less(bContext *C, wmOperator *op)
-{
-       Object *obedit= CTX_data_edit_object(C);
-       BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
-
-       EDBM_select_less(em);
+       if (!EDBM_FinishOp(em, &bmop, op, 1))
+               return OPERATOR_CANCELLED;
 
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
        return OPERATOR_FINISHED;
index 80dd5cdd11bf34fe9d1031d042d86e14ff9b5ff3..21c1c00026b6d573abdecc9c83bbc72bc912ed14 100644 (file)
@@ -502,18 +502,11 @@ short EDBM_Extrude_verts_indiv(BMEditMesh *em, wmOperator *op, short flag, float
        EDBM_InitOpf(em, &bmop, op, "extrude_vert_indiv verts=%hv", flag);
 
        /*deselect original verts*/
-       v = BMO_IterNew(&siter, em->bm, &bmop, "verts", BM_VERT);
-       for (; v; v=BMO_IterStep(&siter)) {
-               BM_Select(em->bm, v, 0);
-       }
+       BMO_UnHeaderFlag_Buffer(em->bm, &bmop, "verts", BM_SELECT);
 
        BMO_Exec_Op(em->bm, &bmop);
 
-       v = BMO_IterNew(&siter, em->bm, &bmop, "vertout", BM_VERT);
-       for (; v; v=BMO_IterStep(&siter)) {
-               BM_Select(em->bm, v, 1);
-       }
-
+       BMO_HeaderFlag_Buffer(em->bm, &bmop, "vertout", BM_SELECT);
        if (!EDBM_FinishOp(em, &bmop, op, 1)) return 0;
 
        return 'g'; // g is grab
index 108aff7bf40cea9a9332240fef4ba6350ec8ff9b..51644457f87e95b0421c2df60cd6533129a66125 100644 (file)
@@ -399,6 +399,37 @@ void EDBM_selectmode_flush(BMEditMesh *em)
        BM_SelectMode_Flush(em->bm);
 }
 
+/*EDBM_select_[more/less] are api functions, I think the uv editor
+  uses them? though the select more/less ops themselves do not.*/
+void EDBM_select_more(BMEditMesh *em)
+{
+       BMOperator bmop;
+       int usefaces = em->selectmode > SCE_SELECT_EDGE;
+
+       BMO_InitOpf(em->bm, &bmop, 
+                   "regionextend geom=%hvef constrict=%d usefaces=%d",
+                   BM_SELECT, 0, usefaces);
+       BMO_Exec_Op(em->bm, &bmop);
+       BMO_HeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT);
+       BMO_Finish_Op(em->bm, &bmop);
+
+       EDBM_selectmode_flush(em);
+}
+
+void EDBM_select_less(BMEditMesh *em)
+{
+       BMOperator bmop;
+       int usefaces = em->selectmode > SCE_SELECT_EDGE;
+
+       BMO_InitOpf(em->bm, &bmop, 
+                   "regionextend geom=%hvef constrict=%d usefaces=%d",
+                   BM_SELECT, 0, usefaces);
+       BMO_Exec_Op(em->bm, &bmop);
+       BMO_HeaderFlag_Buffer(em->bm, &bmop, "geomout", BM_SELECT);
+       BMO_Finish_Op(em->bm, &bmop);
+
+       EDBM_selectmode_flush(em);
+}
 
 int EDBM_get_actSelection(BMEditMesh *em, BMEditSelection *ese)
 {