[Bf-blender-cvs] [afdcd07b328] hair_guides: Mouse-picking operator for groom vertex selection.

Lukas Tönne noreply at git.blender.org
Sat Dec 30 09:45:00 CET 2017


Commit: afdcd07b3289f3dced03e9ae02b616901988b022
Author: Lukas Tönne
Date:   Sat Dec 30 08:44:35 2017 +0000
Branches: hair_guides
https://developer.blender.org/rBafdcd07b3289f3dced03e9ae02b616901988b022

Mouse-picking operator for groom vertex selection.

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

M	source/blender/editors/groom/editgroom_select.c
M	source/blender/editors/include/ED_groom.h
M	source/blender/editors/include/ED_view3d.h
M	source/blender/editors/space_view3d/view3d_iterators.c
M	source/blender/editors/space_view3d/view3d_select.c

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

diff --git a/source/blender/editors/groom/editgroom_select.c b/source/blender/editors/groom/editgroom_select.c
index aeffc858824..190e121ea2b 100644
--- a/source/blender/editors/groom/editgroom_select.c
+++ b/source/blender/editors/groom/editgroom_select.c
@@ -250,3 +250,193 @@ void GROOM_OT_select_all(wmOperatorType *ot)
 	/* properties */
 	WM_operator_properties_select_all(ot);
 }
+
+/****************************** Mouse Selection *************************/
+
+static void select_pick_findnearest_cb(
+        void *userdata,
+        GroomBundle *bundle,
+        GroomSection *section,
+        GroomSectionVertex *vertex,
+        const float screen_co[2])
+{
+	struct
+	{
+		GroomBundle *bundle;
+		GroomSection *section;
+		GroomSectionVertex *vertex;
+		float dist;
+		bool select;
+		float mval_fl[2];
+	} *data = userdata;
+
+	float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co);
+	
+	/* bias towards unselected items */
+	if (data->select &&
+	    ((vertex && vertex->flag & GM_VERTEX_SELECT) ||
+	     (section && section->flag & GM_SECTION_SELECT) ||
+	     (bundle && bundle->flag & GM_BUNDLE_SELECT)))
+	{
+		dist_test += 5.0f;
+	}
+
+	if (dist_test < data->dist) {
+		data->dist = dist_test;
+		data->bundle = bundle;
+		data->section = section;
+		data->vertex = vertex;
+	}
+}
+
+static void groom_set_region_select_flags(Groom *groom, int flag)
+{
+	for (GroomBundle *bundle = groom->editgroom->bundles.first; bundle; bundle = bundle->next)
+	{
+		bundle->flag = (bundle->flag & ~GM_BUNDLE_SELECT) | (flag & GM_BUNDLE_SELECT);
+	}
+}
+
+static void groom_set_curve_select_flags(Groom *groom, int flag)
+{
+	for (GroomBundle *bundle = groom->editgroom->bundles.first; bundle; bundle = bundle->next)
+	{
+		GroomSection *section = bundle->sections;
+		for (int i = 0; i < bundle->totsections; ++i, ++section)
+		{
+			section->flag = (section->flag & ~GM_SECTION_SELECT) | (flag & GM_SECTION_SELECT);
+		}
+	}
+}
+
+static void groom_set_section_select_flags(Groom *groom, int flag)
+{
+	for (GroomBundle *bundle = groom->editgroom->bundles.first; bundle; bundle = bundle->next)
+	{
+		GroomSectionVertex *vertex = bundle->verts;
+		for (int i = 0; i < bundle->totverts; ++i, ++vertex)
+		{
+			vertex->flag = (vertex->flag & ~GM_VERTEX_SELECT) | (flag & GM_VERTEX_SELECT);
+		}
+	}
+}
+
+bool ED_groom_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
+{
+	ViewContext vc;
+	view3d_set_viewcontext(C, &vc);
+	Groom *groom = vc.obedit->data;
+
+	struct
+	{
+		GroomBundle *bundle;
+		GroomSection *section;
+		GroomSectionVertex *vertex;
+		float dist;
+		bool select;
+		float mval_fl[2];
+	} data = {NULL};
+
+	data.dist = ED_view3d_select_dist_px();
+	data.select = true;
+	data.mval_fl[0] = mval[0];
+	data.mval_fl[1] = mval[1];
+
+	ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
+	groom_foreachScreenVert(&vc, select_pick_findnearest_cb, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+
+	bool found = false;
+	if (data.vertex)
+	{
+		if (extend)
+		{
+			data.vertex->flag |= GM_VERTEX_SELECT;
+		}
+		else if (deselect)
+		{
+			data.vertex->flag &= ~GM_VERTEX_SELECT;
+		}
+		else if (toggle)
+		{
+			data.vertex->flag ^= GM_VERTEX_SELECT;
+		}
+		else
+		{
+			/* deselect all other verts */
+			groom_set_section_select_flags(groom, 0);
+			data.vertex->flag |= GM_VERTEX_SELECT;
+		}
+		
+		if (data.vertex->flag & GM_VERTEX_SELECT)
+		{
+			/* set active section */
+			groom_set_region_select_flags(groom, 0);
+			groom_set_curve_select_flags(groom, 0);
+			data.section->flag |= GM_SECTION_SELECT;
+			data.bundle->flag |= GM_BUNDLE_SELECT;
+		}
+		
+		found = true;
+	}
+	else if (data.section)
+	{
+		if (extend)
+		{
+			data.section->flag |= GM_SECTION_SELECT;
+		}
+		else if (deselect)
+		{
+			data.section->flag &= ~GM_SECTION_SELECT;
+		}
+		else if (toggle)
+		{
+			data.section->flag ^= GM_SECTION_SELECT;
+		}
+		else
+		{
+			/* deselect all other sections */
+			groom_set_curve_select_flags(groom, 0);
+			data.section->flag |= GM_SECTION_SELECT;
+		}
+		
+		if (data.section->flag & GM_SECTION_SELECT)
+		{
+			/* set active region */
+			groom_set_region_select_flags(groom, 0);
+			data.bundle->flag |= GM_BUNDLE_SELECT;
+		}
+		
+		found = true;
+	}
+	else if (data.bundle)
+	{
+		if (extend)
+		{
+			data.bundle->flag |= GM_BUNDLE_SELECT;
+		}
+		else if (deselect)
+		{
+			data.bundle->flag &= ~GM_BUNDLE_SELECT;
+		}
+		else if (toggle)
+		{
+			data.bundle->flag ^= GM_BUNDLE_SELECT;
+		}
+		else
+		{
+			/* deselect all other regions */
+			groom_set_region_select_flags(groom, 0);
+			data.bundle->flag |= GM_BUNDLE_SELECT;
+		}
+		
+		found = true;
+	}
+
+	if (found)
+	{
+		WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
+		return true;
+	}
+
+	return false;
+}
diff --git a/source/blender/editors/include/ED_groom.h b/source/blender/editors/include/ED_groom.h
index fecbf88298a..079d2ce3681 100644
--- a/source/blender/editors/include/ED_groom.h
+++ b/source/blender/editors/include/ED_groom.h
@@ -61,4 +61,6 @@ void ED_groom_select_regions(struct EditGroom *edit, EditGroomSelectCb select_cb
 void ED_groom_select_curves(struct EditGroom *edit, EditGroomSelectCb select_cb, void *userdata);
 void ED_groom_select_sections(struct EditGroom *edit, EditGroomSelectCb select_cb, void *userdata);
 
+bool ED_groom_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
+
 #endif /* __ED_GROOM_H__ */
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 69061bdcd26..4a2a15773b5 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -44,6 +44,9 @@ struct Camera;
 struct Depsgraph;
 struct EditBone;
 struct EvaluationContext;
+struct GroomBundle;
+struct GroomSection;
+struct GroomSectionVertex;
 struct ImBuf;
 struct MVert;
 struct Main;
@@ -196,6 +199,15 @@ void pose_foreachScreenBone(
         void (*func)(void *userData, struct bPoseChannel *pchan,
                      const float screen_co_a[2], const float screen_co_b[2]),
         void *userData, const eV3DProjTest clip_flag);
+void groom_foreachScreenVert(
+        struct ViewContext *vc,
+        void (*func)(
+            void *userData,
+            struct GroomBundle *bundle,
+            struct GroomSection *section,
+            struct GroomSectionVertex *vert,
+            const float screen_co[2]),
+        void *userData, const eV3DProjTest clip_flag);
 /* *** end iterators *** */
 
 
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index 4f80270e1e7..945d4aa4a88 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -31,9 +31,11 @@
 #include "DNA_armature_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_groom_types.h"
 
 #include "BLI_utildefines.h"
 #include "BLI_rect.h"
+#include "BLI_math.h"
 
 #include "BKE_armature.h"
 #include "BKE_curve.h"
@@ -41,6 +43,7 @@
 #include "BKE_displist.h"
 #include "BKE_editmesh.h"
 #include "BKE_context.h"
+#include "BKE_groom.h"
 
 #include "DEG_depsgraph.h"
 
@@ -399,6 +402,75 @@ void lattice_foreachScreenVert(
 
 /* ------------------------------------------------------------------------ */
 
+void groom_foreachScreenVert(
+        ViewContext *vc,
+        void (*func)(
+            void *userData,
+            GroomBundle *bundle,
+            GroomSection *section,
+            GroomSectionVertex *vert,
+            const float screen_co[2]),
+        void *userData, const eV3DProjTest clip_flag)
+{
+	GroomEditSettings *edit_settings = &vc->scene->toolsettings->groom_edit_settings;
+	Object *obedit = vc->obedit;
+	Groom *groom = obedit->data;
+	ListBase *bundles = &groom->editgroom->bundles;
+
+	ED_view3d_check_mats_rv3d(vc->rv3d);
+
+	if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
+		ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */
+	}
+
+	switch (edit_settings->mode)
+	{
+		case GM_EDIT_MODE_REGIONS:
+			// TODO
+			break;
+
+		case GM_EDIT_MODE_CURVES:
+			for (GroomBundle *bundle = bundles->first; bundle; bundle = bundle->next)
+			{
+				GroomSection *section = bundle->sections;
+				for (int i = 0; i < bundle->totsections; ++i, ++section)
+				{
+					float screen_co[2];
+					if (ED_view3d_project_float_object(vc->ar, section->center, screen_co, clip_flag) == V3D_PROJ_RET_OK)
+					{
+						func(userData, bundle, section, NULL, screen_co);
+					}
+				}
+			}
+			break;
+
+		case GM_EDIT_MODE_SECTIONS:
+			for (GroomBundle *bundle = bundles->first; bundle; bundle = bundle->next)
+			{
+				GroomSectionVertex *vertex = bundle->verts;
+				GroomSection *section = bundle->sections;
+				for (int i = 0; i < bundle->totsections; ++i, ++section)
+				{
+					for (int j = 0; j < bundle->numloopverts; ++j, ++vertex)
+					{
+						float co[3] = {vertex->co[0], vertex->co[1], 0.0f};
+						mul_m3_v3(section->mat, co);
+						add_v3_v3(co, section->center);
+						
+						float screen_co[2];
+						if (ED_view3d_project_float_object(vc->ar, co, screen_co, clip_flag) == V3D_PROJ_RET_OK)
+						{
+							func(userData, bundle, section, vertex, screen_co);
+						}
+					}
+				}
+			}
+			break;
+	}
+}
+
+/* ------------------------------------------------------------------------ */
+
 /* ED_view3d_init_mats_rv3d must be called first */
 void armature_foreachScreenBone(
         struct ViewContext *vc,
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 28e15b3bfee..53a1f013a23 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -89,6 +89,7 @@
 #include "ED_screen.h"
 #include "ED_sculpt.h"
 #include "ED_mball.h"
+#include "ED_groom.h"
 
 #include "UI_interface.h"
 
@@ -2345,6 +2346,8 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
 			retval = ED_mball_select_pick(C, location, extend, deselect, toggle);
 		else if (obedit->type == OB_FONT)
 			retval = ED_curve_editfont_select_pick(C, location, extend, deselect,

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list