Blender V4.3
draw_common.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "DRW_render.hh"
10
11#include "GPU_matrix.hh"
12#include "GPU_shader.hh"
13#include "GPU_texture.hh"
14
15#include "UI_resources.hh"
16
17#include "BLI_index_range.hh"
18#include "BLI_math_color.h"
19
20#include "BKE_colorband.hh"
21#include "BKE_global.hh"
22#include "BKE_object.hh"
23
24#include "draw_common_c.hh"
25
26#if 0
27# define UI_COLOR_RGB_FROM_U8(r, g, b, v4) \
28 ARRAY_SET_ITEMS(v4, float(r) / 255.0f, float(g) / 255.0f, float(b) / 255.0f, 1.0)
29#endif
30#define UI_COLOR_RGBA_FROM_U8(r, g, b, a, v4) \
31 ARRAY_SET_ITEMS(v4, float(r) / 255.0f, float(g) / 255.0f, float(b) / 255.0f, float(a) / 255.0f)
32
38
39static bool weight_ramp_custom = false;
41
42static GPUTexture *DRW_create_weight_colorramp_texture();
43
44using namespace blender;
45
47{
49
51 if (ctx->rv3d != nullptr) {
52 int plane_len = (RV3D_LOCK_FLAGS(ctx->rv3d) & RV3D_BOXCLIP) ? 4 : 6;
53 for (auto i : IndexRange(plane_len)) {
54 gb->clip_planes[i] = float4(ctx->rv3d->clip[i]);
55 }
56 if (plane_len < 6) {
57 for (auto i : IndexRange(plane_len, 6 - plane_len)) {
58 /* Fill other planes with same valid planes. Avoid changing. */
59 gb->clip_planes[i] = gb->clip_planes[plane_len - 1];
60 }
61 }
62 }
63
68 UI_COLOR_RGBA_FROM_U8(0x88, 0xFF, 0xFF, 155, gb->color_library_select);
69 UI_COLOR_RGBA_FROM_U8(0x55, 0xCC, 0xCC, 155, gb->color_library);
79 UI_COLOR_RGBA_FROM_U8(0xB0, 0x00, 0xB0, 0xFF, gb->color_vertex_missing_data);
85
107 gb->fresnel_mix_edit = ((U.gpu_flag & USER_GPU_FLAG_FRESNEL_EDIT) == 0) ? 0.0f : 1.0f;
109
110 /* Custom median color to slightly affect the edit mesh colors. */
114 blender::float3{0.3333f, 0.3333f, 0.3333f})); /* Desaturate */
115
116#ifdef WITH_FREESTYLE
119#else
122#endif
123
126
127 /* Bone colors */
136 UI_COLOR_RGBA_FROM_U8(255, 255, 0, 80, gb->color_bone_pose_ik);
141 copy_v4_fl4(gb->color_bone_ik_line, 0.8f, 0.8f, 0.0f, 1.0f);
142 copy_v4_fl4(gb->color_bone_ik_line_no_target, 0.8f, 0.5f, 0.2f, 1.0f);
143 copy_v4_fl4(gb->color_bone_ik_line_spline, 0.8f, 0.8f, 0.2f, 1.0f);
144
145 /* Curve */
161
165
166 /* Meta-ball. */
167 UI_COLOR_RGBA_FROM_U8(0xA0, 0x30, 0x30, 0xFF, gb->color_mball_radius);
168 UI_COLOR_RGBA_FROM_U8(0xF0, 0xA0, 0xA0, 0xFF, gb->color_mball_radius_select);
169 UI_COLOR_RGBA_FROM_U8(0x30, 0xA0, 0x30, 0xFF, gb->color_mball_stiffness);
170 UI_COLOR_RGBA_FROM_U8(0xA0, 0xF0, 0xA0, 0xFF, gb->color_mball_stiffness_select);
171
172 /* Grid */
174 /* Emphasize division lines lighter instead of darker, if background is darker than grid. */
176 TH_GRID,
177 (gb->color_grid[0] + gb->color_grid[1] + gb->color_grid[2] + 0.12f >
178 gb->color_background[0] + gb->color_background[1] + gb->color_background[2]) ?
179 20 :
180 -10,
182 /* Grid Axis */
186
190
191 /* UV colors */
193
194 gb->size_pixel = U.pixelsize;
195 gb->size_object_center = (UI_GetThemeValuef(TH_OBCENTER_DIA) + 1.0f) * U.pixelsize;
196 gb->size_light_center = (UI_GetThemeValuef(TH_OBCENTER_DIA) + 1.5f) * U.pixelsize;
197 gb->size_light_circle = U.pixelsize * 9.0f;
198 gb->size_light_circle_shadow = gb->size_light_circle + U.pixelsize * 3.0f;
199
200 /* M_SQRT2 to be at least the same size of the old square */
201 gb->size_vertex = U.pixelsize *
202 max_ff(1.0f, UI_GetThemeValuef(TH_VERTEX_SIZE) * float(M_SQRT2) / 2.0f);
205 gb->size_edge = U.pixelsize * max_ff(1.0f, UI_GetThemeValuef(TH_EDGE_WIDTH)) / 2.0f;
206 gb->size_edge_fix = U.pixelsize * (0.5f + 2.0f * (1.0f * (gb->size_edge * float(M_SQRT1_2))));
207
209
211 copy_v2_v2(&gb->size_viewport[2], &gb->size_viewport[0]);
212 invert_v2(&gb->size_viewport[2]);
213
214 /* Color management. */
215 {
216 float *color = gb->UBO_FIRST_COLOR;
217 do {
218 /* TODO: more accurate transform. */
219 srgb_to_linearrgb_v4(color, color);
220 color += 4;
221 } while (color <= gb->UBO_LAST_COLOR);
222 }
223
224 if (G_draw.block_ubo == nullptr) {
226 sizeof(GlobalsUboStorage), gb, "GlobalsUboStorage");
227 }
228
230
231 if (!G_draw.ramp) {
232 ColorBand ramp = {0};
233 float *colors;
234 int col_size;
235
236 ramp.tot = 3;
237 ramp.data[0].a = 1.0f;
238 ramp.data[0].b = 1.0f;
239 ramp.data[0].pos = 0.0f;
240 ramp.data[1].a = 1.0f;
241 ramp.data[1].g = 1.0f;
242 ramp.data[1].pos = 0.5f;
243 ramp.data[2].a = 1.0f;
244 ramp.data[2].r = 1.0f;
245 ramp.data[2].pos = 1.0f;
246
247 BKE_colorband_evaluate_table_rgba(&ramp, &colors, &col_size);
248
250 "ramp", col_size, 1, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, colors);
251
252 MEM_freeN(colors);
253 }
254
255 /* Weight Painting color ramp texture */
256 bool user_weight_ramp = (U.flag & USER_CUSTOM_RANGE) != 0;
257
258 if (weight_ramp_custom != user_weight_ramp ||
259 (user_weight_ramp && memcmp(&weight_ramp_copy, &U.coba_weight, sizeof(ColorBand)) != 0))
260 {
262 }
263
264 if (G_draw.weight_ramp == nullptr) {
265 weight_ramp_custom = user_weight_ramp;
266 memcpy(&weight_ramp_copy, &U.coba_weight, sizeof(ColorBand));
267
269 }
270}
271
272/* ********************************* SHGROUP ************************************* */
273
275
277 const RegionView3D *rv3d,
278 float offset)
279{
280 /* Create view with depth offset */
281 float viewmat[4][4], winmat[4][4];
282 DRW_view_viewmat_get(parent_view, viewmat, false);
283 DRW_view_winmat_get(parent_view, winmat, false);
284
285 float viewdist = rv3d->dist;
286
287 /* special exception for ortho camera (`viewdist` isn't used for perspective cameras). */
288 if (rv3d->persp == RV3D_CAMOB && rv3d->is_persp == false) {
289 viewdist = 1.0f / max_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1]));
290 }
291
292 winmat[3][2] -= GPU_polygon_offset_calc(winmat, viewdist, offset);
293
294 return DRW_view_create_sub(parent_view, viewmat, winmat);
295}
296
297/* ******************************************** COLOR UTILS ************************************ */
298
299int DRW_object_wire_theme_get(Object *ob, ViewLayer *view_layer, float **r_color)
300{
301 /* TODO: FINISH. */
302
303 const DRWContextState *draw_ctx = DRW_context_state_get();
304 const bool is_edit = (draw_ctx->object_mode & OB_MODE_EDIT) && (ob->mode & OB_MODE_EDIT);
305 BKE_view_layer_synced_ensure(draw_ctx->scene, view_layer);
306 const Base *base = BKE_view_layer_active_base_get(view_layer);
307 const bool active = base && ((ob->base_flag & BASE_FROM_DUPLI) ?
308 (DRW_object_get_dupli_parent(ob) == base->object) :
309 (base->object == ob));
310
311 /* confusing logic here, there are 2 methods of setting the color
312 * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id.
313 *
314 * NOTE: no theme yet for 'colindex'. */
315 int theme_id = is_edit ? TH_WIRE_EDIT : TH_WIRE;
316
317 if (is_edit) {
318 /* fallback to TH_WIRE */
319 }
320 else if (((G.moving & G_TRANSFORM_OBJ) != 0) && ((ob->base_flag & BASE_SELECTED) != 0)) {
321 theme_id = TH_TRANSFORM;
322 }
323 else {
324 /* Sets the 'theme_id' or fallback to wire */
325 if ((ob->base_flag & BASE_SELECTED) != 0) {
326 theme_id = (active) ? TH_ACTIVE : TH_SELECT;
327 }
328 else {
329 switch (ob->type) {
330 case OB_LAMP:
331 theme_id = TH_LIGHT;
332 break;
333 case OB_SPEAKER:
334 theme_id = TH_SPEAKER;
335 break;
336 case OB_CAMERA:
337 theme_id = TH_CAMERA;
338 break;
339 case OB_EMPTY:
340 theme_id = TH_EMPTY;
341 break;
342 case OB_LIGHTPROBE:
343 /* TODO: add light-probe color. */
344 theme_id = TH_EMPTY;
345 break;
346 default:
347 /* fallback to TH_WIRE */
348 break;
349 }
350 }
351 }
352
353 if (r_color != nullptr) {
354 if (UNLIKELY(ob->base_flag & BASE_FROM_SET)) {
355 *r_color = G_draw.block.color_wire;
356 }
357 else {
358 switch (theme_id) {
359 case TH_WIRE_EDIT:
360 *r_color = G_draw.block.color_wire_edit;
361 break;
362 case TH_ACTIVE:
363 *r_color = G_draw.block.color_active;
364 break;
365 case TH_SELECT:
366 *r_color = G_draw.block.color_select;
367 break;
368 case TH_TRANSFORM:
369 *r_color = G_draw.block.color_transform;
370 break;
371 case TH_SPEAKER:
372 *r_color = G_draw.block.color_speaker;
373 break;
374 case TH_CAMERA:
375 *r_color = G_draw.block.color_camera;
376 break;
377 case TH_EMPTY:
378 *r_color = G_draw.block.color_empty;
379 break;
380 case TH_LIGHT:
381 *r_color = G_draw.block.color_light;
382 break;
383 default:
384 *r_color = G_draw.block.color_wire;
385 break;
386 }
387 }
388 }
389
390 return theme_id;
391}
392
394{
395 /* XXX This is very stupid, better find something more general. */
396
397 static float colors[11][4];
398 float *ret;
399
400 switch (theme_id) {
401 case TH_WIRE_EDIT:
402 ret = colors[0];
403 break;
404 case TH_ACTIVE:
405 ret = colors[1];
406 break;
407 case TH_SELECT:
408 ret = colors[2];
409 break;
410 case TH_TRANSFORM:
411 ret = colors[5];
412 break;
413 case TH_SPEAKER:
414 ret = colors[6];
415 break;
416 case TH_CAMERA:
417 ret = colors[7];
418 break;
419 case TH_EMPTY:
420 ret = colors[8];
421 break;
422 case TH_LIGHT:
423 ret = colors[9];
424 break;
425 default:
426 ret = colors[10];
427 break;
428 }
429
430 UI_GetThemeColorBlendShade4fv(theme_id, TH_BACK, 0.5, 0, ret);
431
432 return ret;
433}
434
435bool DRW_object_is_flat(Object *ob, int *r_axis)
436{
437 float dim[3];
438
439 if (!ELEM(ob->type,
440 OB_MESH,
442 OB_SURF,
443 OB_FONT,
444 OB_CURVES,
446 OB_VOLUME))
447 {
448 /* Non-meshes object cannot be considered as flat. */
449 return false;
450 }
451
453 if (dim[0] == 0.0f) {
454 *r_axis = 0;
455 return true;
456 }
457 if (dim[1] == 0.0f) {
458 *r_axis = 1;
459 return true;
460 }
461 if (dim[2] == 0.0f) {
462 *r_axis = 2;
463 return true;
464 }
465 return false;
466}
467
469{
470 float ob_rot[3][3], invviewmat[4][4];
471 DRW_view_viewmat_get(nullptr, invviewmat, true);
472 BKE_object_rot_to_mat3(ob, ob_rot, true);
473 float dot = dot_v3v3(ob_rot[axis], invviewmat[2]);
474 if (fabsf(dot) < 1e-3) {
475 return true;
476 }
477
478 return false;
479}
480
481static void DRW_evaluate_weight_to_color(const float weight, float result[4])
482{
483 if (U.flag & USER_CUSTOM_RANGE) {
484 BKE_colorband_evaluate(&U.coba_weight, weight, result);
485 }
486 else {
487 /* Use gamma correction to even out the color bands:
488 * increasing widens yellow/cyan vs red/green/blue.
489 * Gamma 1.0 produces the original 2.79 color ramp. */
490 const float gamma = 1.5f;
491 const float hsv[3] = {(2.0f / 3.0f) * (1.0f - weight), 1.0f, pow(0.5f + 0.5f * weight, gamma)};
492
493 hsv_to_rgb_v(hsv, result);
494
495 for (int i = 0; i < 3; i++) {
496 result[i] = pow(result[i], 1.0f / gamma);
497 }
498 }
499}
500
502{
503 float pixels[256][4];
504 for (int i = 0; i < 256; i++) {
505 DRW_evaluate_weight_to_color(i / 255.0f, pixels[i]);
506 pixels[i][3] = 1.0f;
507 }
508
510 "weight_color_ramp", 256, 1, GPU_SRGB8_A8, GPU_TEXTURE_USAGE_SHADER_READ, pixels[0]);
511}
void BKE_colorband_evaluate_table_rgba(const ColorBand *coba, float **array, int *size)
Definition colorband.cc:559
bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
Definition colorband.cc:396
@ G_TRANSFORM_OBJ
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
Base * BKE_view_layer_active_base_get(ViewLayer *view_layer)
General operations, lookup, etc. for blender objects.
void BKE_object_rot_to_mat3(const Object *ob, float r_mat[3][3], bool use_drot)
void BKE_object_dimensions_get(Object *ob, float r_vec[3])
MINLINE float max_ff(float a, float b)
#define M_SQRT2
#define M_SQRT1_2
void hsv_to_rgb_v(const float hsv[3], float r_rgb[3])
Definition math_color.cc:57
MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4])
MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
MINLINE void copy_v2_v2(float r[2], const float a[2])
void interp_v4_v4v4(float r[4], const float a[4], const float b[4], float t)
Definition math_vector.c:45
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v4(float r[4])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void invert_v2(float r[2])
#define UNLIKELY(x)
#define ELEM(...)
@ BASE_FROM_DUPLI
@ BASE_FROM_SET
@ OB_MODE_EDIT
@ OB_SPEAKER
@ OB_EMPTY
@ OB_SURF
@ OB_CAMERA
@ OB_FONT
@ OB_LAMP
@ OB_MESH
@ OB_POINTCLOUD
@ OB_VOLUME
@ OB_CURVES_LEGACY
@ OB_CURVES
@ OB_LIGHTPROBE
#define BASE_SELECTED(v3d, base)
@ USER_GPU_FLAG_FRESNEL_EDIT
@ USER_CUSTOM_RANGE
#define RV3D_LOCK_FLAGS(rv3d)
@ RV3D_CAMOB
@ RV3D_BOXCLIP
#define DRW_TEXTURE_FREE_SAFE(tex)
float GPU_polygon_offset_calc(const float(*winmat)[4], float viewdist, float dist)
GPUTexture * GPU_texture_create_1d(const char *name, int width, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_SRGB8_A8
GPUUniformBuf * GPU_uniformbuf_create_ex(size_t size, const void *data, const char *name)
void GPU_uniformbuf_update(GPUUniformBuf *ubo, const void *data)
@ TH_EDGE_SHARP
@ TH_BONE_SOLID
@ TH_HANDLE_ALIGN
@ TH_NORMAL
@ TH_LIGHT
@ TH_FACE_BACK
@ TH_BACK_GRAD
@ TH_LNORMAL
@ TH_EDGE_FACESEL
@ TH_NURB_SEL_VLINE
@ TH_FRAME_AFTER
@ TH_TRANSPARENT_CHECKER_PRIMARY
@ TH_BONE_POSE_ACTIVE
@ TH_FREESTYLE_FACE_MARK
@ TH_FREESTYLE_EDGE_MARK
@ TH_GRID
@ TH_BACK
@ TH_WIRE
@ TH_BONE_LOCKED_WEIGHT
@ TH_FACEDOT_SIZE
@ TH_BONE_POSE
@ TH_HANDLE_SEL_AUTO
@ TH_SKIN_ROOT
@ TH_EDGE_SELECT
@ TH_TRANSPARENT_CHECKER_SECONDARY
@ TH_HANDLE_SEL_AUTOCLAMP
@ TH_ACTIVE_SPLINE
@ TH_CAMERA
@ TH_TRANSFORM
@ TH_EDGE_BEVEL
@ TH_HANDLE_AUTO
@ TH_NURB_VLINE
@ TH_SPEAKER
@ TH_VERTEX
@ TH_VERTEX_SIZE
@ TH_HANDLE_SEL_ALIGN
@ TH_GP_VERTEX_SELECT
@ TH_OBCENTER_DIA
@ TH_UV_SHADOW
@ TH_FACE_RETOPOLOGY
@ TH_HANDLE_SEL_FREE
@ TH_FACE_SELECT
@ TH_CFRAME
@ TH_NURB_ULINE
@ TH_EDGE_SEAM
@ TH_AXIS_Y
@ TH_AXIS_X
@ TH_HANDLE_SEL_VECT
@ TH_VERTEX_SELECT
@ TH_EMPTY
@ TH_FACE_FRONT
@ TH_VERTEX_UNREFERENCED
@ TH_TRANSPARENT_CHECKER_SIZE
@ TH_V3D_CLIPPING_BORDER
@ TH_AXIS_Z
@ TH_EDGE_WIDTH
@ TH_EDITMESH_ACTIVE
@ TH_GP_VERTEX_SIZE
@ TH_GP_VERTEX
@ TH_FRAME_BEFORE
@ TH_FACE_DOT
@ TH_EDGE_MODE_SELECT
@ TH_FACE_MODE_SELECT
@ TH_CAMERA_PATH
@ TH_SELECT
@ TH_HANDLE_FREE
@ TH_HANDLE_AUTOCLAMP
@ TH_EDGE_CREASE
@ TH_HANDLE_VECT
@ TH_TEXT
@ TH_WIRE_EDIT
@ TH_NURB_SEL_ULINE
@ TH_ACTIVE
@ TH_FACE
@ TH_VNORMAL
@ TH_TEXT_HI
void UI_GetThemeColorBlendShade4fv(int colorid1, int colorid2, float fac, int offset, float col[4])
void UI_GetThemeColorBlendShade3fv(int colorid1, int colorid2, float fac, int offset, float col[3])
void UI_GetThemeColorShadeAlpha4fv(int colorid, int coloffset, int alphaoffset, float col[4])
void UI_GetThemeColor4fv(int colorid, float col[4])
void UI_GetThemeColorShade4fv(int colorid, int offset, float col[4])
float UI_GetThemeValuef(int colorid)
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
unsigned int U
Definition btGjkEpa3.h:78
pow(value.r - subtrahend, 2.0)") .do_static_compilation(true)
#define fabsf(x)
int DRW_object_wire_theme_get(Object *ob, ViewLayer *view_layer, float **r_color)
void DRW_globals_free()
DRWView * DRW_view_create_with_zoffset(const DRWView *parent_view, const RegionView3D *rv3d, float offset)
#define UI_COLOR_RGBA_FROM_U8(r, g, b, a, v4)
static void DRW_evaluate_weight_to_color(const float weight, float result[4])
void DRW_globals_update()
static ColorBand weight_ramp_copy
bool DRW_object_is_flat(Object *ob, int *r_axis)
static bool weight_ramp_custom
static GPUTexture * DRW_create_weight_colorramp_texture()
bool DRW_object_axis_orthogonal_to_view(Object *ob, int axis)
DRW_Global G_draw
float * DRW_color_background_blend_get(int theme_id)
#define UBO_LAST_COLOR
Object * DRW_object_get_dupli_parent(const Object *)
const float * DRW_viewport_pixelsize_get()
const float * DRW_viewport_size_get()
const DRWContextState * DRW_context_state_get()
DRWView * DRW_view_create_sub(const DRWView *parent_view, const float viewmat[4][4], const float winmat[4][4])
void DRW_view_winmat_get(const DRWView *view, float mat[4][4], bool inverse)
void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse)
draw_view in_light_buf[] float
RAYTRACE_GROUP_SIZE additional_info("eevee_shared", "eevee_gbuffer_data", "eevee_global_ubo", "eevee_sampling_data", "eevee_utility_texture", "eevee_hiz_data", "draw_view") .specialization_constant(Type RAYTRACE_GROUP_SIZE in_sh_0_tx in_sh_2_tx screen_normal_tx GPU_RGBA8
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
#define G(x, y, z)
VecBase< float, 4 > float4
return ret
struct Object * object
CBData data[32]
eObjectMode object_mode
RegionView3D * rv3d
GlobalsUboStorage block
GPUTexture * weight_ramp
GPUUniformBuf * block_ubo
GPUTexture * ramp
short base_flag
float clip[6][4]