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:
Diffstat (limited to 'source/blender/bmesh/operators')
-rw-r--r--source/blender/bmesh/operators/bmo_bevel.c4
-rw-r--r--source/blender/bmesh/operators/bmo_dupe.c73
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c20
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c39
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide_edgering.c6
5 files changed, 103 insertions, 39 deletions
diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c
index 2ae87b64286..9247c64d3fb 100644
--- a/source/blender/bmesh/operators/bmo_bevel.c
+++ b/source/blender/bmesh/operators/bmo_bevel.c
@@ -63,7 +63,9 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
}
}
- BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide);
+ BM_mesh_bevel(
+ bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material,
+ loop_slide);
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG);
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG);
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index eed87ed20af..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,9 +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");
+ /* 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++) {
@@ -503,14 +525,47 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
BMO_op_finish(bm, &dupop);
}
else {
- BMO_op_initf(bm, &extop, op->flag, "extrude_face_region geom=%S",
- op, "geom_last.out");
+ 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);
}
@@ -521,4 +576,8 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
dvec, op, "space", op, "geom_last.out");
}
}
+
+ if (vtable) {
+ MEM_freeN(vtable);
+ }
}
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 3a6fbd419c1..8c1624740da 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -186,6 +186,7 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
BMOperator dupeop;
BMFace *f;
BMEdge *e, *e_new;
+ const bool use_normal_flip = BMO_slot_bool_get(op->slots_in, "use_normal_flip");
BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
BMO_edge_flag_enable(bm, e, EXT_INPUT);
@@ -212,7 +213,9 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
BMVert *f_verts[4];
e_new = BMO_iter_map_value_ptr(&siter);
- if (e->l && e->v1 != e->l->v) {
+
+ const bool edge_normal_flip = !(e->l && e->v1 != e->l->v);
+ if (edge_normal_flip == use_normal_flip) {
f_verts[0] = e->v1;
f_verts[1] = e->v2;
f_verts[2] = e_new->v2;
@@ -332,9 +335,10 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
BMEdge *e, *e_new;
BMVert *v;
BMFace *f;
- bool found, fwd, delorig = false;
+ bool found, delorig = false;
BMOpSlot *slot_facemap_out;
BMOpSlot *slot_edges_exclude;
+ const bool use_normal_flip = BMO_slot_bool_get(op->slots_in, "use_normal_flip");
/* initialize our sub-operators */
BMO_op_initf(
@@ -488,13 +492,11 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
/* orient loop to give same normal as a loop of newedge
* if it exists (will be an extruded face),
* else same normal as a loop of e, if it exists */
- if (!e_new->l)
- fwd = !e->l || !(e->l->v == e->v1);
- else
- fwd = (e_new->l->v == e_new->v1);
-
-
- if (fwd) {
+ const bool edge_normal_flip = !(
+ e_new->l ?
+ (e_new->l->v == e_new->v1) :
+ (!e->l || !(e->l->v == e->v1)));
+ if (edge_normal_flip == use_normal_flip) {
f_verts[0] = e->v1;
f_verts[1] = e->v2;
f_verts[2] = e_new->v2;
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index c8ba2134a73..66730f8c837 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -182,15 +182,12 @@ static void interp_slerp_co_no_v3(
/* calculate sphere 'center' */
{
/* use point on plane to */
- float plane_a[4], plane_b[4], plane_c[4];
float no_mid[3], no_ortho[3];
/* pass this as an arg instead */
#if 0
float no_dir[3];
#endif
- float v_a_no_ortho[3], v_b_no_ortho[3];
-
add_v3_v3v3(no_mid, no_a, no_b);
normalize_v3(no_mid);
@@ -200,24 +197,28 @@ static void interp_slerp_co_no_v3(
#endif
/* axis of slerp */
+ bool center_ok = false;
cross_v3_v3v3(no_ortho, no_mid, no_dir);
- normalize_v3(no_ortho);
-
- /* create planes */
- cross_v3_v3v3(v_a_no_ortho, no_ortho, no_a);
- cross_v3_v3v3(v_b_no_ortho, no_ortho, no_b);
- project_v3_plane(v_a_no_ortho, no_ortho, v_a_no_ortho);
- project_v3_plane(v_b_no_ortho, no_ortho, v_b_no_ortho);
-
- plane_from_point_normal_v3(plane_a, co_a, v_a_no_ortho);
- plane_from_point_normal_v3(plane_b, co_b, v_b_no_ortho);
- plane_from_point_normal_v3(plane_c, co_b, no_ortho);
-
- /* find the sphere center from 3 planes */
- if (isect_plane_plane_plane_v3(plane_a, plane_b, plane_c, center)) {
- /* pass */
+ if (normalize_v3(no_ortho) != 0.0f) {
+ float plane_a[4], plane_b[4], plane_c[4];
+ float v_a_no_ortho[3], v_b_no_ortho[3];
+
+ /* create planes */
+ cross_v3_v3v3(v_a_no_ortho, no_ortho, no_a);
+ cross_v3_v3v3(v_b_no_ortho, no_ortho, no_b);
+ project_v3_plane(v_a_no_ortho, no_ortho, v_a_no_ortho);
+ project_v3_plane(v_b_no_ortho, no_ortho, v_b_no_ortho);
+
+ plane_from_point_normal_v3(plane_a, co_a, v_a_no_ortho);
+ plane_from_point_normal_v3(plane_b, co_b, v_b_no_ortho);
+ plane_from_point_normal_v3(plane_c, co_b, no_ortho);
+
+ /* find the sphere center from 3 planes */
+ if (isect_plane_plane_plane_v3(plane_a, plane_b, plane_c, center)) {
+ center_ok = true;
+ }
}
- else {
+ if (center_ok == false) {
mid_v3_v3v3(center, co_a, co_b);
}
}
diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
index e6881f6d8b1..251a79e8ff5 100644
--- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c
+++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
@@ -505,7 +505,7 @@ static LoopPairStore *bm_edgering_pair_store_create(
for (v_iter = lb->first, i = 0; v_iter; v_iter = v_iter->next, i++) {
BMVert *v = v_iter->data;
bm_vert_calc_surface_tangent(bm, v, nor[i]);
- BLI_ghash_insert(nors_gh_iter, v, SET_UINT_IN_POINTER(i));
+ BLI_ghash_insert(nors_gh_iter, v, POINTER_FROM_UINT(i));
}
}
@@ -768,8 +768,8 @@ static void bm_edgering_pair_interpolate(
bm_vert_calc_surface_tangent(bm, v_b, no_b);
#else
{
- const uint index_a = GET_UINT_FROM_POINTER(BLI_ghash_lookup(lpair->nors_gh_a, v_a));
- const uint index_b = GET_UINT_FROM_POINTER(BLI_ghash_lookup(lpair->nors_gh_b, v_b));
+ const uint index_a = POINTER_AS_UINT(BLI_ghash_lookup(lpair->nors_gh_a, v_a));
+ const uint index_b = POINTER_AS_UINT(BLI_ghash_lookup(lpair->nors_gh_b, v_b));
BLI_assert(BLI_ghash_haskey(lpair->nors_gh_a, v_a));
BLI_assert(BLI_ghash_haskey(lpair->nors_gh_b, v_b));