Blender V4.3
draw_view_c.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2016 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include "DNA_brush_types.h"
12#include "DNA_screen_types.h"
13#include "DNA_userdef_types.h"
14#include "DNA_view3d_types.h"
15
16#include "ED_screen.hh"
17#include "ED_util.hh"
18#include "ED_view3d.hh"
19
20#include "GPU_debug.hh"
21#include "GPU_immediate.hh"
22#include "GPU_matrix.hh"
23#include "GPU_shader.hh"
24
25#include "UI_resources.hh"
26#include "UI_view2d.hh"
27
28#include "WM_types.hh"
29
30#include "BLI_math_rotation.h"
31
32#include "BKE_global.hh"
33#include "BKE_object.hh"
34#include "BKE_paint.hh"
35
36#include "view3d_intern.hh"
37
38#include "draw_manager_c.hh"
39
40/* ******************** region info ***************** */
41
43{
44 GPU_debug_group_begin("RegionInfo");
45 const DRWContextState *draw_ctx = DRW_context_state_get();
46 ARegion *region = draw_ctx->region;
47
49
50 view3d_draw_region_info(draw_ctx->evil_C, region);
52}
53
54/* **************************** 3D Cursor ******************************** */
55
56static bool is_cursor_visible(const DRWContextState *draw_ctx, Scene *scene, ViewLayer *view_layer)
57{
58 if (G.moving & G_TRANSFORM_CURSOR) {
59 return true;
60 }
61
62 View3D *v3d = draw_ctx->v3d;
64 return false;
65 }
66
67 /* don't draw cursor in paint modes, but with a few exceptions */
68 if ((draw_ctx->object_mode & (OB_MODE_ALL_PAINT | OB_MODE_SCULPT_CURVES)) != 0) {
69 /* exception: object is in weight paint and has deforming armature in pose mode */
70 if (draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) {
71 if (BKE_object_pose_armature_get(draw_ctx->obact) != nullptr) {
72 return true;
73 }
74 }
75 /* exception: object in texture paint mode, clone brush, use_clone_layer disabled */
76 else if (draw_ctx->object_mode & OB_MODE_TEXTURE_PAINT) {
77 const Paint *paint = BKE_paint_get_active(scene, view_layer);
78 const Brush *brush = (paint) ? BKE_paint_brush_for_read(paint) : nullptr;
79
80 if (brush && brush->image_brush_type == IMAGE_PAINT_BRUSH_TYPE_CLONE) {
81 if ((scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) == 0) {
82 return true;
83 }
84 }
85 }
86
87 /* no exception met? then don't draw cursor! */
88 return false;
89 }
91 /* grease pencil hide always in some modes */
92 return false;
93 }
94
95 return true;
96}
97
99{
100 const DRWContextState *draw_ctx = DRW_context_state_get();
101 ARegion *region = draw_ctx->region;
102 Scene *scene = draw_ctx->scene;
103 ViewLayer *view_layer = draw_ctx->view_layer;
104 if (!is_cursor_visible(draw_ctx, scene, view_layer)) {
105 return;
106 }
107
108 GPU_color_mask(true, true, true, true);
109 GPU_depth_mask(false);
111
112 /* Get cursor data into quaternion form */
113 const View3DCursor *cursor = &scene->cursor;
114
115 int co[2];
117 region, cursor->location, co, V3D_PROJ_TEST_NOP | V3D_PROJ_TEST_CLIP_NEAR) !=
119 {
120 return;
121 }
122
123 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
124
125 blender::math::Quaternion cursor_quat = cursor->rotation();
126
127 /* Draw nice Anti Aliased cursor. */
128 GPU_line_width(1.0f);
130 GPU_line_smooth(true);
131
132 float eps = 1e-5f;
133 rv3d->viewquat[0] = -rv3d->viewquat[0];
134 bool is_aligned = compare_v4v4(&cursor_quat.w, rv3d->viewquat, eps);
135 if (is_aligned == false) {
136 float tquat[4];
137 rotation_between_quats_to_quat(tquat, rv3d->viewquat, &cursor_quat.w);
138 is_aligned = tquat[0] - eps < -1.0f;
139 }
140 rv3d->viewquat[0] = -rv3d->viewquat[0];
141
142 /* Draw lines */
143 if (is_aligned == false) {
148
149 const float scale = ED_view3d_pixel_size_no_ui_scale(rv3d, cursor->location) * U.widget_unit;
150
151#define CURSOR_VERT(axis_vec, axis, fac) \
152 immVertex3f(pos, \
153 cursor->location[0] + axis_vec[0] * (fac), \
154 cursor->location[1] + axis_vec[1] * (fac), \
155 cursor->location[2] + axis_vec[2] * (fac))
156
157#define CURSOR_EDGE(axis_vec, axis, sign) \
158 { \
159 CURSOR_VERT(axis_vec, axis, sign 1.0f); \
160 CURSOR_VERT(axis_vec, axis, sign 0.25f); \
161 } \
162 ((void)0)
163
164 for (int axis = 0; axis < 3; axis++) {
165 float axis_vec[3] = {0};
166 axis_vec[axis] = scale;
167 mul_qt_v3(&cursor_quat.w, axis_vec);
168 CURSOR_EDGE(axis_vec, axis, +);
169 CURSOR_EDGE(axis_vec, axis, -);
170 }
171
172#undef CURSOR_VERT
173#undef CURSOR_EDGE
174
175 immEnd();
177 }
178
179 float original_proj[4][4];
180 GPU_matrix_projection_get(original_proj);
182 ED_region_pixelspace(region);
183 GPU_matrix_translate_2f(co[0] + 0.5f, co[1] + 0.5f);
184 GPU_matrix_scale_2f(U.widget_unit, U.widget_unit);
185
186 blender::gpu::Batch *cursor_batch = DRW_cache_cursor_get(is_aligned);
188 GPU_batch_set_shader(cursor_batch, shader);
189
190 GPU_batch_draw(cursor_batch);
191
193 GPU_line_smooth(false);
195 GPU_matrix_projection_set(original_proj);
196}
197
198/* -------------------------------------------------------------------- */
202static bool is_cursor_visible_2d(const DRWContextState *draw_ctx)
203{
204 SpaceInfo *space_data = (SpaceInfo *)draw_ctx->space_data;
205 if (space_data == nullptr) {
206 return false;
207 }
208 if (space_data->spacetype != SPACE_IMAGE) {
209 return false;
210 }
211 SpaceImage *sima = (SpaceImage *)space_data;
212 switch (sima->mode) {
213 case SI_MODE_VIEW:
214 return false;
215 break;
216 case SI_MODE_PAINT:
217 return false;
218 break;
219 case SI_MODE_MASK:
220 break;
221 case SI_MODE_UV:
222 break;
223 }
224 return (sima->overlay.flag & SI_OVERLAY_SHOW_OVERLAYS) != 0;
225}
226
227/* -------------------------------------------------------------------- */
231void DRW_draw_cursor_2d_ex(const ARegion *region, const float cursor[2])
232{
233 int co[2];
234 UI_view2d_view_to_region(&region->v2d, cursor[0], cursor[1], &co[0], &co[1]);
235
236 /* Draw nice Anti Aliased cursor. */
237 GPU_line_width(1.0f);
239 GPU_line_smooth(true);
240
241 /* Draw lines */
242 float original_proj[4][4];
243 GPU_matrix_projection_get(original_proj);
245 ED_region_pixelspace(region);
246 GPU_matrix_translate_2f(co[0] + 0.5f, co[1] + 0.5f);
247 GPU_matrix_scale_2f(U.widget_unit, U.widget_unit);
248
249 blender::gpu::Batch *cursor_batch = DRW_cache_cursor_get(true);
250
252 GPU_batch_set_shader(cursor_batch, shader);
253
254 GPU_batch_draw(cursor_batch);
255
257 GPU_line_smooth(false);
259 GPU_matrix_projection_set(original_proj);
260}
261
265{
266 const DRWContextState *draw_ctx = DRW_context_state_get();
267 ARegion *region = draw_ctx->region;
268
269 GPU_color_mask(true, true, true, true);
270 GPU_depth_mask(false);
272
273 if (is_cursor_visible_2d(draw_ctx)) {
274 const SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
275 DRW_draw_cursor_2d_ex(region, sima->cursor);
276 }
277}
278
281/* **************************** 3D Gizmo ******************************** */
282
284{
285 const DRWContextState *draw_ctx = DRW_context_state_get();
286 ARegion *region = draw_ctx->region;
287
288 /* draw depth culled gizmos - gizmos need to be updated *after* view matrix was set up */
289 /* TODO: depth culling gizmos is not yet supported, just drawing _3D here, should
290 * later become _IN_SCENE (and draw _3D separate) */
291 WM_gizmomap_draw(region->gizmo_map, draw_ctx->evil_C, WM_GIZMOMAP_DRAWSTEP_3D);
292}
293
295{
296 const DRWContextState *draw_ctx = DRW_context_state_get();
297 ARegion *region = draw_ctx->region;
298
299 WM_gizmomap_draw(region->gizmo_map, draw_ctx->evil_C, WM_GIZMOMAP_DRAWSTEP_2D);
300
301 GPU_depth_mask(true);
302}
@ G_TRANSFORM_CURSOR
General operations, lookup, etc. for blender objects.
Object * BKE_object_pose_armature_get(Object *ob)
Paint * BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
Definition paint.cc:438
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Definition paint.cc:654
void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4])
void mul_qt_v3(const float q[4], float r[3])
MINLINE bool compare_v4v4(const float v1[4], const float v2[4], float limit) ATTR_WARN_UNUSED_RESULT
unsigned int uint
@ IMAGE_PAINT_BRUSH_TYPE_CLONE
#define OB_MODE_ALL_PAINT
@ OB_MODE_WEIGHT_PAINT
@ OB_MODE_SCULPT_CURVES
@ OB_MODE_TEXTURE_PAINT
@ OB_MODE_WEIGHT_GREASE_PENCIL
@ IMAGEPAINT_PROJECT_LAYER_CLONE
@ SI_OVERLAY_SHOW_OVERLAYS
@ SPACE_IMAGE
@ SI_MODE_PAINT
@ SI_MODE_VIEW
@ SI_MODE_MASK
@ SI_MODE_UV
@ V3D_OVERLAY_HIDE_CURSOR
@ V3D_HIDE_OVERLAYS
void ED_region_pixelspace(const ARegion *region)
Definition area.cc:121
@ V3D_PROJ_TEST_CLIP_NEAR
Definition ED_view3d.hh:269
@ V3D_PROJ_TEST_NOP
Definition ED_view3d.hh:266
float ED_view3d_pixel_size_no_ui_scale(const RegionView3D *rv3d, const float co[3])
@ V3D_PROJ_RET_OK
Definition ED_view3d.hh:243
eV3DProjStatus ED_view3d_project_int_global(const ARegion *region, const float co[3], int r_co[2], eV3DProjTest flag)
void GPU_batch_set_shader(blender::gpu::Batch *batch, GPUShader *shader)
void GPU_batch_draw(blender::gpu::Batch *batch)
void GPU_debug_group_end()
Definition gpu_debug.cc:33
void GPU_debug_group_begin(const char *name)
Definition gpu_debug.cc:22
void immEnd()
void immUnbindProgram()
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immUniformThemeColor3(int color_id)
GPUVertFormat * immVertexFormat()
void immBegin(GPUPrimType, uint vertex_len)
void GPU_matrix_scale_2f(float x, float y)
void GPU_matrix_push()
#define GPU_matrix_projection_get(x)
#define GPU_matrix_projection_set(x)
void GPU_matrix_pop()
void GPU_matrix_translate_2f(float x, float y)
@ GPU_PRIM_LINES
GPUShader * GPU_shader_get_builtin_shader(eGPUBuiltinShader shader)
@ GPU_SHADER_3D_UNIFORM_COLOR
@ GPU_SHADER_3D_FLAT_COLOR
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA
Definition GPU_state.hh:87
void GPU_blend(eGPUBlend blend)
Definition gpu_state.cc:42
void GPU_line_width(float width)
Definition gpu_state.cc:161
void GPU_line_smooth(bool enable)
Definition gpu_state.cc:78
void GPU_depth_mask(bool depth)
Definition gpu_state.cc:110
void GPU_color_mask(bool r, bool g, bool b, bool a)
Definition gpu_state.cc:98
@ GPU_DEPTH_NONE
Definition GPU_state.hh:108
void GPU_depth_test(eGPUDepthTest test)
Definition gpu_state.cc:68
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
@ TH_VIEW_OVERLAY
void UI_view2d_view_to_region(const View2D *v2d, float x, float y, int *r_region_x, int *r_region_y) ATTR_NONNULL()
Definition view2d.cc:1718
@ WM_GIZMOMAP_DRAWSTEP_3D
@ WM_GIZMOMAP_DRAWSTEP_2D
struct GPUShader GPUShader
unsigned int U
Definition btGjkEpa3.h:78
blender::gpu::Batch * DRW_cache_cursor_get(bool crosshair_lines)
const DRWContextState * DRW_context_state_get()
void DRW_draw_cursor()
void DRW_draw_gizmo_2d()
void DRW_draw_region_info()
void DRW_draw_cursor_2d_ex(const ARegion *region, const float cursor[2])
static bool is_cursor_visible(const DRWContextState *draw_ctx, Scene *scene, ViewLayer *view_layer)
void DRW_draw_cursor_2d()
#define CURSOR_EDGE(axis_vec, axis, sign)
void DRW_draw_gizmo_3d()
static bool is_cursor_visible_2d(const DRWContextState *draw_ctx)
#define G(x, y, z)
const btScalar eps
Definition poly34.cpp:11
char image_brush_type
ViewLayer * view_layer
eObjectMode object_mode
ARegion * region
const bContext * evil_C
SpaceLink * space_data
SpaceImageOverlay overlay
View3DOverlay overlay
void view3d_draw_region_info(const bContext *C, ARegion *region)
void WM_gizmomap_draw(wmGizmoMap *gzmap, const bContext *C, const eWM_GizmoFlagMapDrawStep drawstep)