Blender  V2.93
paint_cursor.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2009 by Nicholas Bishop
17  * All rights reserved.
18  */
19 
24 #include "MEM_guardedalloc.h"
25 
26 #include "BLI_math.h"
27 #include "BLI_rect.h"
28 #include "BLI_task.h"
29 #include "BLI_utildefines.h"
30 
31 #include "DNA_brush_types.h"
32 #include "DNA_color_types.h"
33 #include "DNA_customdata_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_scene_types.h"
36 #include "DNA_screen_types.h"
37 #include "DNA_space_types.h"
38 #include "DNA_userdef_types.h"
39 #include "DNA_view3d_types.h"
40 
41 #include "BKE_brush.h"
42 #include "BKE_colortools.h"
43 #include "BKE_context.h"
44 #include "BKE_curve.h"
45 #include "BKE_image.h"
46 #include "BKE_node.h"
47 #include "BKE_object.h"
48 #include "BKE_paint.h"
49 
50 #include "WM_api.h"
51 #include "wm_cursors.h"
52 
53 #include "IMB_imbuf_types.h"
54 
55 #include "ED_view3d.h"
56 
57 #include "DEG_depsgraph.h"
58 
59 #include "GPU_immediate.h"
60 #include "GPU_immediate_util.h"
61 #include "GPU_matrix.h"
62 #include "GPU_state.h"
63 #include "GPU_texture.h"
64 
65 #include "UI_resources.h"
66 
67 #include "paint_intern.h"
68 /* still needed for sculpt_stroke_get_location, should be
69  * removed eventually (TODO) */
70 #include "sculpt_intern.h"
71 
72 /* TODOs:
73  *
74  * Some of the cursor drawing code is doing non-draw stuff
75  * (e.g. updating the brush rake angle). This should be cleaned up
76  * still.
77  *
78  * There is also some ugliness with sculpt-specific code.
79  */
80 
81 typedef struct TexSnapshot {
83  int winx;
84  int winy;
85  int old_size;
86  float old_zoom;
87  bool old_col;
89 
90 typedef struct CursorSnapshot {
92  int size;
93  int zoom;
96 
100 
101 /* Delete overlay cursor textures to preserve memory and invalidate all overlay flags. */
103 {
106  }
109  }
112  }
113 
114  memset(&primary_snap, 0, sizeof(TexSnapshot));
115  memset(&secondary_snap, 0, sizeof(TexSnapshot));
116  memset(&cursor_snap, 0, sizeof(CursorSnapshot));
117 
119 }
120 
121 static int same_tex_snap(TexSnapshot *snap, MTex *mtex, ViewContext *vc, bool col, float zoom)
122 {
123  return (/* make brush smaller shouldn't cause a resample */
124  //(mtex->brush_map_mode != MTEX_MAP_MODE_VIEW ||
125  //(BKE_brush_size_get(vc->scene, brush) <= snap->BKE_brush_size_get)) &&
126 
128  (vc->region->winx == snap->winx && vc->region->winy == snap->winy)) &&
129  (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL || snap->old_zoom == zoom) &&
130  snap->old_col == col);
131 }
132 
133 static void make_tex_snap(TexSnapshot *snap, ViewContext *vc, float zoom)
134 {
135  snap->old_zoom = zoom;
136  snap->winx = vc->region->winx;
137  snap->winy = vc->region->winy;
138 }
139 
140 typedef struct LoadTexData {
143 
146  bool col;
147 
148  struct ImagePool *pool;
149  int size;
150  float rotation;
151  float radius;
153 
154 static void load_tex_task_cb_ex(void *__restrict userdata,
155  const int j,
156  const TaskParallelTLS *__restrict tls)
157 {
158  LoadTexData *data = userdata;
159  Brush *br = data->br;
160  ViewContext *vc = data->vc;
161 
162  MTex *mtex = data->mtex;
163  uchar *buffer = data->buffer;
164  const bool col = data->col;
165 
166  struct ImagePool *pool = data->pool;
167  const int size = data->size;
168  const float rotation = data->rotation;
169  const float radius = data->radius;
170 
171  bool convert_to_linear = false;
172  struct ColorSpace *colorspace = NULL;
173 
174  const int thread_id = BLI_task_parallel_thread_id(tls);
175 
176  if (mtex->tex && mtex->tex->type == TEX_IMAGE && mtex->tex->ima) {
177  ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(mtex->tex->ima, &mtex->tex->iuser, pool);
178  /* For consistency, sampling always returns color in linear space. */
179  if (tex_ibuf && tex_ibuf->rect_float == NULL) {
180  convert_to_linear = true;
181  colorspace = tex_ibuf->rect_colorspace;
182  }
183  BKE_image_pool_release_ibuf(mtex->tex->ima, tex_ibuf, pool);
184  }
185 
186  for (int i = 0; i < size; i++) {
187  /* Largely duplicated from tex_strength. */
188 
189  int index = j * size + i;
190 
191  float x = (float)i / size;
192  float y = (float)j / size;
193  float len;
194 
195  if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
196  x *= vc->region->winx / radius;
197  y *= vc->region->winy / radius;
198  }
199  else {
200  x = (x - 0.5f) * 2.0f;
201  y = (y - 0.5f) * 2.0f;
202  }
203 
204  len = sqrtf(x * x + y * y);
205 
207  /* It is probably worth optimizing for those cases where the texture is not rotated by
208  * skipping the calls to atan2, sqrtf, sin, and cos. */
209  if (mtex->tex && (rotation > 0.001f || rotation < -0.001f)) {
210  const float angle = atan2f(y, x) + rotation;
211 
212  x = len * cosf(angle);
213  y = len * sinf(angle);
214  }
215 
216  if (col) {
217  float rgba[4];
218 
219  paint_get_tex_pixel_col(mtex, x, y, rgba, pool, thread_id, convert_to_linear, colorspace);
220 
221  buffer[index * 4] = rgba[0] * 255;
222  buffer[index * 4 + 1] = rgba[1] * 255;
223  buffer[index * 4 + 2] = rgba[2] * 255;
224  buffer[index * 4 + 3] = rgba[3] * 255;
225  }
226  else {
227  float avg = paint_get_tex_pixel(mtex, x, y, pool, thread_id);
228 
229  avg += br->texture_sample_bias;
230 
231  /* Clamp to avoid precision overflow. */
232  CLAMP(avg, 0.0f, 1.0f);
233  buffer[index] = 255 - (uchar)(255 * avg);
234  }
235  }
236  else {
237  if (col) {
238  buffer[index * 4] = 0;
239  buffer[index * 4 + 1] = 0;
240  buffer[index * 4 + 2] = 0;
241  buffer[index * 4 + 3] = 0;
242  }
243  else {
244  buffer[index] = 0;
245  }
246  }
247  }
248 }
249 
250 static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool primary)
251 {
252  bool init;
253  TexSnapshot *target;
254 
255  MTex *mtex = (primary) ? &br->mtex : &br->mask_mtex;
257  uchar *buffer = NULL;
258 
259  int size;
260  bool refresh;
261  ePaintOverlayControlFlags invalid =
264  target = (primary) ? &primary_snap : &secondary_snap;
265 
266  refresh = !target->overlay_texture || (invalid != 0) ||
267  !same_tex_snap(target, mtex, vc, col, zoom);
268 
269  init = (target->overlay_texture != 0);
270 
271  if (refresh) {
272  struct ImagePool *pool = NULL;
273  /* Stencil is rotated later. */
274  const float rotation = (mtex->brush_map_mode != MTEX_MAP_MODE_STENCIL) ? -mtex->rot : 0.0f;
275  const float radius = BKE_brush_size_get(vc->scene, br) * zoom;
276 
277  make_tex_snap(target, vc, zoom);
278 
279  if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
280  int s = BKE_brush_size_get(vc->scene, br);
281  int r = 1;
282 
283  for (s >>= 1; s > 0; s >>= 1) {
284  r++;
285  }
286 
287  size = (1 << r);
288 
289  if (size < 256) {
290  size = 256;
291  }
292 
293  if (size < target->old_size) {
294  size = target->old_size;
295  }
296  }
297  else {
298  size = 512;
299  }
300 
301  if (target->old_size != size || target->old_col != col) {
302  if (target->overlay_texture) {
304  target->overlay_texture = NULL;
305  }
306  init = false;
307 
308  target->old_size = size;
309  target->old_col = col;
310  }
311  if (col) {
312  buffer = MEM_mallocN(sizeof(uchar) * size * size * 4, "load_tex");
313  }
314  else {
315  buffer = MEM_mallocN(sizeof(uchar) * size * size, "load_tex");
316  }
317 
319 
320  if (mtex->tex && mtex->tex->nodetree) {
321  /* Has internal flag to detect it only does it once. */
323  }
324 
325  LoadTexData data = {
326  .br = br,
327  .vc = vc,
328  .mtex = mtex,
329  .buffer = buffer,
330  .col = col,
331  .pool = pool,
332  .size = size,
333  .rotation = rotation,
334  .radius = radius,
335  };
336 
337  TaskParallelSettings settings;
340 
341  if (mtex->tex && mtex->tex->nodetree) {
343  }
344 
345  if (pool) {
347  }
348 
349  if (!target->overlay_texture) {
352  "paint_cursor_overlay", size, size, 1, format, NULL);
354 
355  if (!col) {
356  GPU_texture_swizzle_set(target->overlay_texture, "rrrr");
357  }
358  }
359 
360  if (init) {
362  }
363 
364  if (buffer) {
365  MEM_freeN(buffer);
366  }
367  }
368  else {
369  size = target->old_size;
370  }
371 
373 
374  return 1;
375 }
376 
377 static void load_tex_cursor_task_cb(void *__restrict userdata,
378  const int j,
379  const TaskParallelTLS *__restrict UNUSED(tls))
380 {
381  LoadTexData *data = userdata;
382  Brush *br = data->br;
383 
384  uchar *buffer = data->buffer;
385 
386  const int size = data->size;
387 
388  for (int i = 0; i < size; i++) {
389  /* Largely duplicated from tex_strength. */
390 
391  const int index = j * size + i;
392  const float x = (((float)i / size) - 0.5f) * 2.0f;
393  const float y = (((float)j / size) - 0.5f) * 2.0f;
394  const float len = sqrtf(x * x + y * y);
395 
396  if (len <= 1.0f) {
397 
398  /* Falloff curve. */
399  float avg = BKE_brush_curve_strength_clamped(br, len, 1.0f);
400 
401  buffer[index] = (uchar)(255 * avg);
402  }
403  else {
404  buffer[index] = 0;
405  }
406  }
407 }
408 
409 static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
410 {
411  bool init;
412 
414  uchar *buffer = NULL;
415 
416  int size;
417  const bool refresh = !cursor_snap.overlay_texture ||
420 
422 
423  if (refresh) {
424  int s, r;
425 
426  cursor_snap.zoom = zoom;
427 
428  s = BKE_brush_size_get(vc->scene, br);
429  r = 1;
430 
431  for (s >>= 1; s > 0; s >>= 1) {
432  r++;
433  }
434 
435  size = (1 << r);
436 
437  if (size < 256) {
438  size = 256;
439  }
440 
441  if (size < cursor_snap.size) {
443  }
444 
445  if (cursor_snap.size != size) {
449  }
450 
451  init = false;
452 
454  }
455  buffer = MEM_mallocN(sizeof(uchar) * size * size, "load_tex");
456 
458 
459  LoadTexData data = {
460  .br = br,
461  .buffer = buffer,
462  .size = size,
463  };
464 
465  TaskParallelSettings settings;
468 
471  "cursor_snap_overaly", size, size, 1, GPU_R8, NULL);
473 
475  }
476 
477  if (init) {
479  }
480 
481  if (buffer) {
482  MEM_freeN(buffer);
483  }
484  }
485  else {
487  }
488 
491 
492  return 1;
493 }
494 
495 static int project_brush_radius(ViewContext *vc, float radius, const float location[3])
496 {
497  float view[3], nonortho[3], ortho[3], offset[3], p1[2], p2[2];
498 
499  ED_view3d_global_to_vector(vc->rv3d, location, view);
500 
501  /* Create a vector that is not orthogonal to view. */
502 
503  if (fabsf(view[0]) < 0.1f) {
504  nonortho[0] = view[0] + 1.0f;
505  nonortho[1] = view[1];
506  nonortho[2] = view[2];
507  }
508  else if (fabsf(view[1]) < 0.1f) {
509  nonortho[0] = view[0];
510  nonortho[1] = view[1] + 1.0f;
511  nonortho[2] = view[2];
512  }
513  else {
514  nonortho[0] = view[0];
515  nonortho[1] = view[1];
516  nonortho[2] = view[2] + 1.0f;
517  }
518 
519  /* Get a vector in the plane of the view. */
520  cross_v3_v3v3(ortho, nonortho, view);
521  normalize_v3(ortho);
522 
523  /* Make a point on the surface of the brush tangent to the view. */
524  mul_v3_fl(ortho, radius);
525  add_v3_v3v3(offset, location, ortho);
526 
527  /* Project the center of the brush, and the tangent point to the view onto the screen. */
528  if ((ED_view3d_project_float_global(vc->region, location, p1, V3D_PROJ_TEST_NOP) ==
529  V3D_PROJ_RET_OK) &&
531  V3D_PROJ_RET_OK)) {
532  /* The distance between these points is the size of the projected brush in pixels. */
533  return len_v2v2(p1, p2);
534  }
535  /* Assert because the code that sets up the vectors should disallow this. */
536  BLI_assert(0);
537  return 0;
538 }
539 
540 /* Draw an overlay that shows what effect the brush's texture will
541  * have on brush strength. */
543  Brush *brush,
544  ViewContext *vc,
545  int x,
546  int y,
547  float zoom,
548  const ePaintMode mode,
549  bool col,
550  bool primary)
551 {
552  rctf quad;
553  /* Check for overlay mode. */
554 
555  MTex *mtex = (primary) ? &brush->mtex : &brush->mask_mtex;
556  bool valid = ((primary) ? (brush->overlay_flags & BRUSH_OVERLAY_PRIMARY) != 0 :
557  (brush->overlay_flags & BRUSH_OVERLAY_SECONDARY) != 0);
558  int overlay_alpha = (primary) ? brush->texture_overlay_alpha : brush->mask_overlay_alpha;
559 
560  if (mode == PAINT_MODE_TEXTURE_3D) {
561  if (primary && brush->imagepaint_tool != PAINT_TOOL_DRAW) {
562  /* All non-draw tools don't use the primary texture (clone, smear, soften.. etc). */
563  return false;
564  }
565  }
566 
567  if (!(mtex->tex) ||
568  !((mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) ||
570  return false;
571  }
572 
573  if (load_tex(brush, vc, zoom, col, primary)) {
574  GPU_color_mask(true, true, true, true);
576 
577  if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
578  GPU_matrix_push();
579 
580  float center[2] = {
581  ups->draw_anchored ? ups->anchored_initial_mouse[0] : x,
582  ups->draw_anchored ? ups->anchored_initial_mouse[1] : y,
583  };
584 
585  /* Brush rotation. */
589 
590  /* Scale based on tablet pressure. */
591  if (primary && ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
592  const float scale = ups->size_pressure_value;
594  GPU_matrix_scale_2f(scale, scale);
596  }
597 
598  if (ups->draw_anchored) {
599  quad.xmin = center[0] - ups->anchored_size;
600  quad.ymin = center[1] - ups->anchored_size;
601  quad.xmax = center[0] + ups->anchored_size;
602  quad.ymax = center[1] + ups->anchored_size;
603  }
604  else {
605  const int radius = BKE_brush_size_get(vc->scene, brush) * zoom;
606  quad.xmin = center[0] - radius;
607  quad.ymin = center[1] - radius;
608  quad.xmax = center[0] + radius;
609  quad.ymax = center[1] + radius;
610  }
611  }
612  else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
613  quad.xmin = 0;
614  quad.ymin = 0;
615  quad.xmax = BLI_rcti_size_x(&vc->region->winrct);
616  quad.ymax = BLI_rcti_size_y(&vc->region->winrct);
617  }
618  /* Stencil code goes here. */
619  else {
620  if (primary) {
621  quad.xmin = -brush->stencil_dimension[0];
622  quad.ymin = -brush->stencil_dimension[1];
623  quad.xmax = brush->stencil_dimension[0];
624  quad.ymax = brush->stencil_dimension[1];
625  }
626  else {
627  quad.xmin = -brush->mask_stencil_dimension[0];
628  quad.ymin = -brush->mask_stencil_dimension[1];
629  quad.xmax = brush->mask_stencil_dimension[0];
630  quad.ymax = brush->mask_stencil_dimension[1];
631  }
632  GPU_matrix_push();
633  if (primary) {
635  }
636  else {
638  }
640  }
641 
642  /* Set quad color. Colored overlay does not get blending. */
645  uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
646 
647  /* Premultiplied alpha blending. */
649 
651 
652  float final_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
653  if (!col) {
654  copy_v3_v3(final_color, U.sculpt_paint_overlay_col);
655  }
656  mul_v4_fl(final_color, overlay_alpha * 0.01f);
657  immUniformColor4fv(final_color);
658 
661 
666 
667  /* Draw textured quad. */
669  immAttr2f(texCoord, 0.0f, 0.0f);
670  immVertex2f(pos, quad.xmin, quad.ymin);
671  immAttr2f(texCoord, 1.0f, 0.0f);
672  immVertex2f(pos, quad.xmax, quad.ymin);
673  immAttr2f(texCoord, 1.0f, 1.0f);
674  immVertex2f(pos, quad.xmax, quad.ymax);
675  immAttr2f(texCoord, 0.0f, 1.0f);
676  immVertex2f(pos, quad.xmin, quad.ymax);
677  immEnd();
678 
680 
682 
684  GPU_matrix_pop();
685  }
686  }
687  return true;
688 }
689 
690 /* Draw an overlay that shows what effect the brush's texture will
691  * have on brush strength. */
693  UnifiedPaintSettings *ups, Brush *brush, ViewContext *vc, int x, int y, float zoom)
694 {
695  rctf quad;
696  /* Check for overlay mode. */
697 
698  if (!(brush->overlay_flags & BRUSH_OVERLAY_CURSOR)) {
699  return false;
700  }
701 
702  if (load_tex_cursor(brush, vc, zoom)) {
703  bool do_pop = false;
704  float center[2];
705 
706  GPU_color_mask(true, true, true, true);
708 
709  if (ups->draw_anchored) {
711  quad.xmin = ups->anchored_initial_mouse[0] - ups->anchored_size;
712  quad.ymin = ups->anchored_initial_mouse[1] - ups->anchored_size;
713  quad.xmax = ups->anchored_initial_mouse[0] + ups->anchored_size;
714  quad.ymax = ups->anchored_initial_mouse[1] + ups->anchored_size;
715  }
716  else {
717  const int radius = BKE_brush_size_get(vc->scene, brush) * zoom;
718  center[0] = x;
719  center[1] = y;
720 
721  quad.xmin = x - radius;
722  quad.ymin = y - radius;
723  quad.xmax = x + radius;
724  quad.ymax = y + radius;
725  }
726 
727  /* Scale based on tablet pressure. */
728  if (ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
729  do_pop = true;
730  GPU_matrix_push();
734  }
735 
738  uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
739 
741 
743 
744  float final_color[4] = {UNPACK3(U.sculpt_paint_overlay_col), 1.0f};
745  mul_v4_fl(final_color, brush->cursor_overlay_alpha * 0.01f);
746  immUniformColor4fv(final_color);
747 
748  /* Draw textured quad. */
751 
753  immAttr2f(texCoord, 0.0f, 0.0f);
754  immVertex2f(pos, quad.xmin, quad.ymin);
755  immAttr2f(texCoord, 1.0f, 0.0f);
756  immVertex2f(pos, quad.xmax, quad.ymin);
757  immAttr2f(texCoord, 1.0f, 1.0f);
758  immVertex2f(pos, quad.xmax, quad.ymax);
759  immAttr2f(texCoord, 0.0f, 1.0f);
760  immVertex2f(pos, quad.xmin, quad.ymax);
761  immEnd();
762 
764 
766 
767  if (do_pop) {
768  GPU_matrix_pop();
769  }
770  }
771  return true;
772 }
773 
775  Brush *brush,
776  ViewContext *vc,
777  int x,
778  int y,
779  float zoom,
780  ePaintMode mode)
781 {
782  /* Color means that primary brush texture is colored and
783  * secondary is used for alpha/mask control. */
785 
786  bool alpha_overlay_active = false;
787 
789  eGPUBlend blend_state = GPU_blend_get();
790  eGPUDepthTest depth_test = GPU_depth_test_get();
791 
792  /* Translate to region. */
793  GPU_matrix_push();
795  x -= vc->region->winrct.xmin;
796  y -= vc->region->winrct.ymin;
797 
798  /* Colored overlay should be drawn separately. */
799  if (col) {
800  if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY)) {
801  alpha_overlay_active = paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, mode, true, true);
802  }
803  if (!(flags & PAINT_OVERLAY_OVERRIDE_SECONDARY)) {
804  alpha_overlay_active = paint_draw_tex_overlay(
805  ups, brush, vc, x, y, zoom, mode, false, false);
806  }
807  if (!(flags & PAINT_OVERLAY_OVERRIDE_CURSOR)) {
808  alpha_overlay_active = paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
809  }
810  }
811  else {
812  if (!(flags & PAINT_OVERLAY_OVERRIDE_PRIMARY) && (mode != PAINT_MODE_WEIGHT)) {
813  alpha_overlay_active = paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, mode, false, true);
814  }
815  if (!(flags & PAINT_OVERLAY_OVERRIDE_CURSOR)) {
816  alpha_overlay_active = paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
817  }
818  }
819 
820  GPU_matrix_pop();
821  GPU_blend(blend_state);
822  GPU_depth_test(depth_test);
823 
824  return alpha_overlay_active;
825 }
826 
828  const float sel_col[4],
829  const float pivot_col[4],
830  float *co,
831  float width,
832  bool selected)
833 {
834  immUniformColor4fv(selected ? sel_col : pivot_col);
835 
836  GPU_line_width(3.0f);
837 
838  float w = width / 2.0f;
839  const float tri[3][2] = {
840  {co[0], co[1] + w},
841  {co[0] - w, co[1] - w},
842  {co[0] + w, co[1] - w},
843  };
844 
846  immVertex2fv(pos, tri[0]);
847  immVertex2fv(pos, tri[1]);
848  immVertex2fv(pos, tri[2]);
849  immEnd();
850 
851  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
852  GPU_line_width(1.0f);
853 
855  immVertex2fv(pos, tri[0]);
856  immVertex2fv(pos, tri[1]);
857  immVertex2fv(pos, tri[2]);
858  immEnd();
859 }
860 
862  const float sel_col[4],
863  const float handle_col[4],
864  const float *co,
865  float width,
866  bool selected)
867 {
868  immUniformColor4fv(selected ? sel_col : handle_col);
869 
870  GPU_line_width(3.0f);
871 
872  float w = width / 2.0f;
873  float minx = co[0] - w;
874  float miny = co[1] - w;
875  float maxx = co[0] + w;
876  float maxy = co[1] + w;
877 
878  imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy);
879 
880  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
881  GPU_line_width(1.0f);
882 
883  imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy);
884 }
885 
886 BLI_INLINE void draw_bezier_handle_lines(uint pos, const float sel_col[4], BezTriple *bez)
887 {
888  immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
889  GPU_line_width(3.0f);
890 
892  immVertex2fv(pos, bez->vec[0]);
893  immVertex2fv(pos, bez->vec[1]);
894  immVertex2fv(pos, bez->vec[2]);
895  immEnd();
896 
897  GPU_line_width(1.0f);
898 
899  if (bez->f1 || bez->f2) {
900  immUniformColor4fv(sel_col);
901  }
902  else {
903  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
904  }
906  immVertex2fv(pos, bez->vec[0]);
907  immVertex2fv(pos, bez->vec[1]);
908  immEnd();
909 
910  if (bez->f3 || bez->f2) {
911  immUniformColor4fv(sel_col);
912  }
913  else {
914  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.5f);
915  }
917  immVertex2fv(pos, bez->vec[1]);
918  immVertex2fv(pos, bez->vec[2]);
919  immEnd();
920 }
921 
922 static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc)
923 {
924  GPU_matrix_push();
926 
927  if (brush->paint_curve && brush->paint_curve->points) {
928  PaintCurve *pc = brush->paint_curve;
929  PaintCurvePoint *cp = pc->points;
930 
931  GPU_line_smooth(true);
933 
934  /* Draw the bezier handles and the curve segment between the current and next point. */
936 
938 
939  float selec_col[4], handle_col[4], pivot_col[4];
943 
944  for (int i = 0; i < pc->tot_points - 1; i++, cp++) {
945  int j;
946  PaintCurvePoint *cp_next = cp + 1;
947  float data[(PAINT_CURVE_NUM_SEGMENTS + 1) * 2];
948  /* Use color coding to distinguish handles vs curve segments. */
949  draw_bezier_handle_lines(pos, selec_col, &cp->bez);
950  draw_tri_point(pos, selec_col, pivot_col, &cp->bez.vec[1][0], 10.0f, cp->bez.f2);
952  pos, selec_col, handle_col, &cp->bez.vec[0][0], 8.0f, cp->bez.f1 || cp->bez.f2);
954  pos, selec_col, handle_col, &cp->bez.vec[2][0], 8.0f, cp->bez.f3 || cp->bez.f2);
955 
956  for (j = 0; j < 2; j++) {
958  cp->bez.vec[2][j],
959  cp_next->bez.vec[0][j],
960  cp_next->bez.vec[1][j],
961  data + j,
963  sizeof(float[2]));
964  }
965 
966  float(*v)[2] = (float(*)[2])data;
967 
968  immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
969  GPU_line_width(3.0f);
971  for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) {
972  immVertex2fv(pos, v[j]);
973  }
974  immEnd();
975 
976  immUniformColor4f(0.9f, 0.9f, 1.0f, 0.5f);
977  GPU_line_width(1.0f);
979  for (j = 0; j <= PAINT_CURVE_NUM_SEGMENTS; j++) {
980  immVertex2fv(pos, v[j]);
981  }
982  immEnd();
983  }
984 
985  /* Draw last line segment. */
986  draw_bezier_handle_lines(pos, selec_col, &cp->bez);
987  draw_tri_point(pos, selec_col, pivot_col, &cp->bez.vec[1][0], 10.0f, cp->bez.f2);
989  pos, selec_col, handle_col, &cp->bez.vec[0][0], 8.0f, cp->bez.f1 || cp->bez.f2);
991  pos, selec_col, handle_col, &cp->bez.vec[2][0], 8.0f, cp->bez.f3 || cp->bez.f2);
992 
994  GPU_line_smooth(false);
995 
997  }
998  GPU_matrix_pop();
999 }
1000 
1001 /* Special actions taken when paint cursor goes over mesh */
1002 /* TODO: sculpt only for now. */
1004  Brush *brush,
1005  ViewContext *vc,
1006  const float location[3])
1007 {
1008  float unprojected_radius, projected_radius;
1009 
1010  /* Update the brush's cached 3D radius. */
1011  if (!BKE_brush_use_locked_size(vc->scene, brush)) {
1012  /* Get 2D brush radius. */
1013  if (ups->draw_anchored) {
1014  projected_radius = ups->anchored_size;
1015  }
1016  else {
1017  if (brush->flag & BRUSH_ANCHORED) {
1018  projected_radius = 8;
1019  }
1020  else {
1021  projected_radius = BKE_brush_size_get(vc->scene, brush);
1022  }
1023  }
1024 
1025  /* Convert brush radius from 2D to 3D. */
1026  unprojected_radius = paint_calc_object_space_radius(vc, location, projected_radius);
1027 
1028  /* Scale 3D brush radius by pressure. */
1029  if (ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
1030  unprojected_radius *= ups->size_pressure_value;
1031  }
1032 
1033  /* Set cached value in either Brush or UnifiedPaintSettings. */
1034  BKE_brush_unprojected_radius_set(vc->scene, brush, unprojected_radius);
1035  }
1036 }
1037 
1038 static void cursor_draw_point_screen_space(const uint gpuattr,
1039  const ARegion *region,
1040  const float true_location[3],
1041  const float obmat[4][4],
1042  const int size)
1043 {
1044  float translation_vertex_cursor[3], location[3];
1045  copy_v3_v3(location, true_location);
1046  mul_m4_v3(obmat, location);
1047  ED_view3d_project(region, location, translation_vertex_cursor);
1048  /* Do not draw points behind the view. Z [near, far] is mapped to [-1, 1]. */
1049  if (translation_vertex_cursor[2] <= 1.0f) {
1051  gpuattr, translation_vertex_cursor[0], translation_vertex_cursor[1], size, 10);
1052  }
1053 }
1054 
1055 static void cursor_draw_tiling_preview(const uint gpuattr,
1056  const ARegion *region,
1057  const float true_location[3],
1058  Sculpt *sd,
1059  Object *ob,
1060  const float radius)
1061 {
1063  float orgLoc[3], location[3];
1064  int tile_pass = 0;
1065  int start[3];
1066  int end[3];
1067  int cur[3];
1068  const float *bbMin = bb->vec[0];
1069  const float *bbMax = bb->vec[6];
1070  const float *step = sd->paint.tile_offset;
1071 
1072  copy_v3_v3(orgLoc, true_location);
1073  for (int dim = 0; dim < 3; dim++) {
1074  if ((sd->paint.symmetry_flags & (PAINT_TILE_X << dim)) && step[dim] > 0) {
1075  start[dim] = (bbMin[dim] - orgLoc[dim] - radius) / step[dim];
1076  end[dim] = (bbMax[dim] - orgLoc[dim] + radius) / step[dim];
1077  }
1078  else {
1079  start[dim] = end[dim] = 0;
1080  }
1081  }
1082  copy_v3_v3_int(cur, start);
1083  for (cur[0] = start[0]; cur[0] <= end[0]; cur[0]++) {
1084  for (cur[1] = start[1]; cur[1] <= end[1]; cur[1]++) {
1085  for (cur[2] = start[2]; cur[2] <= end[2]; cur[2]++) {
1086  if (!cur[0] && !cur[1] && !cur[2]) {
1087  /* Skip tile at orgLoc, this was already handled before all others. */
1088  continue;
1089  }
1090  tile_pass++;
1091  for (int dim = 0; dim < 3; dim++) {
1092  location[dim] = cur[dim] * step[dim] + orgLoc[dim];
1093  }
1094  cursor_draw_point_screen_space(gpuattr, region, location, ob->obmat, 3);
1095  }
1096  }
1097  }
1098 }
1099 
1100 static void cursor_draw_point_with_symmetry(const uint gpuattr,
1101  const ARegion *region,
1102  const float true_location[3],
1103  Sculpt *sd,
1104  Object *ob,
1105  const float radius)
1106 {
1107  const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
1108  float location[3], symm_rot_mat[4][4];
1109 
1110  for (int i = 0; i <= symm; i++) {
1111  if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
1112 
1113  /* Axis Symmetry. */
1114  flip_v3_v3(location, true_location, (char)i);
1115  cursor_draw_point_screen_space(gpuattr, region, location, ob->obmat, 3);
1116 
1117  /* Tiling. */
1118  cursor_draw_tiling_preview(gpuattr, region, location, sd, ob, radius);
1119 
1120  /* Radial Symmetry. */
1121  for (char raxis = 0; raxis < 3; raxis++) {
1122  for (int r = 1; r < sd->radial_symm[raxis]; r++) {
1123  float angle = 2 * M_PI * r / sd->radial_symm[(int)raxis];
1124  flip_v3_v3(location, true_location, (char)i);
1125  unit_m4(symm_rot_mat);
1126  rotate_m4(symm_rot_mat, raxis + 'X', angle);
1127  mul_m4_v3(symm_rot_mat, location);
1128 
1129  cursor_draw_tiling_preview(gpuattr, region, location, sd, ob, radius);
1130  cursor_draw_point_screen_space(gpuattr, region, location, ob->obmat, 3);
1131  }
1132  }
1133  }
1134  }
1135 }
1136 
1137 static void sculpt_geometry_preview_lines_draw(const uint gpuattr,
1138  Brush *brush,
1139  const bool is_multires,
1140  SculptSession *ss)
1141 {
1142  if (!(brush->flag & BRUSH_GRAB_ACTIVE_VERTEX)) {
1143  return;
1144  }
1145 
1146  if (is_multires) {
1147  return;
1148  }
1149 
1150  if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
1151  return;
1152  }
1153 
1154  if (!ss->deform_modifiers_active) {
1155  return;
1156  }
1157 
1158  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.6f);
1159 
1160  /* Cursor normally draws on top, but for this part we need depth tests. */
1161  const eGPUDepthTest depth_test = GPU_depth_test_get();
1162  if (!depth_test) {
1164  }
1165 
1166  GPU_line_width(1.0f);
1167  if (ss->preview_vert_index_count > 0) {
1169  for (int i = 0; i < ss->preview_vert_index_count; i++) {
1170  immVertex3fv(gpuattr,
1172  }
1173  immEnd();
1174  }
1175 
1176  /* Restore depth test value. */
1177  if (!depth_test) {
1179  }
1180 }
1181 
1183  const Brush *brush,
1184  const float rds,
1185  const float line_width,
1186  const float outline_col[3],
1187  const float alpha)
1188 {
1189  float cursor_trans[4][4];
1190  unit_m4(cursor_trans);
1191  translate_m4(cursor_trans, 0.0f, 0.0f, brush->height);
1192  GPU_matrix_push();
1193  GPU_matrix_mul(cursor_trans);
1194 
1195  GPU_line_width(line_width);
1196  immUniformColor3fvAlpha(outline_col, alpha * 0.5f);
1197  imm_draw_circle_wire_3d(gpuattr, 0, 0, rds, 80);
1198  GPU_matrix_pop();
1199 }
1200 
1202 {
1203  if (mode >= PAINT_MODE_TEXTURE_3D) {
1204  return true;
1205  }
1206  return false;
1207 }
1208 
1214 
1215 typedef struct PaintCursorContext {
1227 
1228  /* Sculpt related data. */
1235  float radius;
1236 
1237  /* 3D view cursor position and normal. */
1238  float location[3];
1240  float normal[3];
1241 
1242  /* Cursor main colors. */
1243  float outline_col[3];
1245 
1246  /* GPU attribute for drawing. */
1248 
1250 
1251  /* This variable is set after drawing the overlay, not on initialization. It can't be used for
1252  * checking if alpha overlay is enabled before drawing it. */
1254 
1255  float zoomx;
1256  int x, y;
1257  float translation[2];
1258 
1261 
1263 
1265  const int x,
1266  const int y,
1267  PaintCursorContext *pcontext)
1268 {
1269  ARegion *region = CTX_wm_region(C);
1270  if (region && region->regiontype != RGN_TYPE_WINDOW) {
1271  return false;
1272  }
1273 
1274  pcontext->C = C;
1275  pcontext->region = region;
1276  pcontext->wm = CTX_wm_manager(C);
1277  pcontext->win = CTX_wm_window(C);
1278  pcontext->depsgraph = CTX_data_depsgraph_pointer(C);
1279  pcontext->scene = CTX_data_scene(C);
1280  pcontext->ups = &pcontext->scene->toolsettings->unified_paint_settings;
1282  if (pcontext->paint == NULL) {
1283  return false;
1284  }
1285  pcontext->brush = BKE_paint_brush(pcontext->paint);
1286  if (pcontext->brush == NULL) {
1287  return false;
1288  }
1290 
1291  ED_view3d_viewcontext_init(C, &pcontext->vc, pcontext->depsgraph);
1292 
1293  if (pcontext->brush->flag & BRUSH_CURVE) {
1294  pcontext->cursor_type = PAINT_CURSOR_CURVE;
1295  }
1296  else if (paint_use_2d_cursor(pcontext->mode)) {
1297  pcontext->cursor_type = PAINT_CURSOR_2D;
1298  }
1299  else {
1300  pcontext->cursor_type = PAINT_CURSOR_3D;
1301  }
1302 
1303  pcontext->x = x;
1304  pcontext->y = y;
1305  pcontext->translation[0] = (float)x;
1306  pcontext->translation[1] = (float)y;
1307 
1308  float zoomx, zoomy;
1309  get_imapaint_zoom(C, &zoomx, &zoomy);
1310  pcontext->zoomx = max_ff(zoomx, zoomy);
1311  pcontext->final_radius = (BKE_brush_size_get(pcontext->scene, pcontext->brush) * zoomx);
1312 
1313  /* There is currently no way to check if the direction is inverted before starting the stroke,
1314  * so this does not reflect the state of the brush in the UI. */
1315  if (((pcontext->ups->draw_inverted == 0) ^ ((pcontext->brush->flag & BRUSH_DIR_IN) == 0)) &&
1317  copy_v3_v3(pcontext->outline_col, pcontext->brush->sub_col);
1318  }
1319  else {
1320  copy_v3_v3(pcontext->outline_col, pcontext->brush->add_col);
1321  }
1322  pcontext->outline_alpha = pcontext->brush->add_col[3];
1323 
1324  Object *active_object = pcontext->vc.obact;
1325  pcontext->ss = active_object ? active_object->sculpt : NULL;
1326 
1327  if (pcontext->ss && pcontext->ss->draw_faded_cursor) {
1328  pcontext->outline_alpha = 0.3f;
1329  copy_v3_fl(pcontext->outline_col, 0.8f);
1330  }
1331 
1332  pcontext->is_stroke_active = pcontext->ups->stroke_active;
1333 
1334  return true;
1335 }
1336 
1338 {
1339  if (pcontext->is_cursor_over_mesh) {
1340  Brush *brush = BKE_paint_brush(pcontext->paint);
1341  pcontext->pixel_radius = project_brush_radius(
1342  &pcontext->vc,
1343  BKE_brush_unprojected_radius_get(pcontext->scene, brush),
1344  pcontext->location);
1345 
1346  if (pcontext->pixel_radius == 0) {
1347  pcontext->pixel_radius = BKE_brush_size_get(pcontext->scene, brush);
1348  }
1349 
1350  copy_v3_v3(pcontext->scene_space_location, pcontext->location);
1351  mul_m4_v3(pcontext->vc.obact->obmat, pcontext->scene_space_location);
1352  }
1353  else {
1354  Sculpt *sd = CTX_data_tool_settings(pcontext->C)->sculpt;
1355  Brush *brush = BKE_paint_brush(&sd->paint);
1356 
1357  pcontext->pixel_radius = BKE_brush_size_get(pcontext->scene, brush);
1358  }
1359 }
1360 
1362 {
1363  BLI_assert(pcontext->ss != NULL);
1364  BLI_assert(pcontext->mode == PAINT_MODE_SCULPT);
1365 
1366  bContext *C = pcontext->C;
1367  SculptSession *ss = pcontext->ss;
1368  Brush *brush = pcontext->brush;
1369  Scene *scene = pcontext->scene;
1370  UnifiedPaintSettings *ups = pcontext->ups;
1371  ViewContext *vc = &pcontext->vc;
1373 
1374  const float mouse[2] = {
1375  pcontext->x - pcontext->region->winrct.xmin,
1376  pcontext->y - pcontext->region->winrct.ymin,
1377  };
1378 
1379  /* This updates the active vertex, which is needed for most of the Sculpt/Vertex Colors tools to
1380  * work correctly */
1382  if (!ups->stroke_active) {
1384  C, &gi, mouse, (pcontext->brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE));
1385  copy_v3_v3(pcontext->location, gi.location);
1386  copy_v3_v3(pcontext->normal, gi.normal);
1387  }
1388  else {
1389  pcontext->is_cursor_over_mesh = ups->last_hit;
1390  copy_v3_v3(pcontext->location, ups->last_location);
1391  }
1392 
1394 
1395  if (BKE_brush_use_locked_size(scene, brush)) {
1396  BKE_brush_size_set(scene, brush, pcontext->pixel_radius);
1397  }
1398 
1399  if (pcontext->is_cursor_over_mesh) {
1401  }
1402 
1403  pcontext->is_multires = ss->pbvh != NULL && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS;
1404 
1405  pcontext->sd = CTX_data_tool_settings(pcontext->C)->sculpt;
1406 }
1407 
1409 {
1410  WM_cursor_set(pcontext->win, WM_CURSOR_PAINT);
1411 }
1412 
1414 {
1415  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
1416 
1417  /* Draw brush outline. */
1418  if (pcontext->ups->stroke_active && BKE_brush_use_size_pressure(pcontext->brush)) {
1419  imm_draw_circle_wire_2d(pcontext->pos,
1420  pcontext->translation[0],
1421  pcontext->translation[1],
1422  pcontext->final_radius * pcontext->ups->size_pressure_value,
1423  40);
1424  /* Outer at half alpha. */
1425  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.5f);
1426  }
1427 
1428  GPU_line_width(1.0f);
1429  imm_draw_circle_wire_2d(pcontext->pos,
1430  pcontext->translation[0],
1431  pcontext->translation[1],
1432  pcontext->final_radius,
1433  40);
1434 }
1435 
1437 {
1438  GPU_line_width(1.0f);
1439  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
1440  imm_draw_circle_wire_3d(pcontext->pos,
1441  pcontext->translation[0],
1442  pcontext->translation[1],
1443  pcontext->final_radius,
1444  40);
1445 }
1446 
1448 {
1449  GPU_line_width(1.0f);
1450  /* Reduce alpha to increase the contrast when the cursor is over the mesh. */
1451  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.8);
1452  imm_draw_circle_wire_3d(pcontext->pos,
1453  pcontext->translation[0],
1454  pcontext->translation[1],
1455  pcontext->final_radius,
1456  80);
1457  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.35f);
1458  imm_draw_circle_wire_3d(pcontext->pos,
1459  pcontext->translation[0],
1460  pcontext->translation[1],
1461  pcontext->final_radius * clamp_f(pcontext->brush->alpha, 0.0f, 1.0f),
1462  80);
1463 }
1464 
1466 {
1467  if (!BKE_brush_use_locked_size(pcontext->scene, pcontext->brush)) {
1469  &pcontext->vc, pcontext->location, BKE_brush_size_get(pcontext->scene, pcontext->brush));
1470  }
1471  else {
1472  pcontext->radius = BKE_brush_unprojected_radius_get(pcontext->scene, pcontext->brush);
1473  }
1474 }
1475 
1477 {
1478  float cursor_trans[4][4], cursor_rot[4][4];
1479  const float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
1480  float quat[4];
1481  copy_m4_m4(cursor_trans, pcontext->vc.obact->obmat);
1482  translate_m4(cursor_trans, pcontext->location[0], pcontext->location[1], pcontext->location[2]);
1483  rotation_between_vecs_to_quat(quat, z_axis, pcontext->normal);
1484  quat_to_mat4(cursor_rot, quat);
1485  GPU_matrix_mul(cursor_trans);
1486  GPU_matrix_mul(cursor_rot);
1487 }
1488 
1490 {
1491  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
1492  GPU_line_width(2.0f);
1493  imm_draw_circle_wire_3d(pcontext->pos, 0, 0, pcontext->radius, 80);
1494 
1495  GPU_line_width(1.0f);
1496  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.5f);
1498  pcontext->pos, 0, 0, pcontext->radius * clamp_f(pcontext->brush->alpha, 0.0f, 1.0f), 80);
1499 }
1500 
1502 {
1503  SculptSession *ss = pcontext->ss;
1504  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
1505  GPU_line_width(2.0f);
1506 
1508  for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
1511  }
1512 
1513  immEnd();
1514 }
1515 
1517 {
1518 
1519  SculptSession *ss = pcontext->ss;
1520  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
1521  for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
1523  pcontext->region,
1525  pcontext->vc.obact->obmat,
1526  3);
1527  }
1528 }
1529 
1531 {
1532 
1533  if (!pcontext->ss->boundary_preview) {
1534  /* There is no guarantee that a boundary preview exists as there may be no boundaries
1535  * inside the brush radius. */
1536  return;
1537  }
1538  immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
1540  pcontext->pos,
1541  pcontext->region,
1542  SCULPT_vertex_co_get(pcontext->ss, pcontext->ss->boundary_preview->pivot_vertex),
1543  pcontext->vc.obact->obmat,
1544  3);
1545 }
1546 
1548  const bool update_previews)
1549 {
1550  SculptSession *ss = pcontext->ss;
1551  if (!(update_previews || !ss->boundary_preview)) {
1552  return;
1553  }
1554 
1555  /* Needed for updating the necessary SculptSession data in order to initialize the
1556  * boundary data for the preview. */
1557  BKE_sculpt_update_object_for_edit(pcontext->depsgraph, pcontext->vc.obact, true, false, false);
1558 
1559  if (ss->boundary_preview) {
1561  }
1562 
1564  pcontext->vc.obact, pcontext->brush, ss->active_vertex_index, pcontext->radius);
1565 }
1566 
1568 {
1569  Brush *brush = pcontext->brush;
1570 
1571  /* 2D falloff is better represented with the default 2D cursor,
1572  * there is no need to draw anything else. */
1573  if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
1575  return;
1576  }
1577 
1578  if (pcontext->alpha_overlay_drawn) {
1580  return;
1581  }
1582 
1583  if (!pcontext->is_cursor_over_mesh) {
1585  return;
1586  }
1587 
1589 
1590  const bool update_previews = pcontext->prev_active_vertex_index !=
1591  SCULPT_active_vertex_get(pcontext->ss);
1592 
1593  /* Setup drawing. */
1594  wmViewport(&pcontext->region->winrct);
1595 
1596  /* Drawing of Cursor overlays in 2D screen space. */
1597 
1598  /* Cursor location symmetry points. */
1599 
1600  const float *active_vertex_co;
1601  if (brush->sculpt_tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
1602  active_vertex_co = SCULPT_vertex_co_for_grab_active_get(
1603  pcontext->ss, SCULPT_active_vertex_get(pcontext->ss));
1604  }
1605  else {
1606  active_vertex_co = SCULPT_active_vertex_co_get(pcontext->ss);
1607  }
1608  if (len_v3v3(active_vertex_co, pcontext->location) < pcontext->radius) {
1609  immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
1611  pcontext->region,
1612  active_vertex_co,
1613  pcontext->sd,
1614  pcontext->vc.obact,
1615  pcontext->radius);
1616  }
1617 
1618  /* Pose brush updates and rotation origins. */
1619 
1620  if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
1621  /* Just after switching to the Pose Brush, the active vertex can be the same and the
1622  * cursor won't be tagged to update, so always initialize the preview chain if it is
1623  * null before drawing it. */
1624  SculptSession *ss = pcontext->ss;
1625  if (update_previews || !ss->pose_ik_chain_preview) {
1627  pcontext->depsgraph, pcontext->vc.obact, true, false, false);
1628 
1629  /* Free the previous pose brush preview. */
1630  if (ss->pose_ik_chain_preview) {
1632  }
1633 
1634  /* Generate a new pose brush preview from the current cursor location. */
1636  pcontext->sd, pcontext->vc.obact, ss, brush, pcontext->location, pcontext->radius);
1637  }
1638 
1639  /* Draw the pose brush rotation origins. */
1641  }
1642 
1643  /* Expand operation origin. */
1644  if (pcontext->ss->expand_cache) {
1646  pcontext->pos,
1647  pcontext->region,
1649  pcontext->vc.obact->obmat,
1650  2);
1651  }
1652 
1653  if (brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) {
1654  paint_cursor_preview_boundary_data_update(pcontext, update_previews);
1656  }
1657 
1658  /* Setup 3D perspective drawing. */
1660  ED_view3d_draw_setup_view(pcontext->wm,
1661  pcontext->win,
1662  pcontext->depsgraph,
1663  pcontext->scene,
1664  pcontext->region,
1665  CTX_wm_view3d(pcontext->C),
1666  NULL,
1667  NULL,
1668  NULL);
1669 
1670  GPU_matrix_push();
1671  GPU_matrix_mul(pcontext->vc.obact->obmat);
1672 
1673  /* Drawing Cursor overlays in 3D object space. */
1674  if (brush->sculpt_tool == SCULPT_TOOL_GRAB && (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX)) {
1675  SCULPT_geometry_preview_lines_update(pcontext->C, pcontext->ss, pcontext->radius);
1677  pcontext->pos, pcontext->brush, pcontext->is_multires, pcontext->ss);
1678  }
1679 
1680  if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
1682  }
1683 
1684  if (brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) {
1686  pcontext->pos, pcontext->ss, pcontext->outline_col, pcontext->outline_alpha);
1687  SCULPT_boundary_pivot_line_preview_draw(pcontext->pos, pcontext->ss);
1688  }
1689 
1690  GPU_matrix_pop();
1691 
1692  /* Drawing Cursor overlays in Paint Cursor space (as additional info on top of the brush cursor)
1693  */
1694  GPU_matrix_push();
1696  /* Main inactive cursor. */
1698 
1699  /* Cloth brush local simulation areas. */
1700  if (brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
1702  const float white[3] = {1.0f, 1.0f, 1.0f};
1703  const float zero_v[3] = {0.0f};
1704  /* This functions sets its own drawing space in order to draw the simulation limits when the
1705  * cursor is active. When used here, this cursor overlay is already in cursor space, so its
1706  * position and normal should be set to 0. */
1708  pcontext->pos, brush, zero_v, zero_v, pcontext->radius, 1.0f, white, 0.25f);
1709  }
1710 
1711  /* Layer brush height. */
1712  if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
1714  brush,
1715  pcontext->radius,
1716  1.0f,
1717  pcontext->outline_col,
1718  pcontext->outline_alpha);
1719  }
1720 
1721  GPU_matrix_pop();
1722 
1723  /* Reset drawing. */
1725  wmWindowViewport(pcontext->win);
1726 }
1727 
1729 {
1730  BLI_assert(pcontext->ss != NULL);
1731  BLI_assert(pcontext->mode == PAINT_MODE_SCULPT);
1732 
1733  SculptSession *ss = pcontext->ss;
1734  Brush *brush = pcontext->brush;
1735 
1736  /* The cursor can be updated as active before creating the StrokeCache, so this needs to be
1737  * checked. */
1738  if (!ss->cache) {
1739  return;
1740  }
1741 
1742  /* Most of the brushes initialize the necessary data for the custom cursor drawing after the
1743  * first brush step, so make sure that it is not drawn before being initialized. */
1745  return;
1746  }
1747 
1748  /* Setup drawing. */
1749  wmViewport(&pcontext->region->winrct);
1751  ED_view3d_draw_setup_view(pcontext->wm,
1752  pcontext->win,
1753  pcontext->depsgraph,
1754  pcontext->scene,
1755  pcontext->region,
1756  CTX_wm_view3d(pcontext->C),
1757  NULL,
1758  NULL,
1759  NULL);
1760  GPU_matrix_push();
1761  GPU_matrix_mul(pcontext->vc.obact->obmat);
1762 
1763  /* Draw the special active cursors different tools may have. */
1764 
1765  if (brush->sculpt_tool == SCULPT_TOOL_GRAB) {
1766  sculpt_geometry_preview_lines_draw(pcontext->pos, brush, pcontext->is_multires, ss);
1767  }
1768 
1771  pcontext->pos, brush, ss, pcontext->outline_col, pcontext->outline_alpha);
1772  }
1773 
1774  if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
1777  pcontext->pos, ss, pcontext->outline_col, pcontext->outline_alpha);
1778  }
1781  /* Display the simulation limits if sculpting outside them. */
1782  /* This does not makes much sense of plane falloff as the falloff is infinite or global. */
1783 
1785  ss->cache->radius * (1.0f + brush->cloth_sim_limit)) {
1786  const float red[3] = {1.0f, 0.2f, 0.2f};
1788  brush,
1791  ss->cache->radius,
1792  2.0f,
1793  red,
1794  0.8f);
1795  }
1796  }
1797  }
1798 
1799  GPU_matrix_pop();
1800 
1802  wmWindowViewport(pcontext->win);
1803 }
1804 
1806 {
1807 
1808  /* These paint tools are not using the SculptSession, so they need to use the default 2D brush
1809  * cursor in the 3D view. */
1810  if (pcontext->mode != PAINT_MODE_SCULPT || !pcontext->ss) {
1812  return;
1813  }
1814 
1816 
1817  if (pcontext->is_stroke_active) {
1819  }
1820  else {
1822  }
1823 }
1824 
1826 {
1827  ViewContext *vc = &pcontext->vc;
1828  return vc->rv3d && (vc->rv3d->rflag & RV3D_NAVIGATING);
1829 }
1830 
1832 {
1833  if (pcontext->paint->flags & PAINT_SHOW_BRUSH) {
1835  pcontext->brush->imagepaint_tool == PAINT_TOOL_FILL) {
1836  return false;
1837  }
1838  return true;
1839  }
1840  return false;
1841 }
1842 
1844 {
1845  /* Don't calculate rake angles while a stroke is active because the rake variables are global
1846  * and we may get interference with the stroke itself.
1847  * For line strokes, such interference is visible. */
1848  if (!pcontext->ups->stroke_active) {
1849  paint_calculate_rake_rotation(pcontext->ups, pcontext->brush, pcontext->translation);
1850  }
1851 }
1852 
1854 {
1855  pcontext->alpha_overlay_drawn = paint_draw_alpha_overlay(pcontext->ups,
1856  pcontext->brush,
1857  &pcontext->vc,
1858  pcontext->x,
1859  pcontext->y,
1860  pcontext->zoomx,
1861  pcontext->mode);
1862 }
1863 
1865 {
1866  UnifiedPaintSettings *ups = pcontext->ups;
1867  if (ups->draw_anchored) {
1868  pcontext->final_radius = ups->anchored_size;
1869  copy_v2_fl2(pcontext->translation,
1870  ups->anchored_initial_mouse[0] + pcontext->region->winrct.xmin,
1871  ups->anchored_initial_mouse[1] + pcontext->region->winrct.ymin);
1872  }
1873 }
1874 
1876 {
1877  GPU_line_width(2.0f);
1879  GPU_line_smooth(true);
1880  pcontext->pos = GPU_vertformat_attr_add(
1883 }
1884 
1886 {
1887  GPU_line_width(2.0f);
1889  GPU_line_smooth(true);
1890  pcontext->pos = GPU_vertformat_attr_add(
1893 }
1894 
1896 {
1897  immUnbindProgram();
1899  GPU_line_smooth(false);
1900 }
1901 
1902 static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
1903 {
1904  PaintCursorContext pcontext;
1905  if (!paint_cursor_context_init(C, x, y, &pcontext)) {
1906  return;
1907  }
1908 
1909  if (!paint_cursor_is_brush_cursor_enabled(&pcontext)) {
1910  return;
1911  }
1912  if (paint_cursor_is_3d_view_navigating(&pcontext)) {
1913  return;
1914  }
1915 
1916  switch (pcontext.cursor_type) {
1917  case PAINT_CURSOR_CURVE:
1918  paint_draw_curve_cursor(pcontext.brush, &pcontext.vc);
1919  break;
1920  case PAINT_CURSOR_2D:
1924 
1925  paint_cursor_setup_2D_drawing(&pcontext);
1928  break;
1929  case PAINT_CURSOR_3D:
1930  paint_update_mouse_cursor(&pcontext);
1931 
1935 
1936  paint_cursor_setup_3D_drawing(&pcontext);
1939  break;
1940  }
1941 }
1942 
1943 /* Public API */
1944 
1945 void paint_cursor_start(Paint *p, bool (*poll)(bContext *C))
1946 {
1947  if (p && !p->paint_cursor) {
1950  }
1951 
1952  /* Invalidate the paint cursors. */
1954 }
typedef float(TangentPoint)[2]
void BKE_brush_size_set(struct Scene *scene, struct Brush *brush, int size)
Definition: brush.c: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.c:2294
bool BKE_brush_use_locked_size(const struct Scene *scene, const struct Brush *brush)
float BKE_brush_curve_strength_clamped(struct Brush *br, float p, const float len)
Definition: brush.c:2464
void BKE_curvemapping_init(struct CurveMapping *cumap)
Definition: colortools.c:1200
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1401
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
Definition: context.c:1208
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride)
Definition: curve.c:1804
void BKE_image_pool_release_ibuf(struct Image *ima, struct ImBuf *ibuf, struct ImagePool *pool)
Definition: image.c:5261
struct ImBuf * BKE_image_pool_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, struct ImagePool *pool)
Definition: image.c:5213
struct ImagePool * BKE_image_pool_new(void)
Definition: image.c:5173
void BKE_image_pool_free(struct ImagePool *pool)
Definition: image.c:5181
void ntreeTexEndExecTree(struct bNodeTreeExec *exec)
struct bNodeTreeExec * ntreeTexBeginExecTree(struct bNodeTree *ntree)
General operations, lookup, etc. for blender objects.
struct BoundBox * BKE_object_boundbox_get(struct Object *ob)
Definition: object.c:3817
bool paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups, struct Brush *brush, const float mouse_pos[2])
Definition: paint.c:1300
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 need_colors)
Definition: paint.c:1817
struct Brush * BKE_paint_brush(struct Paint *paint)
Definition: paint.c:604
ePaintOverlayControlFlags
Definition: BKE_paint.h:101
@ PAINT_OVERLAY_INVALID_CURVE
Definition: BKE_paint.h:104
@ PAINT_OVERLAY_INVALID_TEXTURE_SECONDARY
Definition: BKE_paint.h:103
@ PAINT_OVERLAY_OVERRIDE_CURSOR
Definition: BKE_paint.h:105
@ PAINT_OVERLAY_INVALID_TEXTURE_PRIMARY
Definition: BKE_paint.h:102
@ PAINT_OVERLAY_OVERRIDE_SECONDARY
Definition: BKE_paint.h:107
@ PAINT_OVERLAY_OVERRIDE_PRIMARY
Definition: BKE_paint.h:106
void BKE_paint_reset_overlay_invalid(ePaintOverlayControlFlags flag)
Definition: paint.c:301
struct Paint * BKE_paint_get_active_from_context(const struct bContext *C)
void BKE_paint_invalidate_overlay_all(void)
Definition: paint.c:272
ePaintMode
Definition: BKE_paint.h:78
@ PAINT_MODE_TEXTURE_3D
Definition: BKE_paint.h:84
@ PAINT_MODE_SCULPT
Definition: BKE_paint.h:79
@ PAINT_MODE_WEIGHT
Definition: BKE_paint.h:82
@ PAINT_MODE_TEXTURE_2D
Definition: BKE_paint.h:86
@ PAINT_MODE_VERTEX
Definition: BKE_paint.h:81
ePaintOverlayControlFlags BKE_paint_get_overlay_flags(void)
Definition: paint.c:278
PBVHType BKE_pbvh_type(const PBVH *pbvh)
Definition: pbvh.c:1661
@ PBVH_GRIDS
Definition: BKE_pbvh.h:211
@ PBVH_FACES
Definition: BKE_pbvh.h:210
#define BLI_assert(a)
Definition: BLI_assert.h:58
#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:38
void unit_m4(float m[4][4])
Definition: rct.c:1140
void translate_m4(float mat[4][4], float tx, float ty, float tz)
Definition: math_matrix.c:2325
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
void rotate_m4(float mat[4][4], const char axis, const float angle)
Definition: math_matrix.c:2352
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:157
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:110
int BLI_task_parallel_thread_id(const TaskParallelTLS *tls)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:231
#define UNUSED(x)
#define UNPACK3(a)
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
@ 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_TOOL_FILL
@ PAINT_TOOL_DRAW
@ PAINT_FALLOFF_SHAPE_SPHERE
@ PAINT_FALLOFF_SHAPE_TUBE
@ 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
#define RGN_TYPE_ANY
@ RGN_TYPE_WINDOW
@ 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:193
void ED_view3d_viewcontext_init(struct bContext *C, struct ViewContext *vc, struct Depsgraph *depsgraph)
@ V3D_PROJ_RET_OK
Definition: ED_view3d.h:176
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_project(const struct ARegion *region, const float world[3], float r_region_co[3])
void ED_view3d_global_to_vector(const struct RegionView3D *rv3d, const float coord[3], float vec[3])
eV3DProjStatus ED_view3d_project_float_global(const struct ARegion *region, const float co[3], float r_co[2], const eV3DProjTest flag)
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 GLsizei width
_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
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:142
void GPU_matrix_translate_2fv(const float vec[2])
Definition: gpu_matrix.cc:199
void GPU_matrix_scale_2f(float x, float y)
Definition: gpu_matrix.cc:232
void GPU_matrix_pop_projection(void)
Definition: gpu_matrix.cc:156
#define GPU_matrix_mul(x)
Definition: GPU_matrix.h:223
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:135
void GPU_matrix_scale_1f(float factor)
Definition: gpu_matrix.cc:225
void GPU_matrix_rotate_2d(float deg)
Definition: gpu_matrix.cc:269
void GPU_matrix_translate_2f(float x, float y)
Definition: gpu_matrix.cc:190
void GPU_matrix_push_projection(void)
Definition: gpu_matrix.cc:149
@ GPU_PRIM_TRI_FAN
Definition: GPU_primitive.h:41
@ GPU_PRIM_LINE_LOOP
Definition: GPU_primitive.h:39
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:36
@ GPU_PRIM_LINE_STRIP
Definition: GPU_primitive.h:38
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:171
@ GPU_SHADER_3D_UNIFORM_COLOR
Definition: GPU_shader.h:200
@ GPU_SHADER_2D_IMAGE_COLOR
Definition: GPU_shader.h:187
eGPUBlend
Definition: GPU_state.h:54
@ GPU_BLEND_NONE
Definition: GPU_state.h:55
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:57
@ GPU_BLEND_ALPHA_PREMULT
Definition: GPU_state.h:58
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:55
void GPU_line_width(float width)
Definition: gpu_state.cc:173
void GPU_line_smooth(bool enable)
Definition: gpu_state.cc:85
void GPU_color_mask(bool r, bool g, bool b, bool a)
Definition: gpu_state.cc:105
eGPUBlend GPU_blend_get(void)
Definition: gpu_state.cc:237
eGPUDepthTest
Definition: GPU_state.h:77
@ GPU_DEPTH_LESS_EQUAL
Definition: GPU_state.h:81
@ GPU_DEPTH_NONE
Definition: GPU_state.h:78
eGPUDepthTest GPU_depth_test_get(void)
Definition: gpu_state.cc:255
void GPU_depth_test(eGPUDepthTest test)
Definition: gpu_state.cc:75
eGPUSamplerState
Definition: GPU_texture.h:40
@ GPU_SAMPLER_REPEAT
Definition: GPU_texture.h:52
@ GPU_SAMPLER_FILTER
Definition: GPU_texture.h:42
@ GPU_SAMPLER_CLAMP_BORDER
Definition: GPU_texture.h:47
void GPU_texture_swizzle_set(GPUTexture *tex, const char swizzle[4])
Definition: gpu_texture.cc:503
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
@ GPU_DATA_UBYTE
Definition: GPU_texture.h:175
void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
Definition: gpu_texture.cc:391
void GPU_texture_free(GPUTexture *tex)
Definition: gpu_texture.cc:508
void GPU_texture_unbind(GPUTexture *tex)
Definition: gpu_texture.cc:421
GPUTexture * GPU_texture_create_2d(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:250
eGPUTextureFormat
Definition: GPU_texture.h:84
@ GPU_R8
Definition: GPU_texture.h:108
@ GPU_RGBA8
Definition: GPU_texture.h:88
@ 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 RGB to Bright Vector Camera CLAMP
Group RGB to Bright Vector Camera Vector Combine Material Light Line Style Layer Add Ambient Diffuse Glossy Refraction Transparent Toon Principled Hair Volume Principled Light Particle Volume TEX_IMAGE
#define C
Definition: RandGen.cpp:39
@ TH_PAINT_CURVE_HANDLE
Definition: UI_resources.h:264
@ TH_VERTEX_SELECT
Definition: UI_resources.h:94
@ TH_PAINT_CURVE_PIVOT
Definition: UI_resources.h:265
void UI_GetThemeColorType4fv(int colorid, int spacetype, float col[4])
Definition: resources.c:1208
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
Scene scene
static CCL_NAMESPACE_BEGIN const double alpha
uint pos
uint col
GPUBatch * quad
#define sinf(x)
#define cosf(x)
#define atan2f(x, y)
#define fabsf(x)
#define sqrtf(x)
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
format
Definition: logImageCore.h:47
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static ulong state[N]
vector snap(vector a, vector b)
Definition: node_math.h:72
static ePaintOverlayControlFlags overlay_flags
Definition: paint.c:237
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:542
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:377
static CursorSnapshot cursor_snap
Definition: paint_cursor.c:99
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:97
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:133
void paint_cursor_delete_textures(void)
Definition: paint_cursor.c:102
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:774
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:886
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:495
static int same_tex_snap(TexSnapshot *snap, MTex *mtex, ViewContext *vc, bool col, float zoom)
Definition: paint_cursor.c:121
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:922
static void paint_cursor_update_anchored_location(PaintCursorContext *pcontext)
void paint_cursor_start(Paint *p, bool(*poll)(bContext *C))
static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool primary)
Definition: paint_cursor.c:250
static bool paint_draw_cursor_overlay(UnifiedPaintSettings *ups, Brush *brush, ViewContext *vc, int x, int y, float zoom)
Definition: paint_cursor.c:692
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:409
static bool paint_use_2d_cursor(ePaintMode mode)
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:154
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:98
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:827
static void paint_cursor_update_unprojected_radius(UnifiedPaintSettings *ups, Brush *brush, ViewContext *vc, const float location[3])
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:861
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.c:768
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:151
float paint_get_tex_pixel(const struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread)
void flip_v3_v3(float out[3], const float in[3], const enum ePaintSymmetryFlags symm)
Definition: paint_utils.c:407
#define PAINT_CURVE_NUM_SEGMENTS
Definition: paint_intern.h:368
const float * SCULPT_vertex_co_get(SculptSession *ss, int index)
Definition: sculpt.c:134
int SCULPT_active_vertex_get(SculptSession *ss)
Definition: sculpt.c:277
bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mouse[2], bool use_sampled_normal)
Definition: sculpt.c:7452
const float * SCULPT_vertex_co_for_grab_active_get(SculptSession *ss, int index)
Definition: sculpt.c:207
const float * SCULPT_active_vertex_co_get(SculptSession *ss)
Definition: sculpt.c:285
void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float radius)
Definition: sculpt.c:8605
bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(StrokeCache *cache)
Definition: sculpt.c:935
char SCULPT_mesh_symmetry_xyz_get(Object *object)
Definition: sculpt.c:323
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)
void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr, Brush *brush, SculptSession *ss, const float outline_col[3], const 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], const float radius)
Definition: sculpt_pose.c:945
void SCULPT_pose_ik_chain_free(struct SculptPoseIKChain *ik_chain)
Definition: sculpt_pose.c:1233
short regiontype
float vec[3][3]
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:91
int initial_active_vertex
struct ColorSpace * rect_colorspace
float * rect_float
ViewContext * vc
Definition: paint_cursor.c:142
Brush * br
Definition: paint_cursor.c:141
uchar * buffer
Definition: paint_cursor.c:145
struct ImagePool * pool
Definition: paint_cursor.c:148
float rotation
Definition: paint_cursor.c:150
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:260
SculptPoseIKChain * pose_ik_chain_preview
Definition: BKE_paint.h:554
int preview_vert_index_count
Definition: BKE_paint.h:550
bool draw_faded_cursor
Definition: BKE_paint.h:530
int * preview_vert_index_list
Definition: BKE_paint.h:549
SculptBoundary * boundary_preview
Definition: BKE_paint.h:557
int active_vertex_index
Definition: BKE_paint.h:523
struct StrokeCache * cache
Definition: BKE_paint.h:518
struct ExpandCache * expand_cache
Definition: BKE_paint.h:520
struct PBVH * pbvh
Definition: BKE_paint.h:504
bool deform_modifiers_active
Definition: BKE_paint.h:509
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:86
GPUTexture * overlay_texture
Definition: paint_cursor.c:82
struct ImageUser iuser
short type
struct bNodeTree * nodetree
struct Image * ima
struct UnifiedPaintSettings unified_paint_settings
struct Scene * scene
Definition: ED_view3d.h:76
struct ARegion * region
Definition: ED_view3d.h:80
struct Object * obact
Definition: ED_view3d.h:78
struct RegionView3D * rv3d
Definition: ED_view3d.h:83
struct bNodeTreeExec * execdata
int ymin
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
uint len
void WM_cursor_set(wmWindow *win, int curs)
Definition: wm_cursors.c:142
@ WM_CURSOR_PAINT
Definition: wm_cursors.h:43
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:37
void wmWindowViewport(wmWindow *win)
Definition: wm_subwindow.c:88