Blender  V3.3
overlay_grid.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2019 Blender Foundation. */
3 
8 #include "DRW_render.h"
9 
10 #include "DNA_camera_types.h"
11 #include "DNA_screen_types.h"
12 
13 #include "DEG_depsgraph_query.h"
14 
15 #include "ED_image.h"
16 #include "ED_view3d.h"
17 
18 #include "UI_resources.h"
19 
20 #include "overlay_private.h"
21 
23 
25 {
26  OVERLAY_PrivateData *pd = vedata->stl->pd;
27  OVERLAY_GridData *grid = &pd->grid_data;
28  const DRWContextState *draw_ctx = DRW_context_state_get();
29 
30  float *grid_axes = pd->grid.grid_axes;
31  float *zplane_axes = pd->grid.zplane_axes;
32  float grid_steps[SI_GRID_STEPS_LEN] = {
33  0.001f, 0.01f, 0.1f, 1.0f, 10.0f, 100.0f, 1000.0f, 10000.0f};
34  OVERLAY_GridBits grid_flag = 0, zneg_flag = 0, zpos_flag = 0;
35  grid->line_size = max_ff(0.0f, U.pixelsize - 1.0f) * 0.5f;
36  /* Default, nothing is drawn. */
37  pd->grid.grid_flag = pd->grid.zneg_flag = pd->grid.zpos_flag = 0;
38 
39  if (pd->space_type == SPACE_IMAGE) {
40  SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
41  View2D *v2d = &draw_ctx->region->v2d;
42 
43  /* Only UV Edit mode has the various Overlay options for now. */
44  const bool is_uv_edit = sima->mode == SI_MODE_UV;
45 
46  const bool background_enabled = is_uv_edit ? (!pd->hide_overlays &&
47  (sima->overlay.flag &
49  true;
50  if (background_enabled) {
51  grid_flag = GRID_BACK | PLANE_IMAGE;
52  }
53 
54  const bool draw_grid = is_uv_edit || !ED_space_image_has_buffer(sima);
55  if (background_enabled && draw_grid) {
56  grid_flag |= SHOW_GRID;
57  if (is_uv_edit && (sima->flag & SI_CUSTOM_GRID) != 0) {
58  grid_flag |= CUSTOM_GRID;
59  }
60  }
61 
62  grid->distance = 1.0f;
63  copy_v3_fl3(grid->size, 1.0f, 1.0f, 1.0f);
64  if (is_uv_edit) {
65  grid->size[0] = (float)sima->tile_grid_shape[0];
66  grid->size[1] = (float)sima->tile_grid_shape[1];
67  }
68 
71  }
72  else {
73  /* SPACE_VIEW3D */
74  View3D *v3d = draw_ctx->v3d;
75  Scene *scene = draw_ctx->scene;
76  RegionView3D *rv3d = draw_ctx->rv3d;
77 
78  const bool show_axis_x = (pd->v3d_gridflag & V3D_SHOW_X) != 0;
79  const bool show_axis_y = (pd->v3d_gridflag & V3D_SHOW_Y) != 0;
80  const bool show_axis_z = (pd->v3d_gridflag & V3D_SHOW_Z) != 0;
81  const bool show_floor = (pd->v3d_gridflag & V3D_SHOW_FLOOR) != 0;
82  const bool show_ortho_grid = (pd->v3d_gridflag & V3D_SHOW_ORTHO_GRID) != 0;
83 
86  return;
87  }
88 
89  float viewinv[4][4], wininv[4][4];
90  float viewmat[4][4], winmat[4][4];
91  DRW_view_winmat_get(NULL, winmat, false);
92  DRW_view_winmat_get(NULL, wininv, true);
93  DRW_view_viewmat_get(NULL, viewmat, false);
94  DRW_view_viewmat_get(NULL, viewinv, true);
95 
96  /* If perspective view or non-axis aligned view. */
97  if (winmat[3][3] == 0.0f || rv3d->view == RV3D_VIEW_USER) {
98  if (show_axis_x) {
99  grid_flag |= PLANE_XY | SHOW_AXIS_X;
100  }
101  if (show_axis_y) {
102  grid_flag |= PLANE_XY | SHOW_AXIS_Y;
103  }
104  if (show_floor) {
105  grid_flag |= PLANE_XY | SHOW_GRID;
106  }
107  }
108  else {
109  if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) {
110  grid_flag = PLANE_YZ | SHOW_AXIS_Y | SHOW_AXIS_Z | SHOW_GRID | GRID_BACK;
111  }
112  else if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
113  grid_flag = PLANE_XY | SHOW_AXIS_X | SHOW_AXIS_Y | SHOW_GRID | GRID_BACK;
114  }
115  else if (show_ortho_grid && ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
116  grid_flag = PLANE_XZ | SHOW_AXIS_X | SHOW_AXIS_Z | SHOW_GRID | GRID_BACK;
117  }
118  }
119 
120  grid_axes[0] = (float)((grid_flag & (PLANE_XZ | PLANE_XY)) != 0);
121  grid_axes[1] = (float)((grid_flag & (PLANE_YZ | PLANE_XY)) != 0);
122  grid_axes[2] = (float)((grid_flag & (PLANE_YZ | PLANE_XZ)) != 0);
123 
124  /* Z axis if needed */
125  if (((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) && show_axis_z) {
126  zpos_flag = SHOW_AXIS_Z;
127 
128  float zvec[3], campos[3];
129  negate_v3_v3(zvec, viewinv[2]);
130  copy_v3_v3(campos, viewinv[3]);
131 
132  /* z axis : chose the most facing plane */
133  if (fabsf(zvec[0]) < fabsf(zvec[1])) {
134  zpos_flag |= PLANE_XZ;
135  }
136  else {
137  zpos_flag |= PLANE_YZ;
138  }
139 
140  zneg_flag = zpos_flag;
141 
142  /* Persp : If camera is below floor plane, we switch clipping
143  * Ortho : If eye vector is looking up, we switch clipping */
144  if (((winmat[3][3] == 0.0f) && (campos[2] > 0.0f)) ||
145  ((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) {
146  zpos_flag |= CLIP_ZPOS;
147  zneg_flag |= CLIP_ZNEG;
148  }
149  else {
150  zpos_flag |= CLIP_ZNEG;
151  zneg_flag |= CLIP_ZPOS;
152  }
153 
154  zplane_axes[0] = (float)((zpos_flag & (PLANE_XZ | PLANE_XY)) != 0);
155  zplane_axes[1] = (float)((zpos_flag & (PLANE_YZ | PLANE_XY)) != 0);
156  zplane_axes[2] = (float)((zpos_flag & (PLANE_YZ | PLANE_XZ)) != 0);
157  }
158  else {
159  zneg_flag = zpos_flag = CLIP_ZNEG | CLIP_ZPOS;
160  }
161 
162  float dist;
163  if (rv3d->persp == RV3D_CAMOB && v3d->camera && v3d->camera->type == OB_CAMERA) {
164  Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera);
165  dist = ((Camera *)(camera_object->data))->clip_end;
166  grid_flag |= GRID_CAMERA;
167  zneg_flag |= GRID_CAMERA;
168  zpos_flag |= GRID_CAMERA;
169  }
170  else {
171  dist = v3d->clip_end;
172  }
173 
174  if (winmat[3][3] == 0.0f) {
175  copy_v3_fl(grid->size, dist);
176  }
177  else {
178  float viewdist = 1.0f / min_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1]));
179  copy_v3_fl(grid->size, viewdist * dist);
180  }
181 
182  grid->distance = dist / 2.0f;
183 
184  ED_view3d_grid_steps(scene, v3d, rv3d, grid_steps);
185 
186  if ((v3d->flag & (V3D_XR_SESSION_SURFACE | V3D_XR_SESSION_MIRROR)) != 0) {
187  /* The calculations for the grid parameters assume that the view matrix has no scale
188  * component, which may not be correct if the user is "shrunk" or "enlarged" by zooming in or
189  * out. Therefore, we need to compensate the values here. */
190  /* Assumption is uniform scaling (all column vectors are of same length). */
191  float viewinvscale = len_v3(viewinv[0]);
192  grid->distance *= viewinvscale;
193  }
194  }
195 
196  /* Convert to UBO alignment. */
197  for (int i = 0; i < SI_GRID_STEPS_LEN; i++) {
198  grid->steps[i][0] = grid_steps[i];
199  }
200  pd->grid.grid_flag = grid_flag;
201  pd->grid.zneg_flag = zneg_flag;
202  pd->grid.zpos_flag = zpos_flag;
203 }
204 
206 {
207  OVERLAY_StorageList *stl = ved->stl;
208  OVERLAY_PrivateData *pd = stl->pd;
209  OVERLAY_GridData *grid = &pd->grid_data;
210 
211  OVERLAY_PassList *psl = ved->psl;
213 
214  psl->grid_ps = NULL;
215 
216  if ((pd->grid.grid_flag == 0 && pd->grid.zpos_flag == 0) || !DRW_state_is_fbo()) {
217  return;
218  }
219 
220  if (ved->instance->grid_ubo == NULL) {
222  }
224 
227 
228  if (pd->space_type == SPACE_IMAGE) {
229  float mat[4][4];
230 
231  /* Add quad background. */
234  float color_back[4];
236  DRW_shgroup_uniform_vec4_copy(grp, "color", color_back);
237  DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
238  unit_m4(mat);
239  mat[0][0] = grid->size[0];
240  mat[1][1] = grid->size[1];
241  mat[2][2] = grid->size[2];
243  }
244 
245  {
246  DRWShadingGroup *grp;
247  struct GPUBatch *geom = DRW_cache_grid_get();
248 
250 
251  /* Create 3 quads to render ordered transparency Z axis */
252  grp = DRW_shgroup_create(sh, psl->grid_ps);
253  DRW_shgroup_uniform_block(grp, "grid_buf", ved->instance->grid_ubo);
254  DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
255  DRW_shgroup_uniform_texture_ref(grp, "depth_tx", &dtxl->depth);
256 
257  DRW_shgroup_uniform_int_copy(grp, "grid_flag", pd->grid.zneg_flag);
258  DRW_shgroup_uniform_vec3_copy(grp, "plane_axes", pd->grid.zplane_axes);
259  if (pd->grid.zneg_flag & SHOW_AXIS_Z) {
260  DRW_shgroup_call(grp, geom, NULL);
261  }
262 
263  grp = DRW_shgroup_create_sub(grp);
264  DRW_shgroup_uniform_int_copy(grp, "grid_flag", pd->grid.grid_flag);
265  DRW_shgroup_uniform_vec3_copy(grp, "plane_axes", pd->grid.grid_axes);
266  if (pd->grid.grid_flag) {
267  DRW_shgroup_call(grp, geom, NULL);
268  }
269 
270  grp = DRW_shgroup_create_sub(grp);
271  DRW_shgroup_uniform_int_copy(grp, "grid_flag", pd->grid.zpos_flag);
272  DRW_shgroup_uniform_vec3_copy(grp, "plane_axes", pd->grid.zplane_axes);
273  if (pd->grid.zpos_flag & SHOW_AXIS_Z) {
274  DRW_shgroup_call(grp, geom, NULL);
275  }
276  }
277 
278  if (pd->space_type == SPACE_IMAGE) {
279  float theme_color[4];
280  UI_GetThemeColorShade4fv(TH_BACK, 60, theme_color);
281  srgb_to_linearrgb_v4(theme_color, theme_color);
282 
283  float mat[4][4];
284  /* add wire border */
287  DRW_shgroup_uniform_vec4_copy(grp, "color", theme_color);
288  unit_m4(mat);
289  for (int x = 0; x < grid->size[0]; x++) {
290  mat[3][0] = x;
291  for (int y = 0; y < grid->size[1]; y++) {
292  mat[3][1] = y;
294  }
295  }
296  }
297 }
298 
300 {
301  OVERLAY_PassList *psl = vedata->psl;
302 
303  if (psl->grid_ps) {
304  DRW_draw_pass(psl->grid_ps);
305  }
306 }
typedef float(TangentPoint)[2]
#define BLI_STATIC_ASSERT(a, msg)
Definition: BLI_assert.h:83
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4])
void unit_m4(float m[4][4])
Definition: rct.c:1090
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
void interp_v4_v4v4(float r[4], const float a[4], const float b[4], float t)
Definition: math_vector.c:38
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
#define ELEM(...)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ OB_CAMERA
@ SI_CUSTOM_GRID
@ SI_OVERLAY_SHOW_GRID_BACKGROUND
@ SPACE_IMAGE
#define SI_GRID_STEPS_LEN
@ SI_MODE_UV
#define V3D_SHOW_ORTHO_GRID
#define RV3D_CAMOB
#define RV3D_VIEW_BACK
#define V3D_XR_SESSION_MIRROR
#define V3D_SHOW_Z
#define RV3D_VIEW_BOTTOM
#define V3D_SHOW_Y
#define RV3D_VIEW_LEFT
#define RV3D_VIEW_RIGHT
#define V3D_SHOW_X
#define RV3D_VIEW_TOP
#define V3D_XR_SESSION_SURFACE
#define RV3D_VIEW_USER
#define RV3D_VIEW_FRONT
#define V3D_SHOW_FLOOR
#define RV3D_ORTHO
DRWState
Definition: DRW_render.h:298
@ DRW_STATE_BLEND_ALPHA
Definition: DRW_render.h:328
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:303
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:690
#define DRW_shgroup_uniform_block(shgroup, name, ubo)
Definition: DRW_render.h:651
#define DRW_shgroup_call_obmat(shgroup, geom, obmat)
Definition: DRW_render.h:420
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:414
void ED_space_image_grid_steps(struct SpaceImage *sima, float grid_steps[SI_GRID_STEPS_LEN], int grid_dimension)
Definition: image_draw.c:587
bool ED_space_image_has_buffer(struct SpaceImage *sima)
Definition: image_edit.c:188
float ED_space_image_zoom_level(const struct View2D *v2d, int grid_dimension)
void ED_view3d_grid_steps(const struct Scene *scene, struct View3D *v3d, struct RegionView3D *rv3d, float r_grid_steps[8])
GPUBatch
Definition: GPU_batch.h:78
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
struct GPUShader GPUShader
Definition: GPU_shader.h:20
#define GPU_uniformbuf_create(size)
void GPU_uniformbuf_update(GPUUniformBuf *ubo, const void *data)
@ TH_BACK
Definition: UI_resources.h:39
void UI_GetThemeColorShade4fv(int colorid, int offset, float col[4])
Definition: resources.c:1331
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
SyclQueue void void size_t num_bytes void
GPUBatch * DRW_cache_quad_get(void)
Definition: draw_cache.c:389
GPUBatch * DRW_cache_grid_get(void)
Definition: draw_cache.c:429
GPUBatch * DRW_cache_quad_wires_get(void)
Definition: draw_cache.c:409
struct DRW_Global G_draw
Definition: draw_common.c:32
bool DRW_state_is_fbo(void)
const DRWContextState * DRW_context_state_get(void)
DefaultTextureList * DRW_viewport_texture_list_get(void)
Definition: draw_manager.c:638
void DRW_shgroup_uniform_vec3_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_view_winmat_get(const DRWView *view, float mat[4][4], bool inverse)
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
DRWShadingGroup * DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
void DRW_shgroup_uniform_vec4_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse)
void DRW_draw_pass(DRWPass *pass)
const int state
ccl_gpu_kernel_postfix ccl_global float int int int int sh
#define fabsf(x)
Definition: metal/compat.h:219
void OVERLAY_grid_draw(OVERLAY_Data *vedata)
Definition: overlay_grid.c:299
void OVERLAY_grid_init(OVERLAY_Data *vedata)
Definition: overlay_grid.c:24
void OVERLAY_grid_cache_init(OVERLAY_Data *ved)
Definition: overlay_grid.c:205
GPUShader * OVERLAY_shader_grid_background(void)
GPUShader * OVERLAY_shader_grid(void)
GPUShader * OVERLAY_shader_grid_image(void)
OVERLAY_GridBits
@ SHOW_AXIS_X
@ PLANE_IMAGE
@ SHOW_AXIS_Z
@ SHOW_AXIS_Y
@ CUSTOM_GRID
@ GRID_CAMERA
#define OVERLAY_GRID_STEPS_LEN
struct Scene * scene
Definition: DRW_render.h:979
struct SpaceLink * space_data
Definition: DRW_render.h:977
struct Depsgraph * depsgraph
Definition: DRW_render.h:987
struct View3D * v3d
Definition: DRW_render.h:976
struct ARegion * region
Definition: DRW_render.h:974
struct RegionView3D * rv3d
Definition: DRW_render.h:975
GlobalsUboStorage block
Definition: draw_common.h:127
struct GPUUniformBuf * block_ubo
Definition: draw_common.h:129
struct GPUTexture * depth
OVERLAY_PassList * psl
OVERLAY_StorageList * stl
OVERLAY_Instance * instance
float4 steps[OVERLAY_GRID_STEPS_LEN]
GPUUniformBuf * grid_ubo
OVERLAY_GridBits grid_flag
OVERLAY_GridBits zneg_flag
struct OVERLAY_PrivateData::@248 grid
OVERLAY_GridData grid_data
OVERLAY_GridBits zpos_flag
struct OVERLAY_PrivateData * pd
void * data
int tile_grid_shape[2]
SpaceImageOverlay overlay
float clip_end
struct Object * camera