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:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-04-06 17:24:34 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-04-06 17:24:34 +0400
commitacfc0ea5111bcab5ea5795187d08b2f6ec5addaa (patch)
treed9fb7e477ac551859ca95c1f0482eca8b3af1077 /source/blender/bmesh
parent72d0cc1f6123900f5593cd0fe428568f5aa7f682 (diff)
parent2ed2226ee753cc6a7a19806d99772efa61af897f (diff)
svn merge ^/trunk/blender -r55815:55840
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r--source/blender/bmesh/CMakeLists.txt1
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c6
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c59
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c25
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.h7
-rw-r--r--source/blender/bmesh/intern/bmesh_operators_private.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c28
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.h1
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c227
-rw-r--r--source/blender/bmesh/operators/bmo_join_triangles.c4
-rw-r--r--source/blender/bmesh/operators/bmo_poke.c141
12 files changed, 481 insertions, 24 deletions
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index fcf804c8f4f..472f7d2d8f0 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -54,6 +54,7 @@ set(SRC
operators/bmo_join_triangles.c
operators/bmo_mesh_conv.c
operators/bmo_mirror.c
+ operators/bmo_poke.c
operators/bmo_primitive.c
operators/bmo_removedoubles.c
operators/bmo_similar.c
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index d0ab0ea5d60..6edbae0831e 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -36,12 +36,12 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "BKE_customdata.h"
-#include "BKE_multires.h"
-
#include "BLI_array.h"
#include "BLI_math.h"
+#include "BKE_customdata.h"
+#include "BKE_multires.h"
+
#include "bmesh.h"
#include "intern/bmesh_private.h"
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 7583332c4db..a84958f6827 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -1500,12 +1500,34 @@ static BMOpDefine bmo_solidify_def = {
};
/*
- * Face Inset.
+ * Face Inset (Individual).
*
- * Inset or outset faces.
+ * Insets individual faces.
*/
-static BMOpDefine bmo_inset_def = {
- "inset",
+static BMOpDefine bmo_inset_individual_def = {
+ "inset_individual",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"thickness", BMO_OP_SLOT_FLT},
+ {"depth", BMO_OP_SLOT_FLT},
+ {"use_even_offset", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
+ },
+ bmo_inset_individual_exec,
+ 0
+};
+
+/*
+ * Face Inset (Regions).
+ *
+ * Inset or outset face regions.
+ */
+static BMOpDefine bmo_inset_region_def = {
+ "inset_region",
/* slots_in */
{{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
{"use_boundary", BMO_OP_SLOT_BOOL},
@@ -1520,7 +1542,7 @@ static BMOpDefine bmo_inset_def = {
{{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
{{'\0'}},
},
- bmo_inset_exec,
+ bmo_inset_region_exec,
0
};
@@ -1549,6 +1571,29 @@ static BMOpDefine bmo_wireframe_def = {
0
};
+/*
+ * Pokes a face.
+ *
+ * Splits a face into a triangle fan.
+ */
+static BMOpDefine bmo_poke_def = {
+ "poke",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"offset", BMO_OP_SLOT_FLT}, /* center vertex offset along normal */
+ {"center_mode", BMO_OP_SLOT_INT}, /* calculation mode for center vertex */
+ {"use_relative_offset", BMO_OP_SLOT_BOOL}, /* apply offset */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
+ },
+ bmo_poke_exec,
+ 0
+};
+
#ifdef WITH_BULLET
/*
* Convex Hull
@@ -1647,13 +1692,15 @@ const BMOpDefine *bmo_opdefines[] = {
&bmo_extrude_face_region_def,
&bmo_extrude_vert_indiv_def,
&bmo_find_doubles_def,
- &bmo_inset_def,
+ &bmo_inset_individual_def,
+ &bmo_inset_region_def,
&bmo_join_triangles_def,
&bmo_mesh_to_bmesh_def,
&bmo_mirror_def,
&bmo_object_load_bmesh_def,
&bmo_pointmerge_def,
&bmo_pointmerge_facedata_def,
+ &bmo_poke_def,
&bmo_recalc_face_normals_def,
&bmo_region_extend_def,
&bmo_remove_doubles_def,
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index 180bc53c2e3..c72accbc605 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -482,6 +482,8 @@ typedef struct BMOElemMapping {
extern const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES];
+int BMO_opcode_from_opname(const char *opname);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index a358623834f..1d20f94c51c 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -47,7 +47,6 @@ static void bmo_flag_layer_free(BMesh *bm);
static void bmo_flag_layer_clear(BMesh *bm);
static int bmo_name_to_slotcode(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
static int bmo_name_to_slotcode_check(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
-static int bmo_opname_to_opcode(const char *opname);
static const char *bmo_error_messages[] = {
NULL,
@@ -145,7 +144,7 @@ static void bmo_op_slots_init(const BMOSlotType *slot_types, BMOpSlot *slot_args
*/
void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname)
{
- int opcode = bmo_opname_to_opcode(opname);
+ int opcode = BMO_opcode_from_opname(opname);
#ifdef DEBUG
BM_ELEM_INDEX_VALIDATE(bm, "pre bmo", opname);
@@ -1522,20 +1521,27 @@ static int bmo_name_to_slotcode_check(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], cons
return i;
}
-static int bmo_opname_to_opcode(const char *opname)
+int BMO_opcode_from_opname(const char *opname)
{
- int i;
- for (i = 0; i < bmo_opdefines_total; i++) {
- if (STREQ(opname, bmo_opdefines[i]->opname)) {
+ const unsigned int tot = bmo_opdefines_total;
+ unsigned int i;
+ for (i = 0; i < tot; i++) {
+ if (STREQ(bmo_opdefines[i]->opname, opname)) {
return i;
}
}
-
- fprintf(stderr, "%s: could not find bmesh slot for name %s! (bmesh internal error)\n", __func__, opname);
return -1;
}
+static int BMO_opcode_from_opname_check(const char *opname)
+{
+ int i = BMO_opcode_from_opname(opname);
+ if (i == -1)
+ fprintf(stderr, "%s: could not find bmesh slot for name %s! (bmesh internal error)\n", __func__, opname);
+ return i;
+}
+
/**
* \brief Format Strings for #BMOperator Initialization.
*
@@ -1628,10 +1634,11 @@ bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt,
fmt += i + (noslot ? 0 : 1);
- i = bmo_opname_to_opcode(opname);
+ i = BMO_opcode_from_opname_check(opname);
if (i == -1) {
MEM_freeN(ofmt);
+ BLI_assert(0);
return false;
}
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index 16b38c340ff..ff0fc285dc3 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -95,6 +95,13 @@ enum {
VPATH_SELECT_TOPOLOGICAL
};
+/* Poke face center calculation */
+enum {
+ BMOP_POKE_MEAN_WEIGHTED = 0,
+ BMOP_POKE_MEAN,
+ BMOP_POKE_BOUNDS
+};
+
extern const BMOpDefine *bmo_opdefines[];
extern const int bmo_opdefines_total;
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index 79e688bd5ff..2a67407b261 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -65,7 +65,8 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op);
void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op);
void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op);
void bmo_find_doubles_exec(BMesh *bm, BMOperator *op);
-void bmo_inset_exec(BMesh *bm, BMOperator *op);
+void bmo_inset_individual_exec(BMesh *bm, BMOperator *op);
+void bmo_inset_region_exec(BMesh *bm, BMOperator *op);
void bmo_join_triangles_exec(BMesh *bm, BMOperator *op);
void bmo_mesh_to_bmesh_exec(BMesh *bm, BMOperator *op);
void bmo_mirror_exec(BMesh *bm, BMOperator *op);
@@ -73,6 +74,7 @@ void bmo_object_load_bmesh_exec(BMesh *bm, BMOperator *op);
void bmo_pointmerge_exec(BMesh *bm, BMOperator *op);
void bmo_pointmerge_facedata_exec(BMesh *bm, BMOperator *op);
void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op);
+void bmo_poke_exec(BMesh *bm, BMOperator *op);
void bmo_region_extend_exec(BMesh *bm, BMOperator *op);
void bmo_remove_doubles_exec(BMesh *bm, BMOperator *op);
void bmo_reverse_colors_exec(BMesh *bm, BMOperator *op);
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index d235aaaa622..525dd5b1f9c 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -337,6 +337,34 @@ void BM_face_calc_center_mean(BMFace *f, float r_cent[3])
}
/**
+ * computes the center of a face, using the mean average
+ * weighted by edge length
+ */
+void BM_face_calc_center_mean_weighted(BMFace *f, float r_cent[3])
+{
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ float totw = 0.0f;
+ float w_prev;
+
+ zero_v3(r_cent);
+
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ w_prev = BM_edge_calc_length(l_iter->prev->e);
+ do {
+ const float w_curr = BM_edge_calc_length(l_iter->e);
+ const float w = (w_curr + w_prev);
+ madd_v3_v3fl(r_cent, l_iter->v->co, w);
+ totw += w;
+ w_prev = w_curr;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ if (totw != 0.0f)
+ mul_v3_fl(r_cent, 1.0f / (float) totw);
+}
+
+/**
* COMPUTE POLY PLANE
*
* Projects a set polygon's vertices to
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h
index c439a41f672..d857ba77fe7 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -37,6 +37,7 @@ float BM_face_calc_area(BMFace *f);
float BM_face_calc_perimeter(BMFace *f);
void BM_face_calc_center_bounds(BMFace *f, float center[3]);
void BM_face_calc_center_mean(BMFace *f, float center[3]);
+void BM_face_calc_center_mean_weighted(BMFace *f, float center[3]);
void BM_face_normal_update(BMFace *f);
void BM_face_normal_update_vcos(BMesh *bm, BMFace *f, float no[3],
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index a3656ce5b74..d8ed511bc94 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -24,14 +24,14 @@
* \ingroup bmesh
*
* Inset face regions.
+ * Inset individual faces.
*
- * TODO
- * - Inset indervidual faces.
*/
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
+#include "BLI_array.h"
#include "bmesh.h"
@@ -39,6 +39,227 @@
#define ELE_NEW 1
+
+
+/* -------------------------------------------------------------------- */
+/* Inset Individual */
+
+
+/* Holds Per-Face Inset Edge Data */
+typedef struct EdgeInsetInfo {
+ float no[3];
+ BMEdge *e_old;
+ BMEdge *e_new;
+} EdgeInsetInfo;
+
+/**
+ * Individual Face Inset.
+ * Find all tagged faces (f), duplicate edges around faces, inset verts of
+ * created edges, create new faces between old and new edges, fill face
+ * between connected new edges, kill old face (f).
+ */
+void bmo_inset_individual_exec(BMesh *bm, BMOperator *op)
+{
+ BMEdge **f_edges = NULL;
+ BMVert **f_verts = NULL;
+ BMFace *f;
+
+ BMOIter oiter;
+ EdgeInsetInfo *eiinfo_arr = NULL;
+
+ BLI_array_declare(eiinfo_arr);
+ BLI_array_declare(f_edges);
+ BLI_array_declare(f_verts);
+
+ const float thickness = BMO_slot_float_get(op->slots_in, "thickness");
+ const float depth = BMO_slot_float_get(op->slots_in, "depth");
+ const bool use_even_offset = BMO_slot_bool_get(op->slots_in, "use_even_offset");
+
+ /* Only tag faces in slot */
+ BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
+
+ BMO_slot_buffer_hflag_enable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, false);
+
+ BMO_ITER(f, &oiter, op->slots_in, "faces", BM_FACE) {
+ BMLoop *l_iter, *l_first;
+ BMLoop *l_iter_inner = NULL;
+ int i;
+
+ BLI_array_empty(f_verts);
+ BLI_array_empty(f_edges);
+ BLI_array_empty(eiinfo_arr);
+ BLI_array_grow_items(f_verts, f->len);
+ BLI_array_grow_items(f_edges, f->len);
+ BLI_array_grow_items(eiinfo_arr, f->len);
+
+ /* create verts */
+ i = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ f_verts[i] = BM_vert_create(bm, l_iter->v->co, l_iter->v, 0);
+ i++;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ /* make edges */
+ i = 0;
+ l_iter = l_first;
+ do {
+ f_edges[i] = BM_edge_create(bm, f_verts[i], f_verts[(i + 1) % f->len], l_iter->e, 0);
+
+ eiinfo_arr[i].e_new = f_edges[i];
+ eiinfo_arr[i].e_old = l_iter->e;
+ BM_edge_calc_face_tangent(l_iter->e, l_iter, eiinfo_arr[i].no);
+
+ /* Tagging (old elements) required when iterating over edges
+ * connected to verts for translation vector calculation */
+ BM_elem_flag_enable(l_iter->e, BM_ELEM_TAG);
+ BM_elem_index_set(l_iter->e, i); /* set_dirty! */
+ i++;
+ } while ((l_iter = l_iter->next) != l_first);
+ /* done with edges */
+
+ bm->elem_index_dirty |= BM_EDGE;
+
+ /* Calculate translation vector for new */
+ l_iter = l_first;
+ do {
+ EdgeInsetInfo *ei_prev = &eiinfo_arr[BM_elem_index_get(l_iter->prev->e)];
+ EdgeInsetInfo *ei_next = &eiinfo_arr[BM_elem_index_get(l_iter->e)];
+ float tvec[3];
+ float v_new_co[3];
+ int index = 0;
+
+ add_v3_v3v3(tvec, ei_prev->no, ei_next->no);
+ normalize_v3(tvec);
+
+ /* l->e is traversed in order */
+ index = BM_elem_index_get(l_iter->e);
+
+ copy_v3_v3(v_new_co, eiinfo_arr[index].e_new->v1->co);
+
+ if (use_even_offset) {
+ mul_v3_fl(tvec, shell_angle_to_dist(angle_normalized_v3v3(ei_prev->no, ei_next->no) / 2.0f));
+ }
+
+ /* Modify vertices and their normals */
+ madd_v3_v3fl(v_new_co, tvec, thickness);
+
+ /* Set normal, add depth and write new vertex position*/
+ copy_v3_v3(eiinfo_arr[index].e_new->v1->no, f->no);
+
+ madd_v3_v3fl(v_new_co, f->no, depth);
+
+ copy_v3_v3(eiinfo_arr[index].e_new->v1->co, v_new_co);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ {
+ BMFace *f_new_inner;
+ /* Create New Inset Faces */
+ f_new_inner = BM_face_create(bm, f_verts, f_edges, f->len, 0);
+ if (UNLIKELY(f_new_inner == NULL)) {
+ BMO_error_raise(bm, op, BMERR_MESH_ERROR, "Inset failed: could not create inner face.");
+ BLI_array_free(f_edges);
+ BLI_array_free(f_verts);
+ BLI_array_free(eiinfo_arr);
+ return;
+ }
+
+ /* Copy Face Data */
+ BM_elem_attrs_copy(bm, bm, f, f_new_inner);
+ // Don't tag, gives more useful inner/outer select option
+ // BMO_elem_flag_enable(bm, f_new_inner, ELE_NEW);
+
+ l_iter_inner = BM_FACE_FIRST_LOOP(f_new_inner);
+ }
+
+ l_iter = l_first;
+ do {
+ BMFace *f_new_outer;
+
+ BMLoop *l_iter_sub;
+ BMLoop *l_a = NULL;
+ BMLoop *l_b = NULL;
+ BMLoop *l_a_other = NULL;
+ BMLoop *l_b_other = NULL;
+ BMLoop *l_shared = NULL;
+
+ BM_elem_attrs_copy(bm, bm, l_iter, l_iter_inner);
+
+ f_new_outer = BM_face_create_quad_tri(bm,
+ l_iter->v,
+ l_iter->next->v,
+ l_iter_inner->next->v,
+ l_iter_inner->v,
+ f, false);
+
+ if (UNLIKELY(f_new_outer == NULL)) {
+ BMO_error_raise(bm, op, BMERR_MESH_ERROR, "Inset failed: could not create an outer face.");
+ BLI_array_free(f_edges);
+ BLI_array_free(f_verts);
+ BLI_array_free(eiinfo_arr);
+ return;
+ }
+
+ BM_elem_attrs_copy(bm, bm, f, f_new_outer);
+ BMO_elem_flag_enable(bm, f_new_outer, ELE_NEW);
+ BM_elem_flag_enable(f_new_outer, BM_ELEM_TAG);
+
+ /* Copy Loop Data */
+ l_a = BM_FACE_FIRST_LOOP(f_new_outer);
+ l_b = l_a->next;
+
+ l_iter_sub = l_iter;
+
+ /* Skip old face f and new inset face.
+ * If loop if found we are a boundary. This
+ * is required as opposed to BM_edge_is_boundary()
+ * Because f_new_outer shares an edge with f */
+ do {
+ if (l_iter_sub->f != f && l_iter_sub->f != f_new_outer) {
+ l_shared = l_iter_sub;
+ break;
+ }
+ } while ((l_iter_sub = l_iter_sub->radial_next) != l_iter);
+
+ if (l_shared) {
+ BM_elem_attrs_copy(bm, bm, l_shared, l_a->next);
+ BM_elem_attrs_copy(bm, bm, l_shared->next, l_a);
+ }
+ else {
+ l_a_other = BM_edge_other_loop(l_a->e, l_a);
+ l_b_other = l_a_other->next;
+ BM_elem_attrs_copy(bm, bm, l_a_other, l_a);
+ BM_elem_attrs_copy(bm, bm, l_b_other, l_b);
+ }
+
+ /* Move to the last two loops in new face */
+ l_a = l_b->next;
+ l_b = l_a->next;
+
+ /* This loop should always have >1 radials
+ * (associated edge connects new and old face) */
+ BM_elem_attrs_copy(bm, bm, l_iter, l_b);
+ BM_elem_attrs_copy(bm, bm, l_iter->next, l_a);
+
+ } while ((l_iter_inner = l_iter_inner->next),
+ (l_iter = l_iter->next) != l_first);
+
+ BM_face_kill(bm, f);
+ }
+
+ /* we could flag new edges/verts too, is it useful? */
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, ELE_NEW);
+
+ BLI_array_free(f_verts);
+ BLI_array_free(f_edges);
+ BLI_array_free(eiinfo_arr);
+}
+
+
+
+/* -------------------------------------------------------------------- */
+/* Inset Region */
+
typedef struct SplitEdgeInfo {
float no[3];
float length;
@@ -95,7 +316,7 @@ static BMLoop *bm_edge_is_mixed_face_tag(BMLoop *l)
* - inset the new edges into their faces.
*/
-void bmo_inset_exec(BMesh *bm, BMOperator *op)
+void bmo_inset_region_exec(BMesh *bm, BMOperator *op)
{
const bool use_outset = BMO_slot_bool_get(op->slots_in, "use_outset");
const bool use_boundary = BMO_slot_bool_get(op->slots_in, "use_boundary") && (use_outset == false);
diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c
index 5e4fa29d953..edbb19afc62 100644
--- a/source/blender/bmesh/operators/bmo_join_triangles.c
+++ b/source/blender/bmesh/operators/bmo_join_triangles.c
@@ -33,11 +33,11 @@
#include "DNA_meshdata_types.h"
-#include "BKE_customdata.h"
-
#include "BLI_math.h"
#include "BLI_array.h"
+#include "BKE_customdata.h"
+
#include "bmesh.h"
#include "intern/bmesh_operators_private.h" /* own include */
diff --git a/source/blender/bmesh/operators/bmo_poke.c b/source/blender/bmesh/operators/bmo_poke.c
new file mode 100644
index 00000000000..7105210da04
--- /dev/null
+++ b/source/blender/bmesh/operators/bmo_poke.c
@@ -0,0 +1,141 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Francisco De La Cruz
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/operators/bmo_poke.c
+ * \ingroup bmesh
+ *
+ * Pokes a face.
+ *
+ * Splits a face into a triangle fan.
+ */
+
+#include "BLI_math.h"
+
+#include "bmesh.h"
+
+#include "intern/bmesh_operators_private.h" /* own include */
+
+#define ELE_NEW 1
+
+/**
+ * Pokes a face
+ *
+ * Splits a face into a triangle fan.
+ * Iterate over all selected faces, create a new center vertex and
+ * create triangles between original face edges and new center vertex.
+ */
+void bmo_poke_exec(BMesh *bm, BMOperator *op)
+{
+ BMOIter oiter;
+ BMFace *f;
+
+ const float offset = BMO_slot_float_get(op->slots_in, "offset");
+ const bool use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset");
+ const int center_mode = BMO_slot_int_get(op->slots_in, "center_mode");
+ void (*bm_face_calc_center_fn)(BMFace *f, float r_cent[3]);
+
+ switch (center_mode) {
+ case BMOP_POKE_MEAN_WEIGHTED:
+ bm_face_calc_center_fn = BM_face_calc_center_mean_weighted;
+ break;
+ case BMOP_POKE_BOUNDS:
+ bm_face_calc_center_fn = BM_face_calc_center_bounds;
+ break;
+ case BMOP_POKE_MEAN:
+ bm_face_calc_center_fn = BM_face_calc_center_mean;
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ BMO_ITER(f, &oiter, op->slots_in, "faces", BM_FACE) {
+ BMFace *f_new;
+ float f_center[3];
+ BMVert *v_center = NULL;
+ BMLoop *l_iter, *l_first;
+ /* only interpolate the centeral loop from the face once,
+ * then copy to all others in the fan */
+ BMLoop *l_center_example;
+
+ /* 1.0 or the average length from the center to the face verts */
+ float offset_fac;
+
+ int i;
+
+ bm_face_calc_center_fn(f, f_center);
+ v_center = BM_vert_create(bm, f_center, NULL, 0);
+ BMO_elem_flag_enable(bm, v_center, ELE_NEW);
+
+ /* handled by BM_loop_interp_from_face */
+ // BM_vert_interp_from_face(bm, v_center, f);
+
+ if (use_relative_offset) {
+ offset_fac = 0.0f;
+ }
+ else {
+ offset_fac = 1.0f;
+ }
+
+ i = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BMLoop *l_new;
+
+ f_new = BM_face_create_quad_tri(bm, l_iter->v, l_iter->next->v, v_center, NULL, f, false);
+ l_new = BM_FACE_FIRST_LOOP(f_new);
+
+ if (i == 0) {
+ l_center_example = l_new->prev;
+ BM_loop_interp_from_face(bm, l_center_example, f, true, true);
+ }
+ else {
+ BM_elem_attrs_copy(bm, bm, l_center_example, l_new->prev);
+ }
+
+ /* Copy Loop Data */
+ BM_elem_attrs_copy(bm, bm, l_iter, l_new);
+ BM_elem_attrs_copy(bm, bm, l_iter->next, l_new->next);
+
+ BMO_elem_flag_enable(bm, f_new, ELE_NEW);
+
+ if (use_relative_offset) {
+ offset_fac += len_v3v3(f_center, l_iter->v->co);
+ }
+
+ } while (i++, (l_iter = l_iter->next) != l_first);
+
+ if (use_relative_offset) {
+ offset_fac /= (float)f->len;
+ }
+ /* else remain at 1.0 */
+
+ copy_v3_v3(v_center->no, f->no);
+ madd_v3_v3fl(v_center->co, v_center->no, offset * offset_fac);
+
+ /* Kill Face */
+ BM_face_kill(bm, f);
+ }
+
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, ELE_NEW);
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, ELE_NEW);
+}