bmesh/py operator api:
authorCampbell Barton <ideasman42@gmail.com>
Tue, 27 Nov 2012 00:50:59 +0000 (00:50 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 27 Nov 2012 00:50:59 +0000 (00:50 +0000)
add type checking for element buffers, there was nothing stopping python from passing any element type into an argument when in some cases only verts/edges/faces were expected.
now operator args define which types they support.

16 files changed:
source/blender/bmesh/bmesh_class.h
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/intern/bmesh_operator_api.h
source/blender/bmesh/intern/bmesh_operator_api_inline.h
source/blender/bmesh/intern/bmesh_operators.c
source/blender/bmesh/operators/bmo_dupe.c
source/blender/bmesh/operators/bmo_extrude.c
source/blender/bmesh/operators/bmo_mirror.c
source/blender/bmesh/operators/bmo_subdivide.c
source/blender/bmesh/operators/bmo_utils.c
source/blender/editors/mesh/editmesh_knife.c
source/blender/editors/mesh/editmesh_select.c
source/blender/editors/mesh/editmesh_slide.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/editmesh_utils.c
source/blender/python/bmesh/bmesh_py_ops.c

index f9dbf51a62919df67a45754f25b2134b31ffc4e8..9d797c1e602662fdbd0fa9a9ed2379417c71f5d0 100644 (file)
@@ -226,6 +226,7 @@ enum {
 };
 
 #define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
+#define BM_ALL_NOLOOP (BM_VERT | BM_EDGE | BM_FACE)
 
 /* BMHeader->hflag (char) */
 enum {
index d8f29c082a4e982044f7a56544361ed69fecafa6..f14fac64ba3ad7a7b9e4e2c91e89512f1f9727cc 100644 (file)
 static BMOpDefine bmo_smooth_vert_def = {
        "smooth_vert",
        /* slots_in */
-       {{"verts", BMO_OP_SLOT_ELEMENT_BUF},    /* input vertices */
+       {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
         {"mirror_clip_x", BMO_OP_SLOT_BOOL},   /* set vertices close to the x axis before the operation to 0 */
         {"mirror_clip_y", BMO_OP_SLOT_BOOL},   /* set vertices close to the y axis before the operation to 0 */
         {"mirror_clip_z", BMO_OP_SLOT_BOOL},   /* set vertices close to the z axis before the operation to 0 */
@@ -123,7 +123,7 @@ static BMOpDefine bmo_smooth_vert_def = {
 static BMOpDefine bmo_smooth_laplacian_vert_def = {
        "smooth_laplacian_vert",
        /* slots_in */
-       {{"verts", BMO_OP_SLOT_ELEMENT_BUF},    /* input vertices */
+       {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
         {"lambda", BMO_OP_SLOT_FLT},           /* lambda param */
         {"lambda_border", BMO_OP_SLOT_FLT},    /* lambda param in border */
         {"use_x", BMO_OP_SLOT_BOOL},           /* Smooth object along X axis */
@@ -146,7 +146,7 @@ static BMOpDefine bmo_smooth_laplacian_vert_def = {
 static BMOpDefine bmo_recalc_face_normals_def = {
        "recalc_face_normals",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
         {"use_flip", BMO_OP_SLOT_BOOL},        /* internal flag, used by bmesh_rationalize_normals */
         {{'\0'}},
        },
@@ -168,13 +168,13 @@ static BMOpDefine bmo_recalc_face_normals_def = {
 static BMOpDefine bmo_region_extend_def = {
        "region_extend",
        /* slots_in */
-       {{"geom", BMO_OP_SLOT_ELEMENT_BUF},     /* input geometry */
+       {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input geometry */
         {"use_constrict", BMO_OP_SLOT_BOOL},   /* find boundary inside the regions, not outside. */
         {"use_faces", BMO_OP_SLOT_BOOL},       /* extend from faces instead of edges */
         {{'\0'}},
        },
        /* slots_out */
-       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output slot, computed boundary geometry. */
+       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output slot, computed boundary geometry. */
         {{'\0'}},
        },
        bmo_region_extend_exec,
@@ -190,12 +190,12 @@ static BMOpDefine bmo_region_extend_def = {
 static BMOpDefine bmo_rotate_edges_def = {
        "rotate_edges",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF},    /* input edges */
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
         {"use_ccw", BMO_OP_SLOT_BOOL},         /* rotate edge counter-clockwise if true, othewise clockwise */
         {{'\0'}},
        },
        /* slots_out */
-       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* newly spun edges */
+       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly spun edges */
         {{'\0'}},
        },
        bmo_rotate_edges_exec,
@@ -211,7 +211,7 @@ static BMOpDefine bmo_rotate_edges_def = {
 static BMOpDefine bmo_reverse_faces_def = {
        "reverse_faces",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF},    /* input faces */
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -228,12 +228,12 @@ static BMOpDefine bmo_reverse_faces_def = {
 static BMOpDefine bmo_bisect_edges_def = {
        "bisect_edges",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges */
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
         {"cuts", BMO_OP_SLOT_INT}, /* number of cuts */
         {{'\0'}},
        },
        /* slots_out */
-       {{"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF}, /* newly created vertices and edges */
+       {{"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* newly created vertices and edges */
         {{'\0'}},
        },
        bmo_bisect_edges_exec,
@@ -251,7 +251,7 @@ static BMOpDefine bmo_bisect_edges_def = {
 static BMOpDefine bmo_mirror_def = {
        "mirror",
        /* slots_in */
-       {{"geom", BMO_OP_SLOT_ELEMENT_BUF},     /* input geometry */
+       {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input geometry */
         {"mat",         BMO_OP_SLOT_MAT},      /* matrix defining the mirror transformation */
         {"merge_dist", BMO_OP_SLOT_FLT},       /* maximum distance for merging.  does no merging if 0. */
         {"axis",         BMO_OP_SLOT_INT},     /* the axis to use, 0, 1, or 2 for x, y, z */
@@ -260,7 +260,7 @@ static BMOpDefine bmo_mirror_def = {
         {{'\0'}},
        },
        /* slots_out */
-       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output geometry, mirrored */
+       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output geometry, mirrored */
         {{'\0'}},
        },
        bmo_mirror_exec,
@@ -279,13 +279,13 @@ static BMOpDefine bmo_mirror_def = {
 static BMOpDefine bmo_find_doubles_def = {
        "find_doubles",
        /* slots_in */
-       {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */
-        {"keep_verts", BMO_OP_SLOT_ELEMENT_BUF}, /* list of verts to keep */
+       {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+        {"keep_verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* list of verts to keep */
         {"dist",         BMO_OP_SLOT_FLT}, /* minimum distance */
         {{'\0'}},
        },
        /* slots_out */
-       {{"targetmap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM},
+       {{"targetmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
         {{'\0'}},
        },
        bmo_find_doubles_exec,
@@ -301,7 +301,7 @@ static BMOpDefine bmo_find_doubles_def = {
 static BMOpDefine bmo_remove_doubles_def = {
        "remove_doubles",
        /* slots_in */
-       {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input verts */
+       {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
         {"dist",         BMO_OP_SLOT_FLT}, /* minimum distance */
         {{'\0'}},
        },
@@ -320,7 +320,7 @@ static BMOpDefine bmo_remove_doubles_def = {
 static BMOpDefine bmo_automerge_def = {
        "automerge",
        /* slots_in */
-       {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input verts */
+       {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
         {"dist",         BMO_OP_SLOT_FLT}, /* minimum distance */
         {{'\0'}},
        },
@@ -337,7 +337,7 @@ static BMOpDefine bmo_automerge_def = {
 static BMOpDefine bmo_collapse_def = {
        "collapse",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edge */
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -354,8 +354,8 @@ static BMOpDefine bmo_collapse_def = {
 static BMOpDefine bmo_pointmerge_facedata_def = {
        "pointmerge_facedata",
        /* slots_in */
-       {{"verts", BMO_OP_SLOT_ELEMENT_BUF},    /* input vertices */
-        {"snapv", BMO_OP_SLOT_ELEMENT_BUF},    /* snap vertex */
+       {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
+        {"snapv", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}},    /* snap vertex */
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -373,7 +373,7 @@ static BMOpDefine bmo_pointmerge_facedata_def = {
 static BMOpDefine bmo_average_vert_facedata_def = {
        "average_vert_facedata",
        /* slots_in */
-       {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertice */
+       {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -389,7 +389,7 @@ static BMOpDefine bmo_average_vert_facedata_def = {
 static BMOpDefine bmo_pointmerge_def = {
        "pointmerge",
        /* slots_in */
-       {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertice */
+       {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */
         {"merge_co",         BMO_OP_SLOT_VEC},
         {{'\0'}},
        },
@@ -406,7 +406,7 @@ static BMOpDefine bmo_pointmerge_def = {
 static BMOpDefine bmo_collapse_uvs_def = {
        "collapse_uvs",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edge */
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -425,7 +425,7 @@ static BMOpDefine bmo_weld_verts_def = {
        "weld_verts",
        /* slots_in */
        /* maps welded vertices to verts they should weld to */
-       {{"targetmap", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM},
+       {{"targetmap", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -446,7 +446,7 @@ static BMOpDefine bmo_create_vert_def = {
         {{'\0'}},
        },
        /* slots_out */
-       {{"vert.out", BMO_OP_SLOT_ELEMENT_BUF},  /* the new vert */
+       {{"vert.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* the new vert */
         {{'\0'}},
        },
        bmo_create_vert_exec,
@@ -462,7 +462,7 @@ static BMOpDefine bmo_create_vert_def = {
 static BMOpDefine bmo_join_triangles_def = {
        "join_triangles",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF},    /* input geometry. */
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input geometry. */
         {"cmp_sharp", BMO_OP_SLOT_BOOL},
         {"cmp_uvs", BMO_OP_SLOT_BOOL},
         {"cmp_vcols", BMO_OP_SLOT_BOOL},
@@ -471,7 +471,7 @@ static BMOpDefine bmo_join_triangles_def = {
         {{'\0'}},
        },
        /* slots_out */
-       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF},  /* joined faces */
+       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},  /* joined faces */
         {{'\0'}},
        },
        bmo_join_triangles_exec,
@@ -492,15 +492,15 @@ static BMOpDefine bmo_join_triangles_def = {
 static BMOpDefine bmo_contextual_create_def = {
        "contextual_create",
        /* slots_in */
-       {{"geom", BMO_OP_SLOT_ELEMENT_BUF},     /* input geometry. */
+       {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input geometry. */
         {"mat_nr",         BMO_OP_SLOT_INT},   /* material to use */
         {"use_smooth",        BMO_OP_SLOT_BOOL}, /* smooth to use */
         {{'\0'}},
        },
        /* slots_out */
-       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* newly-made face(s) */
+       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* newly-made face(s) */
        /* note, this is for stand-alone edges only, not edges which are apart of newly created faces */
-        {"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* newly-made edge(s) */
+        {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly-made edge(s) */
         {{'\0'}},
        },
        bmo_contextual_create_exec,
@@ -513,13 +513,13 @@ static BMOpDefine bmo_contextual_create_def = {
 static BMOpDefine bmo_bridge_loops_def = {
        "bridge_loops",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edge */
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
         {"use_merge",        BMO_OP_SLOT_BOOL},
         {"merge_factor",         BMO_OP_SLOT_FLT},
         {{'\0'}},
        },
        /* slots_out */
-       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* new faces */
+       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
         {{'\0'}},
        },
        bmo_bridge_loops_exec,
@@ -529,20 +529,20 @@ static BMOpDefine bmo_bridge_loops_def = {
 static BMOpDefine bmo_edgenet_fill_def = {
        "edgenet_fill",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF}, /* input edge */
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
        /* restricts edges to groups.  maps edges to integer */
-        {"restrict",     BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_BOOL},
+        {"restrict",     BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_BOOL}},
         {"use_restrict",        BMO_OP_SLOT_BOOL},
         {"use_fill_check",        BMO_OP_SLOT_BOOL},
-        {"exclude_faces", BMO_OP_SLOT_ELEMENT_BUF}, /* list of faces to ignore for manifold check */
+        {"exclude_faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* list of faces to ignore for manifold check */
         {"mat_nr",         BMO_OP_SLOT_INT},      /* material to use */
         {"use_smooth",        BMO_OP_SLOT_BOOL},  /* material to use */
         {{'\0'}},
        },
        /* slots_out */
        /* maps new faces to the group numbers they came from */
-       {{"face_groupmap.out",     BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM},
-        {"faces.out", BMO_OP_SLOT_ELEMENT_BUF},     /* new face */
+       {{"face_groupmap.out",     BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+        {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* new face */
         {{'\0'}},
        },
        bmo_edgenet_fill_exec,
@@ -562,11 +562,11 @@ static BMOpDefine bmo_edgenet_fill_def = {
 static BMOpDefine bmo_edgenet_prepare_def = {
        "edgenet_prepare",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF},    /* input edges */
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
         {{'\0'}},
        },
        /* slots_out */
-       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF},  /* new edges */
+       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},  /* new edges */
         {{'\0'}},
        },
        bmo_edgenet_prepare,
@@ -584,7 +584,7 @@ static BMOpDefine bmo_rotate_def = {
        /* slots_in */
        {{"cent", BMO_OP_SLOT_VEC},  /* center of rotation */
         {"mat", BMO_OP_SLOT_MAT},   /* matrix defining rotation */
-        {"verts", BMO_OP_SLOT_ELEMENT_BUF},  /* input vertices */
+        {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -602,7 +602,7 @@ static BMOpDefine bmo_translate_def = {
        "translate",
        /* slots_in */
        {{"vec", BMO_OP_SLOT_VEC},  /* translation offset */
-        {"verts", BMO_OP_SLOT_ELEMENT_BUF},  /* input vertices */
+        {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -619,7 +619,7 @@ static BMOpDefine bmo_scale_def = {
        "scale",
        /* slots_in */
        {{"vec", BMO_OP_SLOT_VEC},  /* scale factor */
-        {"verts", BMO_OP_SLOT_ELEMENT_BUF},  /* input vertices */
+        {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -638,7 +638,7 @@ static BMOpDefine bmo_transform_def = {
        "transform",
        /* slots_in */
        {{"mat", BMO_OP_SLOT_MAT},  /* transform matrix */
-        {"verts", BMO_OP_SLOT_ELEMENT_BUF},  /* input vertices */
+        {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* input vertices */
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -655,8 +655,8 @@ static BMOpDefine bmo_transform_def = {
 static BMOpDefine bmo_object_load_bmesh_def = {
        "object_load_bmesh",
        /* slots_in */
-       {{"scene", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_SCENE},
-        {"object", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_OBJECT},
+       {{"scene", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_SCENE}},
+        {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -675,9 +675,9 @@ static BMOpDefine bmo_bmesh_to_mesh_def = {
        /* slots_in */
        {
        /* pointer to a mesh structure to fill in */
-        {"mesh", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_MESH},
+        {"mesh", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
        /* pointer to an object structure */
-        {"object", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_OBJECT},
+        {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
         {"skip_tessface", BMO_OP_SLOT_BOOL},  /* don't calculate mfaces */
         {{'\0'}},
        },
@@ -697,9 +697,9 @@ static BMOpDefine bmo_mesh_to_bmesh_def = {
        /* slots_in */
        {
        /* pointer to a Mesh structure */
-        {"mesh", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_MESH},
+        {"mesh", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
        /* pointer to an Object structure */
-        {"object", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_OBJECT},
+        {"object", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
         {"use_shapekey", BMO_OP_SLOT_BOOL},  /* load active shapekey coordinates into verts */
         {{'\0'}},
        },
@@ -716,12 +716,11 @@ static BMOpDefine bmo_mesh_to_bmesh_def = {
 static BMOpDefine bmo_extrude_discrete_faces_def = {
        "extrude_discrete_faces",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF},     /* input faces */
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* input faces */
         {{'\0'}},
        },
        /* slots_out */
-       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF},   /* output faces */
-        {"geom_skirt.out", BMO_OP_SLOT_ELEMENT_BUF},  /* output skirt geometry, faces and edges */
+       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},   /* output faces */
         {{'\0'}},
        },
        bmo_extrude_discrete_faces_exec,
@@ -737,11 +736,11 @@ static BMOpDefine bmo_extrude_discrete_faces_def = {
 static BMOpDefine bmo_extrude_edge_only_def = {
        "extrude_edge_only",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF},    /* input vertices */
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input vertices */
         {{'\0'}},
        },
        /* slots_out */
-       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF},  /* output geometry */
+       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},  /* output geometry */
         {{'\0'}},
        },
        bmo_extrude_edge_only_exec,
@@ -756,12 +755,12 @@ static BMOpDefine bmo_extrude_edge_only_def = {
 static BMOpDefine bmo_extrude_vert_indiv_def = {
        "extrude_vert_indiv",
        /* slots_in */
-       {{"verts", BMO_OP_SLOT_ELEMENT_BUF},    /* input vertices */
+       {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
         {{'\0'}},
        },
        /* slots_out */
-       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF},  /* output wire edges */
-        {"verts.out", BMO_OP_SLOT_ELEMENT_BUF},  /* output vertices */
+       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},  /* output wire edges */
+        {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* output vertices */
         {{'\0'}},
        },
        bmo_extrude_vert_indiv_exec,
@@ -771,11 +770,11 @@ static BMOpDefine bmo_extrude_vert_indiv_def = {
 static BMOpDefine bmo_connect_verts_def = {
        "connect_verts",
        /* slots_in */
-       {{"verts", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
         {{'\0'}},
        },
        /* slots_out */
-       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
         {{'\0'}},
        },
        bmo_connect_verts_exec,
@@ -785,13 +784,13 @@ static BMOpDefine bmo_connect_verts_def = {
 static BMOpDefine bmo_extrude_face_region_def = {
        "extrude_face_region",
        /* slots_in */
-       {{"geom", BMO_OP_SLOT_ELEMENT_BUF},     /* edges and faces */
-        {"edges_exclude", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_EMPTY},
+       {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* edges and faces */
+        {"edges_exclude", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}},
         {"use_keep_orig", BMO_OP_SLOT_BOOL},   /* keep original geometry */
         {{'\0'}},
        },
        /* slots_out */
-       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
         {{'\0'}},
        },
        bmo_extrude_face_region_exec,
@@ -801,7 +800,7 @@ static BMOpDefine bmo_extrude_face_region_def = {
 static BMOpDefine bmo_dissolve_verts_def = {
        "dissolve_verts",
        /* slots_in */
-       {{"verts", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -812,12 +811,12 @@ static BMOpDefine bmo_dissolve_verts_def = {
 static BMOpDefine bmo_dissolve_edges_def = {
        "dissolve_edges",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
         {"use_verts", BMO_OP_SLOT_BOOL},  /* dissolve verts left between only 2 edges. */
         {{'\0'}},
        },
        /* slots_out */
-       {{"region.out", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
         {{'\0'}},
        },
        bmo_dissolve_edges_exec,
@@ -827,11 +826,11 @@ static BMOpDefine bmo_dissolve_edges_def = {
 static BMOpDefine bmo_dissolve_edge_loop_def = {
        "dissolve_edge_loop",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
         {{'\0'}},
        },
        /* slots_out */
-       {{"region.out", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
         {{'\0'}},
        },
        bmo_dissolve_edgeloop_exec,
@@ -841,12 +840,12 @@ static BMOpDefine bmo_dissolve_edge_loop_def = {
 static BMOpDefine bmo_dissolve_faces_def = {
        "dissolve_faces",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
         {"use_verts", BMO_OP_SLOT_BOOL},  /* dissolve verts left between only 2 edges. */
         {{'\0'}},
        },
        /* slots_out */
-       {{"region.out", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
         {{'\0'}},
        },
        bmo_dissolve_faces_exec,
@@ -858,8 +857,8 @@ static BMOpDefine bmo_dissolve_limit_def = {
        /* slots_in */
        {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (degrees) */
         {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL},
-        {"verts", BMO_OP_SLOT_ELEMENT_BUF},
-        {"edges", BMO_OP_SLOT_ELEMENT_BUF},
+        {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+        {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -870,14 +869,14 @@ static BMOpDefine bmo_dissolve_limit_def = {
 static BMOpDefine bmo_triangulate_def = {
        "triangulate",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
         {"use_beauty", BMO_OP_SLOT_BOOL},
         {{'\0'}},
        },
        /* slots_out */
-       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF},
-        {"faces.out", BMO_OP_SLOT_ELEMENT_BUF},
-        {"facemap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM},
+       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+        {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+        {"facemap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
         {{'\0'}},
        },
        bmo_triangulate_exec,
@@ -887,7 +886,7 @@ static BMOpDefine bmo_triangulate_def = {
 static BMOpDefine bmo_unsubdivide_def = {
        "unsubdivide",
        /* slots_in */
-       {{"verts", BMO_OP_SLOT_ELEMENT_BUF}, /* input vertices */
+       {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
         {"iterations", BMO_OP_SLOT_INT},
         {{'\0'}},
        },
@@ -899,14 +898,14 @@ static BMOpDefine bmo_unsubdivide_def = {
 static BMOpDefine bmo_subdivide_edges_def = {
        "subdivide_edges",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
         {"smooth", BMO_OP_SLOT_FLT},
         {"fractal", BMO_OP_SLOT_FLT},
         {"along_normal", BMO_OP_SLOT_FLT},
         {"cuts", BMO_OP_SLOT_INT},
         {"seed", BMO_OP_SLOT_INT},
-        {"custompatterns", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL},  /* uses custom pointers */
-        {"edgepercents", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_FLOAT},
+        {"custompatterns", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}},  /* uses custom pointers */
+        {"edgepercents", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_FLOAT}},
 
         {"quad_corner_type",  BMO_OP_SLOT_INT}, /* quad corner type, see bmesh_operators.h */
         {"use_gridfill", BMO_OP_SLOT_BOOL},   /* fill in fully-selected faces with a grid */
@@ -917,9 +916,9 @@ static BMOpDefine bmo_subdivide_edges_def = {
        },
        /* slots_out */
        {/* these next three can have multiple types of elements in them */
-        {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF},
-        {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF},
-        {"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* contains all output geometr */
+        {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+        {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+        {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometr */
         {{'\0'}},
        },
        bmo_subdivide_edges_exec,
@@ -929,7 +928,7 @@ static BMOpDefine bmo_subdivide_edges_def = {
 static BMOpDefine bmo_delete_def = {
        "delete",
        /* slots_in */
-       {{"geom", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
         {"context", BMO_OP_SLOT_INT},
         {{'\0'}},
        },
@@ -941,19 +940,19 @@ static BMOpDefine bmo_delete_def = {
 static BMOpDefine bmo_duplicate_def = {
        "duplicate",
        /* slots_in */
-       {{"geom", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
        /* destination bmesh, if NULL will use current on */
-        {"dest", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_BMESH},
+        {"dest", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
         {{'\0'}},
        },
        /* slots_out */
-       {{"geom_orig.out", BMO_OP_SLOT_ELEMENT_BUF},
-        {"geom.out", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"geom_orig.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+        {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
        /* facemap maps from source faces to dupe
         * faces, and from dupe faces to source faces */
-        {"facemap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM},
-        {"boundarymap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM},
-        {"isovertmap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM},
+        {"facemap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+        {"boundarymap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+        {"isovertmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
        {{'\0'}},
        },
        bmo_duplicate_exec,
@@ -963,16 +962,16 @@ static BMOpDefine bmo_duplicate_def = {
 static BMOpDefine bmo_split_def = {
        "split",
        /* slots_in */
-       {{"geom", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
        /* destination bmesh, if NULL will use current one */
-        {"dest", BMO_OP_SLOT_PTR, BMO_OP_SLOT_SUBTYPE_PTR_BMESH},
+        {"dest", BMO_OP_SLOT_PTR, {BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
         {"use_only_faces", BMO_OP_SLOT_BOOL},  /* when enabled. don't duplicate loose verts/edges */
         {{'\0'}},
        },
        /* slots_out */
-       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF},
-        {"boundarymap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM},
-        {"isovertmap.out", BMO_OP_SLOT_MAPPING, BMO_OP_SLOT_SUBTYPE_MAP_ELEM},
+       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+        {"boundarymap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+        {"isovertmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
         {{'\0'}},
        },
        bmo_split_exec,
@@ -988,7 +987,7 @@ static BMOpDefine bmo_split_def = {
 static BMOpDefine bmo_spin_def = {
        "spin",
        /* slots_in */
-       {{"geom", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
         {"cent", BMO_OP_SLOT_VEC},             /* rotation center */
         {"axis", BMO_OP_SLOT_VEC},             /* rotation axis */
         {"dvec", BMO_OP_SLOT_VEC},             /* translation delta per step */
@@ -998,7 +997,7 @@ static BMOpDefine bmo_spin_def = {
         {{'\0'}},
        },
        /* slots_out */
-       {{"geom_last.out", BMO_OP_SLOT_ELEMENT_BUF}, /* result of last step */
+       {{"geom_last.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* result of last step */
         {{'\0'}},
        },
        bmo_spin_exec,
@@ -1014,14 +1013,14 @@ static BMOpDefine bmo_spin_def = {
 static BMOpDefine bmo_similar_faces_def = {
        "similar_faces",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF},    /* input faces */
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
         {"type", BMO_OP_SLOT_INT},             /* type of selection */
         {"thresh", BMO_OP_SLOT_FLT},           /* threshold of selection */
         {"compare", BMO_OP_SLOT_INT},          /* comparison method */
         {{'\0'}},
        },
        /* slots_out */
-       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF},  /* output faces */
+       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},  /* output faces */
         {{'\0'}},
        },
        bmo_similar_faces_exec,
@@ -1036,14 +1035,14 @@ static BMOpDefine bmo_similar_faces_def = {
 static BMOpDefine bmo_similar_edges_def = {
        "similar_edges",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF},    /* input edges */
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
         {"type", BMO_OP_SLOT_INT},             /* type of selection */
         {"thresh", BMO_OP_SLOT_FLT},           /* threshold of selection */
         {"compare", BMO_OP_SLOT_INT},          /* comparison method */
         {{'\0'}},
        },
        /* slots_out */
-       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF},  /* output edges */
+       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},  /* output edges */
         {{'\0'}},
        },
        bmo_similar_edges_exec,
@@ -1058,14 +1057,14 @@ static BMOpDefine bmo_similar_edges_def = {
 static BMOpDefine bmo_similar_verts_def = {
        "similar_verts",
        /* slots_in */
-       {{"verts", BMO_OP_SLOT_ELEMENT_BUF},    /* input vertices */
+       {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
         {"type", BMO_OP_SLOT_INT},             /* type of selection */
         {"thresh", BMO_OP_SLOT_FLT},           /* threshold of selection */
         {"compare", BMO_OP_SLOT_INT},          /* comparison method */
         {{'\0'}},
        },
        /* slots_out */
-       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF},  /* output vertices */
+       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},  /* output vertices */
         {{'\0'}},
        },
        bmo_similar_verts_exec,
@@ -1079,7 +1078,7 @@ static BMOpDefine bmo_similar_verts_def = {
 static BMOpDefine bmo_rotate_uvs_def = {
        "rotate_uvs",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF},    /* input faces */
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
         {"use_ccw", BMO_OP_SLOT_BOOL},         /* rotate counter-clockwise if true, othewise clockwise */
         {{'\0'}},
        },
@@ -1096,7 +1095,7 @@ static BMOpDefine bmo_rotate_uvs_def = {
 static BMOpDefine bmo_reverse_uvs_def = {
        "reverse_uvs",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF},    /* input faces */
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -1111,7 +1110,7 @@ static BMOpDefine bmo_reverse_uvs_def = {
 static BMOpDefine bmo_rotate_colors_def = {
        "rotate_colors",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF},    /* input faces */
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
         {"use_ccw", BMO_OP_SLOT_BOOL},         /* rotate counter-clockwise if true, othewise clockwise */
         {{'\0'}},
        },
@@ -1127,7 +1126,7 @@ static BMOpDefine bmo_rotate_colors_def = {
 static BMOpDefine bmo_reverse_colors_def = {
        "reverse_colors",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF},    /* input faces */
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
         {{'\0'}},
        },
        {{{'\0'}}},  /* no output */
@@ -1143,13 +1142,13 @@ static BMOpDefine bmo_reverse_colors_def = {
 static BMOpDefine bmo_shortest_path_def = {
        "shortest_path",
        /* slots_in */
-       {{"startv", BMO_OP_SLOT_ELEMENT_BUF},   /* start vertex */
-        {"endv", BMO_OP_SLOT_ELEMENT_BUF},     /* end vertex */
+       {{"startv", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}},   /* start vertex */
+        {"endv", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}},     /* end vertex */
         {"type", BMO_OP_SLOT_INT},             /* type of selection */
         {{'\0'}},
        },
        /* slots_out */
-       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output vertices */
+       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output vertices */
         {{'\0'}},
        },
        bmo_shortest_path_exec,
@@ -1164,14 +1163,14 @@ static BMOpDefine bmo_shortest_path_def = {
 static BMOpDefine bmo_split_edges_def = {
        "split_edges",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF},    /* input edges */
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
         /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */
-        {"verts", BMO_OP_SLOT_ELEMENT_BUF},    /* optional tag verts, use to have greater control of splits */
+        {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* optional tag verts, use to have greater control of splits */
         {"use_verts",        BMO_OP_SLOT_BOOL}, /* use 'verts' for splitting, else just find verts to split from edges */
         {{'\0'}},
        },
        /* slots_out */
-       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF}, /* old output disconnected edges */
+       {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* old output disconnected edges */
         {{'\0'}},
        },
        bmo_split_edges_exec,
@@ -1193,7 +1192,7 @@ static BMOpDefine bmo_create_grid_def = {
         {{'\0'}},
        },
        /* slots_out */
-       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */
+       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
         {{'\0'}},
        },
        bmo_create_grid_exec,
@@ -1215,7 +1214,7 @@ static BMOpDefine bmo_create_uvsphere_def = {
         {{'\0'}},
        },
        /* slots_out */
-       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */
+       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
         {{'\0'}},
        },
        bmo_create_uvsphere_exec,
@@ -1236,7 +1235,7 @@ static BMOpDefine bmo_create_icosphere_def = {
         {{'\0'}},
        },
        /* slots_out */
-       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */
+       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
         {{'\0'}},
        },
        bmo_create_icosphere_exec,
@@ -1255,7 +1254,7 @@ static BMOpDefine bmo_create_monkey_def = {
         {{'\0'}},
        },
        /* slots_out */
-       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */
+       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
         {{'\0'}},
        },
        bmo_create_monkey_exec,
@@ -1280,7 +1279,7 @@ static BMOpDefine bmo_create_cone_def = {
         {{'\0'}},
        },
        /* slots_out */
-       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */
+       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
         {{'\0'}},
        },
        bmo_create_cone_exec,
@@ -1301,7 +1300,7 @@ static BMOpDefine bmo_create_circle_def = {
         {{'\0'}},
        },
        /* slots_out */
-       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */
+       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
         {{'\0'}},
        },
        bmo_create_circle_exec,
@@ -1321,7 +1320,7 @@ static BMOpDefine bmo_create_cube_def = {
         {{'\0'}},
        },
        /* slots_out */
-       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output verts */
+       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
         {{'\0'}},
        },
        bmo_create_cube_exec,
@@ -1336,19 +1335,19 @@ static BMOpDefine bmo_create_cube_def = {
 static BMOpDefine bmo_bevel_def = {
        "bevel",
        /* slots_in */
-       {{"geom", BMO_OP_SLOT_ELEMENT_BUF},     /* input edges and vertices */
+       {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},     /* input edges and vertices */
         {"offset", BMO_OP_SLOT_FLT},           /* amount to offset beveled edge */
         {"segments", BMO_OP_SLOT_INT},         /* number of segments in bevel */
         {{'\0'}},
        },
        /* slots_out */
-       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output faces */
+       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
         {{'\0'}},
        },
 #if 0  /* old bevel*/
-       {{"geom", BMO_OP_SLOT_ELEMENT_BUF}, /* input edges and vertices */
-        {"face_spans", BMO_OP_SLOT_ELEMENT_BUF}, /* new geometry */
-        {"face_holes", BMO_OP_SLOT_ELEMENT_BUF}, /* new geometry */
+       {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input edges and vertices */
+        {"face_spans", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new geometry */
+        {"face_holes", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new geometry */
         {"use_lengths", BMO_OP_SLOT_BOOL}, /* grab edge lengths from a PROP_FLT customdata layer */
         {"use_even", BMO_OP_SLOT_BOOL}, /* corner vert placement: use shell/angle calculations  */
         {"use_dist", BMO_OP_SLOT_BOOL}, /* corner vert placement: evaluate percent as a distance,
@@ -1370,12 +1369,12 @@ static BMOpDefine bmo_bevel_def = {
 static BMOpDefine bmo_beautify_fill_def = {
        "beautify_fill",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF}, /* input faces */
-        {"constrain_edges", BMO_OP_SLOT_ELEMENT_BUF}, /* edges that can't be flipped */
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+        {"constrain_edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* edges that can't be flipped */
         {{'\0'}},
        },
        /* slots_out */
-       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* new flipped faces and edges */
+       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new flipped faces and edges */
         {{'\0'}},
        },
        bmo_beautify_fill_exec,
@@ -1390,11 +1389,11 @@ static BMOpDefine bmo_beautify_fill_def = {
 static BMOpDefine bmo_triangle_fill_def = {
        "triangle_fill",
        /* slots_in */
-       {{"edges", BMO_OP_SLOT_ELEMENT_BUF},    /* input edges */
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input edges */
         {{'\0'}},
        },
        /* slots_out */
-       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF}, /* new faces and edges */
+       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new faces and edges */
         {{'\0'}},
        },
        bmo_triangle_fill_exec,
@@ -1409,12 +1408,12 @@ static BMOpDefine bmo_triangle_fill_def = {
 static BMOpDefine bmo_solidify_def = {
        "solidify",
        /* slots_in */
-       {{"geom", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
         {"thickness", BMO_OP_SLOT_FLT},
         {{'\0'}},
        },
        /* slots_out */
-       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
         {{'\0'}},
        },
        bmo_solidify_face_region_exec,
@@ -1429,7 +1428,7 @@ static BMOpDefine bmo_solidify_def = {
 static BMOpDefine bmo_inset_def = {
        "inset",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF},    /* input faces */
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input faces */
         {"use_boundary", BMO_OP_SLOT_BOOL},
         {"use_even_offset", BMO_OP_SLOT_BOOL},
         {"use_relative_offset", BMO_OP_SLOT_BOOL},
@@ -1439,7 +1438,7 @@ static BMOpDefine bmo_inset_def = {
         {{'\0'}},
        },
        /* slots_out */
-       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output faces */
+       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
         {{'\0'}},
        },
        bmo_inset_exec,
@@ -1454,7 +1453,7 @@ static BMOpDefine bmo_inset_def = {
 static BMOpDefine bmo_wireframe_def = {
        "wireframe",
        /* slots_in */
-       {{"faces", BMO_OP_SLOT_ELEMENT_BUF},   /* input faces */
+       {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},   /* input faces */
         {"use_boundary", BMO_OP_SLOT_BOOL},
         {"use_even_offset", BMO_OP_SLOT_BOOL},
         {"use_crease", BMO_OP_SLOT_BOOL},
@@ -1464,7 +1463,7 @@ static BMOpDefine bmo_wireframe_def = {
         {{'\0'}},
        },
        /* slots_out */
-       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF}, /* output faces */
+       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
         {{'\0'}},
        },
        bmo_wireframe_exec,
@@ -1479,13 +1478,13 @@ static BMOpDefine bmo_wireframe_def = {
 static BMOpDefine bmo_slide_vert_def = {
        "slide_vert",
        /* slots_in */
-       {{"vert", BMO_OP_SLOT_ELEMENT_BUF},
-        {"edge", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"vert", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}},
+        {"edge", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}},
         {"distance_t", BMO_OP_SLOT_FLT},
         {{'\0'}},
        },
        /* slots_out */
-       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
         {{'\0'}},
        },
        bmo_slide_vert_exec,
@@ -1511,15 +1510,15 @@ static BMOpDefine bmo_slide_vert_def = {
 static BMOpDefine bmo_convex_hull_def = {
        "convex_hull",
        /* slots_in */
-       {{"input", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
         {"use_existing_faces", BMO_OP_SLOT_BOOL},
         {{'\0'}},
        },
        /* slots_out */
-       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF},
-        {"geom_interior.out", BMO_OP_SLOT_ELEMENT_BUF},
-        {"geom_unused.out", BMO_OP_SLOT_ELEMENT_BUF},
-        {"geom_holes.out", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+        {"geom_interior.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+        {"geom_unused.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+        {"geom_holes.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
         {{'\0'}},
        },
        bmo_convex_hull_exec,
@@ -1540,12 +1539,12 @@ static BMOpDefine bmo_convex_hull_def = {
 static BMOpDefine bmo_symmetrize_def = {
        "symmetrize",
        /* slots_in */
-       {{"input", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
         {"direction", BMO_OP_SLOT_INT},
         {{'\0'}},
        },
        /* slots_out */
-       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF},
+       {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
         {{'\0'}},
        },
        bmo_symmetrize_exec,
index e84883540d62153930bc6bcc4a059ebfd405d5d6..245a53ebed2408bd75fb7f1ac6022e08cfd4e2bd 100644 (file)
@@ -112,35 +112,43 @@ typedef enum eBMOpSlotType {
 } eBMOpSlotType;
 #define BMO_OP_SLOT_TOTAL_TYPES 11
 
-/* leave zero for invalid/unset */
-typedef enum eBMOpSlotSubType {
-       /* BMO_OP_SLOT_MAPPING */
-#define BMO_OP_SLOT_SUBTYPE_MAP__FIRST BMO_OP_SLOT_SUBTYPE_MAP_EMPTY
-       BMO_OP_SLOT_SUBTYPE_MAP_EMPTY    = 1,  /* use as a set(), unused value */
-       BMO_OP_SLOT_SUBTYPE_MAP_ELEM     = 2,
-       BMO_OP_SLOT_SUBTYPE_MAP_FLOAT    = 3,
-       BMO_OP_SLOT_SUBTYPE_MAP_INT      = 4,
-       BMO_OP_SLOT_SUBTYPE_MAP_BOOL     = 5,
-       BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL = 6,  /* python can't convert these */
-#define BMO_OP_SLOT_SUBTYPE_MAP__LAST BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL
-
-       /* BMO_OP_SLOT_PTR */
-#define BMO_OP_SLOT_SUBTYPE_PTR__FIRST BMO_OP_SLOT_SUBTYPE_PTR_BMESH
-       BMO_OP_SLOT_SUBTYPE_PTR_BMESH  = 10,
-       BMO_OP_SLOT_SUBTYPE_PTR_SCENE  = 11,
-       BMO_OP_SLOT_SUBTYPE_PTR_OBJECT = 12,
-       BMO_OP_SLOT_SUBTYPE_PTR_MESH   = 13,
-#define BMO_OP_SLOT_SUBTYPE_PTR__LAST BMO_OP_SLOT_SUBTYPE_PTR_MESH
-
-} eBMOpSlotSubType;
+/* don't overlap values to avoid confusion */
+typedef enum eBMOpSlotSubType_Elem {
+       /* use as flags */
+       BMO_OP_SLOT_SUBTYPE_ELEM_VERT = BM_VERT,
+       BMO_OP_SLOT_SUBTYPE_ELEM_EDGE = BM_EDGE,
+       BMO_OP_SLOT_SUBTYPE_ELEM_FACE = BM_FACE,
+       BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE = (BM_FACE << 1),
+} eBMOpSlotSubType_Elem;
+typedef enum eBMOpSlotSubType_Map {
+       BMO_OP_SLOT_SUBTYPE_MAP_EMPTY    = 64,  /* use as a set(), unused value */
+       BMO_OP_SLOT_SUBTYPE_MAP_ELEM     = 65,
+       BMO_OP_SLOT_SUBTYPE_MAP_FLOAT    = 66,
+       BMO_OP_SLOT_SUBTYPE_MAP_INT      = 67,
+       BMO_OP_SLOT_SUBTYPE_MAP_BOOL     = 68,
+       BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL = 69,  /* python can't convert these */
+} eBMOpSlotSubType_Map;
+typedef enum eBMOpSlotSubType_Ptr {
+       BMO_OP_SLOT_SUBTYPE_PTR_BMESH  = 100,
+       BMO_OP_SLOT_SUBTYPE_PTR_SCENE  = 101,
+       BMO_OP_SLOT_SUBTYPE_PTR_OBJECT = 102,
+       BMO_OP_SLOT_SUBTYPE_PTR_MESH   = 103,
+} eBMOpSlotSubType_Ptr;
+
+typedef union eBMOpSlotSubType_Union {
+       eBMOpSlotSubType_Map elem;
+       eBMOpSlotSubType_Map ptr;
+       eBMOpSlotSubType_Map map;
+} eBMOpSlotSubType_Union;
 
 /* please ignore all these structures, don't touch them in tool code, except
  * for when your defining an operator with BMOpDefine.*/
 
 typedef struct BMOpSlot {
        const char *slot_name;  /* pointer to BMOpDefine.slot_args */
-       eBMOpSlotType    slot_type;
-       eBMOpSlotSubType slot_subtype;
+       eBMOpSlotType          slot_type;
+       eBMOpSlotSubType_Union slot_subtype;
+
        int len;
 //     int flag;  /* UNUSED */
 //     int index; /* index within slot array */  /* UNUSED */
@@ -190,8 +198,8 @@ enum {
 
 typedef struct BMOSlotType {
        char name[MAX_SLOTNAME];
-       eBMOpSlotType    type;
-       eBMOpSlotSubType subtype;
+       eBMOpSlotType          type;
+       eBMOpSlotSubType_Union subtype;
 } BMOSlotType;
 
 typedef struct BMOpDefine {
index 4143c4d08832f35207edc03aa2edbc157972af2b..96c37b45b05b66899ccd2cd2779432fba9951b7b 100644 (file)
@@ -72,14 +72,14 @@ BLI_INLINE void _bmo_elem_flag_toggle(BMesh *bm, BMFlagLayer *oflags, const shor
 BLI_INLINE void BMO_slot_map_int_insert(BMOperator *op, BMOpSlot *slot,
                                         void *element, const int val)
 {
-       BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INT);
+       BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
        BMO_slot_map_insert(op, slot, element, &val, sizeof(int));
 }
 
 BLI_INLINE void BMO_slot_map_bool_insert(BMOperator *op, BMOpSlot *slot,
                                         void *element, const int val)
 {
-       BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
+       BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
        BLI_assert(val == FALSE || val == TRUE);
        BMO_slot_map_insert(op, slot, element, &val, sizeof(int));
 }
@@ -87,7 +87,7 @@ BLI_INLINE void BMO_slot_map_bool_insert(BMOperator *op, BMOpSlot *slot,
 BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot *slot,
                                           void *element, const float val)
 {
-       BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT);
+       BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT);
        BMO_slot_map_insert(op, slot, element, &val, sizeof(float));
 }
 
@@ -100,14 +100,14 @@ BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot *slot,
 BLI_INLINE void BMO_slot_map_ptr_insert(BMOperator *op, BMOpSlot *slot,
                                         const void *element, void *val)
 {
-       BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
+       BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
        BMO_slot_map_insert(op, slot, element, &val, sizeof(void *));
 }
 
 BLI_INLINE void BMO_slot_map_elem_insert(BMOperator *op, BMOpSlot *slot,
                                         const void *element, void *val)
 {
-       BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
+       BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
        BMO_slot_map_insert(op, slot, element, &val, sizeof(void *));
 }
 
@@ -116,7 +116,7 @@ BLI_INLINE void BMO_slot_map_elem_insert(BMOperator *op, BMOpSlot *slot,
 BLI_INLINE void BMO_slot_map_empty_insert(BMOperator *op, BMOpSlot *slot,
                                         const void *element)
 {
-       BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_EMPTY);
+       BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_EMPTY);
        BMO_slot_map_insert(op, slot, element, NULL, 0);
 }
 
@@ -154,7 +154,7 @@ BLI_INLINE void *BMO_slot_map_data_get(BMOpSlot *slot, const void *element)
 BLI_INLINE float BMO_slot_map_float_get(BMOpSlot *slot, const void *element)
 {
        float *val;
-       BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT);
+       BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLOAT);
 
        val = (float *) BMO_slot_map_data_get(slot, element);
        if (val) return *val;
@@ -165,7 +165,7 @@ BLI_INLINE float BMO_slot_map_float_get(BMOpSlot *slot, const void *element)
 BLI_INLINE int BMO_slot_map_int_get(BMOpSlot *slot, const void *element)
 {
        int *val;
-       BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INT);
+       BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
 
        val = (int *) BMO_slot_map_data_get(slot, element);
        if (val) return *val;
@@ -176,7 +176,7 @@ BLI_INLINE int BMO_slot_map_int_get(BMOpSlot *slot, const void *element)
 BLI_INLINE int BMO_slot_map_bool_get(BMOpSlot *slot, const void *element)
 {
        int *val;
-       BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
+       BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
 
        val = (int *) BMO_slot_map_data_get(slot, element);
        BLI_assert(val == NULL || *val == FALSE || *val == TRUE);
@@ -188,7 +188,7 @@ BLI_INLINE int BMO_slot_map_bool_get(BMOpSlot *slot, const void *element)
 BLI_INLINE void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element)
 {
        void **val = (void **) BMO_slot_map_data_get(slot, element);
-       BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
+       BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
        if (val) return *val;
 
        return NULL;
@@ -197,7 +197,7 @@ BLI_INLINE void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element)
 BLI_INLINE void *BMO_slot_map_elem_get(BMOpSlot *slot, const void *element)
 {
        void **val = (void **) BMO_slot_map_data_get(slot, element);
-       BLI_assert(slot->slot_subtype == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
+       BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
        if (val) return *val;
 
        return NULL;
index 83fd338ef1fcd8f972c74f6fd211e9d5c2fe6d78..f1bf4fd4d373f99059c1613e686e1ab39aff8352 100644 (file)
@@ -884,6 +884,7 @@ static void bmo_slot_buffer_from_flag(BMesh *bm, BMOperator *op,
                totelement = BMO_mesh_disabled_flag_count(bm, htype, oflag);
 
        BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+       BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
 
        if (totelement) {
                BMIter iter;
@@ -959,6 +960,7 @@ void BMO_slot_buffer_hflag_enable(BMesh *bm,
        const char do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
 
        BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+       BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
 
        for (i = 0; i < slot->len; i++, data++) {
                if (!(htype & (*data)->head.htype))
@@ -993,6 +995,7 @@ void BMO_slot_buffer_hflag_disable(BMesh *bm,
        const char do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
 
        BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+       BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
 
        for (i = 0; i < slot->len; i++, data++) {
                if (!(htype & (*data)->head.htype))
@@ -1043,6 +1046,7 @@ void BMO_slot_buffer_flag_enable(BMesh *bm,
        int i;
 
        BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+       BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
 
        for (i = 0; i < slot->len; i++) {
                if (!(htype & data[i]->htype))
@@ -1066,6 +1070,7 @@ void BMO_slot_buffer_flag_disable(BMesh *bm,
        int i;
 
        BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+       BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
 
        for (i = 0; i < slot->len; i++) {
                if (!(htype & data[i]->htype))
@@ -1256,25 +1261,29 @@ void *BMO_iter_new(BMOIter *iter,
 
 void *BMO_iter_step(BMOIter *iter)
 {
-       if (iter->slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF) {
-               BMHeader *h;
+       BMOpSlot *slot = iter->slot;
+       if (slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF) {
+               BMHeader *ele;
 
-               if (iter->cur >= iter->slot->len) {
+               if (iter->cur >= slot->len) {
                        return NULL;
                }
 
-               h = iter->slot->data.buf[iter->cur++];
-               while (!(iter->restrictmask & h->htype)) {
-                       if (iter->cur >= iter->slot->len) {
+               ele = slot->data.buf[iter->cur++];
+               while (!(iter->restrictmask & ele->htype)) {
+                       if (iter->cur >= slot->len) {
                                return NULL;
                        }
 
-                       h = iter->slot->data.buf[iter->cur++];
+                       ele = slot->data.buf[iter->cur++];
+                       BLI_assert((ele == NULL) || (slot->slot_subtype.elem & ele->htype));
                }
 
-               return h;
+               BLI_assert((ele == NULL) || (slot->slot_subtype.elem & ele->htype));
+
+               return ele;
        }
-       else if (iter->slot->slot_type == BMO_OP_SLOT_MAPPING) {
+       else if (slot->slot_type == BMO_OP_SLOT_MAPPING) {
                BMOElemMapping *map;
                void *ret = BLI_ghashIterator_getKey(&iter->giter);
                map = BLI_ghashIterator_getValue(&iter->giter);
@@ -1285,6 +1294,9 @@ void *BMO_iter_step(BMOIter *iter)
 
                return ret;
        }
+       else {
+               BLI_assert(0);
+       }
 
        return NULL;
 }
index 591c758fbb2b4157cb717f13c0264af469eea975..f278d3f8896912df3b9fb6c36f171da9bd27c385 100644 (file)
@@ -330,7 +330,7 @@ void bmo_duplicate_exec(BMesh *bm, BMOperator *op)
                bm2 = bm;
 
        /* flag input */
-       BMO_slot_buffer_flag_enable(bm, dupeop->slots_in, "geom", BM_ALL, DUPE_INPUT);
+       BMO_slot_buffer_flag_enable(bm, dupeop->slots_in, "geom", BM_ALL_NOLOOP, DUPE_INPUT);
 
        /* use the internal copy function */
        bmo_mesh_copy(dupeop, bm, bm2);
@@ -341,7 +341,7 @@ void bmo_duplicate_exec(BMesh *bm, BMOperator *op)
                      dupeop, slots_out, "geom_orig.out");
 
        /* Now alloc the new output buffers */
-       BMO_slot_buffer_from_enabled_flag(bm, dupeop, dupeop->slots_out, "geom.out", BM_ALL, DUPE_NEW);
+       BMO_slot_buffer_from_enabled_flag(bm, dupeop, dupeop->slots_out, "geom.out", BM_ALL_NOLOOP, DUPE_NEW);
 }
 
 #if 0 /* UNUSED */
@@ -396,7 +396,7 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
                      &dupeop, slots_in, "geom");
        BMO_op_exec(bm, &dupeop);
        
-       BMO_slot_buffer_flag_enable(bm, splitop->slots_in, "geom", BM_ALL, SPLIT_INPUT);
+       BMO_slot_buffer_flag_enable(bm, splitop->slots_in, "geom", BM_ALL_NOLOOP, SPLIT_INPUT);
 
        if (use_only_faces) {
                BMVert *v;
@@ -437,7 +437,7 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
 
        /* connect outputs of dupe to delete, exluding keep geometry */
        BMO_slot_int_set(delop.slots_in, "context", DEL_FACES);
-       BMO_slot_buffer_from_enabled_flag(bm, &delop, delop.slots_in, "geom", BM_ALL, SPLIT_INPUT);
+       BMO_slot_buffer_from_enabled_flag(bm, &delop, delop.slots_in, "geom", BM_ALL_NOLOOP, SPLIT_INPUT);
        
        BMO_op_exec(bm, &delop);
 
@@ -465,7 +465,7 @@ void bmo_delete_exec(BMesh *bm, BMOperator *op)
        BMOperator *delop = op;
 
        /* Mark Buffer */
-       BMO_slot_buffer_flag_enable(bm, delop->slots_in, "geom", BM_ALL, DEL_INPUT);
+       BMO_slot_buffer_flag_enable(bm, delop->slots_in, "geom", BM_ALL_NOLOOP, DEL_INPUT);
 
        BMO_remove_tagged_context(bm, DEL_INPUT, BMO_slot_int_get(op->slots_in, "context"));
 
index 25ebf32b25a99806d18d86fcef57e216573050c5..aece270b09c06b19364bbd43f37b363d5f141f1a 100644 (file)
@@ -230,7 +230,7 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
 
        BMO_op_finish(bm, &dupeop);
 
-       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, EXT_KEEP);
+       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, EXT_KEEP);
 }
 
 void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
index 6435f44f1d6d044bf2b3ab483269b7dfbd73edf2..41cfae579ff822b8c9940f62d5b7f8990b9f4888 100644 (file)
@@ -66,7 +66,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
        BMO_op_initf(bm, &dupeop, op->flag, "duplicate geom=%s", op, "geom");
        BMO_op_exec(bm, &dupeop);
        
-       BMO_slot_buffer_flag_enable(bm, dupeop.slots_out, "geom.out", BM_ALL, ELE_NEW);
+       BMO_slot_buffer_flag_enable(bm, dupeop.slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW);
 
        /* create old -> new mappin */
        i = 0;
@@ -123,7 +123,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
        BMO_op_finish(bm, &weldop);
        BMO_op_finish(bm, &dupeop);
 
-       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, ELE_NEW);
+       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW);
 
        BLI_array_free(vmap);
        BLI_array_free(emap);
index 1926e9a0f681c92f778f2ca8084c542665418af2..8da1f5ebfe5d0e15238b18a6de040678ca17ad29 100644 (file)
@@ -1082,10 +1082,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
        BLI_array_free(loops_split);
        BLI_array_free(loops);
 
-       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_inner.out", BM_ALL, ELE_INNER);
-       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL, ELE_SPLIT);
+       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_inner.out", BM_ALL_NOLOOP, ELE_INNER);
+       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL_NOLOOP, ELE_SPLIT);
        
-       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, ELE_INNER | ELE_SPLIT | SUBD_SPLIT);
+       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_INNER | ELE_SPLIT | SUBD_SPLIT);
 }
 
 /* editmesh-emulating function */
@@ -1182,7 +1182,7 @@ void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op)
                bm_subdivide_multicut(bm, e, &params, e->v1, e->v2);
        }
 
-       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL, ELE_SPLIT);
+       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL_NOLOOP, ELE_SPLIT);
 
        BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, skey);
 }
index d56b2ca0d7346b842e3b2186cc7bef80ceabd25e..203acff833226425236763125056e76456383c2c 100644 (file)
@@ -268,14 +268,14 @@ void bmo_region_extend_exec(BMesh *bm, BMOperator *op)
        int use_faces = BMO_slot_bool_get(op->slots_in, "use_faces");
        int constrict = BMO_slot_bool_get(op->slots_in, "use_constrict");
 
-       BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL, SEL_ORIG);
+       BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL_NOLOOP, SEL_ORIG);
 
        if (constrict)
                bmo_region_extend_constrict(bm, op, use_faces);
        else
                bmo_region_extend_extend(bm, op, use_faces);
 
-       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, SEL_FLAG);
+       BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, SEL_FLAG);
 }
 
 /********* righthand faces implementation ****** */
index aed16be5b73083adb2afafe49f235c60a27ab339..47add7afb56cc00cbee3fb271e4c7daf6e48c2e1 100644 (file)
@@ -2067,7 +2067,7 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
                        }
                }
 
-               BLI_scanfill_calc(&sf_ctx, FALSE);
+               BLI_scanfill_calc(&sf_ctx, 0);
 
                for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
                        BMVert *v1 = sf_tri->v3->tmp.p, *v2 = sf_tri->v2->tmp.p, *v3 = sf_tri->v1->tmp.p;
index b46961a95d7e49870153e9222b04d2968adc7f1b..c658272f23f29144c77362644fffd139810d86d0 100644 (file)
@@ -732,7 +732,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
        EDBM_flag_disable_all(em, BM_ELEM_SELECT);
 
        /* select the output */
-       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
 
        /* finish the operator */
        if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
@@ -773,7 +773,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op)
        EDBM_flag_disable_all(em, BM_ELEM_SELECT);
 
        /* select the output */
-       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
        EDBM_selectmode_flush(em);
 
        /* finish the operator */
@@ -817,7 +817,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
        EDBM_flag_disable_all(em, BM_ELEM_SELECT);
 
        /* select the output */
-       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
 
        /* finish the operator */
        if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
index c32033054e0bfc874035d7c0446ff4d9f5a0f91e..3f865678a8902afe34c85cc34fa441fa38cbd398 100644 (file)
@@ -738,10 +738,10 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u
        BMO_op_exec(bm, &bmop);
 
        /* Deselect the input edges */
-       BMO_slot_buffer_hflag_disable(bm, bmop.slots_in, "edge", BM_ALL, BM_ELEM_SELECT, TRUE);
+       BMO_slot_buffer_hflag_disable(bm, bmop.slots_in, "edge", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
 
        /* Select the output vert */
-       BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "verts.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+       BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "verts.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
 
        /* Flush the select buffers */
        EDBM_selectmode_flush(em);
index 335f2a8c8293f23634e64e418e551ae0b2706c48..f28bb753122ea1b6773b975efa2caad5f2a0c868 100644 (file)
@@ -1343,7 +1343,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op)
        BMO_op_exec(em->bm, &bmop);
        EDBM_flag_disable_all(em, BM_ELEM_SELECT);
 
-       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
 
        if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
                return OPERATOR_CANCELLED;
@@ -2317,7 +2317,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op)
        /* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */
 
        /* select the output */
-       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
 
        /* finish the operator */
        if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
@@ -3596,7 +3596,7 @@ static int edbm_split_exec(bContext *C, wmOperator *op)
        EDBM_op_init(em, &bmop, op, "split geom=%hvef use_only_faces=%b", BM_ELEM_SELECT, FALSE);
        BMO_op_exec(em->bm, &bmop);
        BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE);
-       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
        if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
                return OPERATOR_CANCELLED;
        }
@@ -3658,7 +3658,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
        }
        BMO_op_exec(bm, &spinop);
        EDBM_flag_disable_all(em, BM_ELEM_SELECT);
-       BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+       BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
        if (!EDBM_op_finish(em, &spinop, op, TRUE)) {
                return OPERATOR_CANCELLED;
        }
@@ -3782,7 +3782,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
        }
        BMO_op_exec(bm, &spinop);
        EDBM_flag_disable_all(em, BM_ELEM_SELECT);
-       BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL, BM_ELEM_SELECT, TRUE);
+       BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
        if (!EDBM_op_finish(em, &spinop, op, TRUE)) {
                return OPERATOR_CANCELLED;
        }
index 22c71d5d3ca418ddb7636fc96f5937b59b223e8c..639e766826632e4701e460a71be32f07a1501e36 100644 (file)
@@ -285,7 +285,7 @@ int EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select_
 
        BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, FALSE);
 
-       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, select_slot_out, BM_ALL, BM_ELEM_SELECT, TRUE);
+       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, select_slot_out, BM_ALL_NOLOOP, BM_ELEM_SELECT, TRUE);
 
        va_end(list);
        return EDBM_op_finish(em, &bmop, op, TRUE);
@@ -498,7 +498,7 @@ void EDBM_select_more(BMEditMesh *em)
                     BM_ELEM_SELECT, FALSE, use_faces);
        BMO_op_exec(em->bm, &bmop);
        /* don't flush selection in edge/vertex mode  */
-       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
+       BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
        BMO_op_finish(em->bm, &bmop);
 
        EDBM_select_flush(em);
@@ -514,7 +514,7 @@ void EDBM_select_less(BMEditMesh *em)
                     BM_ELEM_SELECT, TRUE, use_faces);
        BMO_op_exec(em->bm, &bmop);
        /* don't flush selection in edge/vertex mode  */
-       BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "geom.out", BM_ALL, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
+       BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, use_faces ? TRUE : FALSE);
        BMO_op_finish(em->bm, &bmop);
 
        EDBM_selectmode_flush(em);
index 84b06504d2e4fd2a4ce19cef3d4a7e31161c357e..09dda7261a8cffd1e3693dcd47e2812ca67b3365 100644 (file)
@@ -242,18 +242,35 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
            return NULL;                                                                      \
        } (void)0
 
+#define BPY_BM_ELEM_TYPE_TEST(type_string)  \
+       if ((slot->slot_subtype.elem & BM_VERT) == 0) { \
+           PyErr_Format(PyExc_TypeError, \
+                        "%.200s: keyword \"%.200s\" expected " \
+                        "a list of %.200s not " type_string, \
+                        self->opname, slot_name, \
+                        BPy_BMElem_StringFromHType(slot->slot_subtype.elem & BM_ALL)); \
+           return NULL; \
+       } (void)0
+
                                        if (BPy_BMVertSeq_Check(value)) {
                                                BPY_BM_GENERIC_MESH_TEST("verts");
+                                               BPY_BM_ELEM_TYPE_TEST("verts");
+
                                                BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_VERT);
                                        }
                                        else if (BPy_BMEdgeSeq_Check(value)) {
                                                BPY_BM_GENERIC_MESH_TEST("edges");
+                                               BPY_BM_ELEM_TYPE_TEST("edges");
                                                BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_EDGE);
                                        }
                                        else if (BPy_BMFaceSeq_Check(value)) {
                                                BPY_BM_GENERIC_MESH_TEST("faces");
+                                               BPY_BM_ELEM_TYPE_TEST("faces");
                                                BMO_slot_buffer_from_all(bm, &bmop, bmop.slots_in, slot_name, BM_FACE);
                                        }
+
+#undef BPY_BM_ELEM_TYPE_TEST
+
                                        else if (BPy_BMElemSeq_Check(value)) {
                                                BMIter iter;
                                                BMHeader *ele;
@@ -281,7 +298,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
                                                Py_ssize_t elem_array_len;
 
                                                elem_array = BPy_BMElem_PySeq_As_Array(&bm, value, 0, PY_SSIZE_T_MAX,
-                                                                                      &elem_array_len, BM_VERT | BM_EDGE | BM_FACE,
+                                                                                      &elem_array_len, (slot->slot_subtype.elem & BM_ALL_NOLOOP),
                                                                                       TRUE, TRUE, slot_name);
 
                                                /* error is set above */
@@ -308,7 +325,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
                                case BMO_OP_SLOT_MAPPING:
                                {
                                        /* first check types */
-                                       if (slot->slot_subtype != BMO_OP_SLOT_SUBTYPE_MAP_EMPTY) {
+                                       if (slot->slot_subtype.map != BMO_OP_SLOT_SUBTYPE_MAP_EMPTY) {
                                                if (!PyDict_Check(value)) {
                                                        PyErr_Format(PyExc_TypeError,
                                                                     "%.200s: keyword \"%.200s\" expected "
@@ -327,7 +344,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
                                                }
                                        }
 
-                                       switch (slot->slot_subtype) {
+                                       switch (slot->slot_subtype.map) {
 
                                                /* this could be a static function */
 #define BPY_BM_MAPPING_KEY_CHECK(arg_key)  \
@@ -467,7 +484,6 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
                                                        break;
                                                }
                                                case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL:
-                                               default:
                                                {
                                                        /* can't convert from these */
                                                        PyErr_Format(PyExc_NotImplementedError,
@@ -548,7 +564,7 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
                                        GHash *slot_hash = BMO_SLOT_AS_GHASH(slot);
                                        GHashIterator hash_iter;
 
-                                       switch (slot->slot_subtype) {
+                                       switch (slot->slot_subtype.map) {
                                                case BMO_OP_SLOT_SUBTYPE_MAP_ELEM:
                                                {
                                                        item = PyDict_New();
@@ -560,6 +576,8 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
                                                                        PyObject *py_key =  BPy_BMElem_CreatePyObject(bm,  ele_key);
                                                                        PyObject *py_val =  BPy_BMElem_CreatePyObject(bm, *(void **)BMO_OP_SLOT_MAPPING_DATA(ele_val));
 
+                                                                       BLI_assert(slot->slot_subtype.elem & ((BPy_BMElem *)py_val)->ele->head.htype);
+
                                                                        PyDict_SetItem(ret, py_key, py_val);
                                                                        Py_DECREF(py_key);
                                                                        Py_DECREF(py_val);
@@ -638,7 +656,6 @@ static PyObject *pyrna_op_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *
                                                        break;
                                                }
                                                case BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL:
-                                               default:
                                                        /* can't convert from these */
                                                        item = (Py_INCREF(Py_None), Py_None);
                                                        break;