Blender  V3.3
paint_cursor.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2009 by Nicholas Bishop. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 #include "BLI_math.h"
11 #include "BLI_rect.h"
12 #include "BLI_task.h"
13 #include "BLI_utildefines.h"
14 
15 #include "DNA_brush_types.h"
16 #include "DNA_color_types.h"
17 #include "DNA_customdata_types.h"
18 #include "DNA_object_types.h"
19 #include "DNA_scene_types.h"
20 #include "DNA_screen_types.h"
21 #include "DNA_space_types.h"
22 #include "DNA_userdef_types.h"
23 #include "DNA_view3d_types.h"
24 
25 #include "BKE_brush.h"
26 #include "BKE_colortools.h"
27 #include "BKE_context.h"
28 #include "BKE_curve.h"
29 #include "BKE_image.h"
30 #include "BKE_node.h"
31 #include "BKE_object.h"
32 #include "BKE_paint.h"
33 
34 #include "NOD_texture.h"
35 
36 #include "WM_api.h"
37 #include "wm_cursors.h"
38 
39 #include "IMB_imbuf_types.h"
40 
41 #include "ED_image.h"
42 #include "ED_view3d.h"
43 
44 #include "DEG_depsgraph.h"
45 
46 #include "GPU_immediate.h"
47 #include "GPU_immediate_util.h"
48 #include "GPU_matrix.h"
49 #include "GPU_state.h"
50 #include "GPU_texture.h"
51 
52 #include "UI_resources.h"
53 
54 #include "paint_intern.h"
55 /* still needed for sculpt_stroke_get_location, should be
56  * removed eventually (TODO) */
57 #include "sculpt_intern.h"
58 
59 /* TODOs:
60  *
61  * Some of the cursor drawing code is doing non-draw stuff
62  * (e.g. updating the brush rake angle). This should be cleaned up
63  * still.
64  *
65  * There is also some ugliness with sculpt-specific code.
66  */
67 
68 typedef struct TexSnapshot {
70  int winx;
71  int winy;
72  int old_size;
73  float old_zoom;
74  bool old_col;
76 
77 typedef struct CursorSnapshot {
79  int size;
80  int zoom;
83 
87 
89 {
92  }
95  }
98  }
99 
100  memset(&primary_snap, 0, sizeof(TexSnapshot));
101  memset(&secondary_snap, 0, sizeof(TexSnapshot));
102  memset(&cursor_snap, 0, sizeof(CursorSnapshot));
103 
105 }
106 
107 static int same_tex_snap(TexSnapshot *snap, MTex *mtex, ViewContext *vc, bool col, float zoom)
108 {
109  return (/* make brush smaller shouldn't cause a resample */
110  //(mtex->brush_map_mode != MTEX_MAP_MODE_VIEW ||
111  //(BKE_brush_size_get(vc->scene, brush) <= snap->BKE_brush_size_get)) &&
112 
114  (vc->region->winx == snap->winx && vc->region->winy == snap->winy)) &&
115  (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL || snap->old_zoom == zoom) &&
116  snap->old_col == col);
117 }
118 
119 static void make_tex_snap(TexSnapshot *snap, ViewContext *vc, float zoom)
120 {
121  snap->old_zoom = zoom;
122  snap->winx = vc->region->winx;
123  snap->winy = vc->region->winy;
124 }
125 
126 typedef struct LoadTexData {
129 
132  bool col;
133 
134  struct ImagePool *pool;
135  int size;
136  float rotation;
137  float radius;
139 
140 static void load_tex_task_cb_ex(void *__restrict userdata,
141  const int j,
142  const TaskParallelTLS *__restrict tls)
143 {
144  LoadTexData *data = userdata;
145  Brush *br = data->br;
146  ViewContext *vc = data->vc;
147 
148  MTex *mtex = data->mtex;
149  uchar *buffer = data->buffer;
150  const bool col = data->col;
151 
152  struct ImagePool *pool = data->pool;
153  const int size = data->size;
154  const float rotation = data->rotation;
155  const float radius = data->radius;
156 
157  bool convert_to_linear = false;
158  struct ColorSpace *colorspace = NULL;
159 
160  const int thread_id = BLI_task_parallel_thread_id(tls);
161 
162  if (mtex->tex && mtex->tex->type == TEX_IMAGE && mtex->tex->ima) {
163  ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(mtex->tex->ima, &mtex->tex->iuser, pool);
164  /* For consistency, sampling always returns color in linear space. */
165  if (tex_ibuf && tex_ibuf->rect_float == NULL) {
166  convert_to_linear = true;
167  colorspace = tex_ibuf->rect_colorspace;
168  }
169  BKE_image_pool_release_ibuf(mtex->tex->ima, tex_ibuf, pool);
170  }
171 
172  for (int i = 0; i < size; i++) {
173  /* Largely duplicated from tex_strength. */
174 
175  int index = j * size + i;
176 
177  float x = (float)i / size;
178  float y = (float)j / size;
179  float len;
180 
181  if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
182  x *= vc->region->winx / radius;
183  y *= vc->region->winy / radius;
184  }
185  else {
186  x = (x - 0.5f) * 2.0f;
187  y = (y - 0.5f) * 2.0f;
188  }
189 
190  len = sqrtf(x * x + y * y);
191 
193  /* It is probably worth optimizing for those cases where the texture is not rotated by
194  * skipping the calls to atan2, sqrtf, sin, and cos. */
195  if (mtex->tex && (rotation > 0.001f || rotation < -0.001f)) {
196  const float angle = atan2f(y, x) + rotation;
197 
198  x = len * cosf(angle);
199  y = len * sinf(angle);
200  }
201 
202  if (col) {
203  float rgba[4];
204 
205  paint_get_tex_pixel_col(mtex, x, y, rgba, pool, thread_id, convert_to_linear, colorspace);
206 
207  buffer[index * 4] = rgba[0] * 255;
208  buffer[index * 4 + 1] = rgba[1] * 255;
209  buffer[index * 4 + 2] = rgba[2] * 255;
210  buffer[index * 4 + 3] = rgba[3] * 255;
211  }
212  else {
213  float avg = paint_get_tex_pixel(mtex, x, y, pool, thread_id);
214 
215  avg += br->texture_sample_bias;
216 
217  /* Clamp to avoid precision overflow. */
218  CLAMP(avg, 0.0f, 1.0f);
219  buffer[index] = 255 - (uchar)(255 * avg);
220  }
221  }
222  else {
223  if (col) {
224  buffer[index * 4] = 0;
225  buffer[index * 4 + 1] = 0;
226  buffer[index * 4 + 2] = 0;
227  buffer[index * 4 + 3] = 0;
228  }
229  else {
230  buffer[index] = 0;
231  }
232  }
233  }
234 }
235 
236 static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool primary)
237 {
238  bool init;
239  TexSnapshot *target;
240 
241  MTex *mtex = (primary) ? &br->mtex : &br->mask_mtex;
243  uchar *buffer = NULL;
244 
245  int size;
246  bool refresh;
247  ePaintOverlayControlFlags invalid =
250  target = (primary) ? &primary_snap : &secondary_snap;
251 
252  refresh = !target->overlay_texture || (invalid != 0) ||
253  !same_tex_snap(target, mtex, vc, col, zoom);
254 
255  init = (target->overlay_texture != 0);
256 
257  if (refresh) {
258  struct ImagePool *pool = NULL;
259  /* Stencil is rotated later. */
260  const float rotation = (mtex->brush_map_mode != MTEX_MAP_MODE_STENCIL) ? -mtex->rot : 0.0f;
261  const float radius = BKE_brush_size_get(vc->scene, br) * zoom;
262 
263  make_tex_snap(target, vc, zoom);
264 
265  if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
266  int s = BKE_brush_size_get(vc->scene, br);
267  int r = 1;
268 
269  for (s >>= 1; s > 0; s >>= 1) {
270  r++;
271  }
272 
273  size = (1 << r);
274 
275  if (size < 256) {
276  size = 256;
277  }
278 
279  if (size < target->old_size) {
280  size = target->old_size;
281  }
282  }
283  else {
284  size = 512;
285  }
286 
287  if (target->old_size != size || target->old_col != col) {
288  if (target->overlay_texture) {
290  target->overlay_texture = NULL;
291  }
292  init = false;
293 
294  target->old_size = size;
295  target->old_col = col;
296  }
297  if (col) {
298  buffer = MEM_mallocN(sizeof(uchar) * size * size * 4, "load_tex");
299  }
300  else {
301  buffer = MEM_mallocN(sizeof(uchar) * size * size, "load_tex");
302  }
303 
305 
306  if (mtex->tex && mtex->tex->nodetree) {
307  /* Has internal flag to detect it only does it once. */
309  }
310 
311  LoadTexData data = {
312  .br = br,
313  .vc = vc,
314  .mtex = mtex,
315  .buffer = buffer,
316  .col = col,
317  .pool = pool,
318  .size = size,
319  .rotation = rotation,
320  .radius = radius,
321  };
322 
323  TaskParallelSettings settings;
326 
327  if (mtex->tex && mtex->tex->nodetree) {
329  }
330 
331  if (pool) {
333  }
334 
335  if (!target->overlay_texture) {
338  "paint_cursor_overlay", size, size, 1, format, NULL);
340 
341  if (!col) {
342  GPU_texture_swizzle_set(target->overlay_texture, "rrrr");
343  }
344  }
345 
346  if (init) {
348  }
349 
350  if (buffer) {
351  MEM_freeN(buffer);
352  }
353  }
354  else {
355  size = target->old_size;
356  }
357 
359 
360  return 1;
361 }
362 
363 static void load_tex_cursor_task_cb(void *__restrict userdata,
364  const int j,
365  const TaskParallelTLS *__restrict UNUSED(tls))
366 {
367  LoadTexData *data = userdata;
368  Brush *br = data->br;
369 
370  uchar *buffer = data->buffer;
371 
372  const int size = data->size;
373 
374  for (int i = 0; i < size; i++) {
375  /* Largely duplicated from tex_strength. */
376 
377  const int index = j * size + i;
378  const float x = (((float)i / size) - 0.5f) * 2.0f;
379  const float y = (((float)j / size) - 0.5f) * 2.0f;
380  const float len = sqrtf(x * x + y * y);
381 
382  if (len <= 1.0f) {
383 
384  /* Falloff curve. */
385  float avg = BKE_brush_curve_strength_clamped(br, len, 1.0f);
386 
387  buffer[index] = (uchar)(255 * avg);
388  }
389  else {
390  buffer[index] = 0;
391  }
392  }
393 }
394 
395 static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
396 {
397  bool init;
398 
400  uchar *buffer = NULL;
401 
402  int size;
403  const bool refresh = !cursor_snap.overlay_texture ||
406 
408 
409  if (refresh) {
410  int s, r;
411 
412  cursor_snap.zoom = zoom;
413 
414  s = BKE_brush_size_get(vc->scene, br);
415  r = 1;
416 
417  for (s >>= 1; s > 0; s >>= 1) {
418  r++;
419  }
420 
421  size = (1 << r);
422 
423  if (size < 256) {
424  size = 256;
425  }
426 
427  if (size < cursor_snap.size) {
429  }
430 
431  if (cursor_snap.size != size) {
435  }
436 
437  init = false;
438 
440  }
441  buffer = MEM_mallocN(sizeof(uchar) * size * size, "load_tex");
442 
444 
445  LoadTexData data = {
446  .br = br,
447  .buffer = buffer,
448  .size = size,
449  };
450 
451  TaskParallelSettings settings;
454 
457  "cursor_snap_overaly", size, size, 1, GPU_R8, NULL);
459 
461  }
462 
463  if (init) {
465  }
466 
467  if (buffer) {
468  MEM_freeN(buffer);
469  }
470  }
471  else {
473  }
474 
477 
478  return 1;
479 }
480 
481 static int project_brush_radius(ViewContext *vc, float radius, const float location[3])
482 {
483  float view[3], nonortho[3], ortho[3], offset[3], p1[2], p2[2];
484 
485  ED_view3d_global_to_vector(vc->rv3d, location, view);
486 
487  /* Create a vector that is not orthogonal to view. */
488 
489  if (fabsf(view[0]) < 0.1f) {
490  nonortho[0] = view[0] + 1.0f;
491  nonortho[1] = view[1];
492  nonortho[2] = view[2];
493  }
494  else if (fabsf(view[1]) < 0.1f) {
495  nonortho[0] = view[0];
496  nonortho[1] = view[1] + 1.0f;
497  nonortho[2] = view[2];
498  }
499  else {
500  nonortho[0] = view[0];
501  nonortho[1] = view[1];
502  nonortho[2] = view[2] + 1.0f;
503  }
504 
505  /* Get a vector in the plane of the view. */
506  cross_v3_v3v3(ortho, nonortho, view);
507  normalize_v3(ortho);
508 
509  /* Make a point on the surface of the brush tangent to the view. */
510  mul_v3_fl(ortho, radius);
511  add_v3_v3v3(offset, location, ortho);
512 
513  /* Project the center of the brush, and the tangent point to the view onto the screen. */
514  if ((ED_view3d_project_float_global(vc->region, location, p1, V3D_PROJ_TEST_NOP) ==
515  V3D_PROJ_RET_OK) &&
517  V3D_PROJ_RET_OK)) {
518  /* The distance between these points is the size of the projected brush in pixels. */
519  return len_v2v2(p1, p2);
520  }
521  /* Assert because the code that sets up the vectors should disallow this. */
522  BLI_assert(0);
523  return 0;
524 }
525 
526 /* Draw an overlay that shows what effect the brush's texture will
527  * have on brush strength. */
529  Brush *brush,
530  ViewContext *vc,
531  int x,
532  int y,
533  float zoom,
534  const ePaintMode mode,
535  bool col,
536  bool primary)
537 {
538  rctf quad;
539  /* Check for overlay mode. */
540 
541  MTex *mtex = (primary) ? &brush->mtex : &brush->mask_mtex;
542  bool valid = ((primary) ? (brush->overlay_flags & BRUSH_OVERLAY_PRIMARY) != 0 :
543  (brush->overlay_flags & BRUSH_OVERLAY_SECONDARY) != 0);
544  int overlay_alpha = (primary) ? brush->texture_overlay_alpha : brush->mask_overlay_alpha;
545 
546  if (mode == PAINT_MODE_TEXTURE_3D) {
547  if (primary && brush->imagepaint_tool != PAINT_TOOL_DRAW) {
548  /* All non-draw tools don't use the primary texture (clone, smear, soften.. etc). */
549  return false;
550  }
551  }
552 
553  if (!(mtex->tex) ||
554  !((mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) ||
556  return false;
557  }
558 
559  if (load_tex(brush, vc, zoom, col, primary)) {
560  GPU_color_mask(true, true, true, true);
562 
563  if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
564  GPU_matrix_push();
565 
566  float center[2] = {
567  ups->draw_anchored ? ups->anchored_initial_mouse[0] : x,
568  ups->draw_anchored ? ups->anchored_initial_mouse[1] : y,
569  };
570 
571  /* Brush rotation. */
575 
576  /* Scale based on tablet pressure. */
577  if (primary && ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
578  const float scale = ups->size_pressure_value;
580  GPU_matrix_scale_2f(scale, scale);
582  }
583 
584  if (ups->draw_anchored) {
585  quad.xmin = center[0] - ups->anchored_size;
586  quad.ymin = center[1] - ups->anchored_size;
587  quad.xmax = center[0] + ups->anchored_size;
588  quad.ymax = center[1] + ups->anchored_size;
589  }
590  else {
591  const int radius = BKE_brush_size_get(vc->scene, brush) * zoom;
592  quad.xmin = center[0] - radius;
593  quad.ymin = center[1] - radius;
594  quad.xmax = center[0] + radius;
595  quad.ymax = center[1] + radius;
596  }
597  }
598  else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
599  quad.xmin = 0;
600  quad.ymin = 0;
601  quad.xmax = BLI_rcti_size_x(&vc->region->winrct);
602  quad.ymax = BLI_rcti_size_y(&vc->region->winrct);
603  }
604  /* Stencil code goes here. */
605  else {
606  if (primary) {
607  quad.xmin = -brush->stencil_dimension[0];
608  quad.ymin = -brush->stencil_dimension[1];
609  quad.xmax = brush->stencil_dimension[0];
610  quad.ymax = brush->stencil_dimension[1];
611  }
612  else {
613  quad.xmin = -brush->mask_stencil_dimension[0];
614  quad.ymin = -brush->mask_stencil_dimension[1];
615  quad.xmax = brush->mask_stencil_dimension[0];
616  quad.ymax = brush->mask_stencil_dimension[1];
617  }
618  GPU_matrix_push();
619  if (primary) {
621  }
622  else {
624  }
626  }
627 
628  /* Set quad color. Colored overlay does not get blending. */
631  uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
632 
633  /* Premultiplied alpha blending. */
635 
637 
638  float final_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
639  if (!col) {
640  copy_v3_v3(final_color, U.sculpt_paint_overlay_col);
641  }
642  mul_v4_fl(final_color, overlay_alpha * 0.01f);
643  immUniformColor4fv(final_color);
644 
645  GPUTexture *texture = (primary) ? primary_snap.overlay_texture :
647 
651  immBindTextureSampler("image", texture, state);
652 
653  /* Draw textured quad. */
655  immAttr2f(texCoord, 0.0f, 0.0f);
656  immVertex2f(pos, quad.xmin, quad.ymin);
657  immAttr2f(texCoord, 1.0f, 0.0f);
658  immVertex2f(pos, quad.xmax, quad.ymin);
659  immAttr2f(texCoord, 1.0f, 1.0f);
660  immVertex2f(pos, quad.xmax, quad.ymax);
661  immAttr2f(texCoord, 0.0f, 1.0f);
662  immVertex2f(pos, quad.xmin, quad.ymax);
663  immEnd();
664 
666 
667  GPU_texture_unbind(texture);
668 
670  GPU_matrix_pop();
671  }
672  }
673  return true;
674 }
675 
676 /* Draw an overlay that shows what effect the brush's texture will
677  * have on brush strength. */
679  UnifiedPaintSettings *ups, Brush *brush, ViewContext *vc, int x, int y, float zoom)
680 {
681  rctf quad;
682  /* Check for overlay mode. */
683 
684  if (!(brush->overlay_flags & BRUSH_OVERLAY_CURSOR)) {
685  return false;
686  }
687 
688  if (load_tex_cursor(brush, vc, zoom)) {
689  bool do_pop = false;
690  float center[2];
691 
692  GPU_color_mask(true, true, true, true);
694 
695  if (ups->draw_anchored) {
697  quad.xmin = ups->anchored_initial_mouse[0] - ups->anchored_size;
698  quad.ymin = ups->anchored_initial_mouse[1] - ups->anchored_size;
699  quad.xmax = ups->anchored_initial_mouse[0] + ups->anchored_size;
700  quad.ymax = ups->anchored_initial_mouse[1] + ups->anchored_size;
701  }
702  else {
703  const int radius = BKE_brush_size_get(vc->scene, brush) * zoom;
704  center[0] = x;
705  center[1] = y;
706 
707  quad.xmin = x - radius;
708  quad.ymin = y - radius;
709  quad.xmax = x + radius;
710  quad.ymax = y + radius;
711  }
712 
713  /* Scale based on tablet pressure. */
714  if (ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
715  do_pop = true;
716  GPU_matrix_push();
720  }
721 
724  uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
725 
727 
729 
730  float final_color[4] = {UNPACK3(U.sculpt_paint_overlay_col), 1.0f};
731  mul_v4_fl(final_color, brush->cursor_overlay_alpha * 0.01f);
732  immUniformColor4fv(final_color);
733 
734  /* Draw textured quad. */
737 
739  immAttr2f(texCoord, 0.0f, 0.0f);
740  immVertex2f(pos, quad.xmin, quad.ymin);
741  immAttr2f(texCoord, 1.0f, 0.0f);
742  immVertex2f(pos, quad.xmax, quad.ymin);
743  immAttr2f(texCoord, 1.0f, 1.0f);
744  immVertex2f(pos, quad.xmax, quad.ymax);
745  immAttr2f(texCoord, 0.0f, 1.0f);
746  immVertex2f(pos, quad.xmin, quad.ymax);
747  immEnd();
748 
750 
752 
753  if (do_pop) {
754  GPU_matrix_pop();
755  }
756  }
757  return true;
758 }
759 
761  Brush *brush,
762  ViewContext *vc,
763  int x,
764  int y,
765  float zoom,
766  ePaintMode mode)
767 {
768  /* Color means that primary brush texture is colored and
769  * secondary is used for alpha/mask control. */
771 
772  bool alpha_overlay_active = false;
773 
775  eGPUBlend blend_state = GPU_blend_get();
776  eGPUDepthTest depth_test = GPU_depth_test_get();
777 
778  /* Translate to region. */
779  GPU_matrix_push();
781  x -= vc->region->winrct.xmin;
782  y -= vc->region->winrct.ymin;
783 
784  /* Colored overlay should be drawn separately. */
785  if (col) {
786  if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY)) {
787  alpha_overlay_active = paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, mode, true, true);
788  }
789  if (!(flags & PAINT_OVERLAY_OVERRIDE_SECONDARY)) {
790  alpha_overlay_active = paint_draw_tex_overlay(
791  ups, brush, vc, x, y, zoom, mode, false, false);
792  }
793  if (!(flags & PAINT_OVERLAY_OVERRIDE_CURSOR)) {
794  alpha_overlay_active = paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
795  }
796  }
797  else {
798  if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY) && (mode != PAINT_MODE_WEIGHT)) {
799  alpha_overlay_active = paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, mode, false, true);
800  }
801  if (!(flags & PAINT_OVERLAY_OVERRIDE_CURSOR)) {
802  alpha_overlay_active = paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
803  }
804  }
805 
806  GPU_matrix_pop();
807  GPU_blend(blend_state);
808  GPU_depth_test(depth_test);
809 
810  return alpha_overlay_active;
811 }
812 
814  const float sel_col[4],
815  const float pivot_col[4],
816  float *co,
817  float width,
818  bool selected)
819 {
820  immUniformColor4fv(selected ? sel_col : pivot_col);
821 
822  GPU_line_width(3.0f);
823 
824  float w = width / 2.0f;
825  const float tri[3][2] = {
826  {co[0], co[1] + w},
827  {co[0] - w, co[1] - w},
828  {co[0] + w, co[1] - w},
829  };
830 
832  immVertex2fv(pos, tri[0]);
833  immVertex2fv(pos, tri[1]);
834  immVertex2fv(pos, tri[2]);
835  immEnd();
836 
837  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
838  GPU_line_width(1.0f);
839 
841  immVertex2fv(pos, tri[0]);
842  immVertex2fv(pos, tri[1]);
843  immVertex2fv(pos, tri[2]);
844  immEnd();
845 }
846 
848  const float sel_col[4],
849  const float handle_col[4],
850  const float *co,
851  float width,
852  bool selected)
853 {
854  immUniformColor4fv(selected ? sel_col : handle_col);
855 
856  GPU_line_width(3.0f);
857 
858  float w = width / 2.0f;
859  float minx = co[0] - w;
860  float miny = co[1] - w;
861  float maxx = co[0] + w;
862  float maxy = co[1] + w;
863 
864  imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy);
865 
866  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
867  GPU_line_width(1.0f);
868 
869  imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy);
870 }
871 
872 BLI_INLINE void draw_bezier_handle_lines(uint pos, const float sel_col[4], BezTriple *bez)
873 {
874  immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
875  GPU_line_width(3.0f);
876 
878  immVertex2fv(pos, bez->vec[0]);
879  immVertex2fv(pos, bez->vec[1]);
880  immVertex2fv(pos, bez->vec[2]);
881  immEnd();
882 
883  GPU_line_width(1.0f);
884 
885  if (bez->f1 || bez->f2) {
886  immUniformColor4fv(sel_col);
887  }
888  else {
889  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
890  }
892  immVertex2fv(pos, bez->vec[0]);
893  immVertex2fv(pos, bez->vec[1]);
894  immEnd();
895 
896  if (bez->f3 || bez->f2) {
897  immUniformColor4fv(sel_col);
898  }
899  else {
900  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
901  }
903  immVertex2fv(pos, bez->vec[1]);
904  immVertex2fv(pos, bez->vec[2]);
905  immEnd();
906 }
907 
908 static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc)
909 {
910  GPU_matrix_push();
912 
913  if (brush->paint_curve && brush->paint_curve->points) {
914  PaintCurve *pc = brush->paint_curve;
915  PaintCurvePoint *cp = pc->points;
916 
917  GPU_line_smooth(true);
919 
920  /* Draw the bezier handles and the curve segment between the current and next point. */
922 
924 
925  float selec_col[4], handle_col[4], pivot_col[4];
929 
930  for (int i = 0; i < pc->tot_points - 1; i++, cp++) {
931  int j;
932  PaintCurvePoint *cp_next = cp + 1;
933  float data[(PAINT_CURVE_NUM_SEGMENTS + 1) * 2];
934  /* Use color coding to distinguish handles vs curve segments. */
935  draw_bezier_handle_lines(pos, selec_col, &cp->bez);
936  draw_tri_point(pos, selec_col, pivot_col, &cp->bez.vec[1][0], 10.0f, cp->bez.f2);
938  pos, selec_col, handle_col, &cp->bez.vec[0][0], 8.0f, cp->bez.f1 || cp->bez.f2);
940  pos, selec_col, handle_col, &cp->bez.vec[2][0], 8.0f, cp->bez.f3 || cp->bez.f2);
941 
942  for (j = 0; j < 2; j++) {
944  cp->bez.vec[2][j],
945  cp_next->bez.vec[0][j],
946  cp_next->bez.vec[1][j],
947  data + j,
949  sizeof(float[2]));
950  }
951 
952  float(*v)[2] = (float(*)[2])data;
953 
954  immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
955  GPU_line_width(3.0f);
957  for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) {
958  immVertex2fv(pos, v[j]);
959  }
960  immEnd();
961 
962  immUniformColor4f(0.9f, 0.9f, 1.0f, 0.5f);
963  GPU_line_width(1.0f);
965  for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) {
966  immVertex2fv(pos, v[j]);
967  }
968  immEnd();
969  }
970 
971  /* Draw last line segment. */
972  draw_bezier_handle_lines(pos, selec_col, &cp->bez);
973  draw_tri_point(pos, selec_col, pivot_col, &cp->bez.vec[1][0], 10.0f, cp->bez.f2);
975  pos, selec_col, handle_col, &cp->bez.vec[0][0], 8.0f, cp->bez.f1 || cp->bez.f2);
977  pos, selec_col, handle_col, &cp->bez.vec[2][0], 8.0f, cp->bez.f3 || cp->bez.f2);
978 
980  GPU_line_smooth(false);
981 
983  }
984  GPU_matrix_pop();
985 }
986 
987 /* Special actions taken when paint cursor goes over mesh */
988 /* TODO: sculpt only for now. */
990  Brush *brush,
991  ViewContext *vc,
992  const float location[3])
993 {
994  float unprojected_radius, projected_radius;
995 
996  /* Update the brush's cached 3D radius. */
997  if (!BKE_brush_use_locked_size(vc->scene, brush)) {
998  /* Get 2D brush radius. */
999  if (ups->draw_anchored) {
1000  projected_radius = ups->anchored_size;
1001  }
1002  else {
1003  if (brush->flag & BRUSH_ANCHORED) {
1004  projected_radius = 8;
1005  }
1006  else {
1007  projected_radius = BKE_brush_size_get(vc->scene, brush);
1008  }
1009  }
1010 
1011  /* Convert brush radius from 2D to 3D. */
1012  unprojected_radius = paint_calc_object_space_radius(vc, location, projected_radius);
1013 
1014  /* Scale 3D brush radius by pressure. */
1015  if (ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
1016  unprojected_radius *= ups->size_pressure_value;
1017  }
1018 
1019  /* Set cached value in either Brush or UnifiedPaintSettings. */
1020  BKE_brush_unprojected_radius_set(vc->scene, brush, unprojected_radius);
1021  }
1022 }
1023 
1024 static void cursor_draw_point_screen_space(const uint gpuattr,
1025  const ARegion *region,
1026  const float true_location[3],
1027  const float obmat[4][4],
1028  const int size)
1029 {
1030  float translation_vertex_cursor[3], location[3];
1031  copy_v3_v3(location, true_location);
1032  mul_m4_v3(obmat, location);
1033  ED_view3d_project_v3(region, location, translation_vertex_cursor);
1034  /* Do not draw points behind the view. Z [near, far] is mapped to [-1, 1]. */
1035  if (translation_vertex_cursor[2] <= 1.0f) {
1037  gpuattr, translation_vertex_cursor[0], translation_vertex_cursor[1], size, 10);
1038  }
1039 }
1040 
1041 static void cursor_draw_tiling_preview(const uint gpuattr,
1042  const ARegion *region,
1043  const float true_location[3],
1044  Sculpt *sd,
1045  Object *ob,
1046  const float radius)
1047 {
1048  const BoundBox *bb = BKE_object_boundbox_get(ob);
1049  float orgLoc[3], location[3];
1050  int tile_pass = 0;
1051  int start[3];
1052  int end[3];
1053  int cur[3];
1054  const float *bbMin = bb->vec[0];
1055  const float *bbMax = bb->vec[6];
1056  const float *step = sd->paint.tile_offset;
1057 
1058  copy_v3_v3(orgLoc, true_location);
1059  for (int dim = 0; dim < 3; dim++) {
1060  if ((sd->paint.symmetry_flags & (PAINT_TILE_X << dim)) && step[dim] > 0) {
1061  start[dim] = (bbMin[dim] - orgLoc[dim] - radius) / step[dim];
1062  end[dim] = (bbMax[dim] - orgLoc[dim] + radius) / step[dim];
1063  }
1064  else {
1065  start[dim] = end[dim] = 0;
1066  }
1067  }
1068  copy_v3_v3_int(cur, start);
1069  for (cur[0] = start[0]; cur[0] <= end[0]; cur[0]++) {
1070  for (cur[1] = start[1]; cur[1] <= end[1]; cur[1]++) {
1071  for (cur[2] = start[2]; cur[2] <= end[2]; cur[2]++) {
1072  if (!cur[0] && !cur[1] && !cur[2]) {
1073  /* Skip tile at orgLoc, this was already handled before all others. */
1074  continue;
1075  }
1076  tile_pass++;
1077  for (int dim = 0; dim < 3; dim++) {
1078  location[dim] = cur[dim] * step[dim] + orgLoc[dim];
1079  }
1080  cursor_draw_point_screen_space(gpuattr, region, location, ob->obmat, 3);
1081  }
1082  }
1083  }
1084 }
1085 
1086 static void cursor_draw_point_with_symmetry(const uint gpuattr,
1087  const ARegion *region,
1088  const float true_location[3],
1089  Sculpt *sd,
1090  Object *ob,
1091  const float radius)
1092 {
1093  const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
1094  float location[3], symm_rot_mat[4][4];
1095 
1096  for (int i = 0; i <= symm; i++) {
1097  if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (!ELEM(i, 3, 5))))) {
1098 
1099  /* Axis Symmetry. */
1100  flip_v3_v3(location, true_location, (char)i);
1101  cursor_draw_point_screen_space(gpuattr, region, location, ob->obmat, 3);
1102 
1103  /* Tiling. */
1104  cursor_draw_tiling_preview(gpuattr, region, location, sd, ob, radius);
1105 
1106  /* Radial Symmetry. */
1107  for (char raxis = 0; raxis < 3; raxis++) {
1108  for (int r = 1; r < sd->radial_symm[raxis]; r++) {
1109  float angle = 2 * M_PI * r / sd->radial_symm[(int)raxis];
1110  flip_v3_v3(location, true_location, (char)i);
1111  unit_m4(symm_rot_mat);
1112  rotate_m4(symm_rot_mat, raxis + 'X', angle);
1113  mul_m4_v3(symm_rot_mat, location);
1114 
1115  cursor_draw_tiling_preview(gpuattr, region, location, sd, ob, radius);
1116  cursor_draw_point_screen_space(gpuattr, region, location, ob->obmat, 3);
1117  }
1118  }
1119  }
1120  }
1121 }
1122 
1123 static void sculpt_geometry_preview_lines_draw(const uint gpuattr,
1124  Brush *brush,
1125  const bool is_multires,
1126  SculptSession *ss)
1127 {
1128  if (!(brush->flag & BRUSH_GRAB_ACTIVE_VERTEX)) {
1129  return;
1130  }
1131 
1132  if (is_multires) {
1133  return;
1134  }
1135 
1136  if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
1137  return;
1138  }
1139 
1140  if (!ss->deform_modifiers_active) {
1141  return;
1142  }
1143 
1144  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.6f);
1145 
1146  /* Cursor normally draws on top, but for this part we need depth tests. */
1147  const eGPUDepthTest depth_test = GPU_depth_test_get();
1148  if (!depth_test) {
1150  }
1151 
1152  GPU_line_width(1.0f);
1153  if (ss->preview_vert_index_count > 0) {
1155  for (int i = 0; i < ss->preview_vert_index_count; i++) {
1156  immVertex3fv(gpuattr,
1158  }
1159  immEnd();
1160  }
1161 
1162  /* Restore depth test value. */
1163  if (!depth_test) {
1165  }
1166 }
1167 
1169  const Brush *brush,
1170  const float rds,
1171  const float line_width,
1172  const float outline_col[3],
1173  const float alpha)
1174 {
1175  float cursor_trans[4][4];
1176  unit_m4(cursor_trans);
1177  translate_m4(cursor_trans, 0.0f, 0.0f, brush->height);
1178  GPU_matrix_push();
1179  GPU_matrix_mul(cursor_trans);
1180 
1181  GPU_line_width(line_width);
1182  immUniformColor3fvAlpha(outline_col, alpha * 0.5f);
1183  imm_draw_circle_wire_3d(gpuattr, 0, 0, rds, 80);
1184  GPU_matrix_pop();
1185 }
1186 
1188 {
1189  if (mode >= PAINT_MODE_TEXTURE_3D) {
1190  return true;
1191  }
1192  return false;
1193 }
1194 
1200 
1201 typedef struct PaintCursorContext {
1213 
1214  /* Sculpt related data. */
1221  float radius;
1222 
1223  /* 3D view cursor position and normal. */
1224  float location[3];
1226  float normal[3];
1227 
1228  /* Cursor main colors. */
1229  float outline_col[3];
1231 
1232  /* GPU attribute for drawing. */
1234 
1236 
1237  /* This variable is set after drawing the overlay, not on initialization. It can't be used for
1238  * checking if alpha overlay is enabled before drawing it. */
1240 
1241  float zoomx;
1242  int x, y;
1243  float translation[2];
1244 
1247 
1249 
1251  const int x,
1252  const int y,
1253  PaintCursorContext *pcontext)
1254 {
1255  ARegion *region = CTX_wm_region(C);
1256  if (region && region->regiontype != RGN_TYPE_WINDOW) {
1257  return false;
1258  }
1259 
1260  pcontext->C = C;
1261  pcontext->region = region;
1262  pcontext->wm = CTX_wm_manager(C);
1263  pcontext->win = CTX_wm_window(C);
1264  pcontext->depsgraph = CTX_data_depsgraph_pointer(C);
1265  pcontext->scene = CTX_data_scene(C);
1266  pcontext->ups = &pcontext->scene->toolsettings->unified_paint_settings;
1268  if (pcontext->paint == NULL) {
1269  return false;
1270  }
1271  pcontext->brush = BKE_paint_brush(pcontext->paint);
1272  if (pcontext->brush == NULL) {
1273  return false;
1274  }
1276 
1277  ED_view3d_viewcontext_init(C, &pcontext->vc, pcontext->depsgraph);
1278 
1279  if (pcontext->brush->flag & BRUSH_CURVE) {
1280  pcontext->cursor_type = PAINT_CURSOR_CURVE;
1281  }
1282  else if (paint_use_2d_cursor(pcontext->mode)) {
1283  pcontext->cursor_type = PAINT_CURSOR_2D;
1284  }
1285  else {
1286  pcontext->cursor_type = PAINT_CURSOR_3D;
1287  }
1288 
1289  pcontext->x = x;
1290  pcontext->y = y;
1291  pcontext->translation[0] = (float)x;
1292  pcontext->translation[1] = (float)y;
1293 
1294  float zoomx, zoomy;
1295  get_imapaint_zoom(C, &zoomx, &zoomy);
1296  pcontext->zoomx = max_ff(zoomx, zoomy);
1297  pcontext->final_radius = (BKE_brush_size_get(pcontext->scene, pcontext->brush) * zoomx);
1298 
1299  /* There is currently no way to check if the direction is inverted before starting the stroke,
1300  * so this does not reflect the state of the brush in the UI. */
1301  if (((pcontext->ups->draw_inverted == 0) ^ ((pcontext->brush->flag & BRUSH_DIR_IN) == 0)) &&
1303  copy_v3_v3(pcontext->outline_col, pcontext->brush->sub_col);
1304  }
1305  else {
1306  copy_v3_v3(pcontext->outline_col, pcontext->brush->add_col);
1307  }
1308  pcontext->outline_alpha = pcontext->brush->add_col[3];
1309 
1310  Object *active_object = pcontext->vc.obact;
1311  pcontext->ss = active_object ? active_object->sculpt : NULL;
1312 
1313  if (pcontext->ss && pcontext->ss->draw_faded_cursor) {
1314  pcontext->outline_alpha = 0.3f;
1315  copy_v3_fl(pcontext->outline_col, 0.8f);
1316  }
1317 
1318  const bool is_brush_tool = PAINT_brush_tool_poll(C);
1319  if (!is_brush_tool) {
1320  /* Use a default color for tools that are not brushes. */
1321  pcontext->outline_alpha = 0.8f;
1322  copy_v3_fl(pcontext->outline_col, 0.8f);
1323  }
1324 
1325  pcontext->is_stroke_active = pcontext->ups->stroke_active;
1326 
1327  return true;
1328 }
1329 
1331 {
1332  if (pcontext->is_cursor_over_mesh) {
1333  Brush *brush = BKE_paint_brush(pcontext->paint);
1334  pcontext->pixel_radius = project_brush_radius(
1335  &pcontext->vc,
1336  BKE_brush_unprojected_radius_get(pcontext->scene, brush),
1337  pcontext->location);
1338 
1339  if (pcontext->pixel_radius == 0) {
1340  pcontext->pixel_radius = BKE_brush_size_get(pcontext->scene, brush);
1341  }
1342 
1343  copy_v3_v3(pcontext->scene_space_location, pcontext->location);
1344  mul_m4_v3(pcontext->vc.obact->obmat, pcontext->scene_space_location);
1345  }
1346  else {
1347  Sculpt *sd = CTX_data_tool_settings(pcontext->C)->sculpt;
1348  Brush *brush = BKE_paint_brush(&sd->paint);
1349 
1350  pcontext->pixel_radius = BKE_brush_size_get(pcontext->scene, brush);
1351  }
1352 }
1353 
1355 {
1356  BLI_assert(pcontext->ss != NULL);
1357  BLI_assert(pcontext->mode == PAINT_MODE_SCULPT);
1358 
1359  bContext *C = pcontext->C;
1360  SculptSession *ss = pcontext->ss;
1361  Brush *brush = pcontext->brush;
1362  Scene *scene = pcontext->scene;
1363  UnifiedPaintSettings *ups = pcontext->ups;
1364  ViewContext *vc = &pcontext->vc;
1366 
1367  const float mval_fl[2] = {
1368  pcontext->x - pcontext->region->winrct.xmin,
1369  pcontext->y - pcontext->region->winrct.ymin,
1370  };
1371 
1372  /* This updates the active vertex, which is needed for most of the Sculpt/Vertex Colors tools to
1373  * work correctly */
1375  if (!ups->stroke_active) {
1377  C, &gi, mval_fl, (pcontext->brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE));
1378  copy_v3_v3(pcontext->location, gi.location);
1379  copy_v3_v3(pcontext->normal, gi.normal);
1380  }
1381  else {
1382  pcontext->is_cursor_over_mesh = ups->last_hit;
1383  copy_v3_v3(pcontext->location, ups->last_location);
1384  }
1385 
1387 
1388  if (BKE_brush_use_locked_size(scene, brush)) {
1389  BKE_brush_size_set(scene, brush, pcontext->pixel_radius);
1390  }
1391 
1392  if (pcontext->is_cursor_over_mesh) {
1394  }
1395 
1396  pcontext->is_multires = ss->pbvh != NULL && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS;
1397 
1398  pcontext->sd = CTX_data_tool_settings(pcontext->C)->sculpt;
1399 }
1400 
1402 {
1403  WM_cursor_set(pcontext->win, WM_CURSOR_PAINT);
1404 }
1405 
1407 {
1408  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
1409 
1410  /* Draw brush outline. */
1411  if (pcontext->ups->stroke_active && BKE_brush_use_size_pressure(pcontext->brush)) {
1412  imm_draw_circle_wire_2d(pcontext->pos,
1413  pcontext->translation[0],
1414  pcontext->translation[1],
1415  pcontext->final_radius * pcontext->ups->size_pressure_value,
1416  40);
1417  /* Outer at half alpha. */
1418  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.5f);
1419  }
1420 
1421  GPU_line_width(1.0f);
1422  imm_draw_circle_wire_2d(pcontext->pos,
1423  pcontext->translation[0],
1424  pcontext->translation[1],
1425  pcontext->final_radius,
1426  40);
1427 }
1428 
1430 {
1431  GPU_line_width(1.0f);
1432  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
1433  imm_draw_circle_wire_3d(pcontext->pos,
1434  pcontext->translation[0],
1435  pcontext->translation[1],
1436  pcontext->final_radius,
1437  40);
1438 }
1439 
1441 {
1442  GPU_line_width(1.0f);
1443  /* Reduce alpha to increase the contrast when the cursor is over the mesh. */
1444  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.8);
1445  imm_draw_circle_wire_3d(pcontext->pos,
1446  pcontext->translation[0],
1447  pcontext->translation[1],
1448  pcontext->final_radius,
1449  80);
1450  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.35f);
1451  imm_draw_circle_wire_3d(pcontext->pos,
1452  pcontext->translation[0],
1453  pcontext->translation[1],
1454  pcontext->final_radius * clamp_f(pcontext->brush->alpha, 0.0f, 1.0f),
1455  80);
1456 }
1457 
1459 {
1460  if (!BKE_brush_use_locked_size(pcontext->scene, pcontext->brush)) {
1462  &pcontext->vc, pcontext->location, BKE_brush_size_get(pcontext->scene, pcontext->brush));
1463  }
1464  else {
1465  pcontext->radius = BKE_brush_unprojected_radius_get(pcontext->scene, pcontext->brush);
1466  }
1467 }
1468 
1470 {
1471  float cursor_trans[4][4], cursor_rot[4][4];
1472  const float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
1473  float quat[4];
1474  copy_m4_m4(cursor_trans, pcontext->vc.obact->obmat);
1475  translate_m4(cursor_trans, pcontext->location[0], pcontext->location[1], pcontext->location[2]);
1476  rotation_between_vecs_to_quat(quat, z_axis, pcontext->normal);
1477  quat_to_mat4(cursor_rot, quat);
1478  GPU_matrix_mul(cursor_trans);
1479  GPU_matrix_mul(cursor_rot);
1480 }
1481 
1483 {
1484  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
1485  GPU_line_width(2.0f);
1486  imm_draw_circle_wire_3d(pcontext->pos, 0, 0, pcontext->radius, 80);
1487 
1488  GPU_line_width(1.0f);
1489  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.5f);
1491  pcontext->pos, 0, 0, pcontext->radius * clamp_f(pcontext->brush->alpha, 0.0f, 1.0f), 80);
1492 }
1493 
1495 {
1496  SculptSession *ss = pcontext->ss;
1497  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
1498  GPU_line_width(2.0f);
1499 
1501  for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
1504  }
1505 
1506  immEnd();
1507 }
1508 
1510 {
1511 
1512  SculptSession *ss = pcontext->ss;
1513  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
1514  for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
1516  pcontext->region,
1518  pcontext->vc.obact->obmat,
1519  3);
1520  }
1521 }
1522 
1524 {
1525 
1526  if (!pcontext->ss->boundary_preview) {
1527  /* There is no guarantee that a boundary preview exists as there may be no boundaries
1528  * inside the brush radius. */
1529  return;
1530  }
1531  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
1533  pcontext->pos,
1534  pcontext->region,
1535  SCULPT_vertex_co_get(pcontext->ss, pcontext->ss->boundary_preview->pivot_vertex),
1536  pcontext->vc.obact->obmat,
1537  3);
1538 }
1539 
1541  const bool update_previews)
1542 {
1543  SculptSession *ss = pcontext->ss;
1544  if (!(update_previews || !ss->boundary_preview)) {
1545  return;
1546  }
1547 
1548  /* Needed for updating the necessary SculptSession data in order to initialize the
1549  * boundary data for the preview. */
1550  BKE_sculpt_update_object_for_edit(pcontext->depsgraph, pcontext->vc.obact, true, false, false);
1551 
1552  if (ss->boundary_preview) {
1554  }
1555 
1557  pcontext->vc.obact, pcontext->brush, ss->active_vertex_index, pcontext->radius);
1558 }
1559 
1561 {
1562  Brush *brush = pcontext->brush;
1563 
1564  /* 2D falloff is better represented with the default 2D cursor,
1565  * there is no need to draw anything else. */
1566  if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
1568  return;
1569  }
1570 
1571  if (pcontext->alpha_overlay_drawn) {
1573  return;
1574  }
1575 
1576  if (!pcontext->is_cursor_over_mesh) {
1578  return;
1579  }
1580 
1582 
1583  const bool update_previews = pcontext->prev_active_vertex_index !=
1584  SCULPT_active_vertex_get(pcontext->ss);
1585 
1586  /* Setup drawing. */
1587  wmViewport(&pcontext->region->winrct);
1588 
1589  /* Drawing of Cursor overlays in 2D screen space. */
1590 
1591  /* Cursor location symmetry points. */
1592 
1593  const float *active_vertex_co;
1594  if (brush->sculpt_tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
1595  active_vertex_co = SCULPT_vertex_co_for_grab_active_get(
1596  pcontext->ss, SCULPT_active_vertex_get(pcontext->ss));
1597  }
1598  else {
1599  active_vertex_co = SCULPT_active_vertex_co_get(pcontext->ss);
1600  }
1601  if (len_v3v3(active_vertex_co, pcontext->location) < pcontext->radius) {
1602  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
1604  pcontext->region,
1605  active_vertex_co,
1606  pcontext->sd,
1607  pcontext->vc.obact,
1608  pcontext->radius);
1609  }
1610 
1611  const bool is_brush_tool = PAINT_brush_tool_poll(pcontext->C);
1612 
1613  /* Pose brush updates and rotation origins. */
1614 
1615  if (is_brush_tool && brush->sculpt_tool == SCULPT_TOOL_POSE) {
1616  /* Just after switching to the Pose Brush, the active vertex can be the same and the
1617  * cursor won't be tagged to update, so always initialize the preview chain if it is
1618  * null before drawing it. */
1619  SculptSession *ss = pcontext->ss;
1620  if (update_previews || !ss->pose_ik_chain_preview) {
1622  pcontext->depsgraph, pcontext->vc.obact, true, false, false);
1623 
1624  /* Free the previous pose brush preview. */
1625  if (ss->pose_ik_chain_preview) {
1627  }
1628 
1629  /* Generate a new pose brush preview from the current cursor location. */
1631  pcontext->sd, pcontext->vc.obact, ss, brush, pcontext->location, pcontext->radius);
1632  }
1633 
1634  /* Draw the pose brush rotation origins. */
1636  }
1637 
1638  /* Expand operation origin. */
1639  if (pcontext->ss->expand_cache) {
1641  pcontext->pos,
1642  pcontext->region,
1644  pcontext->vc.obact->obmat,
1645  2);
1646  }
1647 
1648  if (is_brush_tool && brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) {
1649  paint_cursor_preview_boundary_data_update(pcontext, update_previews);
1651  }
1652 
1653  /* Setup 3D perspective drawing. */
1655  ED_view3d_draw_setup_view(pcontext->wm,
1656  pcontext->win,
1657  pcontext->depsgraph,
1658  pcontext->scene,
1659  pcontext->region,
1660  CTX_wm_view3d(pcontext->C),
1661  NULL,
1662  NULL,
1663  NULL);
1664 
1665  GPU_matrix_push();
1666  GPU_matrix_mul(pcontext->vc.obact->obmat);
1667 
1668  /* Drawing Cursor overlays in 3D object space. */
1669  if (is_brush_tool && brush->sculpt_tool == SCULPT_TOOL_GRAB &&
1670  (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX)) {
1671  SCULPT_geometry_preview_lines_update(pcontext->C, pcontext->ss, pcontext->radius);
1673  pcontext->pos, pcontext->brush, pcontext->is_multires, pcontext->ss);
1674  }
1675 
1676  if (is_brush_tool && brush->sculpt_tool == SCULPT_TOOL_POSE) {
1678  }
1679 
1680  if (is_brush_tool && brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) {
1682  pcontext->pos, pcontext->ss, pcontext->outline_col, pcontext->outline_alpha);
1683  SCULPT_boundary_pivot_line_preview_draw(pcontext->pos, pcontext->ss);
1684  }
1685 
1686  GPU_matrix_pop();
1687 
1688  /* Drawing Cursor overlays in Paint Cursor space (as additional info on top of the brush cursor)
1689  */
1690  GPU_matrix_push();
1692  /* Main inactive cursor. */
1694 
1695  /* Cloth brush local simulation areas. */
1696  if (is_brush_tool && brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
1698  const float white[3] = {1.0f, 1.0f, 1.0f};
1699  const float zero_v[3] = {0.0f};
1700  /* This functions sets its own drawing space in order to draw the simulation limits when the
1701  * cursor is active. When used here, this cursor overlay is already in cursor space, so its
1702  * position and normal should be set to 0. */
1704  pcontext->pos, brush, zero_v, zero_v, pcontext->radius, 1.0f, white, 0.25f);
1705  }
1706 
1707  /* Layer brush height. */
1708  if (is_brush_tool && brush->sculpt_tool == SCULPT_TOOL_LAYER) {
1710  brush,
1711  pcontext->radius,
1712  1.0f,
1713  pcontext->outline_col,
1714  pcontext->outline_alpha);
1715  }
1716 
1717  GPU_matrix_pop();
1718 
1719  /* Reset drawing. */
1721  wmWindowViewport(pcontext->win);
1722 }
1723 
1725 {
1726  BLI_assert(pcontext->ss != NULL);
1727  BLI_assert(pcontext->mode == PAINT_MODE_SCULPT);
1728 
1729  SculptSession *ss = pcontext->ss;
1730  Brush *brush = pcontext->brush;
1731 
1732  /* The cursor can be updated as active before creating the StrokeCache, so this needs to be
1733  * checked. */
1734  if (!ss->cache) {
1735  return;
1736  }
1737 
1738  /* Most of the brushes initialize the necessary data for the custom cursor drawing after the
1739  * first brush step, so make sure that it is not drawn before being initialized. */
1741  return;
1742  }
1743 
1744  /* Setup drawing. */
1745  wmViewport(&pcontext->region->winrct);
1747  ED_view3d_draw_setup_view(pcontext->wm,
1748  pcontext->win,
1749  pcontext->depsgraph,
1750  pcontext->scene,
1751  pcontext->region,
1752  CTX_wm_view3d(pcontext->C),
1753  NULL,
1754  NULL,
1755  NULL);
1756  GPU_matrix_push();
1757  GPU_matrix_mul(pcontext->vc.obact->obmat);
1758 
1759  /* Draw the special active cursors different tools may have. */
1760 
1761  if (brush->sculpt_tool == SCULPT_TOOL_GRAB) {
1762  sculpt_geometry_preview_lines_draw(pcontext->pos, brush, pcontext->is_multires, ss);
1763  }
1764 
1767  pcontext->pos, brush, ss, pcontext->outline_col, pcontext->outline_alpha);
1768  }
1769 
1770  if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
1773  pcontext->pos, ss, pcontext->outline_col, pcontext->outline_alpha);
1774  }
1777  /* Display the simulation limits if sculpting outside them. */
1778  /* This does not makes much sense of plane falloff as the falloff is infinite or global. */
1779 
1781  ss->cache->radius * (1.0f + brush->cloth_sim_limit)) {
1782  const float red[3] = {1.0f, 0.2f, 0.2f};
1784  brush,
1787  ss->cache->radius,
1788  2.0f,
1789  red,
1790  0.8f);
1791  }
1792  }
1793  }
1794 
1795  GPU_matrix_pop();
1796 
1798  wmWindowViewport(pcontext->win);
1799 }
1800 
1802 {
1803 
1804  /* These paint tools are not using the SculptSession, so they need to use the default 2D brush
1805  * cursor in the 3D view. */
1806  if (pcontext->mode != PAINT_MODE_SCULPT || !pcontext->ss) {
1808  return;
1809  }
1810 
1812 
1813  if (pcontext->is_stroke_active) {
1815  }
1816  else {
1818  }
1819 }
1820 
1822 {
1823  ViewContext *vc = &pcontext->vc;
1824  return vc->rv3d && (vc->rv3d->rflag & RV3D_NAVIGATING);
1825 }
1826 
1828 {
1829  if (pcontext->paint->flags & PAINT_SHOW_BRUSH) {
1831  pcontext->brush->imagepaint_tool == PAINT_TOOL_FILL) {
1832  return false;
1833  }
1834  return true;
1835  }
1836  return false;
1837 }
1838 
1840 {
1841  /* Don't calculate rake angles while a stroke is active because the rake variables are global
1842  * and we may get interference with the stroke itself.
1843  * For line strokes, such interference is visible. */
1844  if (!pcontext->ups->stroke_active) {
1845  paint_calculate_rake_rotation(pcontext->ups, pcontext->brush, pcontext->translation);
1846  }
1847 }
1848 
1850 {
1851  pcontext->alpha_overlay_drawn = paint_draw_alpha_overlay(pcontext->ups,
1852  pcontext->brush,
1853  &pcontext->vc,
1854  pcontext->x,
1855  pcontext->y,
1856  pcontext->zoomx,
1857  pcontext->mode);
1858 }
1859 
1861 {
1862  UnifiedPaintSettings *ups = pcontext->ups;
1863  if (ups->draw_anchored) {
1864  pcontext->final_radius = ups->anchored_size;
1865  copy_v2_fl2(pcontext->translation,
1866  ups->anchored_initial_mouse[0] + pcontext->region->winrct.xmin,
1867  ups->anchored_initial_mouse[1] + pcontext->region->winrct.ymin);
1868  }
1869 }
1870 
1872 {
1873  GPU_line_width(2.0f);
1875  GPU_line_smooth(true);
1876  pcontext->pos = GPU_vertformat_attr_add(
1879 }
1880 
1882 {
1883  GPU_line_width(2.0f);
1885  GPU_line_smooth(true);
1886  pcontext->pos = GPU_vertformat_attr_add(
1889 }
1890 
1892 {
1893  immUnbindProgram();
1895  GPU_line_smooth(false);
1896 }
1897 
1898 static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
1899 {
1900  PaintCursorContext pcontext;
1901  if (!paint_cursor_context_init(C, x, y, &pcontext)) {
1902  return;
1903  }
1904 
1905  if (!paint_cursor_is_brush_cursor_enabled(&pcontext)) {
1906  return;
1907  }
1908  if (paint_cursor_is_3d_view_navigating(&pcontext)) {
1909  return;
1910  }
1911 
1912  switch (pcontext.cursor_type) {
1913  case PAINT_CURSOR_CURVE:
1914  paint_draw_curve_cursor(pcontext.brush, &pcontext.vc);
1915  break;
1916  case PAINT_CURSOR_2D:
1920 
1921  paint_cursor_setup_2D_drawing(&pcontext);
1924  break;
1925  case PAINT_CURSOR_3D:
1926  paint_update_mouse_cursor(&pcontext);
1927 
1931 
1932  paint_cursor_setup_3D_drawing(&pcontext);
1935  break;
1936  }
1937 }
1938 
1939 /* Public API */
1940 
1941 void ED_paint_cursor_start(Paint *p, bool (*poll)(bContext *C))
1942 {
1943  if (p && !p->paint_cursor) {
1946  }
1947 
1948  /* Invalidate the paint cursors. */
1950 }
typedef float(TangentPoint)[2]
float BKE_brush_curve_strength_clamped(const struct Brush *br, float p, float len)
void BKE_brush_size_set(struct Scene *scene, struct Brush *brush, int size)
Definition: brush.cc:2234
bool BKE_brush_use_size_pressure(const struct Brush *brush)
bool BKE_brush_sculpt_has_secondary_color(const struct Brush *brush)
int BKE_brush_size_get(const struct Scene *scene, const struct Brush *brush)
float BKE_brush_unprojected_radius_get(const struct Scene *scene, const struct Brush *brush)
void BKE_brush_unprojected_radius_set(struct Scene *scene, struct Brush *brush, float unprojected_radius)
Definition: brush.cc:2294
bool BKE_brush_use_locked_size(const struct Scene *scene, const struct Brush *brush)
void BKE_curvemapping_init(struct CurveMapping *cumap)
Definition: colortools.c:1235
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:784
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
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
Definition: context.c:1282
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride)
Definition: curve.cc:1717
void BKE_image_pool_release_ibuf(struct Image *ima, struct ImBuf *ibuf, struct ImagePool *pool)
struct ImBuf * BKE_image_pool_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, struct ImagePool *pool)
struct ImagePool * BKE_image_pool_new(void)
void BKE_image_pool_free(struct ImagePool *pool)
General operations, lookup, etc. for blender objects.
const struct BoundBox * BKE_object_boundbox_get(struct Object *ob)
Definition: object.cc:3684
bool paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups, struct Brush *brush, const float mouse_pos[2])
Definition: paint.c:1305
ePaintMode BKE_paintmode_get_active_from_context(const struct bContext *C)
void BKE_sculpt_update_object_for_edit(struct Depsgraph *depsgraph, struct Object *ob_orig, bool need_pmap, bool need_mask, bool is_paint_tool)
Definition: paint.c:1914
struct Brush * BKE_paint_brush(struct Paint *paint)
Definition: paint.c:607
ePaintOverlayControlFlags
Definition: BKE_paint.h:92
@ PAINT_OVERLAY_INVALID_CURVE
Definition: BKE_paint.h:95
@ PAINT_OVERLAY_INVALID_TEXTURE_SECONDARY
Definition: BKE_paint.h:94
@ PAINT_OVERLAY_OVERRIDE_CURSOR
Definition: BKE_paint.h:96
@ PAINT_OVERLAY_INVALID_TEXTURE_PRIMARY
Definition: BKE_paint.h:93
@ PAINT_OVERLAY_OVERRIDE_SECONDARY
Definition: BKE_paint.h:98
@ PAINT_OVERLAY_OVERRIDE_PRIMARY
Definition: BKE_paint.h:97
void BKE_paint_reset_overlay_invalid(ePaintOverlayControlFlags flag)
Definition: paint.c:289
struct Paint * BKE_paint_get_active_from_context(const struct bContext *C)
void BKE_paint_invalidate_overlay_all(void)
Definition: paint.c:260
ePaintMode
Definition: BKE_paint.h:67
@ PAINT_MODE_TEXTURE_3D
Definition: BKE_paint.h:73
@ PAINT_MODE_SCULPT
Definition: BKE_paint.h:68
@ PAINT_MODE_WEIGHT
Definition: BKE_paint.h:71
@ PAINT_MODE_TEXTURE_2D
Definition: BKE_paint.h:75
@ PAINT_MODE_VERTEX
Definition: BKE_paint.h:70
ePaintOverlayControlFlags BKE_paint_get_overlay_flags(void)
Definition: paint.c:266
PBVHType BKE_pbvh_type(const PBVH *pbvh)
Definition: pbvh.c:1798
@ PBVH_GRIDS
Definition: BKE_pbvh.h:235
@ PBVH_FACES
Definition: BKE_pbvh.h:234
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_INLINE
MINLINE float max_ff(float a, float b)
MINLINE float clamp_f(float value, float min, float max)
#define M_PI
Definition: BLI_math_base.h:20
void unit_m4(float m[4][4])
Definition: rct.c:1090
void translate_m4(float mat[4][4], float tx, float ty, float tz)
Definition: math_matrix.c:2318
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
void rotate_m4(float mat[4][4], char axis, float angle)
Definition: math_matrix.c:2325
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3])
#define RAD2DEGF(_rad)
void quat_to_mat4(float mat[4][4], const float q[4])
MINLINE void mul_v4_fl(float r[4], float f)
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v2_fl2(float v[2], float x, float y)
MINLINE float normalize_v3(float r[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_v3_int(int r[3], const int a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE float len_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
unsigned char uchar
Definition: BLI_sys_types.h:70
unsigned int uint
Definition: BLI_sys_types.h:67
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:94
int BLI_task_parallel_thread_id(const TaskParallelTLS *tls)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:293
#define UNUSED(x)
#define UNPACK3(a)
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
@ BRUSH_CURVE
@ BRUSH_GRAB_ACTIVE_VERTEX
@ BRUSH_DIR_IN
@ BRUSH_ANCHORED
@ SCULPT_TOOL_CLOTH
@ SCULPT_TOOL_GRAB
@ SCULPT_TOOL_BOUNDARY
@ SCULPT_TOOL_POSE
@ SCULPT_TOOL_LAYER
@ SCULPT_TOOL_MULTIPLANE_SCRAPE
@ PAINT_FALLOFF_SHAPE_SPHERE
@ PAINT_FALLOFF_SHAPE_TUBE
@ PAINT_TOOL_FILL
@ PAINT_TOOL_DRAW
@ BRUSH_OVERLAY_SECONDARY
@ BRUSH_OVERLAY_CURSOR
@ BRUSH_OVERLAY_PRIMARY
@ BRUSH_CLOTH_FORCE_FALLOFF_RADIAL
@ BRUSH_CLOTH_FORCE_FALLOFF_PLANE
@ BRUSH_CLOTH_SIMULATION_AREA_LOCAL
@ BRUSH_CLOTH_SIMULATION_AREA_GLOBAL
Object is a sort of wrapper for general info.
@ PAINT_SHOW_BRUSH
@ PAINT_TILE_X
@ RGN_TYPE_WINDOW
#define RGN_TYPE_ANY
@ SPACE_VIEW3D
#define SPACE_TYPE_ANY
#define MTEX_MAP_MODE_VIEW
#define MTEX_MAP_MODE_STENCIL
#define MTEX_MAP_MODE_TILED
#define RV3D_NAVIGATING
@ V3D_PROJ_TEST_NOP
Definition: ED_view3d.h:234
void ED_view3d_project_v3(const struct ARegion *region, const float world[3], float r_region_co[3])
eV3DProjStatus ED_view3d_project_float_global(const struct ARegion *region, const float co[3], float r_co[2], eV3DProjTest flag)
void ED_view3d_viewcontext_init(struct bContext *C, struct ViewContext *vc, struct Depsgraph *depsgraph)
@ V3D_PROJ_RET_OK
Definition: ED_view3d.h:217
void ED_view3d_draw_setup_view(const struct wmWindowManager *wm, struct wmWindow *win, struct Depsgraph *depsgraph, struct Scene *scene, struct ARegion *region, struct View3D *v3d, const float viewmat[4][4], const float winmat[4][4], const struct rcti *rect)
void ED_view3d_global_to_vector(const struct RegionView3D *rv3d, const float coord[3], float vec[3])
static AppView * view
NSNotificationCenter * center
void immUniformColor4f(float r, float g, float b, float a)
void immUnbindProgram(void)
void immVertex2f(uint attr_id, float x, float y)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immVertex2fv(uint attr_id, const float data[2])
void immBindTextureSampler(const char *name, GPUTexture *tex, eGPUSamplerState state)
void immUniformColor4fv(const float rgba[4])
GPUVertFormat * immVertexFormat(void)
void immAttr2f(uint attr_id, float x, float y)
void immVertex3fv(uint attr_id, const float data[3])
void immBegin(GPUPrimType, uint vertex_len)
void immUniformColor3fvAlpha(const float rgb[3], float a)
void immEnd(void)
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
void imm_draw_circle_wire_3d(uint pos, float x, float y, float radius, int nsegments)
void imm_draw_circle_fill_3d(uint pos, float x, float y, float radius, int nsegments)
void imm_draw_circle_wire_2d(uint shdr_pos, float x, float y, float radius, int nsegments)
_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 GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_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
_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 GLsizei width
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:126
void GPU_matrix_translate_2fv(const float vec[2])
Definition: gpu_matrix.cc:183
void GPU_matrix_scale_2f(float x, float y)
Definition: gpu_matrix.cc:216
void GPU_matrix_pop_projection(void)
Definition: gpu_matrix.cc:140
#define GPU_matrix_mul(x)
Definition: GPU_matrix.h:224
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:119
void GPU_matrix_scale_1f(float factor)
Definition: gpu_matrix.cc:209
void GPU_matrix_rotate_2d(float deg)
Definition: gpu_matrix.cc:253
void GPU_matrix_translate_2f(float x, float y)
Definition: gpu_matrix.cc:174
void GPU_matrix_push_projection(void)
Definition: gpu_matrix.cc:133
@ GPU_PRIM_TRI_FAN
Definition: GPU_primitive.h:25
@ GPU_PRIM_LINE_LOOP
Definition: GPU_primitive.h:23
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:20
@ GPU_PRIM_LINE_STRIP
Definition: GPU_primitive.h:22
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:201
@ GPU_SHADER_3D_UNIFORM_COLOR
Definition: GPU_shader.h:230
@ GPU_SHADER_2D_IMAGE_COLOR
Definition: GPU_shader.h:217
eGPUBlend
Definition: GPU_state.h:59
@ GPU_BLEND_NONE
Definition: GPU_state.h:60
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:62
@ GPU_BLEND_ALPHA_PREMULT
Definition: GPU_state.h:63
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:39
void GPU_line_width(float width)
Definition: gpu_state.cc:158
void GPU_line_smooth(bool enable)
Definition: gpu_state.cc:75
void GPU_color_mask(bool r, bool g, bool b, bool a)
Definition: gpu_state.cc:95
eGPUBlend GPU_blend_get(void)
Definition: gpu_state.cc:218
eGPUDepthTest
Definition: GPU_state.h:82
@ GPU_DEPTH_LESS_EQUAL
Definition: GPU_state.h:86
@ GPU_DEPTH_NONE
Definition: GPU_state.h:83
eGPUDepthTest GPU_depth_test_get(void)
Definition: gpu_state.cc:236
void GPU_depth_test(eGPUDepthTest test)
Definition: gpu_state.cc:65
eGPUSamplerState
Definition: GPU_texture.h:25
@ GPU_SAMPLER_REPEAT
Definition: GPU_texture.h:37
@ GPU_SAMPLER_FILTER
Definition: GPU_texture.h:27
@ GPU_SAMPLER_CLAMP_BORDER
Definition: GPU_texture.h:32
void GPU_texture_swizzle_set(GPUTexture *tex, const char swizzle[4])
Definition: gpu_texture.cc:553
struct GPUTexture GPUTexture
Definition: GPU_texture.h:17
@ GPU_DATA_UBYTE
Definition: GPU_texture.h:174
void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
Definition: gpu_texture.cc:444
void GPU_texture_free(GPUTexture *tex)
Definition: gpu_texture.cc:564
void GPU_texture_unbind(GPUTexture *tex)
Definition: gpu_texture.cc:472
GPUTexture * GPU_texture_create_2d(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:291
eGPUTextureFormat
Definition: GPU_texture.h:83
@ GPU_R8
Definition: GPU_texture.h:107
@ GPU_RGBA8
Definition: GPU_texture.h:87
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a producing a negative Combine Generate a color from its red
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 TEX_IMAGE
void ntreeTexEndExecTree(struct bNodeTreeExec *exec)
struct bNodeTreeExec * ntreeTexBeginExecTree(struct bNodeTree *ntree)
#define C
Definition: RandGen.cpp:25
@ TH_PAINT_CURVE_HANDLE
Definition: UI_resources.h:248
@ TH_VERTEX_SELECT
Definition: UI_resources.h:78
@ TH_PAINT_CURVE_PIVOT
Definition: UI_resources.h:249
void UI_GetThemeColorType4fv(int colorid, int spacetype, float col[4])
Definition: resources.c:1182
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
#define sinf(x)
Definition: cuda/compat.h:102
#define cosf(x)
Definition: cuda/compat.h:101
Scene scene
int len
Definition: draw_manager.c:108
uint pos
uint col
GPUBatch * quad
ccl_global float * buffer
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
const int state
format
Definition: logImageCore.h:38
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
#define atan2f(x, y)
Definition: metal/compat.h:227
#define fabsf(x)
Definition: metal/compat.h:219
#define sqrtf(x)
Definition: metal/compat.h:243
static const pxr::TfToken rgba("rgba", pxr::TfToken::Immortal)
vector snap(vector a, vector b)
Definition: node_math.h:59
static ePaintOverlayControlFlags overlay_flags
Definition: paint.c:225
static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush, ViewContext *vc, int x, int y, float zoom, const ePaintMode mode, bool col, bool primary)
Definition: paint_cursor.c:528
static void paint_draw_legacy_3D_view_brush_cursor(PaintCursorContext *pcontext)
static void paint_cursor_drawing_setup_cursor_space(PaintCursorContext *pcontext)
static void cursor_draw_point_with_symmetry(const uint gpuattr, const ARegion *region, const float true_location[3], Sculpt *sd, Object *ob, const float radius)
struct TexSnapshot TexSnapshot
static void paint_cursor_update_object_space_radius(PaintCursorContext *pcontext)
static void paint_cursor_pose_brush_segments_draw(PaintCursorContext *pcontext)
static void paint_cursor_preview_boundary_data_pivot_draw(PaintCursorContext *pcontext)
static void load_tex_cursor_task_cb(void *__restrict userdata, const int j, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: paint_cursor.c:363
static CursorSnapshot cursor_snap
Definition: paint_cursor.c:86
static void paint_draw_3D_view_inactive_brush_cursor(PaintCursorContext *pcontext)
static void paint_cursor_draw_3D_view_brush_cursor(PaintCursorContext *pcontext)
static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext *pcontext)
static TexSnapshot primary_snap
Definition: paint_cursor.c:84
static bool paint_cursor_context_init(bContext *C, const int x, const int y, PaintCursorContext *pcontext)
static bool paint_cursor_is_brush_cursor_enabled(PaintCursorContext *pcontext)
static void paint_cursor_restore_drawing_state(void)
static void make_tex_snap(TexSnapshot *snap, ViewContext *vc, float zoom)
Definition: paint_cursor.c:119
void paint_cursor_delete_textures(void)
Definition: paint_cursor.c:88
static void paint_cursor_check_and_draw_alpha_overlays(PaintCursorContext *pcontext)
static bool paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush, ViewContext *vc, int x, int y, float zoom, ePaintMode mode)
Definition: paint_cursor.c:760
static void paint_cursor_preview_boundary_data_update(PaintCursorContext *pcontext, const bool update_previews)
struct LoadTexData LoadTexData
BLI_INLINE void draw_bezier_handle_lines(uint pos, const float sel_col[4], BezTriple *bez)
Definition: paint_cursor.c:872
static void paint_cursor_update_pixel_radius(PaintCursorContext *pcontext)
static int project_brush_radius(ViewContext *vc, float radius, const float location[3])
Definition: paint_cursor.c:481
static int same_tex_snap(TexSnapshot *snap, MTex *mtex, ViewContext *vc, bool col, float zoom)
Definition: paint_cursor.c:107
PaintCursorDrawingType
@ PAINT_CURSOR_3D
@ PAINT_CURSOR_CURVE
@ PAINT_CURSOR_2D
static void sculpt_geometry_preview_lines_draw(const uint gpuattr, Brush *brush, const bool is_multires, SculptSession *ss)
static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc)
Definition: paint_cursor.c:908
static void paint_cursor_update_anchored_location(PaintCursorContext *pcontext)
static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool primary)
Definition: paint_cursor.c:236
static bool paint_draw_cursor_overlay(UnifiedPaintSettings *ups, Brush *brush, ViewContext *vc, int x, int y, float zoom)
Definition: paint_cursor.c:678
static void paint_update_mouse_cursor(PaintCursorContext *pcontext)
static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorContext *pcontext)
static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
Definition: paint_cursor.c:395
static bool paint_use_2d_cursor(ePaintMode mode)
void ED_paint_cursor_start(Paint *p, bool(*poll)(bContext *C))
static void cursor_draw_point_screen_space(const uint gpuattr, const ARegion *region, const float true_location[3], const float obmat[4][4], const int size)
static void cursor_draw_tiling_preview(const uint gpuattr, const ARegion *region, const float true_location[3], Sculpt *sd, Object *ob, const float radius)
static void load_tex_task_cb_ex(void *__restrict userdata, const int j, const TaskParallelTLS *__restrict tls)
Definition: paint_cursor.c:140
static void SCULPT_layer_brush_height_preview_draw(const uint gpuattr, const Brush *brush, const float rds, const float line_width, const float outline_col[3], const float alpha)
static void paint_cursor_pose_brush_origins_draw(PaintCursorContext *pcontext)
static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext *pcontext)
static void paint_cursor_setup_2D_drawing(PaintCursorContext *pcontext)
static TexSnapshot secondary_snap
Definition: paint_cursor.c:85
BLI_INLINE void draw_tri_point(uint pos, const float sel_col[4], const float pivot_col[4], float *co, float width, bool selected)
Definition: paint_cursor.c:813
static void paint_cursor_update_unprojected_radius(UnifiedPaintSettings *ups, Brush *brush, ViewContext *vc, const float location[3])
Definition: paint_cursor.c:989
BLI_INLINE void draw_rect_point(uint pos, const float sel_col[4], const float handle_col[4], const float *co, float width, bool selected)
Definition: paint_cursor.c:847
struct CursorSnapshot CursorSnapshot
static bool paint_cursor_is_3d_view_navigating(PaintCursorContext *pcontext)
struct PaintCursorContext PaintCursorContext
static void paint_cursor_draw_main_inactive_cursor(PaintCursorContext *pcontext)
static void paint_draw_2D_view_brush_cursor(PaintCursorContext *pcontext)
static void paint_cursor_update_rake_rotation(PaintCursorContext *pcontext)
static void paint_cursor_setup_3D_drawing(PaintCursorContext *pcontext)
bool get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
Definition: paint_image.cc:404
void paint_get_tex_pixel_col(const struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread, bool convert, struct ColorSpace *colorspace)
float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius)
Definition: paint_utils.c:130
float paint_get_tex_pixel(const struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread)
#define PAINT_CURVE_NUM_SEGMENTS
Definition: paint_intern.h:510
bool PAINT_brush_tool_poll(struct bContext *C)
BLI_INLINE void flip_v3_v3(float out[3], const float in[3], const ePaintSymmetryFlags symm)
Definition: paint_intern.h:392
const float * SCULPT_vertex_co_get(SculptSession *ss, int index)
Definition: sculpt.c:125
int SCULPT_active_vertex_get(SculptSession *ss)
Definition: sculpt.c:271
bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mval[2], bool use_sampled_normal)
Definition: sculpt.c:4835
const float * SCULPT_vertex_co_for_grab_active_get(SculptSession *ss, int index)
Definition: sculpt.c:201
const float * SCULPT_active_vertex_co_get(SculptSession *ss)
Definition: sculpt.c:279
bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(StrokeCache *cache)
Definition: sculpt.c:918
char SCULPT_mesh_symmetry_xyz_get(Object *object)
Definition: sculpt.c:317
void SCULPT_boundary_data_free(SculptBoundary *boundary)
void SCULPT_boundary_pivot_line_preview_draw(const uint gpuattr, SculptSession *ss)
SculptBoundary * SCULPT_boundary_data_init(Object *object, Brush *brush, const int initial_vertex, const float radius)
void SCULPT_boundary_edges_preview_draw(const uint gpuattr, SculptSession *ss, const float outline_col[3], const float outline_alpha)
void SCULPT_cloth_simulation_limits_draw(const uint gpuattr, const Brush *brush, const float location[3], const float normal[3], const float rds, const float line_width, const float outline_col[3], const float alpha)
void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr, SculptSession *ss, const float outline_col[3], float outline_alpha)
struct SculptPoseIKChain * SCULPT_pose_ik_chain_init(struct Sculpt *sd, struct Object *ob, struct SculptSession *ss, struct Brush *br, const float initial_location[3], float radius)
Definition: sculpt_pose.c:922
void SCULPT_multiplane_scrape_preview_draw(uint gpuattr, Brush *brush, SculptSession *ss, const float outline_col[3], float outline_alpha)
void SCULPT_geometry_preview_lines_update(bContext *C, struct SculptSession *ss, float radius)
Definition: sculpt_ops.c:541
void SCULPT_pose_ik_chain_free(struct SculptPoseIKChain *ik_chain)
Definition: sculpt_pose.c:1209
short regiontype
uint8_t f3
float vec[3][3]
uint8_t f1
uint8_t f2
float vec[8][3]
float alpha
int mask_overlay_alpha
float add_col[4]
struct MTex mtex
float stencil_pos[2]
int texture_overlay_alpha
float stencil_dimension[2]
int cursor_overlay_alpha
int curve_preset
struct CurveMapping * curve
float texture_sample_bias
char falloff_shape
float mask_stencil_pos[2]
char imagepaint_tool
float cloth_sim_limit
float height
float sub_col[4]
char sculpt_tool
struct MTex mask_mtex
float mask_stencil_dimension[2]
int cloth_simulation_area_type
struct PaintCurve * paint_curve
int cloth_force_falloff_type
int overlay_flags
GPUTexture * overlay_texture
Definition: paint_cursor.c:78
int initial_active_vertex
struct ColorSpace * rect_colorspace
float * rect_float
ViewContext * vc
Definition: paint_cursor.c:128
Brush * br
Definition: paint_cursor.c:127
uchar * buffer
Definition: paint_cursor.c:131
struct ImagePool * pool
Definition: paint_cursor.c:134
float rotation
Definition: paint_cursor.c:136
char brush_map_mode
float rot
struct Tex * tex
float obmat[4][4]
struct SculptSession * sculpt
UnifiedPaintSettings * ups
float scene_space_location[3]
wmWindowManager * wm
PaintCursorDrawingType cursor_type
Depsgraph * depsgraph
SculptSession * ss
PaintCurvePoint * points
float tile_offset[3]
int symmetry_flags
void * paint_cursor
struct ToolSettings * toolsettings
SculptPoseIKChainSegment * segments
Definition: BKE_paint.h:297
SculptPoseIKChain * pose_ik_chain_preview
Definition: BKE_paint.h:599
int preview_vert_index_count
Definition: BKE_paint.h:595
bool draw_faded_cursor
Definition: BKE_paint.h:575
int * preview_vert_index_list
Definition: BKE_paint.h:594
SculptBoundary * boundary_preview
Definition: BKE_paint.h:602
int active_vertex_index
Definition: BKE_paint.h:568
struct StrokeCache * cache
Definition: BKE_paint.h:563
struct ExpandCache * expand_cache
Definition: BKE_paint.h:565
struct PBVH * pbvh
Definition: BKE_paint.h:550
bool deform_modifiers_active
Definition: BKE_paint.h:555
Paint paint
int radial_symm[3]
float true_location[3]
float true_initial_location[3]
float true_initial_normal[3]
float old_zoom
Definition: paint_cursor.c:73
GPUTexture * overlay_texture
Definition: paint_cursor.c:69
struct ImageUser iuser
short type
struct bNodeTree * nodetree
struct Image * ima
struct UnifiedPaintSettings unified_paint_settings
struct Scene * scene
Definition: ED_view3d.h:65
struct ARegion * region
Definition: ED_view3d.h:69
struct Object * obact
Definition: ED_view3d.h:67
struct RegionView3D * rv3d
Definition: ED_view3d.h:72
struct bNodeTreeExec * execdata
int ymin
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
void WM_cursor_set(wmWindow *win, int curs)
Definition: wm_cursors.c:126
@ WM_CURSOR_PAINT
Definition: wm_cursors.h:27
wmPaintCursor * WM_paint_cursor_activate(short space_type, short region_type, bool(*poll)(bContext *C), wmPaintCursorDraw draw, void *customdata)
void wmViewport(const rcti *winrct)
Definition: wm_subwindow.c:21
void wmWindowViewport(wmWindow *win)
Definition: wm_subwindow.c:72