Blender  V3.3
eyedropper_depth.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2009 Blender Foundation. All rights reserved. */
3 
13 #include "MEM_guardedalloc.h"
14 
15 #include "DNA_camera_types.h"
16 #include "DNA_object_types.h"
17 #include "DNA_screen_types.h"
18 #include "DNA_space_types.h"
19 #include "DNA_view3d_types.h"
20 
21 #include "BLI_math_vector.h"
22 #include "BLI_string.h"
23 
24 #include "BKE_context.h"
25 #include "BKE_lib_id.h"
26 #include "BKE_screen.h"
27 #include "BKE_unit.h"
28 
29 #include "RNA_access.h"
30 #include "RNA_prototypes.h"
31 
32 #include "UI_interface.h"
33 
34 #include "WM_api.h"
35 #include "WM_types.h"
36 
37 #include "ED_screen.h"
38 #include "ED_space_api.h"
39 #include "ED_view3d.h"
40 
41 #include "eyedropper_intern.h"
42 #include "interface_intern.h"
43 
47 typedef struct DepthDropper {
50  bool is_undo;
51 
52  bool is_set;
53  float init_depth; /* For resetting on cancel. */
54 
55  bool accum_start; /* Has mouse been pressed. */
56  float accum_depth;
57  int accum_tot;
58 
61  int name_pos[2];
62  char name[200];
64 
65 static void depthdropper_draw_cb(const struct bContext *UNUSED(C),
66  ARegion *UNUSED(region),
67  void *arg)
68 {
69  DepthDropper *ddr = arg;
71 }
72 
74 {
75  int index_dummy;
76 
77  SpaceType *st;
78  ARegionType *art;
79 
82 
83  DepthDropper *ddr = MEM_callocN(sizeof(DepthDropper), __func__);
84 
85  uiBut *but = UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy);
86 
87  /* fallback to the active camera's dof */
88  if (ddr->prop == NULL) {
90  if (rv3d && rv3d->persp == RV3D_CAMOB) {
91  View3D *v3d = CTX_wm_view3d(C);
92  if (v3d->camera && v3d->camera->data &&
94  Camera *camera = (Camera *)v3d->camera->data;
95  RNA_pointer_create(&camera->id, &RNA_CameraDOFSettings, &camera->dof, &ddr->ptr);
96  ddr->prop = RNA_struct_find_property(&ddr->ptr, "focus_distance");
97  ddr->is_undo = true;
98  }
99  }
100  }
101  else {
103  }
104 
105  if ((ddr->ptr.data == NULL) || (ddr->prop == NULL) ||
106  (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
107  (RNA_property_type(ddr->prop) != PROP_FLOAT)) {
108  MEM_freeN(ddr);
109  return false;
110  }
111  op->customdata = ddr;
112 
113  ddr->art = art;
116  ddr->init_depth = RNA_property_float_get(&ddr->ptr, ddr->prop);
117 
118  return true;
119 }
120 
122 {
124 
125  if (op->customdata) {
126  DepthDropper *ddr = (DepthDropper *)op->customdata;
127 
128  if (ddr->art) {
130  }
131 
132  MEM_freeN(op->customdata);
133 
134  op->customdata = NULL;
135  }
136 }
137 
138 /* *** depthdropper id helper functions *** */
143  DepthDropper *ddr,
144  const int m_xy[2],
145  float *r_depth)
146 {
147  /* we could use some clever */
148  bScreen *screen = CTX_wm_screen(C);
151 
152  ScrArea *area_prev = CTX_wm_area(C);
153  ARegion *region_prev = CTX_wm_region(C);
154 
155  ddr->name[0] = '\0';
156 
157  if (area) {
158  if (area->spacetype == SPACE_VIEW3D) {
160  if (region) {
162  View3D *v3d = area->spacedata.first;
163  RegionView3D *rv3d = region->regiondata;
164  /* weak, we could pass in some reference point */
165  const float *view_co = (v3d->camera && rv3d->persp == RV3D_CAMOB) ? v3d->camera->obmat[3] :
166  rv3d->viewinv[3];
167  const int mval[2] = {m_xy[0] - region->winrct.xmin, m_xy[1] - region->winrct.ymin};
168  copy_v2_v2_int(ddr->name_pos, mval);
169 
170  float co[3];
171 
173  CTX_wm_region_set(C, region);
174 
175  /* Unfortunately it's necessary to always draw otherwise we leave stale text. */
176  ED_region_tag_redraw(region);
177 
179 
180  if (ED_view3d_autodist(depsgraph, region, v3d, mval, co, true, NULL)) {
181  const float mval_center_fl[2] = {(float)region->winx / 2, (float)region->winy / 2};
182  float co_align[3];
183 
184  /* quick way to get view-center aligned point */
185  ED_view3d_win_to_3d(v3d, region, co, mval_center_fl, co_align);
186 
187  *r_depth = len_v3v3(view_co, co_align);
188 
190  sizeof(ddr->name),
191  (double)*r_depth,
192  4,
194  &scene->unit,
195  false);
196  }
197  else {
198  BLI_strncpy(ddr->name, "Nothing under cursor", sizeof(ddr->name));
199  }
200  }
201  }
202  }
203 
204  CTX_wm_area_set(C, area_prev);
205  CTX_wm_region_set(C, region_prev);
206 }
207 
208 /* sets the sample depth RGB, maintaining A */
209 static void depthdropper_depth_set(bContext *C, DepthDropper *ddr, const float depth)
210 {
211  RNA_property_float_set(&ddr->ptr, ddr->prop, depth);
212  ddr->is_set = true;
213  RNA_property_update(C, &ddr->ptr, ddr->prop);
214 }
215 
216 /* set sample from accumulated values */
218 {
219  float depth = ddr->accum_depth;
220  if (ddr->accum_tot) {
221  depth /= (float)ddr->accum_tot;
222  }
223  depthdropper_depth_set(C, ddr, depth);
224 }
225 
226 /* single point sample & set */
227 static void depthdropper_depth_sample(bContext *C, DepthDropper *ddr, const int m_xy[2])
228 {
229  float depth = -1.0f;
230  if (depth != -1.0f) {
231  depthdropper_depth_sample_pt(C, ddr, m_xy, &depth);
232  depthdropper_depth_set(C, ddr, depth);
233  }
234 }
235 
236 static void depthdropper_depth_sample_accum(bContext *C, DepthDropper *ddr, const int m_xy[2])
237 {
238  float depth = -1.0f;
239  depthdropper_depth_sample_pt(C, ddr, m_xy, &depth);
240  if (depth != -1.0f) {
241  ddr->accum_depth += depth;
242  ddr->accum_tot++;
243  }
244 }
245 
247 {
248  DepthDropper *ddr = op->customdata;
249  if (ddr->is_set) {
250  depthdropper_depth_set(C, ddr, ddr->init_depth);
251  }
252  depthdropper_exit(C, op);
253 }
254 
255 /* main modal status check */
256 static int depthdropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
257 {
258  DepthDropper *ddr = (DepthDropper *)op->customdata;
259 
260  /* handle modal keymap */
261  if (event->type == EVT_MODAL_MAP) {
262  switch (event->val) {
263  case EYE_MODAL_CANCEL:
264  depthdropper_cancel(C, op);
265  return OPERATOR_CANCELLED;
267  const bool is_undo = ddr->is_undo;
268  if (ddr->accum_tot == 0) {
269  depthdropper_depth_sample(C, ddr, event->xy);
270  }
271  else {
273  }
274  depthdropper_exit(C, op);
275  /* Could support finished & undo-skip. */
276  return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
277  }
279  /* enable accum and make first sample */
280  ddr->accum_start = true;
281  depthdropper_depth_sample_accum(C, ddr, event->xy);
282  break;
284  ddr->accum_tot = 0;
285  ddr->accum_depth = 0.0f;
286  depthdropper_depth_sample_accum(C, ddr, event->xy);
288  break;
289  }
290  }
291  else if (event->type == MOUSEMOVE) {
292  if (ddr->accum_start) {
293  /* button is pressed so keep sampling */
294  depthdropper_depth_sample_accum(C, ddr, event->xy);
296  }
297  }
298 
299  return OPERATOR_RUNNING_MODAL;
300 }
301 
302 /* Modal Operator init */
303 static int depthdropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
304 {
305  /* init */
306  if (depthdropper_init(C, op)) {
307  wmWindow *win = CTX_wm_window(C);
308  /* Workaround for de-activating the button clearing the cursor, see T76794 */
311 
312  /* add temp handler */
314 
315  return OPERATOR_RUNNING_MODAL;
316  }
317  return OPERATOR_CANCELLED;
318 }
319 
320 /* Repeat operator */
322 {
323  /* init */
324  if (depthdropper_init(C, op)) {
325  /* cleanup */
326  depthdropper_exit(C, op);
327 
328  return OPERATOR_FINISHED;
329  }
330  return OPERATOR_CANCELLED;
331 }
332 
334 {
335  PointerRNA ptr;
336  PropertyRNA *prop;
337  int index_dummy;
338  uiBut *but;
339 
340  /* check if there's an active button taking depth value */
341  if ((CTX_wm_window(C) != NULL) &&
342  (but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) &&
343  (but->type == UI_BTYPE_NUM) && (prop != NULL)) {
344  if ((RNA_property_type(prop) == PROP_FLOAT) &&
346  (RNA_property_array_check(prop) == false)) {
347  return true;
348  }
349  }
350  else {
352  if (rv3d && rv3d->persp == RV3D_CAMOB) {
353  View3D *v3d = CTX_wm_view3d(C);
354  if (v3d->camera && v3d->camera->data &&
356  return true;
357  }
358  }
359  }
360 
361  return false;
362 }
363 
365 {
366  /* identifiers */
367  ot->name = "Eyedropper Depth";
368  ot->idname = "UI_OT_eyedropper_depth";
369  ot->description = "Sample depth from the 3D view";
370 
371  /* api callbacks */
377 
378  /* flags */
380 
381  /* properties */
382 }
typedef float(TangentPoint)[2]
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
void CTX_wm_region_set(bContext *C, struct ARegion *region)
Definition: context.c:1009
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:784
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:733
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1505
void CTX_wm_area_set(bContext *C, struct ScrArea *area)
Definition: context.c:997
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:793
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
bool BKE_id_is_editable(const struct Main *bmain, const struct ID *id)
struct ScrArea struct ScrArea * BKE_screen_find_area_xy(struct bScreen *screen, int spacetype, const int xy[2]) ATTR_NONNULL(1
struct ARegion * BKE_area_find_region_xy(struct ScrArea *area, int regiontype, const int xy[2]) ATTR_NONNULL(3)
Definition: screen.c:898
struct SpaceType * BKE_spacetype_from_id(int spaceid)
Definition: screen.c:353
struct ARegionType * BKE_regiontype_from_id(const struct SpaceType *st, int regionid)
@ B_UNIT_LENGTH
Definition: BKE_unit.h:101
size_t BKE_unit_value_as_string(char *str, int len_max, double value, int prec, int type, const struct UnitSettings *settings, bool pad)
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
#define UNUSED(x)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
Object is a sort of wrapper for general info.
@ RGN_TYPE_WINDOW
@ SPACE_VIEW3D
#define SPACE_TYPE_ANY
#define RV3D_CAMOB
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:655
void * ED_region_draw_cb_activate(struct ARegionType *art, void(*draw)(const struct bContext *, struct ARegion *, void *), void *customdata, int type)
Definition: spacetypes.c:226
#define REGION_DRAW_POST_PIXEL
Definition: ED_space_api.h:63
bool ED_region_draw_cb_exit(struct ARegionType *art, void *handle)
Definition: spacetypes.c:241
void ED_view3d_win_to_3d(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
void view3d_operator_needs_opengl(const struct bContext *C)
bool ED_view3d_autodist(struct Depsgraph *depsgraph, struct ARegion *region, struct View3D *v3d, const int mval[2], float mouse_worldloc[3], bool alphaoverride, const float fallback_depth_pt[3])
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
@ PROP_FLOAT
Definition: RNA_types.h:61
@ PROP_UNIT_LENGTH
Definition: RNA_types.h:71
#define C
Definition: RandGen.cpp:25
@ UI_BUT_UNDO
Definition: UI_interface.h:205
void UI_context_active_but_clear(struct bContext *C, struct wmWindow *win, struct ARegion *region)
uiBut * UI_context_active_but_prop_get(const struct bContext *C, struct PointerRNA *r_ptr, struct PropertyRNA **r_prop, int *r_index)
@ UI_BTYPE_NUM
Definition: UI_interface.h:337
bool UI_but_flag_is_set(uiBut *but, int flag)
Definition: interface.cc:5868
@ OPTYPE_INTERNAL
Definition: WM_types.h:168
@ OPTYPE_BLOCKING
Definition: WM_types.h:150
@ OPTYPE_UNDO
Definition: WM_types.h:148
Scene scene
const Depsgraph * depsgraph
static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, const int m_xy[2], float *r_depth)
get the ID from the screen.
static void depthdropper_draw_cb(const struct bContext *UNUSED(C), ARegion *UNUSED(region), void *arg)
static void depthdropper_depth_set_accum(bContext *C, DepthDropper *ddr)
static int depthdropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
void UI_OT_eyedropper_depth(wmOperatorType *ot)
static void depthdropper_depth_sample(bContext *C, DepthDropper *ddr, const int m_xy[2])
static int depthdropper_exec(bContext *C, wmOperator *op)
static void depthdropper_depth_sample_accum(bContext *C, DepthDropper *ddr, const int m_xy[2])
static int depthdropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void depthdropper_exit(bContext *C, wmOperator *op)
static void depthdropper_cancel(bContext *C, wmOperator *op)
static bool depthdropper_poll(bContext *C)
static void depthdropper_depth_set(bContext *C, DepthDropper *ddr, const float depth)
struct DepthDropper DepthDropper
static int depthdropper_init(bContext *C, wmOperator *op)
@ EYE_MODAL_SAMPLE_BEGIN
@ EYE_MODAL_SAMPLE_RESET
@ EYE_MODAL_CANCEL
@ EYE_MODAL_SAMPLE_CONFIRM
void eyedropper_draw_cursor_text_region(const int xy[2], const char *name)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
static void area(int d1, int d2, int e1, int e2, float weights[2])
static const pxr::TfToken st("st", pxr::TfToken::Immortal)
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2767
bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:1966
bool RNA_property_array_check(PropertyRNA *prop)
Definition: rna_access.c:1080
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
PropertyType RNA_property_type(PropertyRNA *prop)
Definition: rna_access.c:1010
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2138
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
Definition: rna_access.c:2790
PropertySubType RNA_property_subtype(PropertyRNA *prop)
Definition: rna_access.c:1015
void * regiondata
PointerRNA ptr
char name[200]
PropertyRNA * prop
ARegionType * art
void * draw_handle_pixel
float obmat[4][4]
void * data
void * data
Definition: RNA_types.h:38
float viewinv[4][4]
struct UnitSettings unit
struct Object * camera
int ymin
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
eButType type
short val
Definition: WM_types.h:680
int xy[2]
Definition: WM_types.h:682
short type
Definition: WM_types.h:678
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:935
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:927
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
void WM_cursor_modal_set(wmWindow *win, int val)
Definition: wm_cursors.c:191
void WM_cursor_modal_restore(wmWindow *win)
Definition: wm_cursors.c:200
@ WM_CURSOR_EYEDROPPER
Definition: wm_cursors.h:35
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
@ EVT_MODAL_MAP
@ MOUSEMOVE
PointerRNA * ptr
Definition: wm_files.c:3480
wmOperatorType * ot
Definition: wm_files.c:3479