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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-09-02 08:39:48 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-09-02 08:39:48 +0400
commit01a2634d610296f68c3411a3fef6a54a821886e7 (patch)
tree225e32b7546c7c89faf5e9443957c565ed052a77 /source
parent54310b8086e5820049f73f66fde8c92041fdb61a (diff)
fix [#36412] Pivot of active element switches to last selected face after duplicating vertices.
Diffstat (limited to 'source')
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c3
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c38
-rw-r--r--source/blender/bmesh/operators/bmo_dupe.c17
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c20
5 files changed, 75 insertions, 8 deletions
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index b3054a11e56..e6291cac241 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -1177,8 +1177,9 @@ static BMOpDefine bmo_duplicate_def = {
{"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 */
- {"face_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
{"vert_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"edge_map.out", BMO_OP_SLOT_MAPPING, {BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"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'}},
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index 3bfb05221ba..7de158f3c29 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -335,6 +335,11 @@ void BMO_slot_mat3_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_na
void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *op, const char htype, const short oflag);
+void BMO_mesh_selected_remap(BMesh *bm,
+ BMOpSlot *slot_vert_map,
+ BMOpSlot *slot_edge_map,
+ BMOpSlot *slot_face_map);
+
/* copies the values from another slot to the end of the output slot */
#define BMO_slot_buffer_append(op_src, slots_src, slot_name_src, \
op_dst, slots_dst, slot_name_dst) \
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 836001468a2..a3843b683be 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -602,6 +602,44 @@ void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *UNUSED(op), const char hty
}
}
+void BMO_mesh_selected_remap(BMesh *bm,
+ BMOpSlot *slot_vert_map,
+ BMOpSlot *slot_edge_map,
+ BMOpSlot *slot_face_map)
+{
+ if (bm->selected.first) {
+ BMEditSelection *ese, *ese_next;
+ BMOpSlot *slot_elem_map;
+
+ for (ese = bm->selected.first; ese; ese = ese_next) {
+ ese_next = ese->next;
+
+ switch (ese->htype) {
+ case BM_VERT: slot_elem_map = slot_vert_map; break;
+ case BM_EDGE: slot_elem_map = slot_edge_map; break;
+ default: slot_elem_map = slot_face_map; break;
+ }
+
+ ese->ele = BMO_slot_map_elem_get(slot_elem_map, ese->ele);
+
+ if (UNLIKELY((ese->ele == NULL) ||
+ (BM_elem_flag_test(ese->ele, BM_ELEM_SELECT) == false)))
+ {
+ BLI_remlink(&bm->selected, ese);
+ MEM_freeN(ese);
+ }
+ }
+ }
+
+ if (bm->act_face) {
+ BMFace *f = BMO_slot_map_elem_get(slot_face_map, bm->act_face);
+ if (f) {
+ bm->act_face = f;
+ }
+ }
+}
+
+
int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index 2f24920f504..bd2485b92fb 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -75,6 +75,7 @@ static BMVert *bmo_vert_copy(BMOperator *op,
* Copy an existing edge from one bmesh to another.
*/
static BMEdge *bmo_edge_copy(BMOperator *op,
+ BMOpSlot *slot_edgemap_out,
BMOpSlot *slot_boundarymap_out,
BMesh *bm_dst, BMesh *bm_src,
BMEdge *e_src,
@@ -105,7 +106,9 @@ static BMEdge *bmo_edge_copy(BMOperator *op,
/* Create a new edge */
e_dst = BM_edge_create(bm_dst, e_dst_v1, e_dst_v2, NULL, BM_CREATE_SKIP_CD);
-
+ BMO_slot_map_elem_insert(op, slot_edgemap_out, e_src, e_dst);
+ BMO_slot_map_elem_insert(op, slot_edgemap_out, e_dst, e_src);
+
/* add to new/old edge map if necassary */
if (rlen < 2) {
/* not sure what non-manifold cases of greater then three
@@ -192,8 +195,10 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_dst, BMesh *bm_src)
BMOpSlot *slot_boundary_map_out = BMO_slot_get(op->slots_out, "boundary_map.out");
BMOpSlot *slot_isovert_map_out = BMO_slot_get(op->slots_out, "isovert_map.out");
- BMOpSlot *slot_face_map_out = BMO_slot_get(op->slots_out, "face_map.out");
- BMOpSlot *slot_vert_map_out = BMO_slot_get(op->slots_out, "vert_map.out");
+
+ BMOpSlot *slot_vert_map_out = BMO_slot_get(op->slots_out, "vert_map.out");
+ BMOpSlot *slot_edge_map_out = BMO_slot_get(op->slots_out, "edge_map.out");
+ BMOpSlot *slot_face_map_out = BMO_slot_get(op->slots_out, "face_map.out");
/* initialize pointer hashes */
vhash = BLI_ghash_ptr_new("bmesh dupeops v");
@@ -248,7 +253,8 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_dst, BMesh *bm_src)
BMO_elem_flag_enable(bm_src, e->v2, DUPE_DONE);
}
/* now copy the actual edge */
- bmo_edge_copy(op, slot_boundary_map_out, bm_dst, bm_src, e, vhash, ehash);
+ bmo_edge_copy(op, slot_edge_map_out, slot_boundary_map_out,
+ bm_dst, bm_src, e, vhash, ehash);
BMO_elem_flag_enable(bm_src, e, DUPE_DONE);
}
}
@@ -267,7 +273,8 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_dst, BMesh *bm_src)
/* edge pass */
BM_ITER_ELEM (e, &eiter, f, BM_EDGES_OF_FACE) {
if (!BMO_elem_flag_test(bm_src, e, DUPE_DONE)) {
- bmo_edge_copy(op, slot_boundary_map_out, bm_dst, bm_src, e, vhash, ehash);
+ bmo_edge_copy(op, slot_edge_map_out, slot_boundary_map_out,
+ bm_dst, bm_src, e, vhash, ehash);
BMO_elem_flag_enable(bm_src, e, DUPE_DONE);
}
}
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index f384ac9c448..1f5ea9f7b0f 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -892,14 +892,30 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(ob);
+ BMesh *bm = em->bm;
BMOperator bmop;
+ ListBase bm_selected_store = {NULL, NULL};
+
+ /* de-select all would clear otherwise */
+ SWAP(ListBase, bm->selected, bm_selected_store);
EDBM_op_init(em, &bmop, op, "duplicate geom=%hvef", BM_ELEM_SELECT);
- BMO_op_exec(em->bm, &bmop);
+ BMO_op_exec(bm, &bmop);
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true);
+ BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "geom.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true);
+
+ /* rebuild editselection */
+ bm->selected = bm_selected_store;
+
+ if (bm->selected.first) {
+ BMOpSlot *slot_vert_map_out = BMO_slot_get(bmop.slots_out, "vert_map.out");
+ BMOpSlot *slot_edge_map_out = BMO_slot_get(bmop.slots_out, "edge_map.out");
+ BMOpSlot *slot_face_map_out = BMO_slot_get(bmop.slots_out, "face_map.out");
+
+ BMO_mesh_selected_remap(bm, slot_vert_map_out, slot_edge_map_out, slot_face_map_out);
+ }
if (!EDBM_op_finish(em, &bmop, op, true)) {
return OPERATOR_CANCELLED;