[Bf-blender-cvs] [ca1bca4] master: Fix T40993: Store selection history for extrude

Campbell Barton noreply at git.blender.org
Mon Aug 25 09:03:45 CEST 2014


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. @@




More information about the Bf-blender-cvs mailing list