[Bf-blender-cvs] [3d503ea] master: UI: Eyedropper for view-depth

Campbell Barton noreply at git.blender.org
Tue Jan 13 22:47:39 CET 2015


Commit: 3d503ea8d6fa8ff397565b90cb53a4e211aef847
Author: Campbell Barton
Date:   Wed Jan 14 08:01:40 2015 +1100
Branches: master
https://developer.blender.org/rB3d503ea8d6fa8ff397565b90cb53a4e211aef847

UI: Eyedropper for view-depth

Currently this is mainly useful for picking camera DOF depth.

- EKey over a distance field prompts you to pick a depth from the camera.
- WKey (Specials menu) to pick from the 3D view (when the active camera's selected).

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

M	release/scripts/startup/bl_ui/space_view3d.py
M	source/blender/editors/interface/interface_eyedropper.c
M	source/blender/editors/interface/interface_handlers.c
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_ops.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 3ee5e17..1db3aa0 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1169,12 +1169,16 @@ class VIEW3D_MT_object_specials(Menu):
                 props.header_text = "Camera Lens Scale: %.3f"
 
             if not obj.data.dof_object:
-                #layout.label(text="Test Has DOF obj");
-                props = layout.operator("wm.context_modal_mouse", text="DOF Distance")
-                props.data_path_iter = "selected_editable_objects"
-                props.data_path_item = "data.dof_distance"
-                props.input_scale = 0.02
-                props.header_text = "DOF Distance: %.3f"
+                view = context.space_data
+                if view and view.camera == obj and view.region_3d.view_perspective == 'CAMERA':
+                    props = layout.operator("ui.eyedropper_depth", text="DOF Distance (Pick)")
+                else:
+                    props = layout.operator("wm.context_modal_mouse", text="DOF Distance")
+                    props.data_path_iter = "selected_editable_objects"
+                    props.data_path_item = "data.dof_distance"
+                    props.input_scale = 0.02
+                    props.header_text = "DOF Distance: %.3f"
+                del view
 
         if obj.type in {'CURVE', 'FONT'}:
             layout.operator_context = 'INVOKE_REGION_WIN'
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index 1294da3..d7a4720 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -40,6 +40,7 @@
 #include "BKE_screen.h"
 #include "BKE_report.h"
 #include "BKE_idcode.h"
+#include "BKE_unit.h"
 
 #include "RNA_access.h"
 
@@ -64,6 +65,42 @@
 #include "ED_screen.h"
 #include "ED_view3d.h"
 
+/* -------------------------------------------------------------------- */
+/* Utility Functions
+ */
+/** \name Generic Shared Functions
+ * \{ */
+
+static void eyedropper_draw_cursor_text(const struct bContext *C, ARegion *ar, const char *name)
+{
+	int width;
+	wmWindow *win = CTX_wm_window(C);
+	int x = win->eventstate->x;
+	int y = win->eventstate->y;
+
+	if ((name[0] == '\0') ||
+	    (BLI_rcti_isect_pt(&ar->winrct, x, y) == false))
+	{
+		return;
+	}
+
+	width = UI_fontstyle_string_width(name);
+	x = x - ar->winrct.xmin;
+	y = y - ar->winrct.ymin;
+
+	y += 20;
+
+	glColor4ub(0, 0, 0, 50);
+
+	UI_draw_roundbox_corner_set(UI_CNR_ALL | UI_RB_ALPHA);
+	UI_draw_roundbox(x, y, x + width + 8, y + 15, 4);
+
+	glColor4ub(255, 255, 255, 255);
+	UI_draw_string(x + 4, y + 4, name);
+}
+
+/** \} */
+
 
 /* -------------------------------------------------------------------- */
 /* Eyedropper
@@ -369,31 +406,7 @@ typedef struct DataDropper {
 static void datadropper_draw_cb(const struct bContext *C, ARegion *ar, void *arg)
 {
 	DataDropper *ddr = arg;
-	int width;
-	const char *name = ddr->name;
-	wmWindow *win = CTX_wm_window(C);
-	int x = win->eventstate->x;
-	int y = win->eventstate->y;
-
-	if ((name[0] == '\0') ||
-	    (BLI_rcti_isect_pt(&ar->winrct, x, y) == false))
-	{
-		return;
-	}
-
-	width = UI_fontstyle_string_width(name);
-	x = x - ar->winrct.xmin;
-	y = y - ar->winrct.ymin;
-
-	y += 20;
-
-	glColor4ub(0, 0, 0, 50);
-
-	UI_draw_roundbox_corner_set(UI_CNR_ALL | UI_RB_ALPHA);
-	UI_draw_roundbox(x, y, x + width + 8, y + 15, 4);
-
-	glColor4ub(255, 255, 255, 255);
-	UI_draw_string(x + 4, y + 4, name);
+	eyedropper_draw_cursor_text(C, ar, ddr->name);
 }
 
 
@@ -643,3 +656,309 @@ void UI_OT_eyedropper_id(wmOperatorType *ot)
 }
 
 /** \} */
+
+/* -------------------------------------------------------------------- */
+/* Depth Dropper
+ *
+ * note: depthdropper is only internal name to avoid confusion in this file
+ */
+
+/** \name Eyedropper (Depth)
+ * \{ */
+
+typedef struct DepthDropper {
+	PointerRNA ptr;
+	PropertyRNA *prop;
+
+	bool  accum_start; /* has mouse been presed */
+	float accum_depth;
+	int   accum_tot;
+
+	ARegionType *art;
+	void *draw_handle_pixel;
+	char name[200];
+} DepthDropper;
+
+
+static void depthdropper_draw_cb(const struct bContext *C, ARegion *ar, void *arg)
+{
+	DepthDropper *ddr = arg;
+	eyedropper_draw_cursor_text(C, ar, ddr->name);
+}
+
+
+static int depthdropper_init(bContext *C, wmOperator *op)
+{
+	DepthDropper *ddr;
+	int index_dummy;
+
+	SpaceType *st;
+	ARegionType *art;
+
+	st = BKE_spacetype_from_id(SPACE_VIEW3D);
+	art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW);
+
+	op->customdata = ddr = MEM_callocN(sizeof(DepthDropper), "DepthDropper");
+
+	UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy);
+
+	/* fallback to the active camera's dof */
+	if (ddr->prop == NULL) {
+		RegionView3D *rv3d = CTX_wm_region_view3d(C);
+		if (rv3d->persp == RV3D_CAMOB) {
+			View3D *v3d = CTX_wm_view3d(C);
+			if (v3d->camera && v3d->camera->data && (((ID *)v3d->camera->data)->lib == NULL)) {
+				RNA_id_pointer_create(v3d->camera->data, &ddr->ptr);
+				ddr->prop = RNA_struct_find_property(&ddr->ptr, "dof_distance");
+			}
+		}
+	}
+
+	if ((ddr->ptr.data == NULL) ||
+	    (ddr->prop == NULL) ||
+	    (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
+	    (RNA_property_type(ddr->prop) != PROP_FLOAT))
+	{
+		return false;
+	}
+
+	ddr->art = art;
+	ddr->draw_handle_pixel = ED_region_draw_cb_activate(art, depthdropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL);
+
+	return true;
+}
+
+static void depthdropper_exit(bContext *C, wmOperator *op)
+{
+	WM_cursor_modal_restore(CTX_wm_window(C));
+
+	if (op->customdata) {
+		DepthDropper *ddr = (DepthDropper *)op->customdata;
+
+		if (ddr->art) {
+			ED_region_draw_cb_exit(ddr->art, ddr->draw_handle_pixel);
+		}
+
+		MEM_freeN(op->customdata);
+
+		op->customdata = NULL;
+	}
+}
+
+static void depthdropper_cancel(bContext *C, wmOperator *op)
+{
+	depthdropper_exit(C, op);
+}
+
+/* *** depthdropper id helper functions *** */
+/**
+ * \brief get the ID from the screen.
+ *
+ */
+static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx, int my, float *r_depth)
+{
+
+	/* we could use some clever */
+	wmWindow *win = CTX_wm_window(C);
+	ScrArea *sa;
+	Scene *scene = win->screen->scene;
+	UnitSettings *unit = &scene->unit;
+	const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0;
+
+	ScrArea *area_prev = CTX_wm_area(C);
+	ARegion *ar_prev = CTX_wm_region(C);
+
+	ddr->name[0] = '\0';
+
+	for (sa = win->screen->areabase.first; sa; sa = sa->next) {
+		if (BLI_rcti_isect_pt(&sa->totrct, mx, my)) {
+			if (sa->spacetype == SPACE_VIEW3D) {
+				ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
+				if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) {
+					View3D *v3d = sa->spacedata.first;
+					RegionView3D *rv3d = ar->regiondata;
+					/* weak, we could pass in some reference point */
+					const float *view_co = v3d->camera ? v3d->camera->obmat[3] : rv3d->viewinv[3];
+					const int mval[2] = {
+					    mx - ar->winrct.xmin,
+					    my - ar->winrct.ymin};
+					float co[3];
+
+					CTX_wm_area_set(C, sa);
+					CTX_wm_region_set(C, ar);
+
+					/* grr, always draw else we leave stale text */
+					ED_region_tag_redraw(ar);
+
+					view3d_operator_needs_opengl(C);
+
+					if (ED_view3d_autodist(scene, ar, v3d, mval, co, true, NULL)) {
+						const float mval_center_fl[2] = {
+						    (float)ar->winx / 2,
+						    (float)ar->winy / 2};
+						float co_align[3];
+
+						/* quick way to get view-center aligned point */
+						ED_view3d_win_to_3d(ar, co, mval_center_fl, co_align);
+
+						*r_depth = len_v3v3(view_co, co_align);
+
+						bUnit_AsString(ddr->name, sizeof(ddr->name),
+						               (double)*r_depth,
+						               4, unit->system, B_UNIT_LENGTH, do_split, false);
+					}
+					else {
+						BLI_strncpy(ddr->name, "Nothing under cursor", sizeof(ddr->name));
+					}
+					break;
+				}
+			}
+		}
+	}
+
+	CTX_wm_area_set(C, area_prev);
+	CTX_wm_region_set(C, ar_prev);
+}
+
+/* sets the sample depth RGB, maintaining A */
+static void depthdropper_depth_set(bContext *C, DepthDropper *ddr, const float depth)
+{
+	RNA_property_float_set(&ddr->ptr, ddr->prop, depth);
+	RNA_property_update(C, &ddr->ptr, ddr->prop);
+}
+
+/* set sample from accumulated values */
+static void depthdropper_depth_set_accum(bContext *C, DepthDropper *ddr)
+{
+	float depth;
+	depth = ddr->accum_depth * 1.0f / (float)ddr->accum_tot;
+	depthdropper_depth_set(C, ddr, depth);
+}
+
+/* single point sample & set */
+static void depthdropper_depth_sample(bContext *C, DepthDropper *ddr, int mx, int my)
+{
+	float depth = -1.0f;
+	if (depth != -1.0f) {
+		depthdropper_depth_sample_pt(C, ddr, mx, my, &depth);
+		depthdropper_depth_set(C, ddr, depth);
+	}
+}
+
+static void depthdropper_depth_sample_accum(bContext *C, DepthDropper *ddr, int mx, int my)
+{
+	float depth = -1.0f;
+	depthdropper_depth_sample_pt(C, ddr, mx, my, &depth);
+	if (depth != -1.0f) {
+		ddr->accum_depth += depth;
+		ddr->accum_tot++;
+	}
+}
+
+/* main modal status check */
+static int depthdropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+	DepthDropper *ddr = (DepthDropper *)op->customdata;
+
+	switch (event->type) {
+		case ESCKEY:
+		case RIGHTMOUSE:
+			depthdropper_cancel(C, op);
+			return OPERATOR_CANCELLED;
+		case LEFTMOUSE:
+			if (event->val == KM_RELEASE) {
+				if (ddr->accum_tot == 0) {
+					depthdropper_depth_sample(C, ddr, event->x, event->y);
+				}
+				else {
+					depthdropper_depth_set_accum(C, ddr);
+				}
+				depthdropper_exit(C, op);
+				return OPERATOR_FINISHED;
+			}
+			else if (event->val == KM_PRESS) {
+				/* enable accum and make first sample */
+				ddr->accum_start = true;
+				depthdropper_depth_sample_accum(C, ddr, event->x, event->y);
+			}
+			break;
+		case MOUSEMOVE:
+			if (ddr->accum_start) {
+				/* button is pressed so keep sampling */
+				depthdropper_depth_sample_accum(C, ddr, event->x, event->y);
+				depthdropper_depth_set_accum(C, ddr);
+			}
+			break;
+		case SPACEKEY:
+			if (event->val == KM_RELEASE) {
+				ddr->accum_tot = 0;
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list