Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-12-01 06:47:59 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-12-01 06:47:59 +0400
commited0e2fbd9f4edd55e11df694b34e233cb38cb953 (patch)
tree70a0d0fc080339b87cbeb73ebab6d4eda91ca5ba /source/blender/bmesh/intern
parent129a29873e552d769339c2b7d3b99a0afbbf2ae0 (diff)
parent75cce01a614e686530e26dbd186a88d75dc4e7b5 (diff)
Merged changes in the trunk up to revision 52690.
Conflicts resolved: release/datafiles/startup.blend source/blender/blenlib/intern/bpath.c
Diffstat (limited to 'source/blender/bmesh/intern')
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c28
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c106
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h15
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c31
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c7
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c1145
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api.h100
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api_inline.h63
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c219
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.h15
-rw-r--r--source/blender/bmesh/intern/bmesh_operators_private.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c23
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.h1
14 files changed, 1019 insertions, 740 deletions
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index eabbf6f87cd..c805a91ff22 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -105,17 +105,17 @@ BMFace *BM_face_create_quad_tri_v(BMesh *bm, BMVert **verts, int len, const BMFa
/* make new face */
if ((f == NULL) && (!is_overlap)) {
BMEdge *edar[4] = {NULL};
- edar[0] = BM_edge_create(bm, verts[0], verts[1], NULL, TRUE);
- edar[1] = BM_edge_create(bm, verts[1], verts[2], NULL, TRUE);
+ edar[0] = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE);
+ edar[1] = BM_edge_create(bm, verts[1], verts[2], NULL, BM_CREATE_NO_DOUBLE);
if (len == 4) {
- edar[2] = BM_edge_create(bm, verts[2], verts[3], NULL, TRUE);
- edar[3] = BM_edge_create(bm, verts[3], verts[0], NULL, TRUE);
+ edar[2] = BM_edge_create(bm, verts[2], verts[3], NULL, BM_CREATE_NO_DOUBLE);
+ edar[3] = BM_edge_create(bm, verts[3], verts[0], NULL, BM_CREATE_NO_DOUBLE);
}
else {
- edar[2] = BM_edge_create(bm, verts[2], verts[0], NULL, TRUE);
+ edar[2] = BM_edge_create(bm, verts[2], verts[0], NULL, BM_CREATE_NO_DOUBLE);
}
- f = BM_face_create(bm, verts, edar, len, FALSE);
+ f = BM_face_create(bm, verts, edar, len, 0);
if (example && f) {
BM_elem_attrs_copy(bm, bm, example, f);
@@ -171,7 +171,7 @@ void BM_face_copy_shared(BMesh *bm, BMFace *f)
* #BM_face_create should be considered over this function as it
* avoids some unnecessary work.
*/
-BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble)
+BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag)
{
BMEdge **edges2 = NULL;
BLI_array_staticdeclare(edges2, BM_DEFAULT_NGON_STACK_SIZE);
@@ -282,7 +282,7 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i
BM_ELEM_API_FLAG_DISABLE(verts[i], _FLAG_MV);
}
- f = BM_face_create(bm, verts, edges2, len, nodouble);
+ f = BM_face_create(bm, verts, edges2, len, create_flag);
/* clean up flags */
for (i = 0; i < len; i++) {
@@ -338,7 +338,7 @@ static int angle_index_pair_cmp(const void *e1, const void *e2)
*
* \note Since this is a vcloud there is no direction.
*/
-BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, int nodouble)
+BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, const int create_flag)
{
BMFace *f;
@@ -464,7 +464,7 @@ BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, int n
i_prev = totv - 1;
for (i = 0; i < totv; i++) {
- edge_arr[i] = BM_edge_create(bm, vert_arr_map[i_prev], vert_arr_map[i], NULL, TRUE);
+ edge_arr[i] = BM_edge_create(bm, vert_arr_map[i_prev], vert_arr_map[i], NULL, BM_CREATE_NO_DOUBLE);
/* the edge may exist already and be attached to a face
* in this case we can find the best winding to use for the new face */
@@ -493,7 +493,7 @@ BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int totv, int n
/* --- */
/* create the face */
- f = BM_face_create_ngon(bm, vert_arr_map[winding[0]], vert_arr_map[winding[1]], edge_arr, totv, nodouble);
+ f = BM_face_create_ngon(bm, vert_arr_map[winding[0]], vert_arr_map[winding[1]], edge_arr, totv, create_flag);
MEM_freeN(edge_arr);
MEM_freeN(vert_arr_map);
@@ -856,7 +856,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
v = BM_iter_new(&iter, bm_old, BM_VERTS_OF_MESH, NULL);
for (i = 0; v; v = BM_iter_step(&iter), i++) {
- v2 = BM_vert_create(bm_new, v->co, NULL); /* copy between meshes so cant use 'example' argument */
+ v2 = BM_vert_create(bm_new, v->co, NULL, BM_CREATE_SKIP_CD); /* copy between meshes so cant use 'example' argument */
BM_elem_attrs_copy(bm_old, bm_new, v, v2);
vtable[i] = v2;
BM_elem_index_set(v, i); /* set_inline */
@@ -873,7 +873,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
e2 = BM_edge_create(bm_new,
vtable[BM_elem_index_get(e->v1)],
vtable[BM_elem_index_get(e->v2)],
- e, FALSE);
+ e, BM_CREATE_SKIP_CD);
BM_elem_attrs_copy(bm_old, bm_new, e, e2);
etable[i] = e2;
@@ -909,7 +909,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old)
v2 = vtable[BM_elem_index_get(loops[0]->v)];
}
- f2 = BM_face_create_ngon(bm_new, v, v2, edges, f->len, FALSE);
+ f2 = BM_face_create_ngon(bm_new, v, v2, edges, f->len, BM_CREATE_SKIP_CD);
if (UNLIKELY(f2 == NULL)) {
continue;
}
diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h
index 29b84046884..60c465e5f5a 100644
--- a/source/blender/bmesh/intern/bmesh_construct.h
+++ b/source/blender/bmesh/intern/bmesh_construct.h
@@ -36,9 +36,9 @@ BMFace *BM_face_create_quad_tri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, B
void BM_face_copy_shared(BMesh *bm, BMFace *f);
-BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble);
+BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag);
-BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len, int nodouble);
+BMFace *BM_face_create_ngon_vcloud(BMesh *bm, BMVert **vert_arr, int len, const int create_flag);
void BMO_remove_tagged_faces(BMesh *bm, const short oflag);
void BMO_remove_tagged_edges(BMesh *bm, const short oflag);
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 03094873e25..14fab7abdc9 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -54,7 +54,7 @@
/**
* \brief Main function for creating a new vertex.
*/
-BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example)
+BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example, const eBMCreateFlag create_flag)
{
BMVert *v = BLI_mempool_calloc(bm->vpool);
@@ -64,6 +64,9 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example)
BM_elem_index_set(v, -1); /* set_ok_invalid */
#endif
+ /* disallow this flag for verts - its meaningless */
+ BLI_assert((create_flag & BM_CREATE_NO_DOUBLE) == 0);
+
bm->elem_index_dirty |= BM_VERT; /* may add to middle of the pool */
bm->totvert++;
@@ -80,17 +83,20 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example)
v->oflags = BLI_mempool_calloc(bm->toolflagpool);
}
- CustomData_bmesh_set_default(&bm->vdata, &v->head.data);
-
- if (example) {
- int *keyi;
+ if (!(create_flag & BM_CREATE_SKIP_CD)) {
+ if (example) {
+ int *keyi;
- BM_elem_attrs_copy(bm, bm, example, v);
+ BM_elem_attrs_copy(bm, bm, example, v);
- /* exception: don't copy the original shapekey index */
- keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX);
- if (keyi) {
- *keyi = ORIGINDEX_NONE;
+ /* exception: don't copy the original shapekey index */
+ keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX);
+ if (keyi) {
+ *keyi = ORIGINDEX_NONE;
+ }
+ }
+ else {
+ CustomData_bmesh_set_default(&bm->vdata, &v->head.data);
}
}
@@ -105,11 +111,11 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example)
* \note Duplicate edges are supported by the API however users should _never_ see them.
* so unless you need a unique edge or know the edge won't exist, you should call with \a nodouble = TRUE
*/
-BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, int nodouble)
+BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, const eBMCreateFlag create_flag)
{
BMEdge *e;
- if (nodouble && (e = BM_edge_exists(v1, v2)))
+ if ((create_flag & BM_CREATE_NO_DOUBLE) && (e = BM_edge_exists(v1, v2)))
return e;
e = BLI_mempool_calloc(bm->epool);
@@ -136,20 +142,26 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example,
BM_elem_flag_enable(e, BM_ELEM_SMOOTH | BM_ELEM_DRAW);
- CustomData_bmesh_set_default(&bm->edata, &e->head.data);
-
bmesh_disk_edge_append(e, e->v1);
bmesh_disk_edge_append(e, e->v2);
- if (example)
- BM_elem_attrs_copy(bm, bm, example, e);
+ if (!(create_flag & BM_CREATE_SKIP_CD)) {
+ if (example) {
+ BM_elem_attrs_copy(bm, bm, example, e);
+ }
+ else {
+ CustomData_bmesh_set_default(&bm->edata, &e->head.data);
+ }
+ }
+
BM_CHECK_ELEMENT(e);
return e;
}
-static BMLoop *bm_loop_create(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f, const BMLoop *example)
+static BMLoop *bm_loop_create(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f,
+ const BMLoop *example, const eBMCreateFlag create_flag)
{
BMLoop *l = NULL;
@@ -164,22 +176,24 @@ static BMLoop *bm_loop_create(BMesh *bm, BMVert *v, BMEdge *e, BMFace *f, const
bm->totloop++;
- if (example) {
- CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->head.data, &l->head.data);
- }
- else {
- CustomData_bmesh_set_default(&bm->ldata, &l->head.data);
+ if (!(create_flag & BM_CREATE_SKIP_CD)) {
+ if (example) {
+ CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, example->head.data, &l->head.data);
+ }
+ else {
+ CustomData_bmesh_set_default(&bm->ldata, &l->head.data);
+ }
}
return l;
}
-static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge *starte)
+static BMLoop *bm_face_boundary_add(BMesh *bm, BMFace *f, BMVert *startv, BMEdge *starte, const int create_flag)
{
#ifdef USE_BMESH_HOLES
BMLoopList *lst = BLI_mempool_calloc(bm->looplistpool);
#endif
- BMLoop *l = bm_loop_create(bm, startv, starte, f, NULL);
+ BMLoop *l = bm_loop_create(bm, startv, starte, f, starte->l, create_flag);
bmesh_radial_append(starte, l);
@@ -211,7 +225,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
i = 0;
do {
if (copyverts) {
- verts[i] = BM_vert_create(bm, l_iter->v->co, l_iter->v);
+ verts[i] = BM_vert_create(bm, l_iter->v->co, l_iter->v, 0);
}
else {
verts[i] = l_iter->v;
@@ -234,7 +248,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
v1 = verts[(i + 1) % f->len];
}
- edges[i] = BM_edge_create(bm, v1, v2, l_iter->e, FALSE);
+ edges[i] = BM_edge_create(bm, v1, v2, l_iter->e, 0);
}
else {
edges[i] = l_iter->e;
@@ -242,7 +256,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
i++;
} while ((l_iter = l_iter->next) != l_first);
- f_copy = BM_face_create(bm, verts, edges, f->len, FALSE);
+ f_copy = BM_face_create(bm, verts, edges, f->len, BM_CREATE_SKIP_CD);
BM_elem_attrs_copy(bm, bm, f, f_copy);
@@ -263,7 +277,7 @@ BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short co
* only create the face, since this calloc's the length is initialized to 0,
* leave adding loops to the caller.
*/
-BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
+BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm, const eBMCreateFlag create_flag)
{
BMFace *f;
@@ -286,7 +300,9 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
f->oflags = BLI_mempool_calloc(bm->toolflagpool);
}
- CustomData_bmesh_set_default(&bm->pdata, &f->head.data);
+ if (!(create_flag & BM_CREATE_SKIP_CD)) {
+ CustomData_bmesh_set_default(&bm->pdata, &f->head.data);
+ }
#ifdef USE_BMESH_HOLES
f->totbounds = 0;
@@ -298,7 +314,7 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
/**
* \brief Main face creation function
*/
-BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, int nodouble)
+BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, const eBMCreateFlag create_flag)
{
BMFace *f = NULL;
BMLoop *l, *startl, *lastl;
@@ -309,7 +325,7 @@ BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len,
return NULL;
}
- if (nodouble) {
+ if (create_flag & BM_CREATE_NO_DOUBLE) {
/* Check if face already exists */
overlap = BM_face_exists(verts, len, &f);
if (overlap) {
@@ -320,14 +336,14 @@ BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len,
}
}
- f = bm_face_create__internal(bm);
+ f = bm_face_create__internal(bm, create_flag);
- startl = lastl = bm_face_boundary_add(bm, f, verts[0], edges[0]);
+ startl = lastl = bm_face_boundary_add(bm, f, verts[0], edges[0], create_flag);
startl->v = verts[0];
startl->e = edges[0];
for (i = 1; i < len; i++) {
- l = bm_loop_create(bm, verts[i], edges[i], f, edges[i]->l);
+ l = bm_loop_create(bm, verts[i], edges[i], f, edges[i]->l, create_flag);
l->f = f;
bmesh_radial_append(edges[i], l);
@@ -1033,7 +1049,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del
}
/* create region face */
- newf = BM_face_create_ngon(bm, v1, v2, edges, tote, FALSE);
+ newf = tote ? BM_face_create_ngon(bm, v1, v2, edges, tote, 0) : NULL;
if (UNLIKELY(!newf || BMO_error_occurred(bm))) {
if (!BMO_error_occurred(bm))
err = N_("Invalid boundary region to join faces");
@@ -1139,7 +1155,7 @@ static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *UNUSED(example))
BMLoopList *lst;
#endif
- f = bm_face_create__internal(bm);
+ f = bm_face_create__internal(bm, 0);
#ifdef USE_BMESH_HOLES
lst = BLI_mempool_calloc(bm->looplistpool);
@@ -1223,11 +1239,11 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
}
/* allocate new edge between v1 and v2 */
- e = BM_edge_create(bm, v1, v2, example, nodouble);
+ e = BM_edge_create(bm, v1, v2, example, nodouble ? BM_CREATE_NO_DOUBLE : 0);
f2 = bm_face_create__sfme(bm, f);
- f1loop = bm_loop_create(bm, v2, e, f, v2loop);
- f2loop = bm_loop_create(bm, v1, e, f2, v1loop);
+ f1loop = bm_loop_create(bm, v2, e, f, v2loop, 0);
+ f2loop = bm_loop_create(bm, v1, e, f2, v1loop, 0);
f1loop->prev = v2loop->prev;
f2loop->prev = v1loop->prev;
@@ -1334,10 +1350,10 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
* will be attached to that end and is returned in \a r_e.
*
* \par Examples:
+ *
* <pre>
* E
* Before: OV-------------TV
- *
* E RE
* After: OV------NV-----TV
* </pre>
@@ -1359,8 +1375,8 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
valence2 = bmesh_disk_count(tv);
- nv = BM_vert_create(bm, tv->co, tv);
- ne = BM_edge_create(bm, nv, tv, e, FALSE);
+ nv = BM_vert_create(bm, tv->co, tv, 0);
+ ne = BM_edge_create(bm, nv, tv, e, 0);
bmesh_disk_edge_remove(ne, tv);
bmesh_disk_edge_remove(ne, nv);
@@ -1403,7 +1419,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
nextl = nextl != nextl->radial_next ? nextl->radial_next : NULL;
bmesh_radial_loop_remove(l, NULL);
- nl = bm_loop_create(bm, NULL, NULL, l->f, l);
+ nl = bm_loop_create(bm, NULL, NULL, l->f, l, 0);
nl->prev = l;
nl->next = (l->next);
nl->prev->next = nl;
@@ -1919,7 +1935,7 @@ int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len)
verts = MEM_callocN(sizeof(BMVert *) * maxindex, __func__);
verts[0] = v;
for (i = 1; i < maxindex; i++) {
- verts[i] = BM_vert_create(bm, v->co, v);
+ verts[i] = BM_vert_create(bm, v->co, v, 0);
}
/* Replace v with the new verts in each group */
@@ -2085,7 +2101,7 @@ int bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
e->l = l_sep->radial_next;
}
- ne = BM_edge_create(bm, e->v1, e->v2, e, FALSE);
+ ne = BM_edge_create(bm, e->v1, e->v2, e, 0);
bmesh_radial_loop_remove(l_sep, e);
bmesh_radial_append(ne, l_sep);
l_sep->e = ne;
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index 0667ed9ea1c..5fd4a6ec7df 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -29,9 +29,18 @@
BMFace *BM_face_copy(BMesh *bm, BMFace *f, const short copyverts, const short copyedges);
-BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example);
-BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, int nodouble);
-BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, int nodouble);
+typedef enum eBMCreateFlag {
+ /* faces and edges only */
+ BM_CREATE_NO_DOUBLE = (1 << 1),
+ /* Skip CustomData - for all element types data,
+ * use if we immediately write customdata into the element so this skips copying from 'example'
+ * args or setting defaults, speeds up conversion when data is converted all at once. */
+ BM_CREATE_SKIP_CD = (1 << 2),
+} eBMCreateFlag;
+
+BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example, const eBMCreateFlag create_flag);
+BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, const eBMCreateFlag create_flag);
+BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, const eBMCreateFlag create_flag);
void BM_face_edges_kill(BMesh *bm, BMFace *f);
void BM_face_verts_kill(BMesh *bm, BMFace *f);
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 62abf43829b..388d148377a 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -206,7 +206,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
- v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL);
+ v = BM_vert_create(bm, keyco && set_key ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
BM_elem_index_set(v, i); /* set_ok */
vt[i] = v;
@@ -220,11 +220,11 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
normal_short_to_float_v3(v->no, mvert->no);
- BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f);
-
- /* Copy Custom Dat */
+ /* Copy Custom Data */
CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data);
+ BM_elem_float_data_set(&bm->vdata, v, CD_BWEIGHT, (float)mvert->bweight / 255.0f);
+
/* set shapekey data */
if (me->key) {
/* set shape key original index */
@@ -254,7 +254,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
medge = me->medge;
for (i = 0; i < me->totedge; i++, medge++) {
- e = BM_edge_create(bm, vt[medge->v1], vt[medge->v2], NULL, FALSE);
+ e = BM_edge_create(bm, vt[medge->v1], vt[medge->v2], NULL, BM_CREATE_SKIP_CD);
BM_elem_index_set(e, i); /* set_ok */
et[i] = e;
@@ -312,7 +312,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
}
#endif
- f = BM_face_create(bm, verts, fedges, mpoly->totloop, FALSE);
+ f = BM_face_create(bm, verts, fedges, mpoly->totloop, BM_CREATE_SKIP_CD);
if (UNLIKELY(f == NULL)) {
printf("%s: Warning! Bad face in mesh"
@@ -338,7 +338,7 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
j = 0;
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, j) {
/* Save index of correspsonding MLoop */
- BM_elem_index_set(l, mpoly->loopstart + j); /* set_loop */
+ CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data);
}
/* Copy Custom Data */
@@ -347,23 +347,6 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, int set_key, int act_key_nr)
bm->elem_index_dirty &= ~BM_FACE; /* added in order, clear dirty flag */
- {
- BMIter fiter;
- BMIter liter;
-
- /* Copy over loop CustomData. Doing this in a separate loop isn't necessary
- * but is an optimization, to avoid copying a bunch of interpolated customdata
- * for each BMLoop (from previous BMLoops using the same edge), always followed
- * by freeing the interpolated data and overwriting it with data from the Mesh. */
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- int li = BM_elem_index_get(l);
- CustomData_to_bmesh_block(&me->ldata, &bm->ldata, li, &l->head.data);
- BM_elem_index_set(l, 0); /* set_loop */
- }
- }
- }
-
if (me->mselect && me->totselect != 0) {
BMVert **vert_array = MEM_callocN(sizeof(BMVert *) * bm->totvert,
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index dc8b52423ab..89516061f91 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -142,9 +142,10 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v)
return FALSE;
}
#else
- BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE);
-
- if (!BM_vert_collapse_faces(bm, v->e, v, 1.0, FALSE, TRUE)) {
+ if (UNLIKELY(!BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE))) {
+ return FALSE;
+ }
+ else if (UNLIKELY(!BM_vert_collapse_faces(bm, v->e, v, 1.0, FALSE, TRUE))) {
return FALSE;
}
#endif
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index ec07eb5d9f7..58c6e051e48 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -59,8 +59,10 @@
#include "bmesh.h"
#include "intern/bmesh_private.h"
-/* ok, I'm going to write a little docgen script. so all
- * bmop comments must conform to the following template/rules:
+/* The formatting of these bmesh operators is parsed by
+ * 'doc/python_api/rst_from_bmesh_opdefines.py'
+ * for use in python docs, so reStructuredText may be used
+ * rather then doxygen syntax.
*
* template (py quotes used because nested comments don't work
* on all C compilers):
@@ -79,148 +81,149 @@
* so the first line is the "title" of the bmop.
* subsequent line blocks separated by blank lines
* are paragraphs. individual descriptions of slots
- * would be extracted from comments
- * next to them, e.g.
+ * are extracted from comments next to them.
*
- * {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, //output slot, boundary region
+ * eg:
+ * {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, """ 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".
+ * ... or:
*
- * note that slots default to being input slots.
+ * """ output slot, boundary region """
+ * {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
+ *
+ * Both are acceptable.
+ * note that '//' comments are ignored.
*/
/*
- * Vertex Smooth
+ * Vertex Smooth.
*
* Smooths vertices by using a basic vertex averaging scheme.
*/
static BMOpDefine bmo_smooth_vert_def = {
"smooth_vert",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_BOOL, "mirror_clip_x"}, /* set vertices close to the x axis before the operation to 0 */
- {BMO_OP_SLOT_BOOL, "mirror_clip_y"}, /* set vertices close to the y axis before the operation to 0 */
- {BMO_OP_SLOT_BOOL, "mirror_clip_z"}, /* set vertices close to the z axis before the operation to 0 */
- {BMO_OP_SLOT_FLT, "clip_dist"}, /* clipping threshod for the above three slots */
- {BMO_OP_SLOT_BOOL, "use_axis_x"}, /* smooth vertices along X axis */
- {BMO_OP_SLOT_BOOL, "use_axis_y"}, /* smooth vertices along Y axis */
- {BMO_OP_SLOT_BOOL, "use_axis_z"}, /* smooth vertices along Z axis */
- {0},
- },
- {{0}}, /* no output */
+ {{"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 */
+ {"clip_dist", BMO_OP_SLOT_FLT}, /* clipping threshold for the above three slots */
+ {"use_axis_x", BMO_OP_SLOT_BOOL}, /* smooth vertices along X axis */
+ {"use_axis_y", BMO_OP_SLOT_BOOL}, /* smooth vertices along Y axis */
+ {"use_axis_z", BMO_OP_SLOT_BOOL}, /* smooth vertices along Z axis */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
bmo_smooth_vert_exec,
0
};
/*
- * Vertext Smooth Laplacian
+ * Vertext Smooth Laplacian.
+ *
* Smooths vertices by using Laplacian smoothing propose by.
- * Desbrun, et al. Implicit Fairing of Irregular Meshes using Diffusion and Curvature Flow
+ * Desbrun, et al. Implicit Fairing of Irregular Meshes using Diffusion and Curvature Flow.
*/
static BMOpDefine bmo_smooth_laplacian_vert_def = {
"smooth_laplacian_vert",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_FLT, "lambda"}, /* lambda param */
- {BMO_OP_SLOT_FLT, "lambda_border"}, /* lambda param in border */
- {BMO_OP_SLOT_BOOL, "use_x"}, /* Smooth object along X axis */
- {BMO_OP_SLOT_BOOL, "use_y"}, /* Smooth object along Y axis */
- {BMO_OP_SLOT_BOOL, "use_z"}, /* Smooth object along Z axis */
- {BMO_OP_SLOT_BOOL, "preserve_volume"}, /* Apply volume preservation after smooth */
- {0},
+ {{"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 */
+ {"use_y", BMO_OP_SLOT_BOOL}, /* Smooth object along Y axis */
+ {"use_z", BMO_OP_SLOT_BOOL}, /* Smooth object along Z axis */
+ {"preserve_volume", BMO_OP_SLOT_BOOL}, /* Apply volume preservation after smooth */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_smooth_laplacian_vert_exec,
0
};
/*
- * Right-Hand Faces
+ * Right-Hand Faces.
*
* Computes an "outside" normal for the specified input faces.
*/
-
static BMOpDefine bmo_recalc_face_normals_def = {
"recalc_face_normals",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
- {BMO_OP_SLOT_BOOL, "use_flip"}, /* internal flag, used by bmesh_rationalize_normals */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"use_flip", BMO_OP_SLOT_BOOL}, /* Reverse the result */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_recalc_face_normals_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Region Extend
+ * Region Extend.
*
* used to implement the select more/less tools.
* this puts some geometry surrounding regions of
* geometry in geom into geom.out.
*
- * if usefaces is 0 then geom.out spits out verts and edges,
+ * if use_faces is 0 then geom.out spits out verts and edges,
* otherwise it spits out faces.
*/
static BMOpDefine bmo_region_extend_def = {
"region_extend",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input geometry */
- {BMO_OP_SLOT_BOOL, "use_constrict"}, /* find boundary inside the regions, not outside. */
- {BMO_OP_SLOT_BOOL, "use_faces"}, /* extend from faces instead of edges */
- {0},
+ {{"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 */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* output slot, computed boundary geometry. */
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output slot, computed boundary geometry. */
+ {{'\0'}},
},
bmo_region_extend_exec,
0
};
/*
- * Edge Rotate
+ * Edge Rotate.
*
* Rotates edges topologically. Also known as "spin edge" to some people.
- * Simple example: [/] becomes [|] then [\].
+ * Simple example: ``[/] becomes [|] then [\]``.
*/
static BMOpDefine bmo_rotate_edges_def = {
"rotate_edges",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {BMO_OP_SLOT_BOOL, "use_ccw"}, /* rotate edge counter-clockwise if true, othewise clockwise */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate edge counter-clockwise if true, otherwise clockwise */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* newly spun edges */
- {0},
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly spun edges */
+ {{'\0'}},
},
bmo_rotate_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
/*
- * Reverse Faces
+ * Reverse Faces.
*
- * Reverses the winding (vertex order) of faces. This has the effect of
- * flipping the normal.
+ * Reverses the winding (vertex order) of faces.
+ * This has the effect of flipping the normal.
*/
static BMOpDefine bmo_reverse_faces_def = {
"reverse_faces",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_reverse_faces_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Edge Bisect
+ * Edge Bisect.
*
* Splits input edges (but doesn't do anything else).
* This creates a 2-valence vert.
@@ -228,50 +231,49 @@ static BMOpDefine bmo_reverse_faces_def = {
static BMOpDefine bmo_bisect_edges_def = {
"bisect_edges",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {BMO_OP_SLOT_INT, "cuts"}, /* number of cuts */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"cuts", BMO_OP_SLOT_INT}, /* number of cuts */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom_split.out"}, /* newly created vertices and edges */
- {0},
+ {{"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* newly created vertices and edges */
+ {{'\0'}},
},
bmo_bisect_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
/*
- * Mirror
+ * Mirror.
*
* Mirrors geometry along an axis. The resulting geometry is welded on using
* merge_dist. Pairs of original/mirrored vertices are welded using the merge_dist
* parameter (which defines the minimum distance for welding to happen).
*/
-
static BMOpDefine bmo_mirror_def = {
"mirror",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input geometry */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix defining the mirror transformation */
- {BMO_OP_SLOT_FLT, "merge_dist"}, /* maximum distance for merging. does no merging if 0. */
- {BMO_OP_SLOT_INT, "axis"}, /* the axis to use, 0, 1, or 2 for x, y, z */
- {BMO_OP_SLOT_BOOL, "mirror_u"}, /* mirror UVs across the u axis */
- {BMO_OP_SLOT_BOOL, "mirror_v"}, /* mirror UVs across the v axis */
- {0},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
+ {"matrix", 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 */
+ {"mirror_u", BMO_OP_SLOT_BOOL}, /* mirror UVs across the u axis */
+ {"mirror_v", BMO_OP_SLOT_BOOL}, /* mirror UVs across the v axis */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* output geometry, mirrored */
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output geometry, mirrored */
+ {{'\0'}},
},
bmo_mirror_exec,
0,
};
/*
- * Find Doubles
+ * Find Doubles.
*
- * Takes input verts and find vertices they should weld to. Outputs a
- * mapping slot suitable for use with the weld verts bmop.
+ * Takes input verts and find vertices they should weld to.
+ * Outputs a mapping slot suitable for use with the weld verts bmop.
*
* If keep_verts is used, vertices outside that set can only be merged
* with vertices in that set.
@@ -279,21 +281,21 @@ static BMOpDefine bmo_mirror_def = {
static BMOpDefine bmo_find_doubles_def = {
"find_doubles",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_ELEMENT_BUF, "keep_verts"}, /* list of verts to keep */
- {BMO_OP_SLOT_FLT, "dist"}, /* minimum distance */
- {0},
+ {{"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 */
- {{BMO_OP_SLOT_MAPPING, "targetmap.out"},
- {0},
+ {{"targetmap.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
},
bmo_find_doubles_exec,
0,
};
/*
- * Remove Doubles
+ * Remove Doubles.
*
* Finds groups of vertices closer then dist and merges them together,
* using the weld verts bmop.
@@ -301,70 +303,69 @@ static BMOpDefine bmo_find_doubles_def = {
static BMOpDefine bmo_remove_doubles_def = {
"remove_doubles",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input verts */
- {BMO_OP_SLOT_FLT, "dist"}, /* minimum distance */
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
+ {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_remove_doubles_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Auto Merge
+ * Auto Merge.
*
- * Finds groups of vertices closer then dist and merges them together,
+ * Finds groups of vertices closer then **dist** and merges them together,
* using the weld verts bmop. The merges must go from a vert not in
- * verts to one in verts.
+ * **verts** to one in **verts**.
*/
static BMOpDefine bmo_automerge_def = {
"automerge",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input verts */
- {BMO_OP_SLOT_FLT, "dist"}, /* minimum distance */
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
+ {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_automerge_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Collapse Connected
+ * Collapse Connected.
*
* Collapses connected vertices
*/
static BMOpDefine bmo_collapse_def = {
"collapse",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_collapse_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
-
/*
- * Facedata point Merge
+ * Face-Data Point Merge.
*
* Merge uv/vcols at a specific vertex.
*/
static BMOpDefine bmo_pointmerge_facedata_def = {
"pointmerge_facedata",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_ELEMENT_BUF, "snapv"}, /* snap vertex */
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"vert_snap", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* snap vertex */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_pointmerge_facedata_exec,
0,
};
/*
- * Average Vertices Facevert Data
+ * Average Vertices Facevert Data.
*
* Merge uv/vcols associated with the input vertices at
* the bounding box center. (I know, it's not averaging but
@@ -373,67 +374,68 @@ static BMOpDefine bmo_pointmerge_facedata_def = {
static BMOpDefine bmo_average_vert_facedata_def = {
"average_vert_facedata",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_average_vert_facedata_exec,
0,
};
/*
- * Point Merge
+ * Point Merge.
*
* Merge verts together at a point.
*/
static BMOpDefine bmo_pointmerge_def = {
"pointmerge",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertice */
- {BMO_OP_SLOT_VEC, "merge_co"},
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertice */
+ {"merge_co", BMO_OP_SLOT_VEC},
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_pointmerge_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Collapse Connected UVs
+ * Collapse Connected UV's.
*
* Collapses connected UV vertices.
*/
static BMOpDefine bmo_collapse_uvs_def = {
"collapse_uvs",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edge */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_collapse_uvs_exec,
0,
};
/*
- * Weld Verts
+ * Weld Verts.
*
- * Welds verts together (kindof like remove doubles, merge, etc, all of which
+ * Welds verts together (kind-of like remove doubles, merge, etc, all of which
* use or will use this bmop). You pass in mappings from vertices to the vertices
* they weld with.
*/
static BMOpDefine bmo_weld_verts_def = {
"weld_verts",
/* slots_in */
- {{BMO_OP_SLOT_MAPPING, "targetmap"}, /* maps welded vertices to verts they should weld to */
- {0},
+ /* maps welded vertices to verts they should weld to */
+ {{"targetmap", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_weld_verts_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Make Vertex
+ * Make Vertex.
*
* Creates a single vertex; this bmop was necessary
* for click-create-vertex.
@@ -441,19 +443,19 @@ static BMOpDefine bmo_weld_verts_def = {
static BMOpDefine bmo_create_vert_def = {
"create_vert",
/* slots_in */
- {{BMO_OP_SLOT_VEC, "co"}, /* the coordinate of the new vert */
- {0},
+ {{"co", BMO_OP_SLOT_VEC}, /* the coordinate of the new vert */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "vert.out"}, /* the new vert */
- {0},
+ {{"vert.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* the new vert */
+ {{'\0'}},
},
bmo_create_vert_exec,
0,
};
/*
- * Join Triangles
+ * Join Triangles.
*
* Tries to intelligently join triangles according
* to various settings and stuff.
@@ -461,29 +463,28 @@ static BMOpDefine bmo_create_vert_def = {
static BMOpDefine bmo_join_triangles_def = {
"join_triangles",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input geometry. */
- {BMO_OP_SLOT_BOOL, "cmp_sharp"},
- {BMO_OP_SLOT_BOOL, "cmp_uvs"},
- {BMO_OP_SLOT_BOOL, "cmp_vcols"},
- {BMO_OP_SLOT_BOOL, "cmp_materials"},
- {BMO_OP_SLOT_FLT, "limit"},
- {0},
+ {{"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},
+ {"cmp_materials", BMO_OP_SLOT_BOOL},
+ {"limit", BMO_OP_SLOT_FLT},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* joined faces */
- {0},
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* joined faces */
+ {{'\0'}},
},
bmo_join_triangles_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Contextual Create
+ * Contextual Create.
*
- * This is basically fkey, it creates
+ * This is basically F-key, it creates
* new faces from vertices, makes stuff from edge nets,
- * makes wire edges, etc. It also dissolves
- * faces.
+ * makes wire edges, etc. It also dissolves faces.
*
* Three verts become a triangle, four become a quad. Two
* become a wire edge.
@@ -491,63 +492,70 @@ static BMOpDefine bmo_join_triangles_def = {
static BMOpDefine bmo_contextual_create_def = {
"contextual_create",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input geometry. */
- {BMO_OP_SLOT_INT, "mat_nr"}, /* material to use */
- {BMO_OP_SLOT_BOOL, "use_smooth"}, /* smooth to use */
- {0},
+ {{"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 */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* 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 */
- {BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* newly-made edge(s) */
- {0},
+ {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly-made edge(s) */
+ {{'\0'}},
},
bmo_contextual_create_exec,
BMO_OP_FLAG_UNTAN_MULTIRES,
};
/*
- * Bridge edge loops with faces
+ * Bridge edge loops with faces.
*/
static BMOpDefine bmo_bridge_loops_def = {
"bridge_loops",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
- {BMO_OP_SLOT_BOOL, "use_merge"},
- {BMO_OP_SLOT_FLT, "merge_factor"},
- {0},
+ {{"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 */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* new faces */
- {0},
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
+ {{'\0'}},
},
bmo_bridge_loops_exec,
0,
};
+/*
+ * Edge Net Fill.
+ *
+ * Create faces defined by enclosed edges.
+ */
static BMOpDefine bmo_edgenet_fill_def = {
"edgenet_fill",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edge */
- {BMO_OP_SLOT_MAPPING, "restrict"}, /* restricts edges to groups. maps edges to integer */
- {BMO_OP_SLOT_BOOL, "use_restrict"},
- {BMO_OP_SLOT_BOOL, "use_fill_check"},
- {BMO_OP_SLOT_ELEMENT_BUF, "exclude_faces"}, /* list of faces to ignore for manifold check */
- {BMO_OP_SLOT_INT, "mat_nr"}, /* material to use */
- {BMO_OP_SLOT_BOOL, "use_smooth"}, /* material to use */
- {0},
+ {{"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}},
+ {"use_restrict", BMO_OP_SLOT_BOOL},
+ {"use_fill_check", BMO_OP_SLOT_BOOL},
+ {"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 */
- {{BMO_OP_SLOT_MAPPING, "face_groupmap.out"}, /* maps new faces to the group numbers they came from */
- {BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* new face */
- {0},
+ /* 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, {BM_FACE}}, /* new face */
+ {{'\0'}},
},
bmo_edgenet_fill_exec,
0,
};
/*
- * Edgenet Prepare
+ * Edgenet Prepare.
*
* Identifies several useful edge loop cases and modifies them so
* they'll become a face when edgenet_fill is called. The cases covered are:
@@ -559,74 +567,72 @@ static BMOpDefine bmo_edgenet_fill_def = {
static BMOpDefine bmo_edgenet_prepare_def = {
"edgenet_prepare",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* new edges */
- {0},
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* new edges */
+ {{'\0'}},
},
- bmo_edgenet_prepare,
+ bmo_edgenet_prepare_exec,
0,
};
/*
- * Rotate
+ * Rotate.
*
- * Rotate vertices around a center, using a 3x3 rotation
- * matrix. Equivalent of the old rotateflag function.
+ * Rotate vertices around a center, using a 3x3 rotation matrix.
*/
static BMOpDefine bmo_rotate_def = {
"rotate",
/* slots_in */
- {{BMO_OP_SLOT_VEC, "cent"}, /* center of rotation */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix defining rotation */
- {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {0},
+ {{"cent", BMO_OP_SLOT_VEC}, /* center of rotation */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix defining rotation */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_rotate_exec,
0,
};
/*
- * Translate
+ * Translate.
*
- * Translate vertices by an offset. Equivalent of the
- * old translateflag function.
+ * Translate vertices by an offset.
*/
static BMOpDefine bmo_translate_def = {
"translate",
/* slots_in */
- {{BMO_OP_SLOT_VEC, "vec"}, /* translation offset */
- {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {0},
+ {{"vec", BMO_OP_SLOT_VEC}, /* translation offset */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_translate_exec,
0,
};
/*
- * Scale
+ * Scale.
*
* Scales vertices by an offset.
*/
static BMOpDefine bmo_scale_def = {
"scale",
/* slots_in */
- {{BMO_OP_SLOT_VEC, "vec"}, /* scale factor */
- {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {0},
+ {{"vec", BMO_OP_SLOT_VEC}, /* scale factor */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_scale_exec,
0,
};
/*
- * Transform
+ * Transform.
*
* Transforms a set of vertices by a matrix. Multiplies
* the vertex coordinates with the matrix.
@@ -634,17 +640,17 @@ static BMOpDefine bmo_scale_def = {
static BMOpDefine bmo_transform_def = {
"transform",
/* slots_in */
- {{BMO_OP_SLOT_MAT, "mat"}, /* transform matrix */
- {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {0},
+ {{"matrix", BMO_OP_SLOT_MAT}, /* transform matrix */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_transform_exec,
0,
};
/*
- * Object Load BMesh
+ * Object Load BMesh.
*
* Loads a bmesh into an object/mesh. This is a "private"
* bmop.
@@ -652,36 +658,39 @@ static BMOpDefine bmo_transform_def = {
static BMOpDefine bmo_object_load_bmesh_def = {
"object_load_bmesh",
/* slots_in */
- {{BMO_OP_SLOT_PTR, "scene"},
- {BMO_OP_SLOT_PTR, "object"},
- {0},
+ {{"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 */
+ {{{'\0'}}}, /* no output */
bmo_object_load_bmesh_exec,
0,
};
/*
- * BMesh to Mesh
+ * BMesh to Mesh.
*
* Converts a bmesh to a Mesh. This is reserved for exiting editmode.
*/
static BMOpDefine bmo_bmesh_to_mesh_def = {
"bmesh_to_mesh",
/* slots_in */
- {{BMO_OP_SLOT_PTR, "mesh"}, /* pointer to a mesh structure to fill in */
- {BMO_OP_SLOT_PTR, "object"}, /* pointer to an object structure */
- {BMO_OP_SLOT_BOOL, "skip_tessface"}, /* don't calculate mfaces */
- {0},
+ {
+ /* pointer to a mesh structure to fill in */
+ {"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}},
+ {"skip_tessface", BMO_OP_SLOT_BOOL}, /* don't calculate mfaces */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_bmesh_to_mesh_exec,
0,
};
/*
- * Mesh to BMesh
+ * Mesh to BMesh.
*
* Load the contents of a mesh into the bmesh. this bmop is private, it's
* reserved exclusively for entering editmode.
@@ -689,38 +698,40 @@ static BMOpDefine bmo_bmesh_to_mesh_def = {
static BMOpDefine bmo_mesh_to_bmesh_def = {
"mesh_to_bmesh",
/* slots_in */
- {{BMO_OP_SLOT_PTR, "mesh"}, /* pointer to a Mesh structure */
- {BMO_OP_SLOT_PTR, "object"}, /* pointer to an Object structure */
- {BMO_OP_SLOT_BOOL, "use_shapekey"}, /* load active shapekey coordinates into verts */
- {0},
+ {
+ /* pointer to a Mesh structure */
+ {"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}},
+ {"use_shapekey", BMO_OP_SLOT_BOOL}, /* load active shapekey coordinates into verts */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_mesh_to_bmesh_exec,
0
};
/*
- * Individual Face Extrude
+ * Individual Face Extrude.
*
* Extrudes faces individually.
*/
static BMOpDefine bmo_extrude_discrete_faces_def = {
"extrude_discrete_faces",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */
- {BMO_OP_SLOT_ELEMENT_BUF, "geom_skirt.out"}, /* output skirt geometry, faces and edges */
- {0},
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
},
bmo_extrude_discrete_faces_exec,
0
};
/*
- * Extrude Only Edges
+ * Extrude Only Edges.
*
* Extrudes Edges into faces, note that this is very simple, there's no fancy
* winged extrusion.
@@ -728,247 +739,308 @@ static BMOpDefine bmo_extrude_discrete_faces_def = {
static BMOpDefine bmo_extrude_edge_only_def = {
"extrude_edge_only",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input vertices */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* output geometry */
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output geometry */
+ {{'\0'}},
},
bmo_extrude_edge_only_exec,
0
};
/*
- * Individual Vertex Extrude
+ * Individual Vertex Extrude.
*
* Extrudes wire edges from vertices.
*/
static BMOpDefine bmo_extrude_vert_indiv_def = {
"extrude_vert_indiv",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* output wire edges */
- {BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output vertices */
- {0},
+ {{"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,
0
};
+/*
+ * Connect Verts.
+ *
+ * Split faces by adding edges that connect **verts**.
+ */
static BMOpDefine bmo_connect_verts_def = {
"connect_verts",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"},
- {0},
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {{'\0'}},
},
bmo_connect_verts_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Extrude Faces.
+ *
+ * Extrude operator (does not transform)
+ */
static BMOpDefine bmo_extrude_face_region_def = {
"extrude_face_region",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* edges and faces */
- {BMO_OP_SLOT_MAPPING, "edges_exclude"},
- {BMO_OP_SLOT_BOOL, "use_keep_orig"}, /* keep original geometry */
- {0},
+ {{"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 */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{'\0'}},
},
bmo_extrude_face_region_exec,
0
};
+/*
+ * Dissolve Verts.
+ */
static BMOpDefine bmo_dissolve_verts_def = {
"dissolve_verts",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"},
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_dissolve_verts_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Dissolve Edges.
+ */
static BMOpDefine bmo_dissolve_edges_def = {
"dissolve_edges",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
- {BMO_OP_SLOT_BOOL, "use_verts"}, /* dissolve verts left between only 2 edges. */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "region.out"},
- {0},
+ {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
},
bmo_dissolve_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Dissolve Edge Loop.
+ */
static BMOpDefine bmo_dissolve_edge_loop_def = {
"dissolve_edge_loop",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "region.out"},
- {0},
+ {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
},
bmo_dissolve_edgeloop_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Dissolve Faces.
+ */
static BMOpDefine bmo_dissolve_faces_def = {
"dissolve_faces",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
- {BMO_OP_SLOT_BOOL, "use_verts"}, /* dissolve verts left between only 2 edges. */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "region.out"},
- {0},
+ {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
},
bmo_dissolve_faces_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Limited Dissolve.
+ *
+ * Dissolve planar faces and co-linear edges.
+ */
static BMOpDefine bmo_dissolve_limit_def = {
"dissolve_limit",
/* slots_in */
- {{BMO_OP_SLOT_FLT, "angle_limit"}, /* total rotation angle (degrees) */
- {BMO_OP_SLOT_BOOL, "use_dissolve_boundaries"},
- {BMO_OP_SLOT_ELEMENT_BUF, "verts"},
- {BMO_OP_SLOT_ELEMENT_BUF, "edges"},
- {0},
+ {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
+ {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL},
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_dissolve_limit_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Triangulate.
+ */
static BMOpDefine bmo_triangulate_def = {
"triangulate",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"},
- {BMO_OP_SLOT_BOOL, "use_beauty"},
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"use_beauty", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"},
- {BMO_OP_SLOT_ELEMENT_BUF, "faces.out"},
- {BMO_OP_SLOT_MAPPING, "facemap.out"},
- {0},
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"face_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
},
bmo_triangulate_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Un-Subdivide.
+ *
+ * Reduce detail in geometry containing grids.
+ */
static BMOpDefine bmo_unsubdivide_def = {
"unsubdivide",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_INT, "iterations"},
- {0},
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"iterations", BMO_OP_SLOT_INT},
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_unsubdivide_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Subdivide Edges.
+ *
+ * Advanced operator for subdividing edges
+ * with options for face patterns, smoothing and randomization.
+ */
static BMOpDefine bmo_subdivide_edges_def = {
"subdivide_edges",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"},
- {BMO_OP_SLOT_FLT, "smooth"},
- {BMO_OP_SLOT_FLT, "fractal"},
- {BMO_OP_SLOT_FLT, "along_normal"},
- {BMO_OP_SLOT_INT, "cuts"},
- {BMO_OP_SLOT_INT, "seed"},
- {BMO_OP_SLOT_MAPPING, "custompatterns"},
- {BMO_OP_SLOT_MAPPING, "edgepercents"},
-
- {BMO_OP_SLOT_INT, "quad_corner_type"}, /* quad corner type, see bmesh_operators.h */
- {BMO_OP_SLOT_BOOL, "use_gridfill"}, /* fill in fully-selected faces with a grid */
- {BMO_OP_SLOT_BOOL, "use_singleedge"}, /* tessellate the case of one edge selected in a quad or triangle */
- {BMO_OP_SLOT_BOOL, "use_sphere"}, /* for making new primitives only */
- {0},
+ {{"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},
+ {"custom_patterns", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}}, /* uses custom pointers */
+ {"edge_percents", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_FLT}},
+
+ {"quad_corner_type", BMO_OP_SLOT_INT}, /* quad corner type, see bmesh_operators.h */
+ {"use_grid_fill", BMO_OP_SLOT_BOOL}, /* fill in fully-selected faces with a grid */
+ {"use_single_edge", BMO_OP_SLOT_BOOL}, /* tessellate the case of one edge selected in a quad or triangle */
+ {"use_only_quads", BMO_OP_SLOT_BOOL}, /* only subdivide quads (for loopcut) */
+ {"use_sphere", BMO_OP_SLOT_BOOL}, /* for making new primitives only */
+ {{'\0'}},
},
/* slots_out */
{/* these next three can have multiple types of elements in them */
- {BMO_OP_SLOT_ELEMENT_BUF, "geom_inner.out"},
- {BMO_OP_SLOT_ELEMENT_BUF, "geom_split.out"},
- {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* contains all output geometr */
- {0},
+ {"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,
BMO_OP_FLAG_UNTAN_MULTIRES
};
+/*
+ * Delete Geometry.
+ *
+ * Utility operator to delete geometry.
+ */
static BMOpDefine bmo_delete_def = {
"delete",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
- {BMO_OP_SLOT_INT, "context"},
- {0},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"context", BMO_OP_SLOT_INT}, /* enum DEL_VERTS ... */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_delete_exec,
0
};
+/*
+ * Duplicate Geometry.
+ *
+ * Utility operator to duplicate geometry,
+ * optionally into a destination mesh.
+ */
static BMOpDefine bmo_duplicate_def = {
"duplicate",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
- {BMO_OP_SLOT_PTR, "dest"}, /* destination bmesh, if NULL will use current on */
- {0},
+ {{"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}},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom_orig.out"},
- {BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
+ {{"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 */
- {BMO_OP_SLOT_MAPPING, "facemap.out"},
- {BMO_OP_SLOT_MAPPING, "boundarymap.out"},
- {BMO_OP_SLOT_MAPPING, "isovertmap.out"},
- {0},
+ {"face_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"boundary_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"isovert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
},
bmo_duplicate_exec,
0
};
+/*
+ * Split Off Geometry.
+ *
+ * Disconnect geometry from adjacent edges and faces,
+ * optionally into a destination mesh.
+ */
static BMOpDefine bmo_split_def = {
"split",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
- {BMO_OP_SLOT_PTR, "dest"}, /* destination bmesh, if NULL will use current one */
- {BMO_OP_SLOT_BOOL, "use_only_faces"}, /* when enabled. don't duplicate loose verts/edges */
- {0},
+ {{"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}},
+ {"use_only_faces", BMO_OP_SLOT_BOOL}, /* when enabled. don't duplicate loose verts/edges */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
- {BMO_OP_SLOT_MAPPING, "boundarymap.out"},
- {BMO_OP_SLOT_MAPPING, "isovertmap.out"},
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"boundary_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"isovert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
},
bmo_split_exec,
0
};
/*
- * Spin
+ * Spin.
*
* Extrude or duplicate geometry a number of times,
* rotating and possibly translating after each step
@@ -976,18 +1048,18 @@ static BMOpDefine bmo_split_def = {
static BMOpDefine bmo_spin_def = {
"spin",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
- {BMO_OP_SLOT_VEC, "cent"}, /* rotation center */
- {BMO_OP_SLOT_VEC, "axis"}, /* rotation axis */
- {BMO_OP_SLOT_VEC, "dvec"}, /* translation delta per step */
- {BMO_OP_SLOT_FLT, "angle"}, /* total rotation angle (degrees) */
- {BMO_OP_SLOT_INT, "steps"}, /* number of steps */
- {BMO_OP_SLOT_BOOL, "use_duplicate"}, /* duplicate or extrude? */
- {0},
+ {{"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 */
+ {"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
+ {"steps", BMO_OP_SLOT_INT}, /* number of steps */
+ {"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom_last.out"}, /* result of last step */
- {0},
+ {{"geom_last.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* result of last step */
+ {{'\0'}},
},
bmo_spin_exec,
0
@@ -995,486 +1067,490 @@ static BMOpDefine bmo_spin_def = {
/*
- * Similar faces search
+ * Similar Faces Search.
*
* Find similar faces (area/material/perimeter, ...).
*/
static BMOpDefine bmo_similar_faces_def = {
"similar_faces",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_INT, "type"}, /* type of selection */
- {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
- {BMO_OP_SLOT_INT, "compare"}, /* comparison method */
- {0},
+ {{"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 */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */
- {0},
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
},
bmo_similar_faces_exec,
0
};
/*
- * Similar edges search
+ * Similar Edges Search.
*
* Find similar edges (length, direction, edge, seam, ...).
*/
static BMOpDefine bmo_similar_edges_def = {
"similar_edges",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {BMO_OP_SLOT_INT, "type"}, /* type of selection */
- {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
- {BMO_OP_SLOT_INT, "compare"}, /* comparison method */
- {0},
+ {{"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 */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* output edges */
- {0},
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output edges */
+ {{'\0'}},
},
bmo_similar_edges_exec,
0
};
/*
- * Similar vertices search
+ * Similar Verts Search.
*
* Find similar vertices (normal, face, vertex group, ...).
*/
static BMOpDefine bmo_similar_verts_def = {
"similar_verts",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */
- {BMO_OP_SLOT_INT, "type"}, /* type of selection */
- {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */
- {BMO_OP_SLOT_INT, "compare"}, /* comparison method */
- {0},
+ {{"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 */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output vertices */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output vertices */
+ {{'\0'}},
},
bmo_similar_verts_exec,
0
};
/*
- * uv rotation
- * cycle the uvs
+ * UV Rotation.
+ *
+ * Cycle the loop UV's
*/
static BMOpDefine bmo_rotate_uvs_def = {
"rotate_uvs",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_BOOL, "use_ccw"}, /* rotate counter-clockwise if true, othewise clockwise */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, otherwise clockwise */
+ {{'\0'}},
},
/* slots_out */
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_rotate_uvs_exec,
0
};
/*
- * uv reverse
- * reverse the uvs
+ * UV Reverse.
+ *
+ * Reverse the UV's
*/
static BMOpDefine bmo_reverse_uvs_def = {
"reverse_uvs",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_reverse_uvs_exec,
0
};
/*
- * color rotation
- * cycle the colors
+ * Color Rotation.
+ *
+ * Cycle the loop colors
*/
static BMOpDefine bmo_rotate_colors_def = {
"rotate_colors",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_BOOL, "use_ccw"}, /* rotate counter-clockwise if true, othewise clockwise */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, otherwise clockwise */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_rotate_colors_exec,
0
};
/*
- * color reverse
- * reverse the colors
+ * Color Reverse
+ *
+ * Reverse the loop colors.
*/
static BMOpDefine bmo_reverse_colors_def = {
"reverse_colors",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {0},
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {{'\0'}},
},
- {{0}}, /* no output */
+ {{{'\0'}}}, /* no output */
bmo_reverse_colors_exec,
0
};
/*
- * Similar vertices search
+ * Shortest Path.
*
- * Find similar vertices (normal, face, vertex group, ...).
+ * Select the shortest path between 2 verts.
*/
static BMOpDefine bmo_shortest_path_def = {
"shortest_path",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "startv"}, /* start vertex */
- {BMO_OP_SLOT_ELEMENT_BUF, "endv"}, /* end vertex */
- {BMO_OP_SLOT_INT, "type"}, /* type of selection */
- {0},
+ {{"vert_start", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* start vertex */
+ {"vert_end", 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 */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output vertices */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output vertices */
+ {{'\0'}},
},
bmo_shortest_path_exec,
0
};
/*
- * Edge Split
+ * Edge Split.
*
* Disconnects faces along input edges.
*/
static BMOpDefine bmo_split_edges_def = {
"split_edges",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* 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 */
- {BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* optional tag verts, use to have greater control of splits */
- {BMO_OP_SLOT_BOOL, "use_verts"}, /* use 'verts' for splitting, else just find verts to split from edges */
- {0},
+ {"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 */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges.out"}, /* old output disconnected edges */
- {0},
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* old output disconnected edges */
+ {{'\0'}},
},
bmo_split_edges_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
/*
- * Create Grid
+ * Create Grid.
*
* Creates a grid with a variable number of subdivisions
*/
static BMOpDefine bmo_create_grid_def = {
"create_grid",
/* slots_in */
- {{BMO_OP_SLOT_INT, "x_segments"}, /* number of x segments */
- {BMO_OP_SLOT_INT, "y_segments"}, /* number of y segments */
- {BMO_OP_SLOT_FLT, "size"}, /* size of the grid */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"x_segments", BMO_OP_SLOT_INT}, /* number of x segments */
+ {"y_segments", BMO_OP_SLOT_INT}, /* number of y segments */
+ {"size", BMO_OP_SLOT_FLT}, /* size of the grid */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_grid_exec,
0,
};
/*
- * Create UV Sphere
+ * Create UV Sphere.
*
* Creates a grid with a variable number of subdivisions
*/
static BMOpDefine bmo_create_uvsphere_def = {
"create_uvsphere",
/* slots_in */
- {{BMO_OP_SLOT_INT, "u_segments"}, /* number of u segments */
- {BMO_OP_SLOT_INT, "v_segments"}, /* number of v segment */
- {BMO_OP_SLOT_FLT, "diameter"}, /* diameter */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"u_segments", BMO_OP_SLOT_INT}, /* number of u segments */
+ {"v_segments", BMO_OP_SLOT_INT}, /* number of v segment */
+ {"diameter", BMO_OP_SLOT_FLT}, /* diameter */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_uvsphere_exec,
0,
};
/*
- * Create Ico Sphere
+ * Create Ico-Sphere.
*
* Creates a grid with a variable number of subdivisions
*/
static BMOpDefine bmo_create_icosphere_def = {
"create_icosphere",
/* slots_in */
- {{BMO_OP_SLOT_INT, "subdivisions"}, /* how many times to recursively subdivide the sphere */
- {BMO_OP_SLOT_FLT, "diameter"}, /* diameter */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"subdivisions", BMO_OP_SLOT_INT}, /* how many times to recursively subdivide the sphere */
+ {"diameter", BMO_OP_SLOT_FLT}, /* diameter */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_icosphere_exec,
0,
};
/*
- * Create Suzanne
+ * Create Suzanne.
*
- * Creates a monkey. Be wary.
+ * Creates a monkey (standard blender primitive).
*/
static BMOpDefine bmo_create_monkey_def = {
"create_monkey",
/* slots_in */
- {{BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_monkey_exec,
0,
};
/*
- * Create Cone
+ * Create Cone.
*
* Creates a cone with variable depth at both ends
*/
static BMOpDefine bmo_create_cone_def = {
"create_cone",
/* slots_in */
- {{BMO_OP_SLOT_BOOL, "cap_ends"}, /* wheter or not to fill in the ends with faces */
- {BMO_OP_SLOT_BOOL, "cap_tris"}, /* fill ends with triangles instead of ngons */
- {BMO_OP_SLOT_INT, "segments"},
- {BMO_OP_SLOT_FLT, "diameter1"}, /* diameter of one end */
- {BMO_OP_SLOT_FLT, "diameter2"}, /* diameter of the opposite */
- {BMO_OP_SLOT_FLT, "depth"}, /* distance between ends */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */
+ {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */
+ {"segments", BMO_OP_SLOT_INT},
+ {"diameter1", BMO_OP_SLOT_FLT}, /* diameter of one end */
+ {"diameter2", BMO_OP_SLOT_FLT}, /* diameter of the opposite */
+ {"depth", BMO_OP_SLOT_FLT}, /* distance between ends */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_cone_exec,
0,
};
/*
- * Creates a circle
+ * Creates a Circle.
*/
static BMOpDefine bmo_create_circle_def = {
"create_circle",
/* slots_in */
- {{BMO_OP_SLOT_BOOL, "cap_ends"}, /* wheter or not to fill in the ends with faces */
- {BMO_OP_SLOT_BOOL, "cap_tris"}, /* fill ends with triangles instead of ngons */
- {BMO_OP_SLOT_INT, "segments"},
- {BMO_OP_SLOT_FLT, "diameter"}, /* diameter of one end */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */
+ {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */
+ {"segments", BMO_OP_SLOT_INT},
+ {"diameter", BMO_OP_SLOT_FLT}, /* diameter of one end */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_circle_exec,
0,
};
/*
- * Create Cone
+ * Create Cube
*
- * Creates a cone with variable depth at both ends
+ * Creates a cube.
*/
static BMOpDefine bmo_create_cube_def = {
"create_cube",
/* slots_in */
- {{BMO_OP_SLOT_FLT, "size"}, /* size of the cube */
- {BMO_OP_SLOT_MAT, "mat"}, /* matrix to multiply the new geometry with */
- {0},
+ {{"size", BMO_OP_SLOT_FLT}, /* size of the cube */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"}, /* output verts */
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
},
bmo_create_cube_exec,
0,
};
/*
- * Bevel
+ * Bevel.
*
* Bevels edges and vertices
*/
static BMOpDefine bmo_bevel_def = {
"bevel",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */
- {BMO_OP_SLOT_FLT, "offset"}, /* amount to offset beveled edge */
- {BMO_OP_SLOT_INT, "segments"}, /* number of segments in bevel */
- {0},
+ {{"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 */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */
- {0},
- },
-#if 0 /* old bevel*/
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */
- {BMO_OP_SLOT_ELEMENT_BUF, "face_spans"}, /* new geometry */
- {BMO_OP_SLOT_ELEMENT_BUF, "face_holes"}, /* new geometry */
- {BMO_OP_SLOT_BOOL, "use_lengths"}, /* grab edge lengths from a PROP_FLT customdata layer */
- {BMO_OP_SLOT_BOOL, "use_even"}, /* corner vert placement: use shell/angle calculations */
- {BMO_OP_SLOT_BOOL, "use_dist"}, /* corner vert placement: evaluate percent as a distance,
- * modifier uses this. We could do this as another float setting */
- {BMO_OP_SLOT_INT, "lengthlayer"}, /* which PROP_FLT layer to us */
- {BMO_OP_SLOT_FLT, "percent"}, /* percentage to expand beveled edge */
- {0},
- },
-#endif
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
+ },
+/* old bevel*/
+// {{"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,
+// * modifier uses this. We could do this as another float setting */
+// {"lengthlayer", BMO_OP_SLOT_INT}, /* which PROP_FLT layer to us */
+// {"percent", BMO_OP_SLOT_FLT}, /* percentage to expand beveled edge */
+// {{'\0'}},
+// },
+
bmo_bevel_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
/*
- * Beautify Fill
+ * Beautify Fill.
*
- * Makes triangle a bit nicer
+ * Rotate edges to create more evenly spaced triangles.
*/
static BMOpDefine bmo_beautify_fill_def = {
"beautify_fill",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_ELEMENT_BUF, "constrain_edges"}, /* edges that can't be flipped */
- {0},
+ {{"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 */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* new flipped faces and edges */
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new flipped faces and edges */
+ {{'\0'}},
},
bmo_beautify_fill_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
/*
- * Triangle Fill
+ * Triangle Fill.
*
* Fill edges with triangles
*/
static BMOpDefine bmo_triangle_fill_def = {
"triangle_fill",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */
- {0},
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"}, /* new faces and edges */
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new faces and edges */
+ {{'\0'}},
},
bmo_triangle_fill_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
};
/*
- * Solidify
+ * Solidify.
*
* Turns a mesh into a shell with thickness
*/
static BMOpDefine bmo_solidify_def = {
"solidify",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom"},
- {BMO_OP_SLOT_FLT, "thickness"},
- {0},
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"thickness", BMO_OP_SLOT_FLT},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{'\0'}},
},
bmo_solidify_face_region_exec,
0
};
/*
- * Face Inset
+ * Face Inset.
*
- * Extrudes faces individually.
+ * Inset or outset faces.
*/
static BMOpDefine bmo_inset_def = {
"inset",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_BOOL, "use_boundary"},
- {BMO_OP_SLOT_BOOL, "use_even_offset"},
- {BMO_OP_SLOT_BOOL, "use_relative_offset"},
- {BMO_OP_SLOT_FLT, "thickness"},
- {BMO_OP_SLOT_FLT, "depth"},
- {BMO_OP_SLOT_BOOL, "use_outset"},
- {0},
+ {{"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},
+ {"thickness", BMO_OP_SLOT_FLT},
+ {"depth", BMO_OP_SLOT_FLT},
+ {"use_outset", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */
- {0},
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
},
bmo_inset_exec,
0
};
/*
- * Wire Frame
+ * Wire Frame.
*
- * Makes a wire copy of faces.
+ * Makes a wire-frame copy of faces.
*/
static BMOpDefine bmo_wireframe_def = {
"wireframe",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */
- {BMO_OP_SLOT_BOOL, "use_boundary"},
- {BMO_OP_SLOT_BOOL, "use_even_offset"},
- {BMO_OP_SLOT_BOOL, "use_crease"},
- {BMO_OP_SLOT_FLT, "thickness"},
- {BMO_OP_SLOT_BOOL, "use_relative_offset"},
- {BMO_OP_SLOT_FLT, "depth"},
- {0},
+ {{"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},
+ {"thickness", BMO_OP_SLOT_FLT},
+ {"use_relative_offset", BMO_OP_SLOT_BOOL},
+ {"depth", BMO_OP_SLOT_FLT},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "faces.out"}, /* output faces */
- {0},
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
},
bmo_wireframe_exec,
0
};
/*
- * Vertex Slide
+ * Vertex Slide.
*
- * Translates vertes along an edge
+ * Translates verts along an edge
*/
static BMOpDefine bmo_slide_vert_def = {
"slide_vert",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "vert"},
- {BMO_OP_SLOT_ELEMENT_BUF, "edge"},
- {BMO_OP_SLOT_FLT, "distance_t"},
- {0},
+ {{"vert", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}},
+ {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"factor", BMO_OP_SLOT_FLT},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "verts.out"},
- {0},
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {{'\0'}},
},
bmo_slide_vert_exec,
BMO_OP_FLAG_UNTAN_MULTIRES
@@ -1499,16 +1575,16 @@ static BMOpDefine bmo_slide_vert_def = {
static BMOpDefine bmo_convex_hull_def = {
"convex_hull",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "input"},
- {BMO_OP_SLOT_BOOL, "use_existing_faces"},
- {0},
+ {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"use_existing_faces", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "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"},
- {0},
+ {{"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,
0
@@ -1516,9 +1592,9 @@ static BMOpDefine bmo_convex_hull_def = {
#endif
/*
- * Symmetrize
+ * Symmetrize.
*
- * Mekes the mesh elements in the "input" slot symmetrical. Unlike
+ * Makes the mesh elements in the "input" slot symmetrical. Unlike
* normal mirroring, it only copies in one direction, as specified by
* the "direction" slot. The edges and faces that cross the plane of
* symmetry are split as needed to enforce symmetry.
@@ -1528,19 +1604,19 @@ static BMOpDefine bmo_convex_hull_def = {
static BMOpDefine bmo_symmetrize_def = {
"symmetrize",
/* slots_in */
- {{BMO_OP_SLOT_ELEMENT_BUF, "input"},
- {BMO_OP_SLOT_INT, "direction"},
- {0},
+ {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"direction", BMO_OP_SLOT_INT},
+ {{'\0'}},
},
/* slots_out */
- {{BMO_OP_SLOT_ELEMENT_BUF, "geom.out"},
- {0},
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{'\0'}},
},
bmo_symmetrize_exec,
0
};
-BMOpDefine *opdefines[] = {
+const BMOpDefine *bmo_opdefines[] = {
&bmo_automerge_def,
&bmo_average_vert_facedata_def,
&bmo_beautify_fill_def,
@@ -1615,7 +1691,6 @@ BMOpDefine *opdefines[] = {
&bmo_unsubdivide_def,
&bmo_weld_verts_def,
&bmo_wireframe_def,
-
};
-int bmesh_total_ops = (sizeof(opdefines) / sizeof(void *));
+const int bmo_opdefines_total = (sizeof(bmo_opdefines) / sizeof(void *));
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index b87e023e63a..7df9c94a2f1 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -91,15 +91,15 @@ BLI_INLINE void _bmo_elem_flag_toggle( BMesh *bm, BMFlagLayer *oflags, const
/* slot type arrays are terminated by the last member
* having a slot type of 0 */
-enum {
- BMO_OP_SLOT_SENTINEL = 0,
+typedef enum eBMOpSlotType {
+ /* BMO_OP_SLOT_SENTINEL = 0, */
BMO_OP_SLOT_BOOL = 1,
BMO_OP_SLOT_INT = 2,
BMO_OP_SLOT_FLT = 3,
/* normally store pointers to object, scene,
* _never_ store arrays corresponding to mesh elements with this */
- BMO_OP_SLOT_PTR = 4,
+ BMO_OP_SLOT_PTR = 4, /* requres subtype BMO_OP_SLOT_SUBTYPE_PTR_xxx */
BMO_OP_SLOT_MAT = 5,
BMO_OP_SLOT_VEC = 8,
@@ -108,16 +108,47 @@ enum {
*
* it's very important this remain a power of two */
BMO_OP_SLOT_ELEMENT_BUF = 9, /* list of verts/edges/faces */
- BMO_OP_SLOT_MAPPING = 10 /* simple hash map */
-};
+ BMO_OP_SLOT_MAPPING = 10 /* simple hash map, requres subtype BMO_OP_SLOT_SUBTYPE_MAP_xxx */
+} eBMOpSlotType;
#define BMO_OP_SLOT_TOTAL_TYPES 11
+/* 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_FLT = 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_Elem elem;
+ eBMOpSlotSubType_Ptr 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 */
- int slot_type;
+ eBMOpSlotType slot_type;
+ eBMOpSlotSubType_Union slot_subtype;
+
int len;
// int flag; /* UNUSED */
// int index; /* index within slot array */ /* UNUSED */
@@ -166,8 +197,9 @@ enum {
#define MAX_SLOTNAME 32
typedef struct BMOSlotType {
- int type;
char name[MAX_SLOTNAME];
+ eBMOpSlotType type;
+ eBMOpSlotSubType_Union subtype;
} BMOSlotType;
typedef struct BMOpDefine {
@@ -208,43 +240,6 @@ int BMO_mesh_enabled_flag_count(BMesh *bm, const char htype, const short oflag);
int BMO_mesh_disabled_flag_count(BMesh *bm, const char htype, const short oflag);
/*---------formatted operator initialization/execution-----------*/
-/*
- * this system is used to execute or initialize an operator,
- * using a formatted-string system.
- *
- * for example, BMO_op_callf(bm, BMO_FLAG_DEFAULTS, "delete geom=%hf context=%i", BM_ELEM_SELECT, DEL_FACES);
- * . . .will execute the delete operator, feeding in selected faces, deleting them.
- *
- * the basic format for the format string is:
- * [operatorname] [slot_name]=%[code] [slot_name]=%[code]
- *
- * as in printf, you pass in one additional argument to the function
- * for every code.
- *
- * the formatting codes are:
- * %d - put int in slot
- * %f - put float in slot
- * %p - put pointer in slot
- * %h[f/e/v] - put elements with a header flag in slot.
- * the letters after %h define which element types to use,
- * so e.g. %hf will do faces, %hfe will do faces and edges,
- * %hv will do verts, etc. must pass in at least one
- * element type letter.
- * %H[f/e/v] - same as %h, but tests if the flag is disabled
- * %f[f/e/v] - same as %h, except it deals with tool flags instead of
- * header flags.
- * %F[f/e/v] - same as %f, but tests if the flag is disabled
- * %a[f/e/v] - pass all elements (of types specified by f/e/v) to the
- * slot.
- * %e - pass in a single element.
- * %v - pointer to a float vector of length 3.
- * %m[3/4] - matrix, 3/4 refers to the matrix size, 3 or 4. the
- * corresponding argument must be a pointer to
- * a float matrix.
- * %s - copy a slot from another op, instead of mapping to one
- * argument, it maps to two, a pointer to an operator and
- * a slot name.
- */
void BMO_push(BMesh *bm, BMOperator *op);
void BMO_pop(BMesh *bm);
@@ -385,12 +380,16 @@ void BMO_slot_buffer_from_disabled_hflag(BMesh *bm, BMOperator *op,
BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
const char htype, const char hflag);
+void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele);
+void *BMO_slot_buffer_get_single(BMOpSlot *slot);
+
+
/* counts number of elements inside a slot array. */
int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot,
- const void *element, void *data, int len);
+ const void *element, const void *data, const int len);
/* Counts the number of edges with tool flag toolflag around
*/
@@ -407,15 +406,18 @@ void *BMO_slot_buffer_alloc(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS]
void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
const char *slot_name, const char htype);
-/* this part of the API is used to iterate over element buffer or
+/**
+ * This part of the API is used to iterate over element buffer or
* mapping slots.
*
* for example, iterating over the faces in a slot is:
*
+ * \code{.c}
+ *
* BMOIter oiter;
* BMFace *f;
*
- * f = BMO_iter_new(&oiter, bm, some_operator, "slot_name", BM_FACE);
+ * f = BMO_iter_new(&oiter, some_operator, "slot_name", BM_FACE);
* for (; f; f = BMO_iter_step(&oiter)) {
* /do something with the face
* }
@@ -436,6 +438,7 @@ void BMO_slot_buffer_from_all(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_
* // *((void**)BMO_iter_map_value(&oiter));
* //or something like that.
* }
+ * \endcode
*/
/* contents of this structure are private,
@@ -478,6 +481,9 @@ typedef struct BMOElemMapping {
int len;
} BMOElemMapping;
+/* pointer after BMOElemMapping */
+#define BMO_OP_SLOT_MAPPING_DATA(var) (void *)(((BMOElemMapping *)var) + 1)
+
extern const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES];
#ifdef __cplusplus
diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
index b405ecc1841..ad116011421 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
@@ -70,14 +70,24 @@ 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, int val)
+ void *element, const int val)
{
+ 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.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
+ BLI_assert(val == FALSE || val == TRUE);
BMO_slot_map_insert(op, slot, element, &val, sizeof(int));
}
BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op, BMOpSlot *slot,
- void *element, float val)
+ void *element, const float val)
{
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
BMO_slot_map_insert(op, slot, element, &val, sizeof(float));
}
@@ -90,9 +100,26 @@ 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.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.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
+ BMO_slot_map_insert(op, slot, element, &val, sizeof(void *));
+}
+
+
+/* no values */
+BLI_INLINE void BMO_slot_map_empty_insert(BMOperator *op, BMOpSlot *slot,
+ const void *element)
+{
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_EMPTY);
+ BMO_slot_map_insert(op, slot, element, NULL, 0);
+}
+
BLI_INLINE int BMO_slot_map_contains(BMOpSlot *slot, const void *element)
{
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
@@ -126,7 +153,10 @@ 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 = (float *) BMO_slot_map_data_get(slot, element);
+ float *val;
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
+
+ val = (float *) BMO_slot_map_data_get(slot, element);
if (val) return *val;
return 0.0f;
@@ -134,7 +164,22 @@ 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 = (int *) BMO_slot_map_data_get(slot, element);
+ int *val;
+ 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;
+
+ return 0;
+}
+
+BLI_INLINE int BMO_slot_map_bool_get(BMOpSlot *slot, const void *element)
+{
+ int *val;
+ 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);
if (val) return *val;
return 0;
@@ -143,6 +188,16 @@ BLI_INLINE int BMO_slot_map_int_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.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
+ if (val) return *val;
+
+ return NULL;
+}
+
+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.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
if (val) return *val;
return NULL;
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 157837a13c0..ba38f230f0b 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -127,12 +127,13 @@ void BMO_pop(BMesh *bm)
/* use for both slot_types_in and slot_types_out */
-static void bmo_op_slots_init(BMOSlotType *slot_types, BMOpSlot *slot_args)
+static void bmo_op_slots_init(const BMOSlotType *slot_types, BMOpSlot *slot_args)
{
unsigned int i;
for (i = 0; slot_types[i].type; i++) {
- slot_args[i].slot_name = slot_types[i].name;
- slot_args[i].slot_type = slot_types[i].type;
+ slot_args[i].slot_name = slot_types[i].name;
+ slot_args[i].slot_type = slot_types[i].type;
+ slot_args[i].slot_subtype = slot_types[i].subtype;
// slot_args[i].index = i; // UNUSED
}
}
@@ -158,15 +159,15 @@ void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname)
memset(op, 0, sizeof(BMOperator));
op->type = opcode;
- op->type_flag = opdefines[opcode]->type_flag;
+ op->type_flag = bmo_opdefines[opcode]->type_flag;
op->flag = flag;
/* initialize the operator slot types */
- bmo_op_slots_init(opdefines[opcode]->slot_types_in, op->slots_in);
- bmo_op_slots_init(opdefines[opcode]->slot_types_out, op->slots_out);
+ bmo_op_slots_init(bmo_opdefines[opcode]->slot_types_in, op->slots_in);
+ bmo_op_slots_init(bmo_opdefines[opcode]->slot_types_out, op->slots_out);
/* callback */
- op->exec = opdefines[opcode]->exec;
+ op->exec = bmo_opdefines[opcode]->exec;
/* memarena, used for operator's slot buffers */
op->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
@@ -199,7 +200,7 @@ void BMO_op_exec(BMesh *bm, BMOperator *op)
BMO_pop(bm);
}
-static void bmo_op_slots_free(BMOSlotType *slot_types, BMOpSlot *slot_args)
+static void bmo_op_slots_free(const BMOSlotType *slot_types, BMOpSlot *slot_args)
{
BMOpSlot *slot;
unsigned int i;
@@ -220,13 +221,13 @@ static void bmo_op_slots_free(BMOSlotType *slot_types, BMOpSlot *slot_args)
*/
void BMO_op_finish(BMesh *bm, BMOperator *op)
{
- bmo_op_slots_free(opdefines[op->type]->slot_types_in, op->slots_in);
- bmo_op_slots_free(opdefines[op->type]->slot_types_out, op->slots_out);
+ bmo_op_slots_free(bmo_opdefines[op->type]->slot_types_in, op->slots_in);
+ bmo_op_slots_free(bmo_opdefines[op->type]->slot_types_out, op->slots_out);
BLI_memarena_free(op->arena);
#ifdef DEBUG
- BM_ELEM_INDEX_VALIDATE(bm, "post bmo", opdefines[op->type]->opname);
+ BM_ELEM_INDEX_VALIDATE(bm, "post bmo", bmo_opdefines[op->type]->opname);
#else
(void)bm;
#endif
@@ -287,9 +288,49 @@ void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_n
slot_dst->data.buf = NULL;
slot_dst->len = slot_src->len;
if (slot_dst->len) {
- const int slot_alloc_size = BMO_OPSLOT_TYPEINFO[slot_dst->slot_type] * slot_dst->len;
- slot_dst->data.buf = BLI_memarena_alloc(arena_dst, slot_alloc_size);
- memcpy(slot_dst->data.buf, slot_src->data.buf, slot_alloc_size);
+ /* check dest has all flags enabled that the source has */
+ const eBMOpSlotSubType_Elem src_elem_flag = (slot_src->slot_subtype.elem & BM_ALL_NOLOOP);
+ const eBMOpSlotSubType_Elem dst_elem_flag = (slot_dst->slot_subtype.elem & BM_ALL_NOLOOP);
+
+ if ((src_elem_flag | dst_elem_flag) == dst_elem_flag) {
+ /* pass */
+ }
+ else {
+ /* check types */
+ const unsigned int tot = slot_src->len;
+ unsigned int i;
+ unsigned int out = 0;
+ BMElem **ele_src = (BMElem **)slot_src->data.buf;
+ for (i = 0; i < tot; i++, ele_src++) {
+ if ((*ele_src)->head.htype & dst_elem_flag) {
+ out++;
+ }
+ }
+ if (out != tot) {
+ slot_dst->len = out;
+ }
+ }
+
+ if (slot_dst->len) {
+ const int slot_alloc_size = BMO_OPSLOT_TYPEINFO[slot_dst->slot_type] * slot_dst->len;
+ slot_dst->data.buf = BLI_memarena_alloc(arena_dst, slot_alloc_size);
+ if (slot_src->len == slot_dst->len) {
+ memcpy(slot_dst->data.buf, slot_src->data.buf, slot_alloc_size);
+ }
+ else {
+ /* only copy compatible elements */
+ const unsigned int tot = slot_src->len;
+ unsigned int i;
+ BMElem **ele_src = (BMElem **)slot_src->data.buf;
+ BMElem **ele_dst = (BMElem **)slot_dst->data.buf;
+ for (i = 0; i < tot; i++, ele_src++) {
+ if ((*ele_src)->head.htype & dst_elem_flag) {
+ *ele_dst = *ele_src;
+ ele_dst++;
+ }
+ }
+ }
+ }
}
}
else if (slot_dst->slot_type == BMO_OP_SLOT_MAPPING) {
@@ -313,7 +354,7 @@ void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_n
dstmap->element = srcmap->element;
dstmap->len = srcmap->len;
- memcpy(dstmap + 1, srcmap + 1, srcmap->len);
+ memcpy(BMO_OP_SLOT_MAPPING_DATA(dstmap), BMO_OP_SLOT_MAPPING_DATA(srcmap), srcmap->len);
BLI_ghash_insert(slot_dst->data.ghash, dstmap->element, dstmap);
}
@@ -595,7 +636,7 @@ int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_na
* value, it doesn't store a reference to it. */
void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot,
- const void *element, void *data, int len)
+ const void *element, const void *data, const int len)
{
BMOElemMapping *mapping;
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
@@ -605,11 +646,14 @@ void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot,
mapping->element = (BMHeader *) element;
mapping->len = len;
- memcpy(mapping + 1, data, len);
+ memcpy(BMO_OP_SLOT_MAPPING_DATA(mapping), data, len);
if (!slot->data.ghash) {
slot->data.ghash = BLI_ghash_ptr_new("bmesh slot map hash");
}
+ else {
+ BLI_assert(slot->data.ghash);
+ }
BLI_ghash_insert(slot->data.ghash, (void *)element, mapping);
}
@@ -631,7 +675,7 @@ void *bmo_slot_buffer_grow(BMesh *bm, BMOperator *op, int slot_code, int totadd)
if (slot->len >= slot->size) {
slot->size = (slot->size + 1 + totadd) * 2;
- allocsize = BMO_OPSLOT_TYPEINFO[opdefines[op->type]->slot_types[slot_code].type] * slot->size;
+ allocsize = BMO_OPSLOT_TYPEINFO[bmo_opdefines[op->type]->slot_types[slot_code].type] * slot->size;
tmp = slot->data.buf;
slot->data.buf = MEM_callocN(allocsize, "opslot dynamic array");
@@ -646,7 +690,7 @@ void *bmo_slot_buffer_grow(BMesh *bm, BMOperator *op, int slot_code, int totadd)
slot->len += totadd;
slot->size = slot->len + 2;
- allocsize = BMO_OPSLOT_TYPEINFO[opdefines[op->type]->slot_types[slot_code].type] * slot->len;
+ allocsize = BMO_OPSLOT_TYPEINFO[bmo_opdefines[op->type]->slot_types[slot_code].type] * slot->len;
tmp = slot->data.buf;
slot->data.buf = MEM_callocN(allocsize, "opslot dynamic array");
@@ -823,6 +867,29 @@ void BMO_slot_buffer_from_disabled_hflag(BMesh *bm, BMOperator *op,
bmo_slot_buffer_from_hflag(bm, op, slot_args, slot_name, htype, hflag, FALSE);
}
+void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele)
+{
+ BMO_ASSERT_SLOT_IN_OP(slot, op);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE);
+ BLI_assert(slot->len == 0 || slot->len == 1);
+
+ BLI_assert(slot->slot_subtype.elem & ele->htype);
+
+ slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(void *) * 4); /* XXX, why 'x4' ? */
+ slot->len = 1;
+ *slot->data.buf = ele;
+}
+
+void *BMO_slot_buffer_get_single(BMOpSlot *slot)
+{
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE);
+ BLI_assert(slot->len == 0 || slot->len == 1);
+
+ return slot->len ? (BMHeader *)slot->data.buf[0] : NULL;
+}
+
/**
* Copies the values from another slot to the end of the output slot.
*/
@@ -880,6 +947,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;
@@ -955,6 +1023,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))
@@ -989,6 +1058,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))
@@ -1039,6 +1109,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))
@@ -1062,6 +1133,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))
@@ -1252,35 +1324,42 @@ 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);
- iter->val = map + 1;
+ iter->val = BMO_OP_SLOT_MAPPING_DATA(map);
BLI_ghashIterator_step(&iter->giter);
return ret;
}
+ else {
+ BLI_assert(0);
+ }
return NULL;
}
@@ -1393,8 +1472,8 @@ static int bmo_opname_to_opcode(const char *opname)
{
int i;
- for (i = 0; i < bmesh_total_ops; i++) {
- if (!strcmp(opname, opdefines[i]->opname)) {
+ for (i = 0; i < bmo_opdefines_total; i++) {
+ if (!strcmp(opname, bmo_opdefines[i]->opname)) {
return i;
}
}
@@ -1403,23 +1482,63 @@ static int bmo_opname_to_opcode(const char *opname)
return -1;
}
-/* Example:
- * BMO_op_callf(bm, BMO_FLAG_DEFAULTS, "delete %i %hv", DEL_ONLYFACES, BM_ELEM_SELECT);
+/**
+ * \brief Format Strings for #BMOperator Initialization.
+ *
+ * This system is used to execute or initialize an operator,
+ * using a formatted-string system.
+ *
+ * The basic format for the format string is:
+ * `[operatorname] [slot_name]=%[code] [slot_name]=%[code]`
+ *
+ * Example:
+ *
+ * \code{.c}
+ * BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
+ * "delete context=%i geom=%hv",
+ * DEL_ONLYFACES, BM_ELEM_SELECT);
+ * \endcode
+ *
+ *
+ * **Primitive Types**
+ * - `b` - boolean (same as int but 1/0 only). #BMO_OP_SLOT_BOOL
+ * - `i` - int. #BMO_OP_SLOT_INT
+ * - `f` - float. #BMO_OP_SLOT_FLT
+ * - `p` - pointer (normally to a Scene/Mesh/Object/BMesh). #BMO_OP_SLOT_PTR
+ * - `m3` - 3x3 matrix of floats. #BMO_OP_SLOT_MAT
+ * - `m4` - 4x4 matrix of floats. #BMO_OP_SLOT_MAT
+ * - `v` - 3D vector of floats. #BMO_OP_SLOT_VEC
+ *
+ *
+ * **Utility**
+ *
+ * Pass an existing slot which is copied to either an input or output slot.
+ * Taking the operator and slot-name pair of args.
+ * - `s` - slot_in (lower case)
+ * - `S` - slot_out (upper case)
+ *
*
- * i - int
- * b - boolean (same as int but 1/0 only)
- * f - float
- * s - slot_in
- * S - slot_out
- * hv - header flagged verts (hflag)
- * he - header flagged edges (hflag)
- * hf - header flagged faces (hflag)
- * fv - flagged verts (oflag)
- * fe - flagged edges (oflag)
- * ff - flagged faces (oflag)
+ * **Element Buffer** (#BMO_OP_SLOT_ELEMENT_BUF)
+ * - `e` - single element vert/edge/face (use with #BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE).
+ * - `av` - all verts
+ * - `ae` - all edges
+ * - `af` - all faces
+ * - `hv` - header flagged verts (hflag)
+ * - `he` - header flagged edges (hflag)
+ * - `hf` - header flagged faces (hflag)
+ * - `Hv` - header flagged verts (hflag off)
+ * - `He` - header flagged edges (hflag off)
+ * - `Hf` - header flagged faces (hflag off)
+ * - `fv` - flagged verts (oflag)
+ * - `fe` - flagged edges (oflag)
+ * - `ff` - flagged faces (oflag)
+ * - `Fv` - flagged verts (oflag off)
+ * - `Fe` - flagged edges (oflag off)
+ * - `Ff` - flagged faces (oflag off)
*
- * capitals - H, F to use the flag flipped (when the flag is off)
- * Hv, He, Hf, Fv, Fe, Ff,
+ * \note The common v/e/f suffix can be mixed,
+ * so `avef` is can be used for all verts, edges and faces.
+ * Order is not important so `Hfev` is also valid (all unflagged verts, edges and faces).
*/
int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, va_list vlist)
@@ -1463,7 +1582,7 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
}
BMO_op_init(bm, op, flag, opname);
-// def = opdefines[i];
+// def = bmo_opdefines[i];
i = 0;
state = 1; /* 0: not inside slot_code name, 1: inside slot_code name */
@@ -1522,14 +1641,12 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v
state = 1;
break;
}
- case 'e':
+ case 'e': /* single vert/edge/face */
{
BMHeader *ele = va_arg(vlist, void *);
BMOpSlot *slot = BMO_slot_get(op->slots_in, slot_name);
- slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(void *) * 4);
- slot->len = 1;
- *slot->data.buf = ele;
+ BMO_slot_buffer_from_single(op, slot, ele);
state = 1;
break;
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index 1c62a038f34..c98c3eae50b 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -85,29 +85,22 @@ enum {
SIMVERT_EDGE
};
-enum {
- OPUVC_AXIS_X = 1,
- OPUVC_AXIS_Y
-};
-
/* vertex path selection values */
enum {
VPATH_SELECT_EDGE_LENGTH = 0,
VPATH_SELECT_TOPOLOGICAL
};
-extern BMOpDefine *opdefines[];
-extern int bmesh_total_ops;
+extern const BMOpDefine *bmo_opdefines[];
+extern const int bmo_opdefines_total;
/*------specific operator helper functions-------*/
-
-struct Object;
-
void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
float smooth, float fractal, float along_normal,
int numcuts,
int seltype, int cornertype,
- const short use_singleedge, const short use_gridfill,
+ const short use_single_edge, const short use_grid_fill,
+ const short use_only_quads,
int seed);
#include "intern/bmesh_operator_api_inline.h"
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index 65c9cf0c421..9175af1c822 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -61,7 +61,7 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op);
void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op);
void bmo_duplicate_exec(BMesh *bm, BMOperator *op);
void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op);
-void bmo_edgenet_prepare(BMesh *bm, BMOperator *op);
+void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op);
void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op);
void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op);
void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op);
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index ec2e90591cc..195c60c5a9c 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -824,6 +824,29 @@ int BM_edge_share_face_check(BMEdge *e1, BMEdge *e2)
}
/**
+ * Test if e1 shares any quad faces with e2
+ */
+int BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2)
+{
+ BMLoop *l;
+ BMFace *f;
+
+ if (e1->l && e2->l) {
+ l = e1->l;
+ do {
+ f = l->f;
+ if (f->len == 4) {
+ if (bmesh_radial_face_find(e2, f)) {
+ return TRUE;
+ }
+ }
+ l = l->radial_next;
+ } while (l != e1->l);
+ }
+ return FALSE;
+}
+
+/**
* Tests to see if e1 shares a vertex with e2
*/
int BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2)
diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h
index d97faebf021..7a18f69371e 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -90,6 +90,7 @@ int BM_face_share_edge_count(BMFace *f1, BMFace *f2);
int BM_face_share_face_check(BMFace *f1, BMFace *f2);
int BM_face_share_edge_check(BMFace *f1, BMFace *f2);
int BM_edge_share_face_check(BMEdge *e1, BMEdge *e2);
+int BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2);
int BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2);
BMVert *BM_edge_share_vert(BMEdge *e1, BMEdge *e2);