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:
authorCampbell Barton <ideasman42@gmail.com>2018-09-26 03:29:16 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-09-26 03:30:34 +0300
commit07747bcd67b6c8a829febeb34b64c47d0ad8a344 (patch)
treeacc4c2392eb45b1896f0b5f0ec1bdba7352a2614 /source/blender/bmesh
parentc72380a427a4af9cacafc0e6bfe8f0f40c8e6dc5 (diff)
parent34d98cfe61bd34aa742879a31ba0da01d32d7e3a (diff)
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c1
-rw-r--r--source/blender/bmesh/operators/bmo_dupe.c70
2 files changed, 65 insertions, 6 deletions
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index ceeea9de76b..d1366d24b5b 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -1465,6 +1465,7 @@ static BMOpDefine bmo_spin_def = {
{"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
{"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
{"steps", BMO_OP_SLOT_INT}, /* number of steps */
+ {"use_merge", BMO_OP_SLOT_BOOL}, /* Merge first/last when the angle is a full revolution. */
{"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
{"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */
{{'\0'}},
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index af1cd22ac8d..c50c7657deb 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -26,6 +26,8 @@
* Duplicate, Split, Split operators.
*/
+#include "MEM_guardedalloc.h"
+
#include "BLI_math.h"
#include "BLI_alloca.h"
@@ -486,10 +488,29 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
steps = BMO_slot_int_get(op->slots_in, "steps");
phi = BMO_slot_float_get(op->slots_in, "angle") / steps;
do_dupli = BMO_slot_bool_get(op->slots_in, "use_duplicate");
- const bool use_normal_flip = BMO_slot_bool_get(op->slots_in, "use_normal_flip");
+ const bool use_normal_flip = BMO_slot_bool_get(op->slots_in, "use_normal_flip");
+ /* Caller needs to perform other sanity checks (such as the spin being 360d). */
+ const bool use_merge = BMO_slot_bool_get(op->slots_in, "use_merge") && steps >= 3;
axis_angle_normalized_to_mat3(rmat, axis, phi);
+ BMVert **vtable = NULL;
+ if (use_merge) {
+ vtable = MEM_mallocN(sizeof(BMVert *) * bm->totvert, __func__);
+ int i = 0;
+ BMIter iter;
+ BMVert *v;
+ BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
+ vtable[i] = v;
+ /* Evil! store original index in normal,
+ * this is duplicated into every other vertex.
+ * So we can read the original from the final.
+ *
+ * The normals must be recalculated anyway. */
+ *((int *)&v->no[0]) = i;
+ }
+ }
+
BMO_slot_copy(op, slots_in, "geom",
op, slots_out, "geom_last.out");
for (a = 0; a < steps; a++) {
@@ -507,11 +528,44 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
BMO_op_initf(bm, &extop, op->flag, "extrude_face_region geom=%S use_normal_flip=%b",
op, "geom_last.out", use_normal_flip && (a == 0));
BMO_op_exec(bm, &extop);
- BMO_op_callf(bm, op->flag,
- "rotate cent=%v matrix=%m3 space=%s verts=%S",
- cent, rmat, op, "space", &extop, "geom.out");
- BMO_slot_copy(&extop, slots_out, "geom.out",
- op, slots_out, "geom_last.out");
+ if ((use_merge && (a == steps - 1)) == false) {
+ BMO_op_callf(bm, op->flag,
+ "rotate cent=%v matrix=%m3 space=%s verts=%S",
+ cent, rmat, op, "space", &extop, "geom.out");
+ BMO_slot_copy(&extop, slots_out, "geom.out",
+ op, slots_out, "geom_last.out");
+ }
+ else {
+ /* Merge first/last vertices and edges (maintaining 'geom.out' state). */
+ BMOpSlot *slot_geom_out = BMO_slot_get(extop.slots_out, "geom.out");
+ BMElem **elem_array = (BMElem **)slot_geom_out->data.buf;
+ int elem_array_len = slot_geom_out->len;
+ for (int i = 0; i < elem_array_len; ) {
+ if (elem_array[i]->head.htype == BM_VERT) {
+ BMVert *v_src = (BMVert *)elem_array[i];
+ BMVert *v_dst = vtable[*((const int *)&v_src->no[0])];
+ BM_vert_splice(bm, v_dst, v_src);
+ elem_array_len--;
+ elem_array[i] = elem_array[elem_array_len];
+ }
+ else {
+ i++;
+ }
+ }
+ for (int i = 0; i < elem_array_len; ) {
+ if (elem_array[i]->head.htype == BM_EDGE) {
+ BMEdge *e_src = (BMEdge *)elem_array[i];
+ BMEdge *e_dst = BM_edge_find_double(e_src);
+ BM_edge_splice(bm, e_dst, e_src);
+ elem_array_len--;
+ elem_array[i] = elem_array[elem_array_len];
+ }
+ else {
+ i++;
+ }
+ }
+ slot_geom_out->len = elem_array_len;
+ }
BMO_op_finish(bm, &extop);
}
@@ -522,4 +576,8 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
dvec, op, "space", op, "geom_last.out");
}
}
+
+ if (vtable) {
+ MEM_freeN(vtable);
+ }
}