[Bf-blender-cvs] [6146b90] strand_editmode: Select Linked operator for hair edit mode (select all vertices of a strand).
Lukas Tönne
noreply at git.blender.org
Mon Apr 20 14:24:21 CEST 2015
Commit: 6146b9031206b7fff7a0a66a1e27ac0134fda8e4
Author: Lukas Tönne
Date: Tue Jan 6 11:13:39 2015 +0100
Branches: strand_editmode
https://developer.blender.org/rB6146b9031206b7fff7a0a66a1e27ac0134fda8e4
Select Linked operator for hair edit mode (select all vertices of a
strand).
===================================================================
M source/blender/bmesh/intern/bmesh_strands.h
M source/blender/editors/hair/hair_intern.h
M source/blender/editors/hair/hair_ops.c
M source/blender/editors/hair/hair_select.c
===================================================================
diff --git a/source/blender/bmesh/intern/bmesh_strands.h b/source/blender/bmesh/intern/bmesh_strands.h
index f326331..cd4267f 100644
--- a/source/blender/bmesh/intern/bmesh_strands.h
+++ b/source/blender/bmesh/intern/bmesh_strands.h
@@ -73,6 +73,42 @@ BLI_INLINE bool BM_strands_vert_is_tip(BMVert *v)
return false;
}
+/* Next vertex on a strand */
+BLI_INLINE BMVert *BM_strands_vert_next(BMVert *v)
+{
+ BMEdge *e_first = v->e;
+ BMEdge *e_next;
+
+ /* one of the edges leads to the previous vertex */
+ if (e_first) {
+ if (e_first->v1 == v)
+ return e_first->v2;
+
+ e_next = bmesh_disk_edge_next(e_first, v);
+ if (e_next->v1 == v)
+ return e_next->v2;
+ }
+ return NULL;
+}
+
+/* Previous vertex on a strand */
+BLI_INLINE BMVert *BM_strands_vert_prev(BMVert *v)
+{
+ BMEdge *e_first = v->e;
+ BMEdge *e_next;
+
+ /* one of the edges leads to the previous vertex */
+ if (e_first) {
+ if (e_first->v2 == v)
+ return e_first->v1;
+
+ e_next = bmesh_disk_edge_next(e_first, v);
+ if (e_next->v2 == v)
+ return e_next->v1;
+ }
+ return NULL;
+}
+
int BM_strands_count(BMesh *bm);
int BM_strands_keys_count(BMVert *root);
diff --git a/source/blender/editors/hair/hair_intern.h b/source/blender/editors/hair/hair_intern.h
index cd59af7..4854104 100644
--- a/source/blender/editors/hair/hair_intern.h
+++ b/source/blender/editors/hair/hair_intern.h
@@ -49,6 +49,7 @@ void HAIR_OT_hair_edit_toggle(struct wmOperatorType *ot);
/* hair_select.c */
void HAIR_OT_select_all(struct wmOperatorType *ot);
+void HAIR_OT_select_linked(struct wmOperatorType *ot);
/* hair_stroke.c */
void HAIR_OT_stroke(struct wmOperatorType *ot);
diff --git a/source/blender/editors/hair/hair_ops.c b/source/blender/editors/hair/hair_ops.c
index 9792c79..bb3b027 100644
--- a/source/blender/editors/hair/hair_ops.c
+++ b/source/blender/editors/hair/hair_ops.c
@@ -50,6 +50,7 @@ void ED_operatortypes_hair(void)
WM_operatortype_append(HAIR_OT_hair_edit_toggle);
WM_operatortype_append(HAIR_OT_select_all);
+ WM_operatortype_append(HAIR_OT_select_linked);
WM_operatortype_append(HAIR_OT_stroke);
}
@@ -129,6 +130,11 @@ void ED_keymap_hair(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "HAIR_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
+ kmi = WM_keymap_add_item(keymap, "HAIR_OT_select_linked", LKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "deselect", false);
+ kmi = WM_keymap_add_item(keymap, "HAIR_OT_select_linked", LKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "deselect", true);
+
kmi = WM_keymap_add_item(keymap, "HAIR_OT_stroke", LEFTMOUSE, KM_PRESS, 0, 0);
ed_keymap_hair_brush_switch(keymap, "hair_edit");
diff --git a/source/blender/editors/hair/hair_select.c b/source/blender/editors/hair/hair_select.c
index 808a1ce..986e669 100644
--- a/source/blender/editors/hair/hair_select.c
+++ b/source/blender/editors/hair/hair_select.c
@@ -49,6 +49,7 @@
#include "bmesh.h"
#include "RNA_access.h"
+#include "RNA_define.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -92,6 +93,7 @@ BLI_INLINE bool apply_select_action_flag(BMVert *v, int action)
typedef bool (*PollVertexCb)(void *userdata, struct BMVert *v);
/* distance metric function */
typedef bool (*DistanceVertexCb)(void *userdata, struct BMVert *v, float *dist);
+typedef void (*ActionVertexCb)(void *userdata, struct BMVert *v, int action);
static int hair_select_verts_filter(BMEditStrands *edit, HairEditSelectMode select_mode, int action, PollVertexCb cb, void *userdata)
{
@@ -133,13 +135,12 @@ static int hair_select_verts_filter(BMEditStrands *edit, HairEditSelectMode sele
return tot;
}
-static int hair_select_verts_closest(BMEditStrands *edit, HairEditSelectMode select_mode, int action, DistanceVertexCb cb, void *userdata)
+static bool hair_select_verts_closest(BMEditStrands *edit, HairEditSelectMode select_mode, int action, DistanceVertexCb cb, ActionVertexCb action_cb, void *userdata)
{
BMesh *bm = edit->bm;
BMVert *v;
BMIter iter;
- int tot = 0;
float dist;
BMVert *closest_v = NULL;
@@ -177,13 +178,13 @@ static int hair_select_verts_closest(BMEditStrands *edit, HairEditSelectMode sel
}
if (closest_v) {
- if (apply_select_action_flag(closest_v, action))
- ++tot;
+ action_cb(userdata, closest_v, action);
+
+ BM_mesh_select_mode_flush(bm);
+ return true;
}
-
- BM_mesh_select_mode_flush(bm);
-
- return tot;
+ else
+ return false;
}
static void hair_deselect_all(BMEditStrands *edit)
@@ -263,6 +264,11 @@ static bool distance_vertex_circle(void *userdata, struct BMVert *v, float *dist
return hair_test_vertex_inside_circle(&data->viewdata, data->mval, data->radsq, v, dist);
}
+static void closest_vertex_select(void *UNUSED(userdata), struct BMVert *v, int action)
+{
+ apply_select_action_flag(v, action);
+}
+
int ED_hair_mouse_select(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
{
Scene *scene = CTX_data_scene(C);
@@ -290,13 +296,81 @@ int ED_hair_mouse_select(bContext *C, const int mval[2], bool extend, bool desel
else
action = SEL_INVERT;
- hair_select_verts_closest(edit, settings->select_mode, action, distance_vertex_circle, &data);
+ hair_select_verts_closest(edit, settings->select_mode, action, distance_vertex_circle, closest_vertex_select, &data);
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW | NA_SELECTED, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+/************************ select linked operator ************************/
+
+static void linked_vertices_select(void *UNUSED(userdata), struct BMVert *v, int action)
+{
+ BMVert *lv;
+
+ apply_select_action_flag(v, action);
+
+ for (lv = BM_strands_vert_prev(v); lv; lv = BM_strands_vert_prev(lv))
+ apply_select_action_flag(lv, action);
+ for (lv = BM_strands_vert_next(v); lv; lv = BM_strands_vert_next(lv))
+ apply_select_action_flag(lv, action);
+}
+
+static int select_linked_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ BMEditStrands *edit = BKE_editstrands_from_object(ob);
+ HairEditSettings *settings = &scene->toolsettings->hair_edit;
+ float select_radius = ED_view3d_select_dist_px();
+
+ DistanceVertexCirleData data;
+ int location[2];
+ int action;
+
+ RNA_int_get_array(op->ptr, "location", location);
+
+ hair_init_viewdata(C, &data.viewdata);
+ data.mval[0] = location[0];
+ data.mval[1] = location[1];
+ data.radsq = select_radius * select_radius;
+
+ action = RNA_boolean_get(op->ptr, "deselect") ? SEL_DESELECT : SEL_SELECT;
+
+ hair_select_verts_closest(edit, settings->select_mode, action, distance_vertex_circle, linked_vertices_select, &data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW | NA_SELECTED, ob);
return OPERATOR_FINISHED;
}
+static int select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ RNA_int_set_array(op->ptr, "location", event->mval);
+ return select_linked_exec(C, op);
+}
+
+void HAIR_OT_select_linked(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Linked";
+ ot->idname = "HAIR_OT_select_linked";
+ ot->description = "Select connected vertices";
+
+ /* api callbacks */
+ ot->exec = select_linked_exec;
+ ot->invoke = select_linked_invoke;
+ ot->poll = hair_edit_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect linked keys rather than selecting them");
+ RNA_def_int_vector(ot->srna, "location", 2, NULL, 0, INT_MAX, "Location", "", 0, 16384);
+}
+
/************************ border select operator ************************/
typedef struct PollVertexRectData {
More information about the Bf-blender-cvs
mailing list