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
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')
-rw-r--r--source/blender/bmesh/bmesh_class.h1
-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
-rw-r--r--source/blender/bmesh/operators/bmo_connect.c2
-rw-r--r--source/blender/bmesh/operators/bmo_create.c26
-rw-r--r--source/blender/bmesh/operators/bmo_dupe.c51
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c26
-rw-r--r--source/blender/bmesh/operators/bmo_hull.c14
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c4
-rw-r--r--source/blender/bmesh/operators/bmo_mirror.c12
-rw-r--r--source/blender/bmesh/operators/bmo_primitive.c64
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c44
-rw-r--r--source/blender/bmesh/operators/bmo_slide.c21
-rw-r--r--source/blender/bmesh/operators/bmo_smooth_laplacian.c1
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c48
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.h4
-rw-r--r--source/blender/bmesh/operators/bmo_symmetrize.c37
-rw-r--r--source/blender/bmesh/operators/bmo_triangulate.c8
-rw-r--r--source/blender/bmesh/operators/bmo_utils.c26
-rw-r--r--source/blender/bmesh/operators/bmo_wireframe.c8
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c111
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate.h3
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c15
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_dissolve.c3
36 files changed, 1326 insertions, 962 deletions
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index f686e96cb7d..bcd6780b675 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -226,6 +226,7 @@ enum {
};
#define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
+#define BM_ALL_NOLOOP (BM_VERT | BM_EDGE | BM_FACE)
/* BMHeader->hflag (char) */
enum {
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);
diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c
index b7bb57bb19d..12edffec213 100644
--- a/source/blender/bmesh/operators/bmo_connect.c
+++ b/source/blender/bmesh/operators/bmo_connect.c
@@ -54,6 +54,8 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_INPUT);
+ /* BMESH_TODO, loop over vert faces:
+ * faster then looping over all faces, then searching each for flagged verts*/
for (f = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); f; f = BM_iter_step(&iter)) {
BLI_array_empty(loops_split);
BLI_array_empty(verts_pair);
diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c
index 987aa8cdf99..aa69806fb37 100644
--- a/source/blender/bmesh/operators/bmo_create.c
+++ b/source/blender/bmesh/operators/bmo_create.c
@@ -274,7 +274,7 @@ static int UNUSED_FUNCTION(rotsys_fill_faces)(BMesh *bm, EdgeData *edata, VertDa
if (!ok || BLI_array_count(edges) < 3)
continue;
- f = BM_face_create_ngon(bm, verts[0], verts[1], edges, BLI_array_count(edges), TRUE);
+ f = BM_face_create_ngon(bm, verts[0], verts[1], edges, BLI_array_count(edges), BM_CREATE_NO_DOUBLE);
if (UNLIKELY(f == NULL)) {
continue;
}
@@ -611,11 +611,11 @@ static void init_rotsys(BMesh *bm, EdgeData *edata, VertData *vdata)
v2 = BM_vert_create(bm, co, NULL);
BM_elem_index_set(v2, -1); /* set_dirty! */
- //BM_edge_create(bm, cv, v2, NULL, FALSE);
+ //BM_edge_create(bm, cv, v2, NULL, 0);
BM_vert_select_set(bm, v2, TRUE);
if (lastv) {
- e2 = BM_edge_create(bm, lastv, v2, NULL, FALSE);
+ e2 = BM_edge_create(bm, lastv, v2, NULL, 0);
BM_edge_select_set(bm, e2, TRUE);
}
@@ -1051,7 +1051,7 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
/* fairly expensive check - see if there are already faces filling this area */
(BM_face_exists_multi_edge(edges, i) == FALSE))
{
- f = BM_face_create_ngon(bm, v1, v2, edges, i, TRUE);
+ f = BM_face_create_ngon(bm, v1, v2, edges, i, BM_CREATE_NO_DOUBLE);
if (f && !BMO_elem_flag_test(bm, f, ELE_ORIG)) {
BMO_elem_flag_enable(bm, f, FACE_NEW);
f->mat_nr = mat_nr;
@@ -1098,7 +1098,7 @@ static BMEdge *edge_next(BMesh *bm, BMEdge *e)
return NULL;
}
-void bmo_edgenet_prepare(BMesh *bm, BMOperator *op)
+void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op)
{
BMOIter siter;
BMEdge *e;
@@ -1249,9 +1249,9 @@ void bmo_edgenet_prepare(BMesh *bm, BMOperator *op)
SWAP(BMVert *, v3, v4);
}
- e = BM_edge_create(bm, v1, v3, NULL, TRUE);
+ e = BM_edge_create(bm, v1, v3, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_NEW);
- e = BM_edge_create(bm, v2, v4, NULL, TRUE);
+ e = BM_edge_create(bm, v2, v4, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_NEW);
}
else if (edges1) {
@@ -1261,7 +1261,7 @@ void bmo_edgenet_prepare(BMesh *bm, BMOperator *op)
v1 = BM_vert_in_edge(edges1[1], edges1[0]->v1) ? edges1[0]->v2 : edges1[0]->v1;
i = BLI_array_count(edges1) - 1;
v2 = BM_vert_in_edge(edges1[i - 1], edges1[i]->v1) ? edges1[i]->v2 : edges1[i]->v1;
- e = BM_edge_create(bm, v1, v2, NULL, TRUE);
+ e = BM_edge_create(bm, v1, v2, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_NEW);
}
}
@@ -1359,10 +1359,10 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
}
if (ok == TRUE && v_free && v_a && v_b) {
- e = BM_edge_create(bm, v_free, v_a, NULL, TRUE);
+ e = BM_edge_create(bm, v_free, v_a, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_NEW);
- e = BM_edge_create(bm, v_free, v_b, NULL, TRUE);
+ e = BM_edge_create(bm, v_free, v_b, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_NEW);
}
}
@@ -1420,7 +1420,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
if (amount == 2) {
/* create edge */
- e = BM_edge_create(bm, verts[0], verts[1], NULL, TRUE);
+ e = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_OUT);
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT);
}
@@ -1461,7 +1461,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
if (ese->htype == BM_VERT) {
v = (BMVert *)ese->ele;
if (v_prev) {
- e = BM_edge_create(bm, v, v_prev, NULL, TRUE);
+ e = BM_edge_create(bm, v, v_prev, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, ELE_OUT);
}
v_prev = v;
@@ -1483,7 +1483,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
i++;
}
- f = BM_face_create_ngon_vcloud(bm, vert_arr, totv, TRUE);
+ f = BM_face_create_ngon_vcloud(bm, vert_arr, totv, BM_CREATE_NO_DOUBLE);
if (f) {
BMO_elem_flag_enable(bm, f, ELE_OUT);
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index c4f6c821320..9a58d7acfb9 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -49,7 +49,7 @@ static BMVert *copy_vertex(BMesh *source_mesh, BMVert *source_vertex, BMesh *tar
BMVert *target_vertex = NULL;
/* Create a new vertex */
- target_vertex = BM_vert_create(target_mesh, source_vertex->co, NULL);
+ target_vertex = BM_vert_create(target_mesh, source_vertex->co, NULL, BM_CREATE_SKIP_CD);
/* Insert new vertex into the vert hash */
BLI_ghash_insert(vhash, source_vertex, target_vertex);
@@ -98,14 +98,13 @@ static BMEdge *copy_edge(BMOperator *op,
target_vert2 = BLI_ghash_lookup(vhash, source_edge->v2);
/* Create a new edge */
- target_edge = BM_edge_create(target_mesh, target_vert1, target_vert2, NULL, FALSE);
+ target_edge = BM_edge_create(target_mesh, target_vert1, target_vert2, NULL, BM_CREATE_SKIP_CD);
/* add to new/old edge map if necassary */
if (rlen < 2) {
/* not sure what non-manifold cases of greater then three
* radial should do. */
- BMO_slot_map_ptr_insert(op, slot_boundarymap_out,
- source_edge, target_edge);
+ BMO_slot_map_elem_insert(op, slot_boundarymap_out, source_edge, target_edge);
}
/* Insert new edge into the edge hash */
@@ -157,9 +156,9 @@ static BMFace *copy_face(BMOperator *op,
}
/* create new face */
- target_face = BM_face_create(target_mesh, vtar, edar, source_face->len, FALSE);
- BMO_slot_map_ptr_insert(op, slot_facemap_out, source_face, target_face);
- BMO_slot_map_ptr_insert(op, slot_facemap_out, target_face, source_face);
+ target_face = BM_face_create(target_mesh, vtar, edar, source_face->len, BM_CREATE_SKIP_CD);
+ BMO_slot_map_elem_insert(op, slot_facemap_out, source_face, target_face);
+ BMO_slot_map_elem_insert(op, slot_facemap_out, target_face, source_face);
BM_elem_attrs_copy(source_mesh, target_mesh, source_face, target_face);
@@ -200,9 +199,9 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
BMIter viter, eiter, fiter;
GHash *vhash, *ehash;
- BMOpSlot *slot_boundarymap_out = BMO_slot_get(op->slots_out, "boundarymap.out");
- BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "facemap.out");
- BMOpSlot *slot_isovertmap_out = BMO_slot_get(op->slots_out, "isovertmap.out");
+ BMOpSlot *slot_boundary_map_out = BMO_slot_get(op->slots_out, "boundary_map.out");
+ BMOpSlot *slot_face_map_out = BMO_slot_get(op->slots_out, "face_map.out");
+ BMOpSlot *slot_isovert_map_out = BMO_slot_get(op->slots_out, "isovert_map.out");
/* initialize pointer hashes */
vhash = BLI_ghash_ptr_new("bmesh dupeops v");
@@ -235,7 +234,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
}
if (isolated) {
- BMO_slot_map_ptr_insert(op, slot_isovertmap_out, v, v2);
+ BMO_slot_map_elem_insert(op, slot_isovert_map_out, v, v2);
}
BMO_elem_flag_enable(bm_src, v, DUPE_DONE);
@@ -257,7 +256,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
BMO_elem_flag_enable(bm_src, e->v2, DUPE_DONE);
}
/* now copy the actual edge */
- copy_edge(op, slot_boundarymap_out, bm_src, e, bm_dst, vhash, ehash);
+ copy_edge(op, slot_boundary_map_out, bm_src, e, bm_dst, vhash, ehash);
BMO_elem_flag_enable(bm_src, e, DUPE_DONE);
}
}
@@ -276,7 +275,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
/* edge pass */
BM_ITER_ELEM (e, &eiter, f, BM_EDGES_OF_FACE) {
if (!BMO_elem_flag_test(bm_src, e, DUPE_DONE)) {
- copy_edge(op, slot_boundarymap_out, bm_src, e, bm_dst, vhash, ehash);
+ copy_edge(op, slot_boundary_map_out, bm_src, e, bm_dst, vhash, ehash);
BMO_elem_flag_enable(bm_src, e, DUPE_DONE);
}
}
@@ -288,7 +287,7 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst)
BLI_array_grow_items(vtar, f->len);
BLI_array_grow_items(edar, f->len);
- copy_face(op, slot_facemap_out, bm_src, f, bm_dst, vtar, edar, vhash, ehash);
+ copy_face(op, slot_face_map_out, bm_src, f, bm_dst, vtar, edar, vhash, ehash);
BMO_elem_flag_enable(bm_src, f, DUPE_DONE);
}
}
@@ -331,7 +330,7 @@ void bmo_duplicate_exec(BMesh *bm, BMOperator *op)
bm2 = bm;
/* flag input */
- BMO_slot_buffer_flag_enable(bm, dupeop->slots_in, "geom", BM_ALL, DUPE_INPUT);
+ BMO_slot_buffer_flag_enable(bm, dupeop->slots_in, "geom", BM_ALL_NOLOOP, DUPE_INPUT);
/* use the internal copy function */
bmo_mesh_copy(dupeop, bm, bm2);
@@ -342,7 +341,7 @@ void bmo_duplicate_exec(BMesh *bm, BMOperator *op)
dupeop, slots_out, "geom_orig.out");
/* Now alloc the new output buffers */
- BMO_slot_buffer_from_enabled_flag(bm, dupeop, dupeop->slots_out, "geom.out", BM_ALL, DUPE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, dupeop, dupeop->slots_out, "geom.out", BM_ALL_NOLOOP, DUPE_NEW);
}
#if 0 /* UNUSED */
@@ -397,7 +396,7 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
&dupeop, slots_in, "geom");
BMO_op_exec(bm, &dupeop);
- BMO_slot_buffer_flag_enable(bm, splitop->slots_in, "geom", BM_ALL, SPLIT_INPUT);
+ BMO_slot_buffer_flag_enable(bm, splitop->slots_in, "geom", BM_ALL_NOLOOP, SPLIT_INPUT);
if (use_only_faces) {
BMVert *v;
@@ -438,7 +437,7 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
/* connect outputs of dupe to delete, exluding keep geometry */
BMO_slot_int_set(delop.slots_in, "context", DEL_FACES);
- BMO_slot_buffer_from_enabled_flag(bm, &delop, delop.slots_in, "geom", BM_ALL, SPLIT_INPUT);
+ BMO_slot_buffer_from_enabled_flag(bm, &delop, delop.slots_in, "geom", BM_ALL_NOLOOP, SPLIT_INPUT);
BMO_op_exec(bm, &delop);
@@ -446,11 +445,11 @@ void bmo_split_exec(BMesh *bm, BMOperator *op)
BMO_slot_copy(&dupeop, slots_out, "geom.out",
splitop, slots_out, "geom.out");
- BMO_slot_copy(&dupeop, slots_out, "boundarymap.out",
- splitop, slots_out, "boundarymap.out");
+ BMO_slot_copy(&dupeop, slots_out, "boundary_map.out",
+ splitop, slots_out, "boundary_map.out");
- BMO_slot_copy(&dupeop, slots_out, "isovertmap.out",
- splitop, slots_out, "isovertmap.out");
+ BMO_slot_copy(&dupeop, slots_out, "isovert_map.out",
+ splitop, slots_out, "isovert_map.out");
/* cleanup */
@@ -466,7 +465,7 @@ void bmo_delete_exec(BMesh *bm, BMOperator *op)
BMOperator *delop = op;
/* Mark Buffer */
- BMO_slot_buffer_flag_enable(bm, delop->slots_in, "geom", BM_ALL, DEL_INPUT);
+ BMO_slot_buffer_flag_enable(bm, delop->slots_in, "geom", BM_ALL_NOLOOP, DEL_INPUT);
BMO_remove_tagged_context(bm, DEL_INPUT, BMO_slot_int_get(op->slots_in, "context"));
@@ -495,7 +494,7 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
BMO_slot_vec_get(op->slots_in, "dvec", dvec);
usedvec = !is_zero_v3(dvec);
steps = BMO_slot_int_get(op->slots_in, "steps");
- phi = BMO_slot_float_get(op->slots_in, "angle") * DEG2RADF(1.0f) / steps;
+ phi = BMO_slot_float_get(op->slots_in, "angle") / steps;
do_dupli = BMO_slot_bool_get(op->slots_in, "use_duplicate");
axis_angle_to_mat3(rmat, axis, phi);
@@ -507,7 +506,7 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
BMO_op_initf(bm, &dupop, op->flag, "duplicate geom=%S", op, "geom_last.out");
BMO_op_exec(bm, &dupop);
BMO_op_callf(bm, op->flag,
- "rotate cent=%v mat=%m3 verts=%S",
+ "rotate cent=%v matrix=%m3 verts=%S",
cent, rmat, &dupop, "geom.out");
BMO_slot_copy(&dupop, slots_out, "geom.out",
op, slots_out, "geom_last.out");
@@ -518,7 +517,7 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
op, "geom_last.out");
BMO_op_exec(bm, &extop);
BMO_op_callf(bm, op->flag,
- "rotate cent=%v mat=%m3 verts=%S",
+ "rotate cent=%v matrix=%m3 verts=%S",
cent, rmat, &extop, "geom.out");
BMO_slot_copy(&extop, slots_out, "geom.out",
op, slots_out, "geom_last.out");
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 6a9d9c1e48b..065a1b57737 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -67,11 +67,11 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
i = 0;
firstv = lastv = NULL;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- v = BM_vert_create(bm, l->v->co, l->v);
+ v = BM_vert_create(bm, l->v->co, l->v, 0);
/* skip on the first iteration */
if (lastv) {
- e = BM_edge_create(bm, lastv, v, l->e, FALSE);
+ e = BM_edge_create(bm, lastv, v, l->e, 0);
edges[i++] = e;
}
@@ -81,12 +81,12 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
}
/* this fits in the array because we skip one in the loop above */
- e = BM_edge_create(bm, v, firstv, laste, FALSE);
+ e = BM_edge_create(bm, v, firstv, laste, 0);
edges[i++] = e;
BMO_elem_flag_enable(bm, f, EXT_DEL);
- f2 = BM_face_create_ngon(bm, firstv, BM_edge_other_vert(edges[0], firstv), edges, f->len, FALSE);
+ f2 = BM_face_create_ngon(bm, firstv, BM_edge_other_vert(edges[0], firstv), edges, f->len, 0);
if (UNLIKELY(f2 == NULL)) {
BMO_error_raise(bm, op, BMERR_MESH_ERROR, "Extrude failed: could not create face");
BLI_array_free(edges);
@@ -198,7 +198,7 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
}
}
- for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundarymap.out", 0); e; e = BMO_iter_step(&siter)) {
+ for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundary_map.out", 0); e; e = BMO_iter_step(&siter)) {
BMVert *f_verts[4];
e_new = *(BMEdge **)BMO_iter_map_value(&siter);
@@ -230,7 +230,7 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
BMO_op_finish(bm, &dupeop);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, EXT_KEEP);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, EXT_KEEP);
}
void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
@@ -241,11 +241,11 @@ void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
const int has_vskin = CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN);
for (v = BMO_iter_new(&siter, op->slots_in, "verts", BM_VERT); v; v = BMO_iter_step(&siter)) {
- dupev = BM_vert_create(bm, v->co, v);
+ dupev = BM_vert_create(bm, v->co, v, 0);
if (has_vskin)
bm_extrude_disable_skin_root(bm, v);
- e = BM_edge_create(bm, v, dupev, NULL, FALSE);
+ e = BM_edge_create(bm, v, dupev, NULL, 0);
BMO_elem_flag_enable(bm, e, EXT_KEEP);
BMO_elem_flag_enable(bm, dupev, EXT_KEEP);
@@ -352,9 +352,9 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
}
}
- slot_facemap_out = BMO_slot_get(dupeop.slots_out, "facemap.out");
+ slot_facemap_out = BMO_slot_get(dupeop.slots_out, "face_map.out");
if (bm->act_face && BMO_elem_flag_test(bm, bm->act_face, EXT_INPUT)) {
- bm->act_face = BMO_slot_map_ptr_get(slot_facemap_out, bm->act_face);
+ bm->act_face = BMO_slot_map_elem_get(slot_facemap_out, bm->act_face);
}
if (delorig) {
@@ -374,7 +374,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
op, slots_out, "geom.out");
slot_edges_exclude = BMO_slot_get(op->slots_in, "edges_exclude");
- for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundarymap.out", 0); e; e = BMO_iter_step(&siter)) {
+ for (e = BMO_iter_new(&siter, dupeop.slots_out, "boundary_map.out", 0); e; e = BMO_iter_step(&siter)) {
BMVert *f_verts[4];
/* this should always be wire, so this is mainly a speedup to avoid map lookup */
@@ -428,9 +428,9 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
}
/* link isolated vert */
- for (v = BMO_iter_new(&siter, dupeop.slots_out, "isovertmap.out", 0); v; v = BMO_iter_step(&siter)) {
+ for (v = BMO_iter_new(&siter, dupeop.slots_out, "isovert_map.out", 0); v; v = BMO_iter_step(&siter)) {
v2 = *((void **)BMO_iter_map_value(&siter));
- BM_edge_create(bm, v, v2, v->e, TRUE);
+ BM_edge_create(bm, v, v2, v->e, BM_CREATE_NO_DOUBLE);
}
/* cleanup */
diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c
index 117f65ae4ea..e2da4f4f89c 100644
--- a/source/blender/bmesh/operators/bmo_hull.c
+++ b/source/blender/bmesh/operators/bmo_hull.c
@@ -113,9 +113,9 @@ static void hull_output_triangles(BMesh *bm, GHash *hull_triangles)
if (!t->skip) {
BMEdge *edges[3] = {
- BM_edge_create(bm, t->v[0], t->v[1], NULL, TRUE),
- BM_edge_create(bm, t->v[1], t->v[2], NULL, TRUE),
- BM_edge_create(bm, t->v[2], t->v[0], NULL, TRUE)
+ BM_edge_create(bm, t->v[0], t->v[1], NULL, BM_CREATE_NO_DOUBLE),
+ BM_edge_create(bm, t->v[1], t->v[2], NULL, BM_CREATE_NO_DOUBLE),
+ BM_edge_create(bm, t->v[2], t->v[0], NULL, BM_CREATE_NO_DOUBLE)
};
BMFace *f, *example = NULL;
@@ -604,22 +604,22 @@ void bmo_convex_hull_exec(BMesh *bm, BMOperator *op)
/* Output slot of input elements that ended up inside the hull
* rather than part of it */
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_interior.out",
- BM_ALL, HULL_FLAG_INTERIOR_ELE);
+ BM_ALL_NOLOOP, HULL_FLAG_INTERIOR_ELE);
/* Output slot of input elements that ended up inside the hull and
* are are unused by other geometry. */
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_unused.out",
- BM_ALL, HULL_FLAG_DEL);
+ BM_ALL_NOLOOP, HULL_FLAG_DEL);
/* Output slot of faces and edges that were in the input and on
* the hull (useful for cases like bridging where you want to
* delete some input geometry) */
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_holes.out",
- BM_ALL, HULL_FLAG_HOLE);
+ BM_ALL_NOLOOP, HULL_FLAG_HOLE);
/* Output slot of all hull vertices, faces, and edges */
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out",
- BM_ALL, HULL_FLAG_OUTPUT_GEOM);
+ BM_ALL_NOLOOP, HULL_FLAG_OUTPUT_GEOM);
}
#endif /* WITH_BULLET */
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index 9abf129a529..cef1181f63b 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -181,7 +181,7 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
if (es->e_new == es->e_old) { /* happens on boundary edges */
/* take care here, we're creating this double edge which _must_ have its verts replaced later on */
- es->e_old = BM_edge_create(bm, es->e_new->v1, es->e_new->v2, es->e_new, FALSE);
+ es->e_old = BM_edge_create(bm, es->e_new->v1, es->e_new->v2, es->e_new, 0);
}
/* store index back to original in 'edge_info' */
@@ -205,7 +205,7 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op)
v1 = BM_vert_create(bm, tvec, NULL);
v2 = BM_vert_create(bm, tvec, NULL);
madd_v3_v3fl(v2->co, es->no, 0.1f);
- BM_edge_create(bm, v1, v2, NULL, FALSE);
+ BM_edge_create(bm, v1, v2, NULL, 0);
}
#endif
diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c
index 01bce976ec0..61b061dd21f 100644
--- a/source/blender/bmesh/operators/bmo_mirror.c
+++ b/source/blender/bmesh/operators/bmo_mirror.c
@@ -60,13 +60,13 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
ototvert = bm->totvert;
/* ototedge = bm->totedge; */ /* UNUSED */
- BMO_slot_mat4_get(op->slots_in, "mat", mtx);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mtx);
invert_m4_m4(imtx, mtx);
BMO_op_initf(bm, &dupeop, op->flag, "duplicate geom=%s", op, "geom");
BMO_op_exec(bm, &dupeop);
- BMO_slot_buffer_flag_enable(bm, dupeop.slots_out, "geom.out", BM_ALL, ELE_NEW);
+ BMO_slot_buffer_flag_enable(bm, dupeop.slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW);
/* create old -> new mappin */
i = 0;
@@ -81,9 +81,9 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
/* feed old data to transform bmo */
scale[axis] = -1.0f;
- BMO_op_callf(bm, op->flag, "transform verts=%fv mat=%m4", ELE_NEW, mtx);
+ BMO_op_callf(bm, op->flag, "transform verts=%fv matrix=%m4", ELE_NEW, mtx);
BMO_op_callf(bm, op->flag, "scale verts=%fv vec=%v", ELE_NEW, scale);
- BMO_op_callf(bm, op->flag, "transform verts=%fv mat=%m4", ELE_NEW, imtx);
+ BMO_op_callf(bm, op->flag, "transform verts=%fv matrix=%m4", ELE_NEW, imtx);
BMO_op_init(bm, &weldop, op->flag, "weld_verts");
@@ -92,7 +92,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
v = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
for (i = 0; i < ototvert; i++) {
if (fabsf(v->co[axis]) <= dist) {
- BMO_slot_map_ptr_insert(&weldop, slot_targetmap, vmap[i], v);
+ BMO_slot_map_elem_insert(&weldop, slot_targetmap, vmap[i], v);
}
v = BM_iter_step(&iter);
}
@@ -123,7 +123,7 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
BMO_op_finish(bm, &weldop);
BMO_op_finish(bm, &dupeop);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, ELE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_NEW);
BLI_array_free(vmap);
BLI_array_free(emap);
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index 71f63bbaf28..c582f710f43 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -237,7 +237,7 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
float vec[3], mat[4][4], phi, phid;
int a;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
/* one segment first: the X axis */
phi = 1.0f;
@@ -248,11 +248,11 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
vec[2] = 0.0f;
mul_m4_v3(mat, vec);
- eve = BM_vert_create(bm, vec, NULL);
+ eve = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, eve, VERT_MARK);
if (a != 0) {
- e = BM_edge_create(bm, preveve, eve, NULL, TRUE);
+ e = BM_edge_create(bm, preveve, eve, NULL, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(bm, e, EDGE_ORIG);
}
@@ -304,7 +304,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
float phid;
int a;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
phid = 2.0f * (float)M_PI / tot;
/* phi = 0.25f * (float)M_PI; */ /* UNUSED */
@@ -317,11 +317,11 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
vec[0] = -dia * sinf(phi);
vec[1] = 0.0;
vec[2] = dia * cosf(phi);
- eve = BM_vert_create(bm, vec, NULL);
+ eve = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, eve, VERT_MARK);
if (a != 0) {
- e = BM_edge_create(bm, preveve, eve, NULL, FALSE);
+ e = BM_edge_create(bm, preveve, eve, NULL, 0);
BMO_elem_flag_enable(bm, e, EDGE_ORIG);
}
@@ -348,7 +348,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
}
BMO_slot_buffer_flag_enable(bm, bmop.slots_out, "geom.out", BM_VERT, VERT_MARK);
- BMO_op_callf(bm, op->flag, "rotate cent=%v mat=%m3 verts=%S", vec, cmat, &bmop, "geom.out");
+ BMO_op_callf(bm, op->flag, "rotate cent=%v matrix=%m3 verts=%S", vec, cmat, &bmop, "geom.out");
prevop = bmop;
}
@@ -397,7 +397,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
float vec[3], mat[4][4] /* , phi, phid */;
int a;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
/* phid = 2.0f * (float)M_PI / subdiv; */ /* UNUSED */
/* phi = 0.25f * (float)M_PI; */ /* UNUSED */
@@ -407,7 +407,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
vec[0] = dia_div * icovert[a][0];
vec[1] = dia_div * icovert[a][1];
vec[2] = dia_div * icovert[a][2];
- eva[a] = BM_vert_create(bm, vec, NULL);
+ eva[a] = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, eva[a], VERT_MARK);
}
@@ -436,7 +436,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
"subdivide_edges edges=%fe "
"smooth=%f "
"cuts=%i "
- "use_gridfill=%b use_sphere=%b",
+ "use_grid_fill=%b use_sphere=%b",
EDGE_MARK, dia, (1 << (subdiv - 1)) - 1,
TRUE, TRUE);
@@ -463,19 +463,19 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op)
float mat[4][4];
int i;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
for (i = 0; i < monkeynv; i++) {
float v[3];
v[0] = (monkeyv[i][0] + 127) / 128.0, v[1] = monkeyv[i][1] / 128.0, v[2] = monkeyv[i][2] / 128.0;
- tv[i] = BM_vert_create(bm, v, NULL);
+ tv[i] = BM_vert_create(bm, v, NULL, 0);
BMO_elem_flag_enable(bm, tv[i], VERT_MARK);
tv[monkeynv + i] = (fabsf(v[0] = -v[0]) < 0.001f) ?
tv[i] :
- (eve = BM_vert_create(bm, v, NULL), mul_m4_v3(mat, eve->co), eve);
+ (eve = BM_vert_create(bm, v, NULL, 0), mul_m4_v3(mat, eve->co), eve);
BMO_elem_flag_enable(bm, tv[monkeynv + i], VERT_MARK);
@@ -518,7 +518,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
if (!segs)
return;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
phid = 2.0f * (float)M_PI / segs;
phi = 0;
@@ -527,7 +527,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
zero_v3(vec);
mul_m4_v3(mat, vec);
- cent1 = BM_vert_create(bm, vec, NULL);
+ cent1 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, cent1, VERT_MARK);
}
@@ -537,12 +537,12 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
vec[1] = dia * cosf(phi);
vec[2] = 0.0f;
mul_m4_v3(mat, vec);
- v1 = BM_vert_create(bm, vec, NULL);
+ v1 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v1, VERT_MARK);
if (lastv1)
- BM_edge_create(bm, v1, lastv1, NULL, FALSE);
+ BM_edge_create(bm, v1, lastv1, NULL, 0);
if (a && cap_ends) {
BMFace *f;
@@ -560,7 +560,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
if (!a)
return;
- BM_edge_create(bm, lastv1, firstv1, NULL, FALSE);
+ BM_edge_create(bm, firstv1, lastv1, NULL, 0);
if (cap_ends) {
BMFace *f;
@@ -591,7 +591,7 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
if (!segs)
return;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
phid = 2.0f * (float)M_PI / segs;
phi = 0;
@@ -602,13 +602,13 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
vec[2] = -depth;
mul_m4_v3(mat, vec);
- cent1 = BM_vert_create(bm, vec, NULL);
+ cent1 = BM_vert_create(bm, vec, NULL, 0);
vec[0] = vec[1] = 0.0f;
vec[2] = depth;
mul_m4_v3(mat, vec);
- cent2 = BM_vert_create(bm, vec, NULL);
+ cent2 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, cent1, VERT_MARK);
BMO_elem_flag_enable(bm, cent2, VERT_MARK);
@@ -619,13 +619,13 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
vec[1] = dia1 * cosf(phi);
vec[2] = -depth;
mul_m4_v3(mat, vec);
- v1 = BM_vert_create(bm, vec, NULL);
+ v1 = BM_vert_create(bm, vec, NULL, 0);
vec[0] = dia2 * sinf(phi);
vec[1] = dia2 * cosf(phi);
vec[2] = depth;
mul_m4_v3(mat, vec);
- v2 = BM_vert_create(bm, vec, NULL);
+ v2 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v1, VERT_MARK);
BMO_elem_flag_enable(bm, v2, VERT_MARK);
@@ -677,7 +677,7 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op)
BMVert *v1, *v2, *v3, *v4, *v5, *v6, *v7, *v8;
float vec[3], mat[4][4], off = BMO_slot_float_get(op->slots_in, "size") / 2.0f;
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
if (!off) off = 0.5f;
@@ -685,56 +685,56 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op)
vec[1] = -off;
vec[2] = -off;
mul_m4_v3(mat, vec);
- v1 = BM_vert_create(bm, vec, NULL);
+ v1 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v1, VERT_MARK);
vec[0] = -off;
vec[1] = off;
vec[2] = -off;
mul_m4_v3(mat, vec);
- v2 = BM_vert_create(bm, vec, NULL);
+ v2 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v2, VERT_MARK);
vec[0] = off;
vec[1] = off;
vec[2] = -off;
mul_m4_v3(mat, vec);
- v3 = BM_vert_create(bm, vec, NULL);
+ v3 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v3, VERT_MARK);
vec[0] = off;
vec[1] = -off;
vec[2] = -off;
mul_m4_v3(mat, vec);
- v4 = BM_vert_create(bm, vec, NULL);
+ v4 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v4, VERT_MARK);
vec[0] = -off;
vec[1] = -off;
vec[2] = off;
mul_m4_v3(mat, vec);
- v5 = BM_vert_create(bm, vec, NULL);
+ v5 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v5, VERT_MARK);
vec[0] = -off;
vec[1] = off;
vec[2] = off;
mul_m4_v3(mat, vec);
- v6 = BM_vert_create(bm, vec, NULL);
+ v6 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v6, VERT_MARK);
vec[0] = off;
vec[1] = off;
vec[2] = off;
mul_m4_v3(mat, vec);
- v7 = BM_vert_create(bm, vec, NULL);
+ v7 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v7, VERT_MARK);
vec[0] = off;
vec[1] = -off;
vec[2] = off;
mul_m4_v3(mat, vec);
- v8 = BM_vert_create(bm, vec, NULL);
+ v8 = BM_vert_create(bm, vec, NULL, 0);
BMO_elem_flag_enable(bm, v8, VERT_MARK);
/* the four sides */
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index 45e678b96bb..87e26f11d4b 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -44,7 +44,7 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot
int split = FALSE;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- v2 = BMO_slot_map_ptr_get(slot_targetmap, l->v);
+ v2 = BMO_slot_map_elem_get(slot_targetmap, l->v);
/* ok: if v2 is NULL (e.g. not in the map) then it's
* a target vert, otherwise it's a double */
if ((v2 && BM_vert_in_face(f, v2)) &&
@@ -110,7 +110,7 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
/* mark merge verts for deletion */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- if ((v2 = BMO_slot_map_ptr_get(slot_targetmap, v))) {
+ if ((v2 = BMO_slot_map_elem_get(slot_targetmap, v))) {
BMO_elem_flag_enable(bm, v, ELE_DEL);
/* merge the vertex flags, else we get randomly selected/unselected verts */
@@ -126,8 +126,8 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BMO_elem_flag_test(bm, e->v1, ELE_DEL) || BMO_elem_flag_test(bm, e->v2, ELE_DEL)) {
- v = BMO_slot_map_ptr_get(slot_targetmap, e->v1);
- v2 = BMO_slot_map_ptr_get(slot_targetmap, e->v2);
+ v = BMO_slot_map_elem_get(slot_targetmap, e->v1);
+ v2 = BMO_slot_map_elem_get(slot_targetmap, e->v2);
if (!v) v = e->v1;
if (!v2) v2 = e->v2;
@@ -136,7 +136,7 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_enable(bm, e, EDGE_COL);
}
else if (!BM_edge_exists(v, v2)) {
- BM_edge_create(bm, v, v2, e, TRUE);
+ BM_edge_create(bm, v, v2, e, BM_CREATE_NO_DOUBLE);
}
BMO_elem_flag_enable(bm, e, ELE_DEL);
@@ -175,10 +175,10 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
v = l->v;
v2 = l->next->v;
if (BMO_elem_flag_test(bm, v, ELE_DEL)) {
- v = BMO_slot_map_ptr_get(slot_targetmap, v);
+ v = BMO_slot_map_elem_get(slot_targetmap, v);
}
if (BMO_elem_flag_test(bm, v2, ELE_DEL)) {
- v2 = BMO_slot_map_ptr_get(slot_targetmap, v2);
+ v2 = BMO_slot_map_elem_get(slot_targetmap, v2);
}
e2 = v != v2 ? BM_edge_exists(v, v2) : NULL;
@@ -208,13 +208,13 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
v2 = loops[1]->v;
if (BMO_elem_flag_test(bm, v, ELE_DEL)) {
- v = BMO_slot_map_ptr_get(slot_targetmap, v);
+ v = BMO_slot_map_elem_get(slot_targetmap, v);
}
if (BMO_elem_flag_test(bm, v2, ELE_DEL)) {
- v2 = BMO_slot_map_ptr_get(slot_targetmap, v2);
+ v2 = BMO_slot_map_elem_get(slot_targetmap, v2);
}
- f2 = BM_face_create_ngon(bm, v, v2, edges, a, TRUE);
+ f2 = BM_face_create_ngon(bm, v, v2, edges, a, BM_CREATE_NO_DOUBLE);
if (f2 && (f2 != f)) {
BM_elem_attrs_copy(bm, bm, f, f2);
@@ -258,19 +258,19 @@ void bmo_pointmerge_facedata_exec(BMesh *bm, BMOperator *op)
{
BMOIter siter;
BMIter iter;
- BMVert *v, *snapv;
+ BMVert *v, *vert_snap;
BMLoop *l, *firstl = NULL;
float fac;
int i, tot;
- snapv = BMO_iter_new(&siter, op->slots_in, "snapv", BM_VERT);
- tot = BM_vert_face_count(snapv);
+ vert_snap = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert_snap"));
+ tot = BM_vert_face_count(vert_snap);
if (!tot)
return;
fac = 1.0f / tot;
- BM_ITER_ELEM (l, &iter, snapv, BM_LOOPS_OF_VERT) {
+ BM_ITER_ELEM (l, &iter, vert_snap, BM_LOOPS_OF_VERT) {
if (!firstl) {
firstl = l;
}
@@ -343,7 +343,7 @@ void bmo_pointmerge_exec(BMesh *bm, BMOperator *op)
{
BMOperator weldop;
BMOIter siter;
- BMVert *v, *snapv = NULL;
+ BMVert *v, *vert_snap = NULL;
float vec[3];
BMOpSlot *slot_targetmap;
@@ -355,12 +355,12 @@ void bmo_pointmerge_exec(BMesh *bm, BMOperator *op)
slot_targetmap = BMO_slot_get(weldop.slots_in, "targetmap");
BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
- if (!snapv) {
- snapv = v;
- copy_v3_v3(snapv->co, vec);
+ if (!vert_snap) {
+ vert_snap = v;
+ copy_v3_v3(vert_snap->co, vec);
}
else {
- BMO_slot_map_ptr_insert(&weldop, slot_targetmap, v, snapv);
+ BMO_slot_map_elem_insert(&weldop, slot_targetmap, v, vert_snap);
}
}
@@ -414,9 +414,9 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
copy_v3_v3(edges[i]->v2->co, center);
if (edges[i]->v1 != edges[0]->v1)
- BMO_slot_map_ptr_insert(&weldop, slot_targetmap, edges[i]->v1, edges[0]->v1);
+ BMO_slot_map_elem_insert(&weldop, slot_targetmap, edges[i]->v1, edges[0]->v1);
if (edges[i]->v2 != edges[0]->v1)
- BMO_slot_map_ptr_insert(&weldop, slot_targetmap, edges[i]->v2, edges[0]->v1);
+ BMO_slot_map_elem_insert(&weldop, slot_targetmap, edges[i]->v2, edges[0]->v1);
}
}
@@ -554,7 +554,7 @@ static void bmesh_find_doubles_common(BMesh *bm, BMOperator *op,
BMO_elem_flag_enable(bm, v_other, VERT_DOUBLE);
BMO_elem_flag_enable(bm, v_check, VERT_TARGET);
- BMO_slot_map_ptr_insert(optarget, optarget_slot, v_other, v_check);
+ BMO_slot_map_elem_insert(optarget, optarget_slot, v_other, v_check);
}
}
}
diff --git a/source/blender/bmesh/operators/bmo_slide.c b/source/blender/bmesh/operators/bmo_slide.c
index 9dde2461364..ea9f9bf9eba 100644
--- a/source/blender/bmesh/operators/bmo_slide.c
+++ b/source/blender/bmesh/operators/bmo_slide.c
@@ -53,11 +53,10 @@ void bmo_slide_vert_exec(BMesh *bm, BMOperator *op)
int selected_edges = 0;
/* Get slide amount */
- const float distance_t = BMO_slot_float_get(op->slots_in, "distance_t");
+ const float factor = BMO_slot_float_get(op->slots_in, "factor");
/* Get start vertex */
- vertex = BMO_iter_new(&oiter, op->slots_in, "vert", BM_VERT);
-
+ vertex = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert"));
if (!vertex) {
if (G.debug & G_DEBUG) {
@@ -67,15 +66,13 @@ void bmo_slide_vert_exec(BMesh *bm, BMOperator *op)
return;
}
+ /* BMESH_TODO - this is odd, it only uses one edge, why take a list at all? */
/* Count selected edges */
- BMO_ITER (h, &oiter, op->slots_in, "edge", BM_VERT | BM_EDGE) {
- switch (h->htype) {
- case BM_EDGE:
- selected_edges++;
- /* Mark all selected edges (cast BMHeader->BMEdge) */
- BMO_elem_flag_enable(bm, (BMElemF *)h, EDGE_MARK);
- break;
- }
+ BMO_ITER (h, &oiter, op->slots_in, "edges", BM_EDGE) {
+ selected_edges++;
+ /* Mark all selected edges (cast BMHeader->BMEdge) */
+ BMO_elem_flag_enable(bm, (BMElemF *)h, EDGE_MARK);
+ break;
}
/* Only allow sliding if an edge is selected */
@@ -104,7 +101,7 @@ void bmo_slide_vert_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_enable(bm, vertex, VERT_MARK);
/* Interpolate */
- interp_v3_v3v3(vertex->co, vertex->co, other->co, distance_t);
+ interp_v3_v3v3(vertex->co, vertex->co, other->co, factor);
}
/* Return the new edge. The same previously marked with VERT_MARK */
diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
index 4137c31961c..4a367a8fd6f 100644
--- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c
+++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
@@ -544,6 +544,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
BMVert *v;
LaplacianSystem *sys;
+ if (bm->totface == 0) return;
sys = init_laplacian_system(bm->totedge, bm->totface, bm->totvert);
if (!sys) return;
sys->bm = bm;
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index f9b6611c88b..7407eb4423a 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -226,7 +226,7 @@ static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, BMEdge *oedge,
float percent, percent2 = 0.0f;
if (BMO_elem_flag_test(bm, edge, EDGE_PERCENT) && totpoint == 1) {
- percent = BMO_slot_map_float_get(params->slot_edgepercents, edge);
+ percent = BMO_slot_map_float_get(params->slot_edge_percents, edge);
}
else {
percent = 1.0f / (float)(totpoint + 1 - curpoint);
@@ -715,7 +715,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BMFace *face;
BLI_array_declare(verts);
float smooth, fractal, along_normal;
- int use_sphere, cornertype, use_singleedge, use_gridfill;
+ int use_sphere, cornertype, use_single_edge, use_grid_fill, use_only_quads;
int skey, seed, i, j, matched, a, b, numcuts, totesel;
BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, SUBD_SPLIT);
@@ -727,9 +727,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
along_normal = BMO_slot_float_get(op->slots_in, "along_normal");
cornertype = BMO_slot_int_get(op->slots_in, "quad_corner_type");
- use_singleedge = BMO_slot_bool_get(op->slots_in, "use_singleedge");
- use_gridfill = BMO_slot_bool_get(op->slots_in, "use_gridfill");
- use_sphere = BMO_slot_bool_get(op->slots_in, "use_sphere");
+ use_single_edge = BMO_slot_bool_get(op->slots_in, "use_single_edge");
+ use_grid_fill = BMO_slot_bool_get(op->slots_in, "use_grid_fill");
+ use_only_quads = BMO_slot_bool_get(op->slots_in, "use_only_quads");
+ use_sphere = BMO_slot_bool_get(op->slots_in, "use_sphere");
BLI_srandom(seed);
@@ -747,7 +748,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
break;
}
- if (use_singleedge) {
+ if (use_single_edge) {
patterns[0] = &quad_1edge;
patterns[2] = &tri_1edge;
}
@@ -756,7 +757,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
patterns[2] = NULL;
}
- if (use_gridfill) {
+ if (use_grid_fill) {
patterns[3] = &quad_4edge;
patterns[5] = &tri_3edge;
}
@@ -779,8 +780,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
params.numcuts = numcuts;
params.op = op;
- params.slot_edgepercents = BMO_slot_get(op->slots_in, "edgepercents");
- params.slot_custompatterns = BMO_slot_get(op->slots_in, "custompatterns");
+ params.slot_edge_percents = BMO_slot_get(op->slots_in, "edge_percents");
+ params.slot_custom_patterns = BMO_slot_get(op->slots_in, "custom_patterns");
params.smooth = smooth;
params.seed = seed;
params.fractal = fractal;
@@ -793,10 +794,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
params.off[1] = (float)BLI_drand() * 200.0f;
params.off[2] = (float)BLI_drand() * 200.0f;
- BMO_slot_map_to_flag(bm, op->slots_in, "custompatterns",
+ BMO_slot_map_to_flag(bm, op->slots_in, "custom_patterns",
BM_FACE, FACE_CUSTOMFILL);
- BMO_slot_map_to_flag(bm, op->slots_in, "edgepercents",
+ BMO_slot_map_to_flag(bm, op->slots_in, "edge_percents",
BM_EDGE, EDGE_PERCENT);
@@ -804,6 +805,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BMEdge *e1 = NULL, *e2 = NULL;
float vec1[3], vec2[3];
+ /* skip non-quads if requested */
+ if (use_only_quads && face->len != 4)
+ continue;
+
/* figure out which pattern to use */
BLI_array_empty(edges);
@@ -840,7 +845,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
if (BMO_elem_flag_test(bm, face, FACE_CUSTOMFILL)) {
- pat = BMO_slot_map_data_get(params.slot_custompatterns, face);
+ pat = BMO_slot_map_data_get(params.slot_custom_patterns, face);
for (i = 0; i < pat->len; i++) {
matched = 1;
for (j = 0; j < pat->len; j++) {
@@ -1077,10 +1082,10 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BLI_array_free(loops_split);
BLI_array_free(loops);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_inner.out", BM_ALL, ELE_INNER);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL, ELE_SPLIT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_inner.out", BM_ALL_NOLOOP, ELE_INNER);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL_NOLOOP, ELE_SPLIT);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, ELE_INNER | ELE_SPLIT | SUBD_SPLIT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, ELE_INNER | ELE_SPLIT | SUBD_SPLIT);
}
/* editmesh-emulating function */
@@ -1088,7 +1093,8 @@ 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)
{
BMOperator op;
@@ -1099,13 +1105,15 @@ void BM_mesh_esubdivide(BMesh *bm, const char edge_hflag,
"smooth=%f fractal=%f along_normal=%f "
"cuts=%i "
"quad_corner_type=%i "
- "use_singleedge=%b use_gridfill=%b "
+ "use_single_edge=%b use_grid_fill=%b "
+ "use_only_quads=%b "
"seed=%i",
edge_hflag,
smooth, fractal, along_normal,
numcuts,
cornertype,
- use_singleedge, use_gridfill,
+ use_single_edge, use_grid_fill,
+ use_only_quads,
seed);
BMO_op_exec(bm, &op);
@@ -1162,7 +1170,7 @@ void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op)
params.numcuts = BMO_slot_int_get(op->slots_in, "cuts");
params.op = op;
- params.slot_edgepercents = BMO_slot_get(op->slots_in, "edgepercents");
+ params.slot_edge_percents = BMO_slot_get(op->slots_in, "edge_percents");
BM_data_layer_add(bm, &bm->vdata, CD_SHAPEKEY);
skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY) - 1;
@@ -1174,7 +1182,7 @@ void bmo_bisect_edges_exec(BMesh *bm, BMOperator *op)
bm_subdivide_multicut(bm, e, &params, e->v1, e->v2);
}
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL, ELE_SPLIT);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom_split.out", BM_ALL_NOLOOP, ELE_SPLIT);
BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, skey);
}
diff --git a/source/blender/bmesh/operators/bmo_subdivide.h b/source/blender/bmesh/operators/bmo_subdivide.h
index d0676508917..529075aab02 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.h
+++ b/source/blender/bmesh/operators/bmo_subdivide.h
@@ -39,8 +39,8 @@ typedef struct SubDParams {
int seed;
int origkey; /* shapekey holding displaced vertex coordinates for current geometry */
BMOperator *op;
- BMOpSlot *slot_edgepercents; /* BMO_slot_get(params->op->slots_in, "edgepercents"); */
- BMOpSlot *slot_custompatterns; /* BMO_slot_get(params->op->slots_in, "custompatterns"); */
+ BMOpSlot *slot_edge_percents; /* BMO_slot_get(params->op->slots_in, "edge_percents"); */
+ BMOpSlot *slot_custom_patterns; /* BMO_slot_get(params->op->slots_in, "custom_patterns"); */
float off[3];
} SubDParams;
diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c
index 8c440cae83e..248c7268ac6 100644
--- a/source/blender/bmesh/operators/bmo_symmetrize.c
+++ b/source/blender/bmesh/operators/bmo_symmetrize.c
@@ -106,7 +106,7 @@ static void symm_verts_mirror(Symm *symm)
copy_v3_v3(co, src_v->co);
co[symm->axis] = -co[symm->axis];
- dst_v = BM_vert_create(symm->bm, co, src_v);
+ dst_v = BM_vert_create(symm->bm, co, src_v, 0);
BMO_elem_flag_enable(symm->bm, dst_v, SYMM_OUTPUT_GEOM);
BLI_ghash_insert(symm->vert_symm_map, src_v, dst_v);
break;
@@ -183,7 +183,7 @@ static void symm_split_asymmetric_edges(Symm *symm)
co[symm->axis] = 0;
/* Edge is asymmetric, split it with a new vertex */
- v = BM_vert_create(symm->bm, co, e->v1);
+ v = BM_vert_create(symm->bm, co, e->v1, 0);
BMO_elem_flag_enable(symm->bm, v, SYMM_OUTPUT_GEOM);
BLI_ghash_insert(symm->edge_split_map, e, v);
}
@@ -203,7 +203,7 @@ static void symm_mirror_edges(Symm *symm)
v2 = BLI_ghash_lookup(symm->vert_symm_map, e->v2);
if (v1 && v2) {
- e_new = BM_edge_create(symm->bm, v1, v2, e, TRUE);
+ e_new = BM_edge_create(symm->bm, v1, v2, e, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM);
}
else if (v1 || v2) {
@@ -212,18 +212,18 @@ static void symm_mirror_edges(Symm *symm)
/* Output the keep side of the split edge */
if (!v1) {
- e_new = BM_edge_create(symm->bm, v_split, e->v2, e, TRUE);
+ e_new = BM_edge_create(symm->bm, v_split, e->v2, e, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM);
v1 = v_split;
}
else {
- e_new = BM_edge_create(symm->bm, e->v1, v_split, e, TRUE);
+ e_new = BM_edge_create(symm->bm, e->v1, v_split, e, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM);
v2 = v_split;
}
/* Output the kill side of the split edge */
- e_new = BM_edge_create(symm->bm, v1, v2, e, TRUE);
+ e_new = BM_edge_create(symm->bm, v1, v2, e, BM_CREATE_NO_DOUBLE);
BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM);
}
}
@@ -245,6 +245,8 @@ typedef struct {
/* True only if none of the polygon's edges were split */
int already_symmetric;
+
+ BMFace *src_face;
} SymmPoly;
static void symm_poly_with_splits(const Symm *symm,
@@ -255,6 +257,8 @@ static void symm_poly_with_splits(const Symm *symm,
BMLoop *l;
int i;
+ out->src_face = f;
+
/* Count vertices and check for edge splits */
out->len = f->len;
out->already_symmetric = TRUE;
@@ -351,7 +355,8 @@ static int symm_poly_next_crossing(const Symm *symm,
return FALSE;
}
-static BMFace *symm_face_create_v(BMesh *bm, BMVert **fv, BMEdge **fe, int len)
+static BMFace *symm_face_create_v(BMesh *bm, BMFace *example,
+ BMVert **fv, BMEdge **fe, int len)
{
BMFace *f_new;
int i;
@@ -360,11 +365,13 @@ static BMFace *symm_face_create_v(BMesh *bm, BMVert **fv, BMEdge **fe, int len)
int j = (i + 1) % len;
fe[i] = BM_edge_exists(fv[i], fv[j]);
if (!fe[i]) {
- fe[i] = BM_edge_create(bm, fv[i], fv[j], NULL, FALSE);
+ fe[i] = BM_edge_create(bm, fv[i], fv[j], NULL, 0);
BMO_elem_flag_enable(bm, fe[i], SYMM_OUTPUT_GEOM);
}
}
- f_new = BM_face_create(bm, fv, fe, len, TRUE);
+ f_new = BM_face_create(bm, fv, fe, len, BM_CREATE_NO_DOUBLE);
+ if (example)
+ BM_elem_attrs_copy(bm, bm, example, f_new);
BM_face_select_set(bm, f_new, TRUE);
BMO_elem_flag_enable(bm, f_new, SYMM_OUTPUT_GEOM);
return f_new;
@@ -399,7 +406,7 @@ static void symm_mesh_output_poly_zero_splits(Symm *symm,
}
}
- symm_face_create_v(symm->bm, fv, fe, j);
+ symm_face_create_v(symm->bm, sp->src_face, fv, fe, j);
}
static void symm_mesh_output_poly_with_splits(Symm *symm,
@@ -422,7 +429,7 @@ static void symm_mesh_output_poly_with_splits(Symm *symm,
fv[i] = v;
}
- symm_face_create_v(symm->bm, fv, fe, segment_len);
+ symm_face_create_v(symm->bm, sp->src_face, fv, fe, segment_len);
/* Output the kill side of the input polygon */
@@ -434,7 +441,7 @@ static void symm_mesh_output_poly_with_splits(Symm *symm,
}
- symm_face_create_v(symm->bm, fv, fe, segment_len);
+ symm_face_create_v(symm->bm, sp->src_face, fv, fe, segment_len);
}
static void symm_mirror_polygons(Symm *symm)
@@ -482,7 +489,7 @@ static void symm_mirror_polygons(Symm *symm)
fv[i] = l->v;
}
- symm_face_create_v(symm->bm, fv, fe, f->len);
+ symm_face_create_v(symm->bm, f, fv, fe, f->len);
}
else if (ignore_all) {
BM_face_kill(symm->bm, f);
@@ -589,7 +596,7 @@ static void symm_mirror_polygons(Symm *symm)
BLI_assert(fv[0] && fv[1] && fv[2]);
- symm_face_create_v(symm->bm, fv, fe, 3);
+ symm_face_create_v(symm->bm, NULL, fv, fe, 3);
}
}
}
@@ -659,5 +666,5 @@ void bmo_symmetrize_exec(BMesh *bm, BMOperator *op)
BLI_ghash_free(symm.edge_split_map, NULL, NULL);
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out",
- BM_ALL, SYMM_OUTPUT_GEOM);
+ BM_ALL_NOLOOP, SYMM_OUTPUT_GEOM);
}
diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c
index 775fa0cb60d..d20d01af114 100644
--- a/source/blender/bmesh/operators/bmo_triangulate.c
+++ b/source/blender/bmesh/operators/bmo_triangulate.c
@@ -53,7 +53,7 @@ void bmo_triangulate_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(projectverts);
int i;
const int use_beauty = BMO_slot_bool_get(op->slots_in, "use_beauty");
- BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "facemap.out");
+ BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "face_map.out");
for (face = BMO_iter_new(&siter, op->slots_in, "faces", BM_FACE); face; face = BMO_iter_step(&siter)) {
@@ -65,9 +65,9 @@ void bmo_triangulate_exec(BMesh *bm, BMOperator *op)
BM_face_triangulate(bm, face, projectverts, EDGE_NEW, FACE_NEW, newfaces, use_beauty);
- BMO_slot_map_ptr_insert(op, slot_facemap_out, face, face);
+ BMO_slot_map_elem_insert(op, slot_facemap_out, face, face);
for (i = 0; newfaces[i]; i++) {
- BMO_slot_map_ptr_insert(op, slot_facemap_out, newfaces[i], face);
+ BMO_slot_map_elem_insert(op, slot_facemap_out, newfaces[i], face);
}
}
@@ -190,7 +190,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
/* sf_edge->tmp.p = e; */ /* UNUSED */
}
- BLI_scanfill_calc(&sf_ctx, FALSE);
+ BLI_scanfill_calc(&sf_ctx, 0);
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
BMFace *f = BM_face_create_quad_tri(bm,
diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c
index d56b2ca0d73..64dbf0cc0e7 100644
--- a/source/blender/bmesh/operators/bmo_utils.c
+++ b/source/blender/bmesh/operators/bmo_utils.c
@@ -47,7 +47,7 @@ void bmo_create_vert_exec(BMesh *bm, BMOperator *op)
BMO_slot_vec_get(op->slots_in, "co", vec);
- BMO_elem_flag_enable(bm, BM_vert_create(bm, vec, NULL), 1);
+ BMO_elem_flag_enable(bm, BM_vert_create(bm, vec, NULL, 0), 1);
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "vert.out", BM_VERT, 1);
}
@@ -57,7 +57,7 @@ void bmo_transform_exec(BMesh *UNUSED(bm), BMOperator *op)
BMVert *v;
float mat[4][4];
- BMO_slot_mat4_get(op->slots_in, "mat", mat);
+ BMO_slot_mat4_get(op->slots_in, "matrix", mat);
BMO_ITER (v, &iter, op->slots_in, "verts", BM_VERT) {
mul_m4_v3(mat, v->co);
@@ -73,7 +73,7 @@ void bmo_translate_exec(BMesh *bm, BMOperator *op)
unit_m4(mat);
copy_v3_v3(mat[3], vec);
- BMO_op_callf(bm, op->flag, "transform mat=%m4 verts=%s", mat, op, "verts");
+ BMO_op_callf(bm, op->flag, "transform matrix=%m4 verts=%s", mat, op, "verts");
}
void bmo_scale_exec(BMesh *bm, BMOperator *op)
@@ -87,7 +87,7 @@ void bmo_scale_exec(BMesh *bm, BMOperator *op)
mat[1][1] = vec[1];
mat[2][2] = vec[2];
- BMO_op_callf(bm, op->flag, "transform mat=%m3 verts=%s", mat, op, "verts");
+ BMO_op_callf(bm, op->flag, "transform matrix=%m3 verts=%s", mat, op, "verts");
}
void bmo_rotate_exec(BMesh *bm, BMOperator *op)
@@ -102,7 +102,7 @@ void bmo_rotate_exec(BMesh *bm, BMOperator *op)
mul_v3_fl(vec, -1.0f);
BMO_op_callf(bm, op->flag, "translate verts=%s vec=%v", op, "verts", vec);
- BMO_op_callf(bm, op->flag, "transform mat=%s verts=%s", op, "mat", op, "verts");
+ BMO_op_callf(bm, op->flag, "transform matrix=%s verts=%s", op, "matrix", op, "verts");
mul_v3_fl(vec, -1.0f);
BMO_op_callf(bm, op->flag, "translate verts=%s vec=%v", op, "verts", vec);
@@ -268,14 +268,14 @@ void bmo_region_extend_exec(BMesh *bm, BMOperator *op)
int use_faces = BMO_slot_bool_get(op->slots_in, "use_faces");
int constrict = BMO_slot_bool_get(op->slots_in, "use_constrict");
- BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL, SEL_ORIG);
+ BMO_slot_buffer_flag_enable(bm, op->slots_in, "geom", BM_ALL_NOLOOP, SEL_ORIG);
if (constrict)
bmo_region_extend_constrict(bm, op, use_faces);
else
bmo_region_extend_extend(bm, op, use_faces);
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL, SEL_FLAG);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_ALL_NOLOOP, SEL_FLAG);
}
/********* righthand faces implementation ****** */
@@ -701,9 +701,8 @@ typedef struct ElemNode {
void bmo_shortest_path_exec(BMesh *bm, BMOperator *op)
{
- BMOIter vs_iter /* , vs2_iter */; /* selected verts iterator */
BMIter v_iter; /* mesh verts iterator */
- BMVert *vs, *sv, *ev; /* starting vertex, ending vertex */
+ BMVert *sv, *ev; /* starting vertex, ending vertex */
BMVert *v; /* mesh vertex */
Heap *h = NULL;
@@ -712,13 +711,8 @@ void bmo_shortest_path_exec(BMesh *bm, BMOperator *op)
int num_total = 0 /*, num_sels = 0 */, i = 0;
const int type = BMO_slot_int_get(op->slots_in, "type");
- /* BMESH_TODO use BMO_slot_buffer_elem_first here? */
- BMO_ITER (vs, &vs_iter, op->slots_in, "startv", BM_VERT) {
- sv = vs;
- }
- BMO_ITER (vs, &vs_iter, op->slots_in, "endv", BM_VERT) {
- ev = vs;
- }
+ sv = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert_start"));
+ ev = BMO_slot_buffer_get_single(BMO_slot_get(op->slots_in, "vert_end"));
num_total = BM_mesh_elem_count(bm, BM_VERT);
diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c
index 532145ab129..7401704310f 100644
--- a/source/blender/bmesh/operators/bmo_wireframe.c
+++ b/source/blender/bmesh/operators/bmo_wireframe.c
@@ -227,9 +227,9 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
}
madd_v3_v3v3fl(tvec, v_src->co, v_src->no, -fac);
- verts_neg[i] = BM_vert_create(bm, tvec, v_src);
+ verts_neg[i] = BM_vert_create(bm, tvec, v_src, 0);
madd_v3_v3v3fl(tvec, v_src->co, v_src->no, fac);
- verts_pos[i] = BM_vert_create(bm, tvec, v_src);
+ verts_pos[i] = BM_vert_create(bm, tvec, v_src, 0);
}
else {
/* could skip this */
@@ -267,7 +267,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
}
madd_v3_v3v3fl(tvec, l->v->co, tvec, fac);
- verts_loop[verts_loop_tot] = BM_vert_create(bm, tvec, l->v);
+ verts_loop[verts_loop_tot] = BM_vert_create(bm, tvec, l->v, 0);
if (use_boundary) {
@@ -301,7 +301,7 @@ void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
fac *= verts_relfac[BM_elem_index_get(l_pair[i]->v)];
}
madd_v3_v3v3fl(tvec, l_pair[i]->v->co, tvec, fac);
- verts_boundary[BM_elem_index_get(l_pair[i]->v)] = BM_vert_create(bm, tvec, l_pair[i]->v);
+ verts_boundary[BM_elem_index_get(l_pair[i]->v)] = BM_vert_create(bm, tvec, l_pair[i]->v, 0);
}
}
}
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 75e74155f66..cb35616a1f7 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -164,7 +164,7 @@ static NewVert *mesh_vert(VMesh *vm, int i, int j, int k)
static void create_mesh_bmvert(BMesh *bm, VMesh *vm, int i, int j, int k, BMVert *eg)
{
NewVert *nv = mesh_vert(vm, i, j, k);
- nv->v = BM_vert_create(bm, nv->co, eg);
+ nv->v = BM_vert_create(bm, nv->co, eg, 0);
}
static void copy_mesh_vert(VMesh *vm, int ito, int jto, int kto,
@@ -264,14 +264,13 @@ static BMFace *bev_create_ngon(BMesh *bm, BMVert **vert_arr, const int totv, BMF
else {
int i;
BMEdge **ee = NULL;
- BLI_array_staticdeclare(ee, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_array_fixedstack_declare(ee, BM_DEFAULT_NGON_STACK_SIZE, totv, __func__);
- BLI_array_grow_items(ee, totv);
for (i = 0; i < totv; i++) {
- ee[i] = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, TRUE);
+ ee[i] = BM_edge_create(bm, vert_arr[i], vert_arr[(i + 1) % totv], NULL, BM_CREATE_NO_DOUBLE);
}
- f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, FALSE);
- BLI_array_free(ee);
+ f = BM_face_create_ngon(bm, vert_arr[0], vert_arr[1], ee, totv, 0);
+ BLI_array_fixedstack_free(ee);
}
if (facerep && f) {
int has_mdisps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
@@ -366,13 +365,19 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f,
}
/* Like offset_meet, but here f1 and f2 must not be NULL and give the
- * planes in which to run the offset lines. They may not meet exactly,
- * but the line intersection routine will find the closest approach point. */
-static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, BMVert *v,
- BMFace *f1, BMFace *f2, float meetco[3])
+ * planes in which to run the offset lines.
+ * They may not meet exactly: the offsets for the edges may be different
+ * or both the planes and the lines may be angled so that they can't meet.
+ * In that case, pick a close point on emid, which should be the dividing
+ * edge between the two planes.
+ * TODO: should have a global 'offset consistency' prepass to adjust offset
+ * widths so that all edges have the same offset at both ends. */
+static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid,
+ BMVert *v, BMFace *f1, BMFace *f2, float meetco[3])
{
float dir1[3], dir2[3], norm_perp1[3], norm_perp2[3],
- off1a[3], off1b[3], off2a[3], off2b[3], isect2[3];
+ off1a[3], off1b[3], off2a[3], off2b[3], isect2[3], co[3];
+ int iret;
BLI_assert(f1 != NULL && f2 != NULL);
@@ -398,9 +403,21 @@ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, BMVert *v,
/* lines are parallel; off1a is a good meet point */
copy_v3_v3(meetco, off1a);
}
- else if (!isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2)) {
- /* another test says they are parallel */
- copy_v3_v3(meetco, off1a);
+ else {
+ iret =isect_line_line_v3(off1a, off1b, off2a, off2b, meetco, isect2);
+ if (iret == 0) {
+ /* lines colinear: another test says they are parallel. so shouldn't happen */
+ copy_v3_v3(meetco, off1a);
+ }
+ else if (iret == 2) {
+ /* lines are not coplanar; meetco and isect2 are nearest to first and second lines */
+ if (len_v3v3(meetco, isect2) > 100.0f * (float)BEVEL_EPSILON) {
+ /* offset lines don't meet: project average onto emid; this is not ideal (see TODO above) */
+ mid_v3_v3v3(co, meetco, isect2);
+ closest_to_line_v3(meetco, co, v->co, BM_edge_other_vert(emid->e, v)->co);
+ }
+ }
+ /* else iret == 1 and the lines are coplanar so meetco has the intersection */
}
}
@@ -546,6 +563,7 @@ static void get_point_on_round_edge(const float uv[2],
#else /* USE_ALTERNATE_ADJ */
+#ifdef OLD_ROUND_EDGE
/*
* calculation of points on the round profile
* r - result, coordinate of point on round profile
@@ -633,6 +651,66 @@ static void get_point_on_round_edge(EdgeHalf *e, int k,
interp_v3_v3v3(r_co, va, vb, (float)k / (float)n);
}
}
+#else
+
+/*
+ * Find the point (/n) of the way around the round profile for e,
+ * where start point is va, midarc point is vmid, and end point is vb.
+ * Return the answer in profileco.
+ * Method:
+ * Find vo, the origin of the parallelogram with other three points va, vmid, vb.
+ * Also find vd, which is in direction normal to parallelogram and 1 unit away
+ * from the origin.
+ * The quarter circle in first quadrant of unit square will be mapped to the
+ * quadrant of a sheared ellipse in the parallelgram, using a matrix.
+ * The matrix mat is calculated to map:
+ * (0,1,0) -> va
+ * (1,1,0) -> vmid
+ * (1,0,0) -> vb
+ * (0,1,1) -> vd
+ * However if va -- vmid -- vb is approximately a straight line, just
+ * interpolate along the line.
+ */
+static void get_point_on_round_edge(EdgeHalf *e, int k,
+ const float va[3], const float vmid[3], const float vb[3],
+ float r_co[3])
+{
+ float vo[3], vd[3], vb_vmid[3], va_vmid[3], vddir[3], p[3], angle;
+ float m[4][4] = MAT4_UNITY;
+ int n = e->seg;
+
+ sub_v3_v3v3(va_vmid, vmid, va);
+ sub_v3_v3v3(vb_vmid, vmid, vb);
+ if (fabsf(angle_v3v3(va_vmid, vb_vmid) - (float)M_PI) > 100.f *(float)BEVEL_EPSILON) {
+ sub_v3_v3v3(vo, va, vb_vmid);
+ cross_v3_v3v3(vddir, vb_vmid, va_vmid);
+ normalize_v3(vddir);
+ add_v3_v3v3(vd, vo, vddir);
+
+ /* The cols of m are: {vmid - va, vmid - vb, vmid + vd - va -vb, va + vb - vmid;
+ * blender transform matrices are stored such that m[i][*] is ith column;
+ * the last elements of each col remain as they are in unity matrix */
+ sub_v3_v3v3(&m[0][0], vmid, va);
+ sub_v3_v3v3(&m[1][0], vmid, vb);
+ add_v3_v3v3(&m[2][0], vmid, vd);
+ sub_v3_v3(&m[2][0], va);
+ sub_v3_v3(&m[2][0], vb);
+ add_v3_v3v3(&m[3][0], va, vb);
+ sub_v3_v3(&m[3][0], vmid);
+
+ /* Now find point k/(e->seg) along quarter circle from (0,1,0) to (1,0,0) */
+ angle = (float)M_PI * (float)k / (2.0f * (float)n); /* angle from y axis */
+ p[0] = sinf(angle);
+ p[1] = cosf(angle);
+ p[2] = 0.0f;
+ mul_v3_m4v3(r_co, m, p);
+ }
+ else {
+ /* planar case */
+ interp_v3_v3v3(r_co, va, vb, (float)k / (float)n);
+ }
+}
+#endif /* ! OLD_ROUND_EDGE */
#endif /* !USE_ALTERNATE_ADJ */
@@ -693,8 +771,7 @@ static void build_boundary(MemArena *mem_arena, BevVert *bv)
if (e->prev->prev->is_bev) {
BLI_assert(e->prev->prev != e); /* see: edgecount 2, selcount 1 case */
/* find meet point between e->prev->prev and e and attach e->prev there */
- /* TODO: fix case when one or both faces in following are NULL */
- offset_in_two_planes(e->prev->prev, e, bv->v,
+ offset_in_two_planes(e->prev->prev, e, e->prev, bv->v,
e->prev->prev->fnext, e->fprev, co);
v = add_new_bound_vert(mem_arena, vm, co);
v->efirst = e->prev->prev;
@@ -987,7 +1064,7 @@ static void bevel_build_rings(BMesh *bm, BevVert *bv)
}
} while ((v = v->next) != vm->boundstart);
mul_v3_fl(midco, 1.0f / nn);
- bmv = BM_vert_create(bm, midco, NULL);
+ bmv = BM_vert_create(bm, midco, NULL, 0);
v = vm->boundstart;
do {
i = v->index;
diff --git a/source/blender/bmesh/tools/bmesh_decimate.h b/source/blender/bmesh/tools/bmesh_decimate.h
index 4d382d65659..4a557c20ae3 100644
--- a/source/blender/bmesh/tools/bmesh_decimate.h
+++ b/source/blender/bmesh/tools/bmesh_decimate.h
@@ -37,5 +37,8 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int
BMEdge **einput_arr, const int einput_len);
void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const int do_dissolve_boundaries);
+/* these weights are accumulated so too high values may reach 'inf' too quickly */
+#define BM_MESH_DECIM_WEIGHT_MAX 100000.0f
+#define BM_MESH_DECIM_WEIGHT_EPS (1.0f / BM_MESH_DECIM_WEIGHT_MAX)
#endif /* __BMESH_DECIMATE_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 781001508f2..7c054d84405 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -223,8 +223,8 @@ static void bm_decim_build_edge_cost_single(BMEdge *e,
}
if (vweights) {
- if ((vweights[BM_elem_index_get(e->v1)] < FLT_EPSILON) &&
- (vweights[BM_elem_index_get(e->v2)] < FLT_EPSILON))
+ if ((vweights[BM_elem_index_get(e->v1)] >= BM_MESH_DECIM_WEIGHT_MAX) &&
+ (vweights[BM_elem_index_get(e->v2)] >= BM_MESH_DECIM_WEIGHT_MAX))
{
/* skip collapsing this edge */
eheap_table[BM_elem_index_get(e)] = NULL;
@@ -244,8 +244,9 @@ static void bm_decim_build_edge_cost_single(BMEdge *e,
BLI_quadric_evaluate(q2, optimize_co));
}
else {
- cost = ((BLI_quadric_evaluate(q1, optimize_co) * vweights[BM_elem_index_get(e->v1)]) +
- (BLI_quadric_evaluate(q2, optimize_co) * vweights[BM_elem_index_get(e->v2)]));
+ /* add 1.0 so planar edges are still weighted against */
+ cost = (((BLI_quadric_evaluate(q1, optimize_co) + 1.0f) * vweights[BM_elem_index_get(e->v1)]) +
+ ((BLI_quadric_evaluate(q2, optimize_co) + 1.0f) * vweights[BM_elem_index_get(e->v2)]));
}
// print("COST %.12f\n");
@@ -877,9 +878,7 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e,
int i;
if (vweights) {
- const int fac = CLAMPIS(customdata_fac, 0.0f, 1.0f);
- vweights[BM_elem_index_get(v_other)] = (vweights[v_clear_index] * (1.0f - fac)) +
- (vweights[BM_elem_index_get(v_other)] * fac);
+ vweights[BM_elem_index_get(v_other)] += vweights[v_clear_index];
}
e = NULL; /* paranoid safety check */
@@ -960,7 +959,7 @@ static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e,
* \brief BM_mesh_decimate
* \param bm The mesh
* \param factor face count multiplier [0 - 1]
- * \param vertex_weights Optional array of vertex aligned weights [0 - 1],
+ * \param vweights Optional array of vertex aligned weights [0 - 1],
* a vertex group is the usual source for this.
*/
void BM_mesh_decimate_collapse(BMesh *bm, const float factor, float *vweights, const int do_triangulate)
diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
index d2a5c580ae6..f67f01e4585 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
@@ -69,9 +69,6 @@ static int dissolve_elem_cmp(const void *a1, const void *a2)
return 0;
}
-/**
- * \param do_all_verts Collapse all verts between 2 faces - don't check their edge angle.
- */
void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int do_dissolve_boundaries,
BMVert **vinput_arr, const int vinput_len,
BMEdge **einput_arr, const int einput_len)