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>2014-08-25 10:48:47 +0400
committerCampbell Barton <ideasman42@gmail.com>2014-08-25 10:57:38 +0400
commitca1bca442ab3ae6ab4332a24a784a1c79bde4e27 (patch)
treeb67221277ced8aca98d8659e00542b9d93f89ef5 /source/blender/editors/mesh
parent470e694652a28d20d31e001240fdb9727a6d1480 (diff)
Fix T40993: Store selection history for extrude
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r--source/blender/editors/mesh/editmesh_extrude.c182
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c23
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c9
3 files changed, 128 insertions, 86 deletions
diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index 595c43c1060..3e403387a67 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -33,6 +33,7 @@
#include "DNA_object_types.h"
#include "BLI_math.h"
+#include "BLI_listbase.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -65,6 +66,75 @@ static void add_normal_aligned(float nor[3], const float add[3])
}
}
+static void edbm_extrude_edge_exclude_mirror(
+ Object *obedit, BMEditMesh *em,
+ const char hflag,
+ BMOperator *op, BMOpSlot *slot_edges_exclude)
+{
+ BMesh *bm = em->bm;
+ ModifierData *md;
+
+ /* If a mirror modifier with clipping is on, we need to adjust some
+ * of the cases above to handle edges on the line of symmetry.
+ */
+ for (md = obedit->modifiers.first; md; md = md->next) {
+ if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) {
+ MirrorModifierData *mmd = (MirrorModifierData *) md;
+
+ if (mmd->flag & MOD_MIR_CLIPPING) {
+ BMIter iter;
+ BMEdge *edge;
+
+ float mtx[4][4];
+ if (mmd->mirror_ob) {
+ float imtx[4][4];
+ invert_m4_m4(imtx, mmd->mirror_ob->obmat);
+ mul_m4_m4m4(mtx, imtx, obedit->obmat);
+ }
+
+ BM_ITER_MESH (edge, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(edge, hflag) &&
+ BM_edge_is_boundary(edge) &&
+ BM_elem_flag_test(edge->l->f, hflag))
+ {
+ float co1[3], co2[3];
+
+ copy_v3_v3(co1, edge->v1->co);
+ copy_v3_v3(co2, edge->v2->co);
+
+ if (mmd->mirror_ob) {
+ mul_v3_m4v3(co1, mtx, co1);
+ mul_v3_m4v3(co2, mtx, co2);
+ }
+
+ if (mmd->flag & MOD_MIR_AXIS_X) {
+ if ((fabsf(co1[0]) < mmd->tolerance) &&
+ (fabsf(co2[0]) < mmd->tolerance))
+ {
+ BMO_slot_map_empty_insert(op, slot_edges_exclude, edge);
+ }
+ }
+ if (mmd->flag & MOD_MIR_AXIS_Y) {
+ if ((fabsf(co1[1]) < mmd->tolerance) &&
+ (fabsf(co2[1]) < mmd->tolerance))
+ {
+ BMO_slot_map_empty_insert(op, slot_edges_exclude, edge);
+ }
+ }
+ if (mmd->flag & MOD_MIR_AXIS_Z) {
+ if ((fabsf(co1[2]) < mmd->tolerance) &&
+ (fabsf(co2[2]) < mmd->tolerance))
+ {
+ BMO_slot_map_empty_insert(op, slot_edges_exclude, edge);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
/* individual face extrude */
/* will use vertex normals for extrusion directions, so *nor is unaffected */
static short edbm_extrude_discrete_faces(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor))
@@ -75,7 +145,10 @@ static short edbm_extrude_discrete_faces(BMEditMesh *em, wmOperator *op, const c
BMLoop *l;
BMOperator bmop;
- EDBM_op_init(em, &bmop, op, "extrude_discrete_faces faces=%hf", hflag);
+ EDBM_op_init(
+ em, &bmop, op,
+ "extrude_discrete_faces faces=%hf use_select_history=%b",
+ hflag, true);
/* deselect original verts */
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
@@ -101,12 +174,18 @@ static short edbm_extrude_discrete_faces(BMEditMesh *em, wmOperator *op, const c
/* extrudes individual edges */
static short edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor))
{
+ BMesh *bm = em->bm;
BMOperator bmop;
- EDBM_op_init(em, &bmop, op, "extrude_edge_only edges=%he", hflag);
+ EDBM_op_init(
+ em, &bmop, op,
+ "extrude_edge_only edges=%he use_select_history=%b",
+ hflag, true);
/* deselect original verts */
+ BM_SELECT_HISTORY_BACKUP(bm);
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+ BM_SELECT_HISTORY_RESTORE(bm);
BMO_op_exec(em->bm, &bmop);
BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true);
@@ -123,7 +202,10 @@ static short edbm_extrude_verts_indiv(BMEditMesh *em, wmOperator *op, const char
{
BMOperator bmop;
- EDBM_op_init(em, &bmop, op, "extrude_vert_indiv verts=%hv", hflag);
+ EDBM_op_init(
+ em, &bmop, op,
+ "extrude_vert_indiv verts=%hv use_select_history=%b",
+ hflag, true);
/* deselect original verts */
BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_in, "verts", BM_VERT, BM_ELEM_SELECT, true);
@@ -138,82 +220,32 @@ static short edbm_extrude_verts_indiv(BMEditMesh *em, wmOperator *op, const char
return 'g'; /* g is grab */
}
-static short edbm_extrude_edge(Object *obedit, BMEditMesh *em, const char hflag, float nor[3])
+static short edbm_extrude_edge_ex(
+ Object *obedit, BMEditMesh *em,
+ const char hflag, float nor[3],
+ const bool use_mirror,
+ const bool use_select_history)
{
BMesh *bm = em->bm;
- BMIter iter;
BMOIter siter;
BMOperator extop;
- BMEdge *edge;
BMFace *f;
- ModifierData *md;
BMElem *ele;
- BMOpSlot *slot_edges_exclude;
BMO_op_init(bm, &extop, BMO_FLAG_DEFAULTS, "extrude_face_region");
+ BMO_slot_bool_set(extop.slots_in, "use_select_history", use_select_history);
BMO_slot_buffer_from_enabled_hflag(bm, &extop, extop.slots_in, "geom", BM_VERT | BM_EDGE | BM_FACE, hflag);
- slot_edges_exclude = BMO_slot_get(extop.slots_in, "edges_exclude");
+ if (use_mirror) {
+ BMOpSlot *slot_edges_exclude;
+ slot_edges_exclude = BMO_slot_get(extop.slots_in, "edges_exclude");
- /* If a mirror modifier with clipping is on, we need to adjust some
- * of the cases above to handle edges on the line of symmetry.
- */
- md = obedit->modifiers.first;
- for (; md; md = md->next) {
- if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) {
- MirrorModifierData *mmd = (MirrorModifierData *) md;
-
- if (mmd->flag & MOD_MIR_CLIPPING) {
- float mtx[4][4];
- if (mmd->mirror_ob) {
- float imtx[4][4];
- invert_m4_m4(imtx, mmd->mirror_ob->obmat);
- mul_m4_m4m4(mtx, imtx, obedit->obmat);
- }
-
- BM_ITER_MESH (edge, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(edge, hflag) &&
- BM_edge_is_boundary(edge) &&
- BM_elem_flag_test(edge->l->f, hflag))
- {
- float co1[3], co2[3];
-
- copy_v3_v3(co1, edge->v1->co);
- copy_v3_v3(co2, edge->v2->co);
-
- if (mmd->mirror_ob) {
- mul_v3_m4v3(co1, mtx, co1);
- mul_v3_m4v3(co2, mtx, co2);
- }
-
- if (mmd->flag & MOD_MIR_AXIS_X) {
- if ((fabsf(co1[0]) < mmd->tolerance) &&
- (fabsf(co2[0]) < mmd->tolerance))
- {
- BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge);
- }
- }
- if (mmd->flag & MOD_MIR_AXIS_Y) {
- if ((fabsf(co1[1]) < mmd->tolerance) &&
- (fabsf(co2[1]) < mmd->tolerance))
- {
- BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge);
- }
- }
- if (mmd->flag & MOD_MIR_AXIS_Z) {
- if ((fabsf(co1[2]) < mmd->tolerance) &&
- (fabsf(co2[2]) < mmd->tolerance))
- {
- BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge);
- }
- }
- }
- }
- }
- }
+ edbm_extrude_edge_exclude_mirror(obedit, em, hflag, &extop, slot_edges_exclude);
}
+ BM_SELECT_HISTORY_BACKUP(bm);
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+ BM_SELECT_HISTORY_RESTORE(bm);
BMO_op_exec(bm, &extop);
@@ -236,6 +268,13 @@ static short edbm_extrude_edge(Object *obedit, BMEditMesh *em, const char hflag,
return is_zero_v3(nor) ? 'g' : 'n';
}
+static short edbm_extrude_edge(
+ Object *obedit, BMEditMesh *em,
+ const char hflag, float nor[3])
+{
+ return edbm_extrude_edge_ex(obedit, em, hflag, nor, true, true);
+}
+
static short edbm_extrude_vert(Object *obedit, BMEditMesh *em, const char hflag, float nor[3])
{
BMIter iter;
@@ -288,13 +327,12 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
mul_m3_v3(tmat, dvec);
for (a = 0; a < steps; a++) {
- edbm_extrude_edge(obedit, em, BM_ELEM_SELECT, nor);
- //BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, "extrude_face_region geom=%hef", BM_ELEM_SELECT);
- BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS,
- "translate vec=%v verts=%hv",
- dvec, BM_ELEM_SELECT);
- //extrudeflag(obedit, em, SELECT, nor);
- //translateflag(em, SELECT, dvec);
+ edbm_extrude_edge_ex(obedit, em, BM_ELEM_SELECT, nor, false, false);
+
+ BMO_op_callf(
+ em->bm, BMO_FLAG_DEFAULTS,
+ "translate vec=%v verts=%hv",
+ dvec, BM_ELEM_SELECT);
}
EDBM_mesh_normals_update(em);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 92bbd9482e2..12b6428f0fe 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -1019,28 +1019,23 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op)
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 use_select_history=%b",
+ BM_ELEM_SELECT, true);
- EDBM_op_init(em, &bmop, op, "duplicate geom=%hvef", BM_ELEM_SELECT);
-
BMO_op_exec(bm, &bmop);
+
+ /* de-select all would clear otherwise */
+ BM_SELECT_HISTORY_BACKUP(bm);
+
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
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);
- }
+ BM_SELECT_HISTORY_RESTORE(bm);
if (!EDBM_op_finish(em, &bmop, op, true)) {
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 8adaae5fe42..c7d1d883537 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -1328,6 +1328,15 @@ void EDBM_update_generic(BMEditMesh *em, const bool do_tessface, const bool is_d
/* don't keep stale derivedMesh data around, see: [#38872] */
BKE_editmesh_free_derivedmesh(em);
+
+#ifdef DEBUG
+ {
+ BMEditSelection *ese;
+ for (ese = em->bm->selected.first; ese; ese = ese->next) {
+ BLI_assert(BM_elem_flag_test(ese->ele, BM_ELEM_SELECT));
+ }
+ }
+#endif
}
/* poll call for mesh operators requiring a view3d context */