[Bf-blender-cvs] [dbe1472] temp_manipulators_core: Refactor lookups for hovered manipulator

Julian Eisel noreply at git.blender.org
Mon Oct 3 00:27:48 CEST 2016


Commit: dbe147257d6b82c7911d6670568ccc41913109fd
Author: Julian Eisel
Date:   Mon Oct 3 00:23:34 2016 +0200
Branches: temp_manipulators_core
https://developer.blender.org/rBdbe147257d6b82c7911d6670568ccc41913109fd

Refactor lookups for hovered manipulator

2D manipulators now have priority over 3D ones, think that's what you'd want usually. Untested code, need to merge into custom_manipulators first.

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

M	source/blender/windowmanager/intern/wm_event_system.c
M	source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
M	source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
M	source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c
M	source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h

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

diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 1fa5b22..8da107f 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2113,11 +2113,7 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers
 
 				/* handle manipulator highlighting */
 				if (event->type == MOUSEMOVE && !wm_manipulatormap_get_active_manipulator(mmap)) {
-					/* TODO should check for both, 2D and 3D manipulators and choose the one closest to cursor */
-					manipulator = wm_manipulatormap_find_highlighted_3D(mmap, C, event, &part);
-					if (!manipulator) {
-						manipulator = wm_manipulatormap_find_highlighted_manipulator(mmap, C, event, &part);
-					}
+					manipulator = wm_manipulatormap_find_highlighted_manipulator(mmap, C, event, &part);
 					wm_manipulatormap_set_highlighted_manipulator(mmap, C, manipulator, part);
 				}
 				/* handle user configurable manipulator-map keymap */
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
index 52a5cb3..b830301 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_intern.h
@@ -143,6 +143,11 @@ enum {
 
 struct wmManipulatorGroup *wm_manipulatorgroup_new_from_type(struct wmManipulatorGroupType *mgrouptype);
 void wm_manipulatorgroup_free(bContext *C, struct wmManipulatorMap *mmap, struct wmManipulatorGroup *mgroup);
+wmManipulator *wm_manipulatorgroup_find_intersected_mainpulator(
+        const struct wmManipulatorGroup *mgroup, struct bContext *C, const struct wmEvent *event,
+        unsigned char *part);
+void wm_manipulatorgroup_intersectable_manipulators_to_list(
+        const struct wmManipulatorGroup *mgroup, struct ListBase *listbase);
 void wm_manipulatorgroup_ensure_initialized(struct wmManipulatorGroup *mgroup, const struct bContext *C);
 bool wm_manipulatorgroup_is_visible(const struct wmManipulatorGroup *mgroup, const struct bContext *C);
 
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
index 3f635f8..a938e8b 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatorgroup.c
@@ -140,6 +140,37 @@ void wm_manipulatorgroup_attach_to_modal_handler(
 	WM_event_add_mousemove(C);
 }
 
+wmManipulator *wm_manipulatorgroup_find_intersected_mainpulator(
+        const wmManipulatorGroup *mgroup, bContext *C, const wmEvent *event,
+        unsigned char *part)
+{
+	for (wmManipulator *manipulator = mgroup->manipulators.first; manipulator; manipulator = manipulator->next) {
+		if (manipulator->intersect && (manipulator->flag & WM_MANIPULATOR_HIDDEN) == 0) {
+			if ((*part = manipulator->intersect(C, event, manipulator))) {
+				return manipulator;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * Adds all manipulators of \a mgroup that can be selected to the head of \a listbase. Added items need freeing!
+ */
+void wm_manipulatorgroup_intersectable_manipulators_to_list(const wmManipulatorGroup *mgroup, ListBase *listbase)
+{
+	for (wmManipulator *manipulator = mgroup->manipulators.first; manipulator; manipulator = manipulator->next) {
+		if ((manipulator->flag & WM_MANIPULATOR_HIDDEN) == 0) {
+			if ((mgroup->type->is_3d && manipulator->render_3d_intersection) ||
+			    (!mgroup->type->is_3d && manipulator->intersect))
+			{
+				BLI_addhead(listbase, BLI_genericNodeN(manipulator));
+			}
+		}
+	}
+}
+
 void wm_manipulatorgroup_ensure_initialized(wmManipulatorGroup *mgroup, const bContext *C)
 {
 	/* prepare for first draw */
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c
index 9a4c568..dab7d61 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulatormap.c
@@ -330,8 +330,8 @@ static void manipulator_find_active_3D_loop(const bContext *C, ListBase *visible
 	}
 }
 
-static int manipulator_find_highlighted_3D_intern(
-        ListBase *visible_manipulators, const bContext *C, const wmEvent *event,
+static int manipulator_find_intersected_3D_intern(
+        ListBase *visible_manipulators, const bContext *C, const int co[2],
         const float hotspot)
 {
 	ScrArea *sa = CTX_wm_area(C);
@@ -346,10 +346,10 @@ static int manipulator_find_highlighted_3D_intern(
 	extern void view3d_winmatrix_set(ARegion *ar, View3D *v3d, rctf *rect);
 
 
-	rect.xmin = event->mval[0] - hotspot;
-	rect.xmax = event->mval[0] + hotspot;
-	rect.ymin = event->mval[1] - hotspot;
-	rect.ymax = event->mval[1] + hotspot;
+	rect.xmin = co[0] - hotspot;
+	rect.xmax = co[0] + hotspot;
+	rect.ymin = co[1] - hotspot;
+	rect.ymax = co[1] + hotspot;
 
 	selrect = rect;
 
@@ -377,58 +377,69 @@ static int manipulator_find_highlighted_3D_intern(
 	return hits > 0 ? buffer[3] : -1;
 }
 
-static void manipulators_prepare_visible_3D(wmManipulatorMap *mmap, ListBase *visible_manipulators, bContext *C)
-{
-	wmManipulator *manipulator;
-
-	for (wmManipulatorGroup *mgroup = mmap->manipulator_groups.first; mgroup; mgroup = mgroup->next) {
-		if (mgroup->type->is_3d &&
-		    (!mgroup->type->poll || mgroup->type->poll(C, mgroup->type)))
-		{
-			for (manipulator = mgroup->manipulators.first; manipulator; manipulator = manipulator->next) {
-				if (manipulator->render_3d_intersection && (manipulator->flag & WM_MANIPULATOR_HIDDEN) == 0) {
-					BLI_addhead(visible_manipulators, BLI_genericNodeN(manipulator));
-				}
-			}
-		}
-	}
-}
-
-wmManipulator *wm_manipulatormap_find_highlighted_3D(
-        wmManipulatorMap *mmap, bContext *C, const wmEvent *event,
+/**
+ * Try to find a 3D manipulator at screen-space coordinate \a co. Uses OpenGL picking.
+ */
+static wmManipulator *manipulator_find_intersected_3D(
+        bContext *C, const int co[2], ListBase *visible_manipulators,
         unsigned char *part)
 {
 	wmManipulator *result = NULL;
-	ListBase visible_manipulators = {0};
 	const float hotspot = 14.0f;
 	int ret;
 
-	manipulators_prepare_visible_3D(mmap, &visible_manipulators, C);
-
 	*part = 0;
 	/* set up view matrices */
 	view3d_operator_needs_opengl(C);
 
-	ret = manipulator_find_highlighted_3D_intern(&visible_manipulators, C, event, 0.5f * hotspot);
+	ret = manipulator_find_intersected_3D_intern(visible_manipulators, C, co, 0.5f * hotspot);
 
 	if (ret != -1) {
 		LinkData *link;
 		int retsec;
-		retsec = manipulator_find_highlighted_3D_intern(&visible_manipulators, C, event, 0.2f * hotspot);
+		retsec = manipulator_find_intersected_3D_intern(visible_manipulators, C, co, 0.2f * hotspot);
 
 		if (retsec != -1)
 			ret = retsec;
 
-		link = BLI_findlink(&visible_manipulators, ret >> 8);
+		link = BLI_findlink(visible_manipulators, ret >> 8);
 		*part = ret & 255;
 		result = link->data;
 	}
 
-	BLI_freelistN(&visible_manipulators);
-
 	return result;
 }
 
+/**
+ * Try to find a manipulator under the mouse position. 2D intersections have priority over
+ * 3D ones (could check for smallest screen-space distance but not needed right now).
+ */
+wmManipulator *wm_manipulatormap_find_highlighted_manipulator(
+        wmManipulatorMap *mmap, bContext *C, const wmEvent *event,
+        unsigned char *part)
+{
+	wmManipulator *manipulator = NULL;
+	ListBase visible_3d_manipulators;
+
+	for (wmManipulatorGroup *mgroup = mmap->manipulator_groups.first; mgroup; mgroup = mgroup->next) {
+		if (wm_manipulatorgroup_is_visible(mgroup, C)) {
+			if (mgroup->type->is_3d) {
+				wm_manipulatorgroup_intersectable_manipulators_to_list(mgroup, &visible_3d_manipulators);
+			}
+			else if ((manipulator = wm_manipulatorgroup_find_intersected_mainpulator(mgroup, C, event, part))) {
+				break;
+			}
+		}
+	}
+
+	if (!BLI_listbase_is_empty(&visible_3d_manipulators)) {
+		manipulator = manipulator_find_intersected_3D(C, event->mval, &visible_3d_manipulators, part);
+		BLI_freelistN(&visible_3d_manipulators);
+	}
+
+	return manipulator;
+}
+
 void WM_manipulatormaps_add_handlers(ARegion *ar, wmManipulatorMap *mmap)
 {
 	wmEventHandler *handler = MEM_callocN(sizeof(wmEventHandler), "manipulator handler");
@@ -611,29 +622,6 @@ void wm_manipulatormap_handler_context(bContext *C, wmEventHandler *handler)
 	}
 }
 
-
-wmManipulator *wm_manipulatormap_find_highlighted_manipulator(
-        wmManipulatorMap *mmap, bContext *C, const wmEvent *event,
-        unsigned char *part)
-{
-	wmManipulator *manipulator;
-
-	for (wmManipulatorGroup *mgroup = mmap->manipulator_groups.first; mgroup; mgroup = mgroup->next) {
-		if (!mgroup->type->is_3d &&
-		    (!mgroup->type->poll || mgroup->type->poll(C, mgroup->type)))
-		{
-			for (manipulator = mgroup->manipulators.first; manipulator; manipulator = manipulator->next) {
-				if (manipulator->intersect) {
-					if ((*part = manipulator->intersect(C, event, manipulator)))
-						return manipulator;
-				}
-			}
-		}
-	}
-
-	return NULL;
-}
-
 bool WM_manipulatormap_cursor_set(const wmManipulatorMap *mmap, wmWindow *win)
 {
 	for (; mmap; mmap = mmap->next) {
diff --git a/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h b/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h
index fbdca91..cff0bca 100644
--- a/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h
+++ b/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h
@@ -75,9 +75,6 @@ void wm_manipulatormaps_handled_modal_update(
         const struct wmOperatorType *ot);
 void wm_manipulatormap_handler_context(bContext *C, struct wmEventHandler *handler);
 
-struct wmManipulator *wm_manipulatormap_find_highlighted_3D(
-        struct wmManipulatorMap *mmap, bContext *C,
-        const struct wmEvent *event, unsigned char *part);
 struct wmManipulator *wm_manipulatormap_find_highlighted_manipulator(
         struct wmManipulatorMap *mmap, bContext *C,
         const struct

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list