Commit: ca1bca442ab3ae6ab4332a24a784a1c79bde4e27
Author: Campbell Barton
Date:   Mon Aug 25 16:48:47 2014 +1000
Branches: master
https://developer.blender.org/rBca1bca442ab3ae6ab4332a24a784a1c79bde4e27

Fix T40993: Store selection history for extrude

===================================================================

M       source/blender/bmesh/intern/bmesh_marking.c
M       source/blender/bmesh/intern/bmesh_marking.h
M       source/blender/bmesh/intern/bmesh_opdefines.c
M       source/blender/bmesh/intern/bmesh_operator_api.h
M       source/blender/bmesh/intern/bmesh_operators.c
M       source/blender/bmesh/operators/bmo_dupe.c
M       source/blender/bmesh/operators/bmo_extrude.c
M       source/blender/bmesh/operators/bmo_fill_attribute.c
M       source/blender/editors/mesh/editmesh_extrude.c
M       source/blender/editors/mesh/editmesh_tools.c
M       source/blender/editors/mesh/editmesh_utils.c

===================================================================

diff --git a/source/blender/bmesh/intern/bmesh_marking.c 
b/source/blender/bmesh/intern/bmesh_marking.c
index e23a572..cde842c 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -899,6 +899,27 @@ bool BM_select_history_active_get(BMesh *bm, 
BMEditSelection *ese)
        return true;
 }
 
+/**
+ * Return a map from BMVert/Edge/Face -> BMEditSelection
+ */
+GHash *BM_select_history_map_create(BMesh *bm)
+{
+       BMEditSelection *ese;
+       GHash *map;
+
+       if (BLI_listbase_is_empty(&bm->selected)) {
+               return NULL;
+       }
+
+       map = BLI_ghash_ptr_new(__func__);
+
+       for (ese = bm->selected.first; ese; ese = ese->next) {
+               BLI_ghash_insert(map, ese->ele, ese);
+       }
+
+       return map;
+}
+
 void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char 
hflag,
                                      const bool respecthide, const bool 
overwrite, const char hflag_test)
 {
diff --git a/source/blender/bmesh/intern/bmesh_marking.h 
b/source/blender/bmesh/intern/bmesh_marking.h
index 655ace6..9e0c092 100644
--- a/source/blender/bmesh/intern/bmesh_marking.h
+++ b/source/blender/bmesh/intern/bmesh_marking.h
@@ -100,5 +100,12 @@ void _bm_select_history_store_after_notest(BMesh *bm,  
BMEditSelection *ese_ref,
 void BM_select_history_validate(BMesh *bm);
 void BM_select_history_clear(BMesh *bm);
 bool BM_select_history_active_get(BMesh *bm, struct BMEditSelection *ese);
+struct GHash *BM_select_history_map_create(BMesh *bm);
+
+#define BM_SELECT_HISTORY_BACKUP(bm) { \
+       ListBase _bm_prev_selected = (bm)->selected; 
BLI_listbase_clear(&(bm)->selected)
+
+#define BM_SELECT_HISTORY_RESTORE(bm) \
+       (bm)->selected = _bm_prev_selected; } (void)0
 
 #endif /* __BMESH_MARKING_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c 
b/source/blender/bmesh/intern/bmesh_opdefines.c
index 5e568f8..886181c 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -854,6 +854,7 @@ static BMOpDefine bmo_extrude_discrete_faces_def = {
        "extrude_discrete_faces",
        /* slots_in */
        {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* input faces */
+        {"use_select_history", BMO_OP_SLOT_BOOL},  /* pass to duplicate */
         {{'\0'}},
        },
        /* slots_out */
@@ -874,6 +875,7 @@ static BMOpDefine bmo_extrude_edge_only_def = {
        "extrude_edge_only",
        /* slots_in */
        {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input vertices */
+        {"use_select_history", BMO_OP_SLOT_BOOL},  /* pass to duplicate */
         {{'\0'}},
        },
        /* slots_out */
@@ -893,6 +895,7 @@ static BMOpDefine bmo_extrude_vert_indiv_def = {
        "extrude_vert_indiv",
        /* slots_in */
        {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},    /* input vertices */
+        {"use_select_history", BMO_OP_SLOT_BOOL},  /* pass to duplicate */
         {{'\0'}},
        },
        /* slots_out */
@@ -982,6 +985,7 @@ static BMOpDefine bmo_extrude_face_region_def = {
        {{"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 */
+        {"use_select_history", BMO_OP_SLOT_BOOL},  /* pass to duplicate */
         {{'\0'}},
        },
        /* slots_out */
@@ -1267,6 +1271,7 @@ static BMOpDefine bmo_duplicate_def = {
        {{"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}},
+        {"use_select_history", BMO_OP_SLOT_BOOL},
         {{'\0'}},
        },
        /* slots_out */
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h 
b/source/blender/bmesh/intern/bmesh_operator_api.h
index ef4990a..287aafc 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -338,7 +338,8 @@ void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *op, 
const char htype, cons
 void BMO_mesh_selected_remap(BMesh *bm,
                              BMOpSlot *slot_vert_map,
                              BMOpSlot *slot_edge_map,
-                             BMOpSlot *slot_face_map);
+                             BMOpSlot *slot_face_map,
+                             const bool check_select);
 
 /* 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,              \
diff --git a/source/blender/bmesh/intern/bmesh_operators.c 
b/source/blender/bmesh/intern/bmesh_operators.c
index 7f87261..6bca5ca 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -605,7 +605,8 @@ 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)
+                             BMOpSlot *slot_face_map,
+                             const bool check_select)
 {
        if (bm->selected.first) {
                BMEditSelection *ese, *ese_next;
@@ -623,7 +624,7 @@ void BMO_mesh_selected_remap(BMesh *bm,
                        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)))
+                                    (check_select && 
(BM_elem_flag_test(ese->ele, BM_ELEM_SELECT) == false))))
                        {
                                BLI_remlink(&bm->selected, ese);
                                MEM_freeN(ese);
diff --git a/source/blender/bmesh/operators/bmo_dupe.c 
b/source/blender/bmesh/operators/bmo_dupe.c
index 794c688..cd5592f 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -183,6 +183,7 @@ static BMFace *bmo_face_copy(BMOperator *op,
  */
 static void bmo_mesh_copy(BMOperator *op, BMesh *bm_dst, BMesh *bm_src)
 {
+       const bool use_select_history = BMO_slot_bool_get(op->slots_in, 
"use_select_history");
 
        BMVert *v = NULL, *v2;
        BMEdge *e = NULL;
@@ -285,6 +286,16 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_dst, 
BMesh *bm_src)
        /* free pointer hashes */
        BLI_ghash_free(vhash, NULL, NULL);
        BLI_ghash_free(ehash, NULL, NULL);
+
+       if (use_select_history) {
+               BLI_assert(bm_src == bm_dst);
+               BMO_mesh_selected_remap(
+                       bm_dst,
+                       slot_vert_map_out,
+                       slot_edge_map_out,
+                       slot_face_map_out,
+                       false);
+       }
 }
 
 /**
diff --git a/source/blender/bmesh/operators/bmo_extrude.c 
b/source/blender/bmesh/operators/bmo_extrude.c
index 510c3ae..88b53b6 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -53,9 +53,16 @@ enum {
 
 void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op)
 {
+       const bool use_select_history = BMO_slot_bool_get(op->slots_in, 
"use_select_history");
+       GHash *select_history_map = NULL;
+
        BMOIter siter;
        BMFace *f_org;
 
+       if (use_select_history) {
+               select_history_map = BM_select_history_map_create(bm);
+       }
+
        BMO_ITER (f_org, &siter, op->slots_in, "faces", BM_FACE) {
                BMFace *f_new;
                BMLoop *l_org, *l_org_first;
@@ -66,6 +73,14 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator 
*op)
                f_new = BM_face_copy(bm, bm, f_org, true, true);
                BMO_elem_flag_enable(bm, f_new, EXT_KEEP);
 
+               if (select_history_map) {
+                       BMEditSelection *ese;
+                       ese = BLI_ghash_lookup(select_history_map, f_org);
+                       if (ese) {
+                               ese->ele = (BMElem *)f_new;
+                       }
+               }
+
                l_org = l_org_first = BM_FACE_FIRST_LOOP(f_org);
                l_new = BM_FACE_FIRST_LOOP(f_new);
 
@@ -85,10 +100,28 @@ void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator 
*op)
                        BM_elem_attrs_copy(bm, bm, l_org->next, l_side_iter);  
l_side_iter = l_side_iter->next;
                        BM_elem_attrs_copy(bm, bm, l_org, l_side_iter);        
l_side_iter = l_side_iter->next;
                        BM_elem_attrs_copy(bm, bm, l_org, l_side_iter);
+
+                       if (select_history_map) {
+                               BMEditSelection *ese;
+
+                               ese = BLI_ghash_lookup(select_history_map, 
l_org->v);
+                               if (ese) {
+                                       ese->ele = (BMElem *)l_new->v;
+                               }
+                               ese = BLI_ghash_lookup(select_history_map, 
l_org->e);
+                               if (ese) {
+                                       ese->ele = (BMElem *)l_new->e;
+                               }
+                       }
+
                } while (((l_new = l_new->next),
                          (l_org = l_org->next)) != l_org_first);
        }
 
+       if (select_history_map) {
+               BLI_ghash_free(select_history_map, NULL, NULL);
+       }
+
        BMO_op_callf(bm, op->flag,
                     "delete geom=%ff context=%i",
                     EXT_DEL, DEL_ONLYFACES);
@@ -157,7 +190,11 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
                BMO_elem_flag_enable(bm, e->v2, EXT_INPUT);
        }
 
-       BMO_op_initf(bm, &dupeop, op->flag, "duplicate geom=%fve", EXT_INPUT);
+       BMO_op_initf(
+               bm, &dupeop, op->flag,
+               "duplicate geom=%fve use_select_history=%b",
+               EXT_INPUT, BMO_slot_bool_get(op->slots_in, 
"use_select_history"));
+
        BMO_op_exec(bm, &dupeop);
 
        /* disable root flag on all new skin nodes */
@@ -205,10 +242,16 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op)
 
 void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
 {
+       const bool use_select_history = BMO_slot_bool_get(op->slots_in, 
"use_select_history");
        BMOIter siter;
        BMVert *v, *dupev;
        BMEdge *e;
        const bool has_vskin = CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN);
+       GHash *select_history_map = NULL;
+
+       if (use_select_history) {
+               select_history_map = BM_select_history_map_create(bm);
+       }
 
        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, BM_CREATE_NOP);
@@ -217,6 +260,14 @@ void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
                if (has_vskin)
                        bm_extrude_disable_skin_root(bm, v);
 
+               if (select_history_map) {
+                       BMEditSelection *ese;
+                       ese = BLI_ghash_lookup(select_history_map, v);
+                       if (ese) {
+                               ese->ele = (BMElem *)dupev;
+                       }
+               }
+
                /* not essential, but ensures face normals from extruded edges 
are contiguous */
                if (BM_vert_is_wire_endpoint(v)) {
                        if (v->e->v1 == v) {
@@ -228,6 +279,10 @@ void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op)
                BMO_elem_flag_enable(bm, e, EXT_KEEP);
        }


@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to