Blender V4.5
paint_ops.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <algorithm>
10#include <cstdlib>
11#include <cstring>
12
13#include "MEM_guardedalloc.h"
14
15#include "BLI_ghash.h"
16#include "BLI_listbase.h"
17#include "BLI_math_vector.h"
18#include "BLI_utildefines.h"
19
20#include "IMB_interp.hh"
21
22#include "DNA_brush_types.h"
23#include "DNA_scene_types.h"
24
25#include "BKE_brush.hh"
26#include "BKE_context.hh"
27#include "BKE_image.hh"
28#include "BKE_lib_id.hh"
29#include "BKE_library.hh"
30#include "BKE_main.hh"
31#include "BKE_paint.hh"
32#include "BKE_report.hh"
33
34#include "ED_image.hh"
35#include "ED_paint.hh"
36#include "ED_screen.hh"
37
38#include "WM_api.hh"
39#include "WM_toolsystem.hh"
40#include "WM_types.hh"
41
42#include "RNA_access.hh"
43#include "RNA_define.hh"
44
46#include "paint_hide.hh"
47#include "paint_intern.hh"
48#include "paint_mask.hh"
49#include "sculpt_intern.hh"
50
52{
53 Scene *scene = CTX_data_scene(C);
55 Brush *brush = BKE_paint_brush(paint);
56 float scalar = RNA_float_get(op->ptr, "scalar");
57
58 /* Grease Pencil brushes in Paint mode do not use unified size. */
59 const bool use_unified_size = !(brush && brush->gpencil_settings &&
61
62 if (brush) {
63 /* Pixel radius. */
64 {
65 const int old_size = (use_unified_size) ? BKE_brush_size_get(scene, brush) : brush->size;
66 int size = int(scalar * old_size);
67
68 if (abs(old_size - size) < U.pixelsize) {
69 if (scalar > 1) {
70 size += U.pixelsize;
71 }
72 else if (scalar < 1) {
73 size -= U.pixelsize;
74 }
75 }
76
77 if (use_unified_size) {
78 BKE_brush_size_set(scene, brush, size);
79 }
80 else {
81 brush->size = max_ii(size, 1);
83 }
84 }
85
86 /* Unprojected radius. */
87 {
88 float unprojected_radius = scalar * (use_unified_size ?
90 brush->unprojected_radius);
91
92 unprojected_radius = std::max(unprojected_radius, 0.001f);
93
94 if (use_unified_size) {
95 BKE_brush_unprojected_radius_set(scene, brush, unprojected_radius);
96 }
97 else {
98 brush->unprojected_radius = unprojected_radius;
100 }
101 }
102
104 }
105
106 return OPERATOR_FINISHED;
107}
108
110{
111 /* identifiers */
112 ot->name = "Scale Sculpt/Paint Brush Size";
113 ot->description = "Change brush size by a scalar";
114 ot->idname = "BRUSH_OT_scale_size";
115
116 /* API callbacks. */
118
119 /* flags */
120 ot->flag = 0;
121
122 RNA_def_float(ot->srna, "scalar", 1, 0, 2, "Scalar", "Factor to scale brush size by", 0, 2);
123}
124
125/* Palette operators */
126
128{
130 Main *bmain = CTX_data_main(C);
131 Palette *palette;
132
133 palette = BKE_palette_add(bmain, "Palette");
134
135 BKE_paint_palette_set(paint, palette);
136
137 return OPERATOR_FINISHED;
138}
139
141{
142 /* identifiers */
143 ot->name = "Add New Palette";
144 ot->description = "Add new palette";
145 ot->idname = "PALETTE_OT_new";
146
147 /* API callbacks. */
148 ot->exec = palette_new_exec;
149
150 /* flags */
152}
153
155{
157
158 if (paint && paint->palette != nullptr && ID_IS_EDITABLE(paint->palette) &&
160 {
161 return true;
162 }
163
164 return false;
165}
166
168{
169 Scene *scene = CTX_data_scene(C);
172 Palette *palette = paint->palette;
173 PaletteColor *color;
174
175 color = BKE_palette_color_add(palette);
176 palette->active_color = BLI_listbase_count(&palette->colors) - 1;
177
178 const Brush *brush = BKE_paint_brush_for_read(paint);
179 if (brush) {
180 if (ELEM(mode,
187 {
188 copy_v3_v3(color->rgb, BKE_brush_color_get(scene, paint, brush));
189 color->value = 0.0;
190 }
191 else if (mode == PaintMode::Weight) {
192 zero_v3(color->rgb);
193 color->value = brush->weight;
194 }
195 }
196
197 return OPERATOR_FINISHED;
198}
199
201{
202 /* identifiers */
203 ot->name = "New Palette Color";
204 ot->description = "Add new color to active palette";
205 ot->idname = "PALETTE_OT_color_add";
206
207 /* API callbacks. */
209 ot->poll = palette_poll;
210 /* flags */
212}
213
215{
217 Palette *palette = paint->palette;
218 PaletteColor *color = static_cast<PaletteColor *>(
219 BLI_findlink(&palette->colors, palette->active_color));
220
221 if (color) {
222 BKE_palette_color_remove(palette, color);
223 }
224
225 return OPERATOR_FINISHED;
226}
227
229{
230 /* identifiers */
231 ot->name = "Delete Palette Color";
232 ot->description = "Remove active color from palette";
233 ot->idname = "PALETTE_OT_color_delete";
234
235 /* API callbacks. */
237 ot->poll = palette_poll;
238 /* flags */
240}
241
242/* --- Extract Palette from Image. */
244{
246 if ((sl != nullptr) && (sl->spacetype == SPACE_IMAGE)) {
248 Image *image = sima->image;
249 ImageUser iuser = sima->iuser;
250 return BKE_image_has_ibuf(image, &iuser);
251 }
252
253 return false;
254}
255
257{
258 const int threshold = RNA_int_get(op->ptr, "threshold");
259
260 Main *bmain = CTX_data_main(C);
261 bool done = false;
262
264 Image *image = sima->image;
265 ImageUser iuser = sima->iuser;
266 void *lock;
267 ImBuf *ibuf;
268 GHash *color_table = BLI_ghash_int_new(__func__);
269
270 ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
271
272 if (ibuf && ibuf->byte_buffer.data) {
273 /* Extract all colors. */
274 const int range = int(pow(10.0f, threshold));
275 for (int row = 0; row < ibuf->y; row++) {
276 for (int col = 0; col < ibuf->x; col++) {
277 float color[4];
278 IMB_sampleImageAtLocation(ibuf, float(col), float(row), false, color);
279 for (int i = 0; i < 3; i++) {
280 color[i] = truncf(color[i] * range) / range;
281 }
282
283 uint key = rgb_to_cpack(color[0], color[1], color[2]);
284 if (!BLI_ghash_haskey(color_table, POINTER_FROM_INT(key))) {
285 BLI_ghash_insert(color_table, POINTER_FROM_INT(key), POINTER_FROM_INT(key));
286 }
287 }
288 }
289
290 done = BKE_palette_from_hash(bmain, color_table, image->id.name + 2, false);
291 }
292
293 /* Free memory. */
294 BLI_ghash_free(color_table, nullptr, nullptr);
295 BKE_image_release_ibuf(image, ibuf, lock);
296
297 if (done) {
298 BKE_reportf(op->reports, RPT_INFO, "Palette created");
299 }
300
301 return OPERATOR_FINISHED;
302}
303
305{
306 PropertyRNA *prop;
307
308 /* identifiers */
309 ot->name = "Extract Palette from Image";
310 ot->idname = "PALETTE_OT_extract_from_image";
311 ot->description = "Extract all colors used in Image and create a Palette";
312
313 /* API callbacks. */
316
317 /* flags */
319
320 /* properties */
321 prop = RNA_def_int(ot->srna, "threshold", 1, 1, 1, "Threshold", "", 1, 1);
323}
324
325/* Sort Palette color by Hue and Saturation. */
327{
328 const int type = RNA_enum_get(op->ptr, "type");
329
331 Palette *palette = paint->palette;
332
333 if (palette == nullptr) {
334 return OPERATOR_CANCELLED;
335 }
336
337 tPaletteColorHSV *color_array = nullptr;
338 tPaletteColorHSV *col_elm = nullptr;
339
340 const int totcol = BLI_listbase_count(&palette->colors);
341
342 if (totcol > 0) {
343 color_array = MEM_calloc_arrayN<tPaletteColorHSV>(totcol, __func__);
344 /* Put all colors in an array. */
345 int t = 0;
346 LISTBASE_FOREACH (PaletteColor *, color, &palette->colors) {
347 float h, s, v;
348 rgb_to_hsv(color->rgb[0], color->rgb[1], color->rgb[2], &h, &s, &v);
349 col_elm = &color_array[t];
350 copy_v3_v3(col_elm->rgb, color->rgb);
351 col_elm->value = color->value;
352 col_elm->h = h;
353 col_elm->s = s;
354 col_elm->v = v;
355 t++;
356 }
357 /* Sort */
358 if (type == 1) {
359 BKE_palette_sort_hsv(color_array, totcol);
360 }
361 else if (type == 2) {
362 BKE_palette_sort_svh(color_array, totcol);
363 }
364 else if (type == 3) {
365 BKE_palette_sort_vhs(color_array, totcol);
366 }
367 else {
368 BKE_palette_sort_luminance(color_array, totcol);
369 }
370
371 /* Clear old color swatches. */
372 LISTBASE_FOREACH_MUTABLE (PaletteColor *, color, &palette->colors) {
373 BKE_palette_color_remove(palette, color);
374 }
375
376 /* Recreate swatches sorted. */
377 for (int i = 0; i < totcol; i++) {
378 col_elm = &color_array[i];
379 PaletteColor *palcol = BKE_palette_color_add(palette);
380 if (palcol) {
381 copy_v3_v3(palcol->rgb, col_elm->rgb);
382 }
383 }
384 }
385
386 /* Free memory. */
387 if (totcol > 0) {
388 MEM_SAFE_FREE(color_array);
389 }
390
392
393 return OPERATOR_FINISHED;
394}
395
397{
398 static const EnumPropertyItem sort_type[] = {
399 {1, "HSV", 0, "Hue, Saturation, Value", ""},
400 {2, "SVH", 0, "Saturation, Value, Hue", ""},
401 {3, "VHS", 0, "Value, Hue, Saturation", ""},
402 {4, "LUMINANCE", 0, "Luminance", ""},
403 {0, nullptr, 0, nullptr, nullptr},
404 };
405
406 /* identifiers */
407 ot->name = "Sort Palette";
408 ot->idname = "PALETTE_OT_sort";
409 ot->description = "Sort Palette Colors";
410
411 /* API callbacks. */
412 ot->exec = palette_sort_exec;
413 ot->poll = palette_poll;
414
415 /* flags */
417
418 ot->prop = RNA_def_enum(ot->srna, "type", sort_type, 1, "Type", "");
419}
420
421/* Move colors in palette. */
423{
425 Palette *palette = paint->palette;
426 PaletteColor *palcolor = static_cast<PaletteColor *>(
427 BLI_findlink(&palette->colors, palette->active_color));
428
429 if (palcolor == nullptr) {
430 return OPERATOR_CANCELLED;
431 }
432
433 const int direction = RNA_enum_get(op->ptr, "type");
434
435 BLI_assert(ELEM(direction, -1, 0, 1)); /* we use value below */
436 if (BLI_listbase_link_move(&palette->colors, palcolor, direction)) {
437 palette->active_color += direction;
439 }
440
441 return OPERATOR_FINISHED;
442}
443
445{
446 static const EnumPropertyItem slot_move[] = {
447 {-1, "UP", 0, "Up", ""},
448 {1, "DOWN", 0, "Down", ""},
449 {0, nullptr, 0, nullptr, nullptr},
450 };
451
452 /* identifiers */
453 ot->name = "Move Palette Color";
454 ot->idname = "PALETTE_OT_color_move";
455 ot->description = "Move the active Color up/down in the list";
456
457 /* API callbacks. */
459 ot->poll = palette_poll;
460
461 /* flags */
463
464 ot->prop = RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
465}
466
467/* Join Palette swatches. */
469{
470 Main *bmain = CTX_data_main(C);
472 Palette *palette = paint->palette;
473 Palette *palette_join = nullptr;
474 bool done = false;
475
476 char name[MAX_ID_NAME - 2];
477 RNA_string_get(op->ptr, "palette", name);
478
479 if ((palette == nullptr) || (name[0] == '\0')) {
480 return OPERATOR_CANCELLED;
481 }
482
483 palette_join = (Palette *)BKE_libblock_find_name(bmain, ID_PAL, name);
484 if (palette_join == nullptr) {
485 return OPERATOR_CANCELLED;
486 }
487
488 const int totcol = BLI_listbase_count(&palette_join->colors);
489
490 if (totcol > 0) {
491 LISTBASE_FOREACH (PaletteColor *, color, &palette_join->colors) {
492 PaletteColor *palcol = BKE_palette_color_add(palette);
493 if (palcol) {
494 copy_v3_v3(palcol->rgb, color->rgb);
495 palcol->value = color->value;
496 done = true;
497 }
498 }
499 }
500
501 if (done) {
502 /* Clear old color swatches. */
503 LISTBASE_FOREACH_MUTABLE (PaletteColor *, color, &palette_join->colors) {
504 BKE_palette_color_remove(palette_join, color);
505 }
506
507 /* Notifier. */
509 }
510
511 return OPERATOR_FINISHED;
512}
513
515{
516 /* identifiers */
517 ot->name = "Join Palette Swatches";
518 ot->idname = "PALETTE_OT_join";
519 ot->description = "Join Palette Swatches";
520
521 /* API callbacks. */
522 ot->exec = palette_join_exec;
523 ot->poll = palette_poll;
524
525 /* flags */
527
528 /* properties */
529 RNA_def_string(ot->srna, "palette", nullptr, MAX_ID_NAME - 2, "Palette", "Name of the Palette");
530}
531
532/***** Stencil Control *****/
533
539
544
549
568
570{
571 Brush *br = scd->br;
572 float mdiff[2];
573 if (scd->mask) {
576 scd->init_rot = br->mask_mtex.rot;
577
579 scd->rot_target = &br->mask_mtex.rot;
580 scd->pos_target = br->mask_stencil_pos;
581
582 sub_v2_v2v2(mdiff, scd->init_mouse, br->mask_stencil_pos);
583 }
584 else {
587 scd->init_rot = br->mtex.rot;
588
589 scd->dim_target = br->stencil_dimension;
590 scd->rot_target = &br->mtex.rot;
591 scd->pos_target = br->stencil_pos;
592
593 sub_v2_v2v2(mdiff, scd->init_mouse, br->stencil_pos);
594 }
595
596 scd->lenorig = len_v2(mdiff);
597
598 scd->init_angle = atan2f(mdiff[1], mdiff[0]);
599}
600
602{
604 Brush *br = BKE_paint_brush(paint);
605 const float mvalf[2] = {float(event->mval[0]), float(event->mval[1])};
606 ARegion *region = CTX_wm_region(C);
608 int mask = RNA_enum_get(op->ptr, "texmode");
609
610 if (mask) {
612 return OPERATOR_CANCELLED;
613 }
614 }
615 else {
617 return OPERATOR_CANCELLED;
618 }
619 }
620
621 scd = MEM_mallocN<StencilControlData>(__func__);
622 scd->mask = mask;
623 scd->br = br;
624
625 copy_v2_v2(scd->init_mouse, mvalf);
626
628
629 scd->mode = StencilControlMode(RNA_enum_get(op->ptr, "mode"));
631 scd->area_size[0] = region->winx;
632 scd->area_size[1] = region->winy;
633
634 op->customdata = scd;
636
638}
639
641{
642 copy_v2_v2(scd->dim_target, scd->init_sdim);
643 copy_v2_v2(scd->pos_target, scd->init_spos);
644 *scd->rot_target = scd->init_rot;
645}
646
648{
649 StencilControlData *scd = static_cast<StencilControlData *>(op->customdata);
650 stencil_restore(scd);
651 MEM_freeN(scd);
652}
653
654static void stencil_control_calculate(StencilControlData *scd, const int mval[2])
655{
656#define PIXEL_MARGIN 5
657
658 float mdiff[2];
659 const float mvalf[2] = {float(mval[0]), float(mval[1])};
660 switch (scd->mode) {
662 sub_v2_v2v2(mdiff, mvalf, scd->init_mouse);
663 add_v2_v2v2(scd->pos_target, scd->init_spos, mdiff);
664 CLAMP(scd->pos_target[0],
665 -scd->dim_target[0] + PIXEL_MARGIN,
666 scd->area_size[0] + scd->dim_target[0] - PIXEL_MARGIN);
667
668 CLAMP(scd->pos_target[1],
669 -scd->dim_target[1] + PIXEL_MARGIN,
670 scd->area_size[1] + scd->dim_target[1] - PIXEL_MARGIN);
672
673 break;
674 case STENCIL_SCALE: {
675 float len, factor;
676 sub_v2_v2v2(mdiff, mvalf, scd->pos_target);
677 len = len_v2(mdiff);
678 factor = len / scd->lenorig;
679 copy_v2_v2(mdiff, scd->init_sdim);
681 mdiff[0] = factor * scd->init_sdim[0];
682 }
684 mdiff[1] = factor * scd->init_sdim[1];
685 }
686 clamp_v2(mdiff, 5.0f, 10000.0f);
687 copy_v2_v2(scd->dim_target, mdiff);
689 break;
690 }
691 case STENCIL_ROTATE: {
692 float angle;
693 sub_v2_v2v2(mdiff, mvalf, scd->pos_target);
694 angle = atan2f(mdiff[1], mdiff[0]);
695 angle = scd->init_rot + angle - scd->init_angle;
696 if (angle < 0.0f) {
697 angle += float(2 * M_PI);
698 }
699 if (angle > float(2 * M_PI)) {
700 angle -= float(2 * M_PI);
701 }
702 *scd->rot_target = angle;
704 break;
705 }
706 }
707#undef PIXEL_MARGIN
708}
709
711{
712 StencilControlData *scd = static_cast<StencilControlData *>(op->customdata);
713
714 if (event->type == scd->launch_event && event->val == KM_RELEASE) {
715 MEM_freeN(scd);
717 return OPERATOR_FINISHED;
718 }
719
720 switch (event->type) {
721 case MOUSEMOVE:
722 stencil_control_calculate(scd, event->mval);
723 break;
724 case EVT_ESCKEY:
725 if (event->val == KM_PRESS) {
728 return OPERATOR_CANCELLED;
729 }
730 break;
731 case EVT_XKEY:
732 if (event->val == KM_PRESS) {
733
736 }
737 else {
739 }
740
741 stencil_control_calculate(scd, event->mval);
742 }
743 break;
744 case EVT_YKEY:
745 if (event->val == KM_PRESS) {
748 }
749 else {
751 }
752
753 stencil_control_calculate(scd, event->mval);
754 }
755 break;
756 default:
757 break;
758 }
759
761
763}
764
766{
768
769 Paint *paint;
770 Brush *br;
771
773 return false;
774 }
775
777 br = BKE_paint_brush(paint);
778 return (br && (br->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL ||
780}
781
783{
784 static const EnumPropertyItem stencil_control_items[] = {
785 {STENCIL_TRANSLATE, "TRANSLATION", 0, "Translation", ""},
786 {STENCIL_SCALE, "SCALE", 0, "Scale", ""},
787 {STENCIL_ROTATE, "ROTATION", 0, "Rotation", ""},
788 {0, nullptr, 0, nullptr, nullptr},
789 };
790
791 static const EnumPropertyItem stencil_texture_items[] = {
792 {STENCIL_PRIMARY, "PRIMARY", 0, "Primary", ""},
793 {STENCIL_SECONDARY, "SECONDARY", 0, "Secondary", ""},
794 {0, nullptr, 0, nullptr, nullptr},
795 };
796 /* identifiers */
797 ot->name = "Stencil Brush Control";
798 ot->description = "Control the stencil brush";
799 ot->idname = "BRUSH_OT_stencil_control";
800
801 /* API callbacks. */
802 ot->invoke = stencil_control_invoke;
803 ot->modal = stencil_control_modal;
804 ot->cancel = stencil_control_cancel;
805 ot->poll = stencil_control_poll;
806
807 /* flags */
808 ot->flag = 0;
809
810 PropertyRNA *prop;
811 prop = RNA_def_enum(ot->srna, "mode", stencil_control_items, STENCIL_TRANSLATE, "Tool", "");
813 prop = RNA_def_enum(ot->srna, "texmode", stencil_texture_items, STENCIL_PRIMARY, "Tool", "");
815}
816
818{
820 Brush *br = BKE_paint_brush(paint);
821 bool use_scale = RNA_boolean_get(op->ptr, "use_scale");
822 bool use_repeat = RNA_boolean_get(op->ptr, "use_repeat");
823 bool do_mask = RNA_boolean_get(op->ptr, "mask");
824 Tex *tex = nullptr;
825 MTex *mtex = nullptr;
826 if (br) {
827 mtex = do_mask ? &br->mask_mtex : &br->mtex;
828 tex = mtex->tex;
829 }
830
831 if (tex && tex->type == TEX_IMAGE && tex->ima) {
832 float aspx, aspy;
833 Image *ima = tex->ima;
834 float orig_area, stencil_area, factor;
835 ED_image_get_uv_aspect(ima, nullptr, &aspx, &aspy);
836
837 if (use_scale) {
838 aspx *= mtex->size[0];
839 aspy *= mtex->size[1];
840 }
841
842 if (use_repeat && tex->extend == TEX_REPEAT) {
843 aspx *= tex->xrepeat;
844 aspy *= tex->yrepeat;
845 }
846
847 orig_area = fabsf(aspx * aspy);
848
849 if (do_mask) {
850 stencil_area = fabsf(br->mask_stencil_dimension[0] * br->mask_stencil_dimension[1]);
851 }
852 else {
853 stencil_area = fabsf(br->stencil_dimension[0] * br->stencil_dimension[1]);
854 }
855
856 factor = sqrtf(stencil_area / orig_area);
857
858 if (do_mask) {
859 br->mask_stencil_dimension[0] = fabsf(factor * aspx);
860 br->mask_stencil_dimension[1] = fabsf(factor * aspy);
861 }
862 else {
863 br->stencil_dimension[0] = fabsf(factor * aspx);
864 br->stencil_dimension[1] = fabsf(factor * aspy);
865 }
867 }
868
870
871 return OPERATOR_FINISHED;
872}
873
875{
876 /* identifiers */
877 ot->name = "Image Aspect";
878 ot->description =
879 "When using an image texture, adjust the stencil size to fit the image aspect ratio";
880 ot->idname = "BRUSH_OT_stencil_fit_image_aspect";
881
882 /* API callbacks. */
884 ot->poll = stencil_control_poll;
885
886 /* flags */
888
889 RNA_def_boolean(ot->srna, "use_repeat", true, "Use Repeat", "Use repeat mapping values");
890 RNA_def_boolean(ot->srna, "use_scale", true, "Use Scale", "Use texture scale values");
892 ot->srna, "mask", false, "Modify Mask Stencil", "Modify either the primary or mask stencil");
893}
894
896{
898 Brush *br = BKE_paint_brush(paint);
899 bool do_mask = RNA_boolean_get(op->ptr, "mask");
900
901 if (!br) {
902 return OPERATOR_CANCELLED;
903 }
904
905 if (do_mask) {
906 br->mask_stencil_pos[0] = 256;
907 br->mask_stencil_pos[1] = 256;
908
909 br->mask_stencil_dimension[0] = 256;
910 br->mask_stencil_dimension[1] = 256;
911
912 br->mask_mtex.rot = 0;
913 }
914 else {
915 br->stencil_pos[0] = 256;
916 br->stencil_pos[1] = 256;
917
918 br->stencil_dimension[0] = 256;
919 br->stencil_dimension[1] = 256;
920
921 br->mtex.rot = 0;
922 }
923
926
927 return OPERATOR_FINISHED;
928}
929
931{
932 /* identifiers */
933 ot->name = "Reset Transform";
934 ot->description = "Reset the stencil transformation to the default";
935 ot->idname = "BRUSH_OT_stencil_reset_transform";
936
937 /* API callbacks. */
939 ot->poll = stencil_control_poll;
940
941 /* flags */
943
945 ot->srna, "mask", false, "Modify Mask Stencil", "Modify either the primary or mask stencil");
946}
947
948/**************************** registration **********************************/
949
951{
953 wmOperatorTypeMacro *otmacro;
954
955 ot = WM_operatortype_append_macro("PAINTCURVE_OT_add_point_slide",
956 "Add Curve Point and Slide",
957 "Add new curve point and slide it",
959 ot->description = "Add new curve point and slide it";
960 WM_operatortype_macro_define(ot, "PAINTCURVE_OT_add_point");
961 otmacro = WM_operatortype_macro_define(ot, "PAINTCURVE_OT_slide");
962 RNA_boolean_set(otmacro->ptr, "align", true);
963 RNA_boolean_set(otmacro->ptr, "select", false);
964}
965
967{
968 /* palette */
969 using namespace blender::ed::sculpt_paint;
973
978
979 /* paint curve */
987
988 /* brush */
1002
1003 /* image */
1013
1014 /* weight */
1022
1023 /* uv */
1027
1028 /* vertex selection */
1036
1037 /* vertex */
1042
1048
1049 /* face-select */
1057
1059
1060 /* partial visibility */
1069
1070 /* paint masking */
1076}
1077
1079{
1080 using namespace blender::ed::sculpt_paint;
1081 wmKeyMap *keymap;
1082
1083 keymap = WM_keymap_ensure(keyconf, "Paint Curve", SPACE_EMPTY, RGN_TYPE_WINDOW);
1084 keymap->poll = paint_curve_poll;
1085
1086 /* Sculpt mode */
1087 keymap = WM_keymap_ensure(keyconf, "Sculpt", SPACE_EMPTY, RGN_TYPE_WINDOW);
1088 keymap->poll = SCULPT_mode_poll;
1089
1090 /* Vertex Paint mode */
1091 keymap = WM_keymap_ensure(keyconf, "Vertex Paint", SPACE_EMPTY, RGN_TYPE_WINDOW);
1092 keymap->poll = vertex_paint_mode_poll;
1093
1094 /* Weight Paint mode */
1095 keymap = WM_keymap_ensure(keyconf, "Weight Paint", SPACE_EMPTY, RGN_TYPE_WINDOW);
1096 keymap->poll = weight_paint_mode_poll;
1097
1098 /* Weight paint's Vertex Selection Mode. */
1099 keymap = WM_keymap_ensure(
1100 keyconf, "Paint Vertex Selection (Weight, Vertex)", SPACE_EMPTY, RGN_TYPE_WINDOW);
1101 keymap->poll = vert_paint_poll;
1102
1103 /* Image/Texture Paint mode */
1104 keymap = WM_keymap_ensure(keyconf, "Image Paint", SPACE_EMPTY, RGN_TYPE_WINDOW);
1106
1107 /* face-mask mode */
1108 keymap = WM_keymap_ensure(
1109 keyconf, "Paint Face Mask (Weight, Vertex, Texture)", SPACE_EMPTY, RGN_TYPE_WINDOW);
1110 keymap->poll = facemask_paint_poll;
1111
1112 /* paint stroke */
1113 keymap = paint_stroke_modal_keymap(keyconf);
1114 WM_modalkeymap_assign(keymap, "SCULPT_OT_brush_stroke");
1115
1116 /* Curves Sculpt mode. */
1117 keymap = WM_keymap_ensure(keyconf, "Sculpt Curves", SPACE_EMPTY, RGN_TYPE_WINDOW);
1118 keymap->poll = curves_sculpt_poll;
1119
1120 /* sculpt expand. */
1121 expand::modal_keymap(keyconf);
1122}
float BKE_brush_unprojected_radius_get(const Scene *scene, const Brush *brush)
Definition brush.cc:1249
int BKE_brush_size_get(const Scene *scene, const Brush *brush)
Definition brush.cc:1210
void BKE_brush_unprojected_radius_set(Scene *scene, Brush *brush, float unprojected_radius)
Definition brush.cc:1236
void BKE_brush_size_set(Scene *scene, Brush *brush, int size)
Definition brush.cc:1194
const float * BKE_brush_color_get(const Scene *scene, const Paint *paint, const Brush *brush)
Definition brush.cc:1128
void BKE_brush_tag_unsaved_changes(Brush *brush)
Definition brush.cc:720
SpaceImage * CTX_wm_space_image(const bContext *C)
SpaceLink * CTX_wm_space_data(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
bool BKE_image_has_ibuf(Image *ima, ImageUser *iuser)
ID * BKE_libblock_find_name(Main *bmain, short type, const char *name, const std::optional< Library * > lib=std::nullopt) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition lib_id.cc:1679
PaletteColor * BKE_palette_color_add(Palette *palette)
Definition paint.cc:1390
void BKE_palette_sort_hsv(tPaletteColorHSV *color_array, int totcol)
Definition paint.cc:1434
bool BKE_palette_from_hash(Main *bmain, GHash *color_table, const char *name, bool linear)
Definition paint.cc:1537
PaintMode
Definition BKE_paint.hh:93
void BKE_palette_sort_svh(tPaletteColorHSV *color_array, int totcol)
Definition paint.cc:1471
void BKE_palette_color_remove(Palette *palette, PaletteColor *color)
Definition paint.cc:1362
void BKE_palette_sort_vhs(tPaletteColorHSV *color_array, int totcol)
Definition paint.cc:1508
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Definition paint.cc:641
Paint * BKE_paint_get_active_from_context(const bContext *C)
Definition paint.cc:467
Palette * BKE_palette_add(Main *bmain, const char *name)
Definition paint.cc:1384
void BKE_palette_sort_luminance(tPaletteColorHSV *color_array, int totcol)
Definition paint.cc:1531
Brush * BKE_paint_brush(Paint *paint)
Definition paint.cc:636
void BKE_paint_palette_set(Paint *paint, Palette *palette)
Definition paint.cc:1348
PaintMode BKE_paintmode_get_active_from_context(const bContext *C)
Definition paint.cc:496
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert(a)
Definition BLI_assert.h:46
bool BLI_ghash_haskey(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.cc:819
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition BLI_ghash.cc:707
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.cc:860
GHash * BLI_ghash_int_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void void void bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL()
Definition listbase.cc:436
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
MINLINE int max_ii(int a, int b)
unsigned int rgb_to_cpack(float r, float g, float b)
void rgb_to_hsv(float r, float g, float b, float *r_h, float *r_s, float *r_v)
#define M_PI
MINLINE float len_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void clamp_v2(float vec[2], float min, float max)
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void zero_v3(float r[3])
unsigned int uint
#define CLAMP(a, b, c)
#define POINTER_FROM_INT(i)
#define ELEM(...)
@ ID_PAL
@ OB_MODE_PAINT_GREASE_PENCIL
@ RGN_TYPE_WINDOW
@ SPACE_EMPTY
@ SPACE_IMAGE
@ MTEX_MAP_MODE_STENCIL
@ TEX_REPEAT
@ TEX_IMAGE
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
void ED_image_get_uv_aspect(Image *ima, ImageUser *iuser, float *r_aspx, float *r_aspy)
void ED_region_tag_redraw(ARegion *region)
Definition area.cc:639
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
void IMB_sampleImageAtLocation(ImBuf *ibuf, float x, float y, bool make_linear_rgb, float color[4])
Definition interp.cc:12
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition RNA_types.hh:330
@ PROP_HIDDEN
Definition RNA_types.hh:324
#define C
Definition RandGen.cpp:29
#define NC_WINDOW
Definition WM_types.hh:372
#define NC_BRUSH
Definition WM_types.hh:382
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
#define NA_EDITED
Definition WM_types.hh:581
@ KM_PRESS
Definition WM_types.hh:308
@ KM_RELEASE
Definition WM_types.hh:309
volatile int lock
#define U
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
#define atan2f(x, y)
#define fabsf(x)
#define sqrtf(x)
uint col
#define pow
#define abs
#define MEM_SAFE_FREE(v)
#define MAX_ID_NAME
#define ID_IS_EDITABLE(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void modal_keymap(wmKeyConfig *keyconf)
void PAINT_OT_hide_show_polyline_gesture(wmOperatorType *ot)
void PAINT_OT_hide_show_masked(wmOperatorType *ot)
void PAINT_OT_hide_show_line_gesture(wmOperatorType *ot)
void PAINT_OT_visibility_invert(wmOperatorType *ot)
void PAINT_OT_hide_show_lasso_gesture(wmOperatorType *ot)
void PAINT_OT_visibility_filter(wmOperatorType *ot)
void PAINT_OT_hide_show_all(wmOperatorType *ot)
void PAINT_OT_hide_show(wmOperatorType *ot)
void PAINT_OT_mask_polyline_gesture(wmOperatorType *ot)
void PAINT_OT_mask_line_gesture(wmOperatorType *ot)
void PAINT_OT_mask_box_gesture(wmOperatorType *ot)
void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot)
void PAINT_OT_mask_flood_fill(wmOperatorType *ot)
bool curves_sculpt_poll(bContext *C)
void BRUSH_OT_asset_save(wmOperatorType *ot)
bool paint_supports_texture(PaintMode mode)
void BRUSH_OT_asset_delete(wmOperatorType *ot)
void BRUSH_OT_asset_edit_metadata(wmOperatorType *ot)
void BRUSH_OT_asset_load_preview(wmOperatorType *ot)
void BRUSH_OT_asset_revert(wmOperatorType *ot)
wmKeyMap * paint_stroke_modal_keymap(wmKeyConfig *keyconf)
void BRUSH_OT_asset_save_as(wmOperatorType *ot)
void BRUSH_OT_asset_activate(wmOperatorType *ot)
bool paint_curve_poll(bContext *C)
void PAINTCURVE_OT_new(wmOperatorType *ot)
void PAINTCURVE_OT_add_point(wmOperatorType *ot)
void PAINTCURVE_OT_delete_point(wmOperatorType *ot)
void PAINTCURVE_OT_draw(wmOperatorType *ot)
void PAINTCURVE_OT_cursor(wmOperatorType *ot)
void PAINTCURVE_OT_slide(wmOperatorType *ot)
void PAINTCURVE_OT_select(wmOperatorType *ot)
bool vert_paint_poll(bContext *C)
bool facemask_paint_poll(bContext *C)
bool image_texture_paint_poll(bContext *C)
void PAINT_OT_sample_color(wmOperatorType *ot)
void PAINT_OT_texture_paint_toggle(wmOperatorType *ot)
void PAINT_OT_brush_colors_flip(wmOperatorType *ot)
void PAINT_OT_grab_clone(wmOperatorType *ot)
void PAINT_OT_image_paint(wmOperatorType *ot)
void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot)
void PAINT_OT_add_simple_uvs(wmOperatorType *ot)
void PAINT_OT_project_image(wmOperatorType *ot)
void PAINT_OT_image_from_view(wmOperatorType *ot)
void SCULPT_OT_uv_sculpt_relax(wmOperatorType *ot)
Definition sculpt_uv.cc:995
void PAINT_OT_weight_set(wmOperatorType *ot)
void PAINT_OT_vertex_color_set(wmOperatorType *ot)
void PAINT_OT_face_select_more(wmOperatorType *ot)
void PAINT_OT_vert_select_less(wmOperatorType *ot)
void PAINT_OT_vertex_color_smooth(wmOperatorType *ot)
void PAINT_OT_weight_paint(wmOperatorType *ot)
void PAINT_OT_face_select_hide(wmOperatorType *ot)
void PAINT_OT_face_select_loop(wmOperatorType *ot)
void PAINT_OT_vertex_color_hsv(wmOperatorType *ot)
void PAINT_OT_vert_select_linked(wmOperatorType *ot)
void PAINT_OT_vertex_paint(wmOperatorType *ot)
void PAINT_OT_face_select_linked_pick(wmOperatorType *ot)
bool weight_paint_mode_poll(bContext *C)
void PAINT_OT_vert_select_linked_pick(wmOperatorType *ot)
void PAINT_OT_vert_select_ungrouped(wmOperatorType *ot)
void BRUSH_OT_sculpt_curves_falloff_preset(wmOperatorType *ot)
void BRUSH_OT_curve_preset(wmOperatorType *ot)
void PAINT_OT_face_select_less(wmOperatorType *ot)
void PAINT_OT_weight_sample(wmOperatorType *ot)
void PAINT_OT_vert_select_all(wmOperatorType *ot)
void PAINT_OT_vertex_color_levels(wmOperatorType *ot)
void PAINT_OT_face_select_all(wmOperatorType *ot)
void PAINT_OT_vertex_color_from_weight(wmOperatorType *ot)
void PAINT_OT_face_select_linked(wmOperatorType *ot)
bool vertex_paint_mode_poll(bContext *C)
void PAINT_OT_weight_from_bones(wmOperatorType *ot)
void PAINT_OT_vertex_color_brightness_contrast(wmOperatorType *ot)
void PAINT_OT_weight_paint_toggle(wmOperatorType *ot)
void PAINT_OT_weight_gradient(wmOperatorType *ot)
void SCULPT_OT_uv_sculpt_pinch(wmOperatorType *ot)
void PAINT_OT_vertex_paint_toggle(wmOperatorType *ot)
void PAINT_OT_vertex_color_invert(wmOperatorType *ot)
void PAINT_OT_vert_select_hide(wmOperatorType *ot)
void PAINT_OT_weight_sample_group(wmOperatorType *ot)
void PAINT_OT_vert_select_more(wmOperatorType *ot)
void SCULPT_OT_uv_sculpt_grab(wmOperatorType *ot)
Definition sculpt_uv.cc:980
void PAINT_OT_face_vert_reveal(wmOperatorType *ot)
static void BRUSH_OT_scale_size(wmOperatorType *ot)
Definition paint_ops.cc:109
static wmOperatorStatus palette_color_delete_exec(bContext *C, wmOperator *)
Definition paint_ops.cc:214
static void PALETTE_OT_join(wmOperatorType *ot)
Definition paint_ops.cc:514
StencilConstraint
Definition paint_ops.cc:545
@ STENCIL_CONSTRAINT_Y
Definition paint_ops.cc:547
@ STENCIL_CONSTRAINT_X
Definition paint_ops.cc:546
static bool stencil_control_poll(bContext *C)
Definition paint_ops.cc:765
void ED_operatortypes_paint()
Definition paint_ops.cc:966
static void PALETTE_OT_extract_from_image(wmOperatorType *ot)
Definition paint_ops.cc:304
static void BRUSH_OT_stencil_reset_transform(wmOperatorType *ot)
Definition paint_ops.cc:930
static wmOperatorStatus palette_sort_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:326
static bool palette_poll(bContext *C)
Definition paint_ops.cc:154
static wmOperatorStatus palette_join_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:468
static wmOperatorStatus stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition paint_ops.cc:710
static void BRUSH_OT_stencil_fit_image_aspect(wmOperatorType *ot)
Definition paint_ops.cc:874
static wmOperatorStatus palette_color_add_exec(bContext *C, wmOperator *)
Definition paint_ops.cc:167
static void stencil_control_calculate(StencilControlData *scd, const int mval[2])
Definition paint_ops.cc:654
static wmOperatorStatus stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition paint_ops.cc:601
static void stencil_set_target(StencilControlData *scd)
Definition paint_ops.cc:569
static wmOperatorStatus palette_new_exec(bContext *C, wmOperator *)
Definition paint_ops.cc:127
void ED_operatormacros_paint()
Definition paint_ops.cc:950
static wmOperatorStatus palette_extract_img_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:256
static void PALETTE_OT_new(wmOperatorType *ot)
Definition paint_ops.cc:140
static void PALETTE_OT_color_delete(wmOperatorType *ot)
Definition paint_ops.cc:228
StencilControlMode
Definition paint_ops.cc:534
@ STENCIL_SCALE
Definition paint_ops.cc:536
@ STENCIL_TRANSLATE
Definition paint_ops.cc:535
@ STENCIL_ROTATE
Definition paint_ops.cc:537
StencilTextureMode
Definition paint_ops.cc:540
@ STENCIL_SECONDARY
Definition paint_ops.cc:542
@ STENCIL_PRIMARY
Definition paint_ops.cc:541
static void PALETTE_OT_color_move(wmOperatorType *ot)
Definition paint_ops.cc:444
static wmOperatorStatus brush_scale_size_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:51
static void PALETTE_OT_color_add(wmOperatorType *ot)
Definition paint_ops.cc:200
#define PIXEL_MARGIN
static wmOperatorStatus stencil_reset_transform_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:895
static void BRUSH_OT_stencil_control(wmOperatorType *ot)
Definition paint_ops.cc:782
static wmOperatorStatus palette_color_move_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:422
static void stencil_restore(StencilControlData *scd)
Definition paint_ops.cc:640
static bool palette_extract_img_poll(bContext *C)
Definition paint_ops.cc:243
static void PALETTE_OT_sort(wmOperatorType *ot)
Definition paint_ops.cc:396
static void stencil_control_cancel(bContext *, wmOperator *op)
Definition paint_ops.cc:647
static wmOperatorStatus stencil_fit_image_aspect_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:817
void ED_keymap_paint(wmKeyConfig *keyconf)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
int RNA_int_get(PointerRNA *ptr, const char *name)
float RNA_float_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
bool SCULPT_mode_poll(bContext *C)
Definition sculpt.cc:3660
struct MTex mtex
float stencil_pos[2]
float unprojected_radius
short ob_mode
float stencil_dimension[2]
float mask_stencil_pos[2]
struct BrushGpencilSettings * gpencil_settings
struct MTex mask_mtex
float mask_stencil_dimension[2]
float weight
char name[66]
Definition DNA_ID.h:415
ImBufByteBuffer byte_buffer
char brush_map_mode
float size[3]
struct Tex * tex
struct Palette * palette
ListBase colors
struct ImageUser iuser
struct Image * image
StencilConstraint constrain_mode
Definition paint_ops.cc:559
StencilControlMode mode
Definition paint_ops.cc:558
short xrepeat
struct Image * ima
short extend
short yrepeat
wmEventType type
Definition WM_types.hh:754
short val
Definition WM_types.hh:756
int mval[2]
Definition WM_types.hh:760
bool(* poll)(struct bContext *)
struct ReportList * reports
struct PointerRNA * ptr
i
Definition text_draw.cc:230
uint len
int WM_userdef_event_type_from_keymap_type(int kmitype)
void WM_main_add_notifier(uint type, void *reference)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ EVT_YKEY
@ EVT_XKEY
@ MOUSEMOVE
@ EVT_ESCKEY
wmOperatorType * ot
Definition wm_files.cc:4225
void WM_modalkeymap_assign(wmKeyMap *km, const char *opname)
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
Definition wm_keymap.cc:893
wmOperatorTypeMacro * WM_operatortype_macro_define(wmOperatorType *ot, const char *idname)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
wmOperatorType * WM_operatortype_append_macro(const char *idname, const char *name, const char *description, int flag)