Blender V5.0
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_color.h"
18#include "BLI_math_vector.h"
19#include "BLI_utildefines.h"
20
21#include "IMB_interp.hh"
22
23#include "DNA_brush_types.h"
24#include "DNA_scene_types.h"
25
26#include "BKE_brush.hh"
27#include "BKE_context.hh"
28#include "BKE_image.hh"
29#include "BKE_lib_id.hh"
30#include "BKE_library.hh"
31#include "BKE_main.hh"
32#include "BKE_paint.hh"
33#include "BKE_paint_types.hh"
34#include "BKE_report.hh"
35
36#include "ED_image.hh"
37#include "ED_paint.hh"
38#include "ED_screen.hh"
39
40#include "WM_api.hh"
41#include "WM_types.hh"
42
43#include "RNA_access.hh"
44#include "RNA_define.hh"
45
47
49#include "paint_hide.hh"
50#include "paint_intern.hh"
51#include "paint_mask.hh"
52#include "sculpt_intern.hh"
53
55{
57 Brush *brush = BKE_paint_brush(paint);
58 float scalar = RNA_float_get(op->ptr, "scalar");
59
60 /* Grease Pencil brushes in Paint mode do not use unified size. */
61 const bool use_unified_size = !(brush && brush->gpencil_settings &&
63
64 if (brush) {
65 /* Pixel diameter. */
66 {
67 const int old_size = (use_unified_size) ? BKE_brush_size_get(paint, brush) : brush->size;
68 int size = int(scalar * old_size);
69
70 if (abs(old_size - size) < U.pixelsize) {
71 if (scalar > 1) {
72 size += U.pixelsize;
73 }
74 else if (scalar < 1) {
75 size -= U.pixelsize;
76 }
77 }
78
79 if (use_unified_size) {
80 BKE_brush_size_set(paint, brush, size);
81 }
82 else {
83 brush->size = max_ii(size, 1);
85 }
86 }
87
88 /* Unprojected diameter. */
89 {
90 float unprojected_size = scalar * (use_unified_size ?
91 BKE_brush_unprojected_size_get(paint, brush) :
92 brush->unprojected_size);
93
94 unprojected_size = std::max(unprojected_size, 0.001f);
95
96 if (use_unified_size) {
97 BKE_brush_unprojected_size_set(paint, brush, unprojected_size);
98 }
99 else {
100 brush->unprojected_size = unprojected_size;
102 }
103 }
104
106 }
107
108 return OPERATOR_FINISHED;
109}
110
112{
113 /* identifiers */
114 ot->name = "Scale Sculpt/Paint Brush Size";
115 ot->description = "Change brush size by a scalar";
116 ot->idname = "BRUSH_OT_scale_size";
117
118 /* API callbacks. */
120
121 /* flags */
122 ot->flag = 0;
123
124 RNA_def_float(ot->srna, "scalar", 1, 0, 2, "Scalar", "Factor to scale brush size by", 0, 2);
125}
126
127/* Palette operators */
128
130{
132 Main *bmain = CTX_data_main(C);
133 Palette *palette;
134
135 palette = BKE_palette_add(bmain, "Palette");
136
137 BKE_paint_palette_set(paint, palette);
138
139 return OPERATOR_FINISHED;
140}
141
143{
144 /* identifiers */
145 ot->name = "Add New Palette";
146 ot->description = "Add new palette";
147 ot->idname = "PALETTE_OT_new";
148
149 /* API callbacks. */
150 ot->exec = palette_new_exec;
151
152 /* flags */
154}
155
157{
159
160 if (paint && paint->palette != nullptr && ID_IS_EDITABLE(paint->palette) &&
162 {
163 return true;
164 }
165
166 return false;
167}
168
170{
173 Palette *palette = paint->palette;
174 PaletteColor *color;
175
176 color = BKE_palette_color_add(palette);
177 palette->active_color = BLI_listbase_count(&palette->colors) - 1;
178
179 const Brush *brush = BKE_paint_brush_for_read(paint);
180 if (brush) {
181 if (ELEM(mode,
188 {
189 copy_v3_v3(color->color, BKE_brush_color_get(paint, brush));
190 color->value = 0.0;
191 }
192 else if (mode == PaintMode::Weight) {
193 zero_v3(color->color);
194 color->value = brush->weight;
195 }
196 }
197
198 return OPERATOR_FINISHED;
199}
200
202{
203 /* identifiers */
204 ot->name = "New Palette Color";
205 ot->description = "Add new color to active palette";
206 ot->idname = "PALETTE_OT_color_add";
207
208 /* API callbacks. */
210 ot->poll = palette_poll;
211 /* flags */
213}
214
216{
218 Palette *palette = paint->palette;
219 PaletteColor *color = static_cast<PaletteColor *>(
220 BLI_findlink(&palette->colors, palette->active_color));
221
222 if (color) {
223 BKE_palette_color_remove(palette, color);
224 }
225
226 return OPERATOR_FINISHED;
227}
228
230{
231 /* identifiers */
232 ot->name = "Delete Palette Color";
233 ot->description = "Remove active color from palette";
234 ot->idname = "PALETTE_OT_color_delete";
235
236 /* API callbacks. */
238 ot->poll = palette_poll;
239 /* flags */
241}
242
243/* --- Extract Palette from Image. */
245{
247 if ((sl != nullptr) && (sl->spacetype == SPACE_IMAGE)) {
249 Image *image = sima->image;
250 ImageUser iuser = sima->iuser;
251 return BKE_image_has_ibuf(image, &iuser);
252 }
253
254 return false;
255}
256
258{
259 const int threshold = RNA_int_get(op->ptr, "threshold");
260
261 Main *bmain = CTX_data_main(C);
262 bool done = false;
263
265 Image *image = sima->image;
266 ImageUser iuser = sima->iuser;
267 void *lock;
268 ImBuf *ibuf;
269 GHash *color_table = BLI_ghash_int_new(__func__);
270
271 ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
272
273 if (ibuf && ibuf->byte_buffer.data) {
274 /* Extract all colors. */
275 const int range = int(pow(10.0f, threshold));
276 for (int row = 0; row < ibuf->y; row++) {
277 for (int col = 0; col < ibuf->x; col++) {
278 float color[3];
279 IMB_sampleImageAtLocation(ibuf, float(col), float(row), color);
280 /* Convert to sRGB for hex. */
282 for (int i = 0; i < 3; i++) {
283 color[i] = truncf(color[i] * range) / range;
284 }
285
286 uint key = rgb_to_cpack(color[0], color[1], color[2]);
287 if (!BLI_ghash_haskey(color_table, POINTER_FROM_INT(key))) {
288 BLI_ghash_insert(color_table, POINTER_FROM_INT(key), POINTER_FROM_INT(key));
289 }
290 }
291 }
292
293 done = BKE_palette_from_hash(bmain, color_table, image->id.name + 2);
294 }
295
296 /* Free memory. */
297 BLI_ghash_free(color_table, nullptr, nullptr);
298 BKE_image_release_ibuf(image, ibuf, lock);
299
300 if (done) {
301 BKE_reportf(op->reports, RPT_INFO, "Palette created");
302 }
303
304 return OPERATOR_FINISHED;
305}
306
308{
309 PropertyRNA *prop;
310
311 /* identifiers */
312 ot->name = "Extract Palette from Image";
313 ot->idname = "PALETTE_OT_extract_from_image";
314 ot->description = "Extract all colors used in Image and create a Palette";
315
316 /* API callbacks. */
319
320 /* flags */
322
323 /* properties */
324 prop = RNA_def_int(ot->srna, "threshold", 1, 1, 1, "Threshold", "", 1, 1);
326}
327
328/* Sort Palette color by Hue and Saturation. */
330{
331 const int type = RNA_enum_get(op->ptr, "type");
332
334 Palette *palette = paint->palette;
335
336 if (palette == nullptr) {
337 return OPERATOR_CANCELLED;
338 }
339
340 tPaletteColorHSV *color_array = nullptr;
341 tPaletteColorHSV *col_elm = nullptr;
342
343 const int totcol = BLI_listbase_count(&palette->colors);
344
345 if (totcol > 0) {
346 color_array = MEM_calloc_arrayN<tPaletteColorHSV>(totcol, __func__);
347 /* Put all colors in an array. */
348 int t = 0;
349 LISTBASE_FOREACH (PaletteColor *, color, &palette->colors) {
350 float h, s, v;
351 rgb_to_hsv(color->color[0], color->color[1], color->color[2], &h, &s, &v);
352 col_elm = &color_array[t];
353 copy_v3_v3(col_elm->rgb, color->color);
354 col_elm->value = color->value;
355 col_elm->h = h;
356 col_elm->s = s;
357 col_elm->v = v;
358 t++;
359 }
360 /* Sort */
361 if (type == 1) {
362 BKE_palette_sort_hsv(color_array, totcol);
363 }
364 else if (type == 2) {
365 BKE_palette_sort_svh(color_array, totcol);
366 }
367 else if (type == 3) {
368 BKE_palette_sort_vhs(color_array, totcol);
369 }
370 else {
371 BKE_palette_sort_luminance(color_array, totcol);
372 }
373
374 /* Clear old color swatches. */
375 LISTBASE_FOREACH_MUTABLE (PaletteColor *, color, &palette->colors) {
376 BKE_palette_color_remove(palette, color);
377 }
378
379 /* Recreate swatches sorted. */
380 for (int i = 0; i < totcol; i++) {
381 col_elm = &color_array[i];
382 PaletteColor *palcol = BKE_palette_color_add(palette);
383 if (palcol) {
384 copy_v3_v3(palcol->color, col_elm->rgb);
385 }
386 }
387 }
388
389 /* Free memory. */
390 if (totcol > 0) {
391 MEM_SAFE_FREE(color_array);
392 }
393
395
396 return OPERATOR_FINISHED;
397}
398
400{
401 static const EnumPropertyItem sort_type[] = {
402 {1, "HSV", 0, "Hue, Saturation, Value", ""},
403 {2, "SVH", 0, "Saturation, Value, Hue", ""},
404 {3, "VHS", 0, "Value, Hue, Saturation", ""},
405 {4, "LUMINANCE", 0, "Luminance", ""},
406 {0, nullptr, 0, nullptr, nullptr},
407 };
408
409 /* identifiers */
410 ot->name = "Sort Palette";
411 ot->idname = "PALETTE_OT_sort";
412 ot->description = "Sort Palette Colors";
413
414 /* API callbacks. */
415 ot->exec = palette_sort_exec;
416 ot->poll = palette_poll;
417
418 /* flags */
420
421 ot->prop = RNA_def_enum(ot->srna, "type", sort_type, 1, "Type", "");
422}
423
424/* Move colors in palette. */
426{
428 Palette *palette = paint->palette;
429 PaletteColor *palcolor = static_cast<PaletteColor *>(
430 BLI_findlink(&palette->colors, palette->active_color));
431
432 if (palcolor == nullptr) {
433 return OPERATOR_CANCELLED;
434 }
435
436 const int direction = RNA_enum_get(op->ptr, "type");
437
438 BLI_assert(ELEM(direction, -1, 0, 1)); /* we use value below */
439 if (BLI_listbase_link_move(&palette->colors, palcolor, direction)) {
440 palette->active_color += direction;
442 }
443
444 return OPERATOR_FINISHED;
445}
446
448{
449 static const EnumPropertyItem slot_move[] = {
450 {-1, "UP", 0, "Up", ""},
451 {1, "DOWN", 0, "Down", ""},
452 {0, nullptr, 0, nullptr, nullptr},
453 };
454
455 /* identifiers */
456 ot->name = "Move Palette Color";
457 ot->idname = "PALETTE_OT_color_move";
458 ot->description = "Move the active Color up/down in the list";
459
460 /* API callbacks. */
462 ot->poll = palette_poll;
463
464 /* flags */
466
467 ot->prop = RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
468}
469
470/* Join Palette swatches. */
472{
473 Main *bmain = CTX_data_main(C);
475 Palette *palette = paint->palette;
476 Palette *palette_join = nullptr;
477 bool done = false;
478
479 char name[MAX_ID_NAME - 2];
480 RNA_string_get(op->ptr, "palette", name);
481
482 if ((palette == nullptr) || (name[0] == '\0')) {
483 return OPERATOR_CANCELLED;
484 }
485
486 palette_join = (Palette *)BKE_libblock_find_name(bmain, ID_PAL, name);
487 if (palette_join == nullptr) {
488 return OPERATOR_CANCELLED;
489 }
490
491 const int totcol = BLI_listbase_count(&palette_join->colors);
492
493 if (totcol > 0) {
494 LISTBASE_FOREACH (PaletteColor *, color, &palette_join->colors) {
495 PaletteColor *palcol = BKE_palette_color_add(palette);
496 if (palcol) {
497 copy_v3_v3(palcol->color, color->color);
498 palcol->value = color->value;
499 done = true;
500 }
501 }
502 }
503
504 if (done) {
505 /* Clear old color swatches. */
506 LISTBASE_FOREACH_MUTABLE (PaletteColor *, color, &palette_join->colors) {
507 BKE_palette_color_remove(palette_join, color);
508 }
509
510 /* Notifier. */
512 }
513
514 return OPERATOR_FINISHED;
515}
516
518{
519 /* identifiers */
520 ot->name = "Join Palette Swatches";
521 ot->idname = "PALETTE_OT_join";
522 ot->description = "Join Palette Swatches";
523
524 /* API callbacks. */
525 ot->exec = palette_join_exec;
526 ot->poll = palette_poll;
527
528 /* flags */
530
531 /* properties */
532 RNA_def_string(ot->srna, "palette", nullptr, MAX_ID_NAME - 2, "Palette", "Name of the Palette");
533}
534
535/***** Stencil Control *****/
536
542
547
552
571
573{
574 Brush *br = scd->br;
575 float mdiff[2];
576 if (scd->mask) {
579 scd->init_rot = br->mask_mtex.rot;
580
582 scd->rot_target = &br->mask_mtex.rot;
583 scd->pos_target = br->mask_stencil_pos;
584
585 sub_v2_v2v2(mdiff, scd->init_mouse, br->mask_stencil_pos);
586 }
587 else {
590 scd->init_rot = br->mtex.rot;
591
592 scd->dim_target = br->stencil_dimension;
593 scd->rot_target = &br->mtex.rot;
594 scd->pos_target = br->stencil_pos;
595
596 sub_v2_v2v2(mdiff, scd->init_mouse, br->stencil_pos);
597 }
598
599 scd->lenorig = len_v2(mdiff);
600
601 scd->init_angle = atan2f(mdiff[1], mdiff[0]);
602}
603
605{
607 Brush *br = BKE_paint_brush(paint);
608 const float mvalf[2] = {float(event->mval[0]), float(event->mval[1])};
609 ARegion *region = CTX_wm_region(C);
611 int mask = RNA_enum_get(op->ptr, "texmode");
612
613 if (mask) {
615 return OPERATOR_CANCELLED;
616 }
617 }
618 else {
620 return OPERATOR_CANCELLED;
621 }
622 }
623
624 scd = MEM_mallocN<StencilControlData>(__func__);
625 scd->mask = mask;
626 scd->br = br;
627
628 copy_v2_v2(scd->init_mouse, mvalf);
629
631
632 scd->mode = StencilControlMode(RNA_enum_get(op->ptr, "mode"));
634 scd->area_size[0] = region->winx;
635 scd->area_size[1] = region->winy;
636
637 op->customdata = scd;
639
641}
642
644{
645 copy_v2_v2(scd->dim_target, scd->init_sdim);
646 copy_v2_v2(scd->pos_target, scd->init_spos);
647 *scd->rot_target = scd->init_rot;
648}
649
651{
652 StencilControlData *scd = static_cast<StencilControlData *>(op->customdata);
653 stencil_restore(scd);
654 MEM_freeN(scd);
655}
656
657static void stencil_control_calculate(StencilControlData *scd, const int mval[2])
658{
659#define PIXEL_MARGIN 5
660
661 float mdiff[2];
662 const float mvalf[2] = {float(mval[0]), float(mval[1])};
663 switch (scd->mode) {
665 sub_v2_v2v2(mdiff, mvalf, scd->init_mouse);
666 add_v2_v2v2(scd->pos_target, scd->init_spos, mdiff);
667 CLAMP(scd->pos_target[0],
668 -scd->dim_target[0] + PIXEL_MARGIN,
669 scd->area_size[0] + scd->dim_target[0] - PIXEL_MARGIN);
670
671 CLAMP(scd->pos_target[1],
672 -scd->dim_target[1] + PIXEL_MARGIN,
673 scd->area_size[1] + scd->dim_target[1] - PIXEL_MARGIN);
675
676 break;
677 case STENCIL_SCALE: {
678 float len, factor;
679 sub_v2_v2v2(mdiff, mvalf, scd->pos_target);
680 len = len_v2(mdiff);
681 factor = len / scd->lenorig;
682 copy_v2_v2(mdiff, scd->init_sdim);
684 mdiff[0] = factor * scd->init_sdim[0];
685 }
687 mdiff[1] = factor * scd->init_sdim[1];
688 }
689 clamp_v2(mdiff, 5.0f, 10000.0f);
690 copy_v2_v2(scd->dim_target, mdiff);
692 break;
693 }
694 case STENCIL_ROTATE: {
695 float angle;
696 sub_v2_v2v2(mdiff, mvalf, scd->pos_target);
697 angle = atan2f(mdiff[1], mdiff[0]);
698 angle = scd->init_rot + angle - scd->init_angle;
699 if (angle < 0.0f) {
700 angle += float(2 * M_PI);
701 }
702 if (angle > float(2 * M_PI)) {
703 angle -= float(2 * M_PI);
704 }
705 *scd->rot_target = angle;
707 break;
708 }
709 }
710#undef PIXEL_MARGIN
711}
712
714{
715 StencilControlData *scd = static_cast<StencilControlData *>(op->customdata);
716
717 if (event->type == scd->launch_event && event->val == KM_RELEASE) {
718 MEM_freeN(scd);
720 return OPERATOR_FINISHED;
721 }
722
723 switch (event->type) {
724 case MOUSEMOVE:
725 stencil_control_calculate(scd, event->mval);
726 break;
727 case EVT_ESCKEY:
728 if (event->val == KM_PRESS) {
731 return OPERATOR_CANCELLED;
732 }
733 break;
734 case EVT_XKEY:
735 if (event->val == KM_PRESS) {
736
739 }
740 else {
742 }
743
744 stencil_control_calculate(scd, event->mval);
745 }
746 break;
747 case EVT_YKEY:
748 if (event->val == KM_PRESS) {
751 }
752 else {
754 }
755
756 stencil_control_calculate(scd, event->mval);
757 }
758 break;
759 default:
760 break;
761 }
762
764
766}
767
769{
771
772 Paint *paint;
773 Brush *br;
774
776 return false;
777 }
778
780 br = BKE_paint_brush(paint);
781 return (br && (br->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL ||
783}
784
786{
787 static const EnumPropertyItem stencil_control_items[] = {
788 {STENCIL_TRANSLATE, "TRANSLATION", 0, "Translation", ""},
789 {STENCIL_SCALE, "SCALE", 0, "Scale", ""},
790 {STENCIL_ROTATE, "ROTATION", 0, "Rotation", ""},
791 {0, nullptr, 0, nullptr, nullptr},
792 };
793
794 static const EnumPropertyItem stencil_texture_items[] = {
795 {STENCIL_PRIMARY, "PRIMARY", 0, "Primary", ""},
796 {STENCIL_SECONDARY, "SECONDARY", 0, "Secondary", ""},
797 {0, nullptr, 0, nullptr, nullptr},
798 };
799 /* identifiers */
800 ot->name = "Stencil Brush Control";
801 ot->description = "Control the stencil brush";
802 ot->idname = "BRUSH_OT_stencil_control";
803
804 /* API callbacks. */
805 ot->invoke = stencil_control_invoke;
806 ot->modal = stencil_control_modal;
807 ot->cancel = stencil_control_cancel;
808 ot->poll = stencil_control_poll;
809
810 /* flags */
811 ot->flag = 0;
812
813 PropertyRNA *prop;
814 prop = RNA_def_enum(ot->srna, "mode", stencil_control_items, STENCIL_TRANSLATE, "Tool", "");
816 prop = RNA_def_enum(ot->srna, "texmode", stencil_texture_items, STENCIL_PRIMARY, "Tool", "");
818}
819
821{
823 Brush *br = BKE_paint_brush(paint);
824 bool use_scale = RNA_boolean_get(op->ptr, "use_scale");
825 bool use_repeat = RNA_boolean_get(op->ptr, "use_repeat");
826 bool do_mask = RNA_boolean_get(op->ptr, "mask");
827 Tex *tex = nullptr;
828 MTex *mtex = nullptr;
829 if (br) {
830 mtex = do_mask ? &br->mask_mtex : &br->mtex;
831 tex = mtex->tex;
832 }
833
834 if (tex && tex->type == TEX_IMAGE && tex->ima) {
835 float aspx, aspy;
836 Image *ima = tex->ima;
837 float orig_area, stencil_area, factor;
838 ED_image_get_uv_aspect(ima, nullptr, &aspx, &aspy);
839
840 if (use_scale) {
841 aspx *= mtex->size[0];
842 aspy *= mtex->size[1];
843 }
844
845 if (use_repeat && tex->extend == TEX_REPEAT) {
846 aspx *= tex->xrepeat;
847 aspy *= tex->yrepeat;
848 }
849
850 orig_area = fabsf(aspx * aspy);
851
852 if (do_mask) {
853 stencil_area = fabsf(br->mask_stencil_dimension[0] * br->mask_stencil_dimension[1]);
854 }
855 else {
856 stencil_area = fabsf(br->stencil_dimension[0] * br->stencil_dimension[1]);
857 }
858
859 factor = sqrtf(stencil_area / orig_area);
860
861 if (do_mask) {
862 br->mask_stencil_dimension[0] = fabsf(factor * aspx);
863 br->mask_stencil_dimension[1] = fabsf(factor * aspy);
864 }
865 else {
866 br->stencil_dimension[0] = fabsf(factor * aspx);
867 br->stencil_dimension[1] = fabsf(factor * aspy);
868 }
870 }
871
873
874 return OPERATOR_FINISHED;
875}
876
878{
879 /* identifiers */
880 ot->name = "Image Aspect";
881 ot->description =
882 "When using an image texture, adjust the stencil size to fit the image aspect ratio";
883 ot->idname = "BRUSH_OT_stencil_fit_image_aspect";
884
885 /* API callbacks. */
887 ot->poll = stencil_control_poll;
888
889 /* flags */
891
892 RNA_def_boolean(ot->srna, "use_repeat", true, "Use Repeat", "Use repeat mapping values");
893 RNA_def_boolean(ot->srna, "use_scale", true, "Use Scale", "Use texture scale values");
895 ot->srna, "mask", false, "Modify Mask Stencil", "Modify either the primary or mask stencil");
896}
897
899{
901 Brush *br = BKE_paint_brush(paint);
902 bool do_mask = RNA_boolean_get(op->ptr, "mask");
903
904 if (!br) {
905 return OPERATOR_CANCELLED;
906 }
907
908 if (do_mask) {
909 br->mask_stencil_pos[0] = 256;
910 br->mask_stencil_pos[1] = 256;
911
912 br->mask_stencil_dimension[0] = 256;
913 br->mask_stencil_dimension[1] = 256;
914
915 br->mask_mtex.rot = 0;
916 }
917 else {
918 br->stencil_pos[0] = 256;
919 br->stencil_pos[1] = 256;
920
921 br->stencil_dimension[0] = 256;
922 br->stencil_dimension[1] = 256;
923
924 br->mtex.rot = 0;
925 }
926
929
930 return OPERATOR_FINISHED;
931}
932
934{
935 /* identifiers */
936 ot->name = "Reset Transform";
937 ot->description = "Reset the stencil transformation to the default";
938 ot->idname = "BRUSH_OT_stencil_reset_transform";
939
940 /* API callbacks. */
942 ot->poll = stencil_control_poll;
943
944 /* flags */
946
948 ot->srna, "mask", false, "Modify Mask Stencil", "Modify either the primary or mask stencil");
949}
950
951/**************************** registration **********************************/
952
954{
956 wmOperatorTypeMacro *otmacro;
957
958 ot = WM_operatortype_append_macro("PAINTCURVE_OT_add_point_slide",
959 "Add Curve Point and Slide",
960 "Add new curve point and slide it",
962 ot->description = "Add new curve point and slide it";
963 WM_operatortype_macro_define(ot, "PAINTCURVE_OT_add_point");
964 otmacro = WM_operatortype_macro_define(ot, "PAINTCURVE_OT_slide");
965 RNA_boolean_set(otmacro->ptr, "align", true);
966 RNA_boolean_set(otmacro->ptr, "select", false);
967}
968
970{
971 /* palette */
972 using namespace blender::ed::sculpt_paint;
976
981
982 /* paint curve */
990
991 /* brush */
1003
1004 /* image */
1014
1015 /* weight */
1023
1024 /* uv */
1028
1029 /* vertex selection */
1037
1038 /* vertex */
1043
1049
1050 /* face-select */
1058
1060
1061 /* partial visibility */
1070
1071 /* paint masking */
1077}
1078
1080{
1081 using namespace blender::ed::sculpt_paint;
1082 wmKeyMap *keymap;
1083
1084 keymap = WM_keymap_ensure(keyconf, "Paint Curve", SPACE_EMPTY, RGN_TYPE_WINDOW);
1085 keymap->poll = paint_curve_poll;
1086
1087 /* Sculpt mode */
1088 keymap = WM_keymap_ensure(keyconf, "Sculpt", SPACE_EMPTY, RGN_TYPE_WINDOW);
1089 keymap->poll = SCULPT_mode_poll;
1090
1091 /* Vertex Paint mode */
1092 keymap = WM_keymap_ensure(keyconf, "Vertex Paint", SPACE_EMPTY, RGN_TYPE_WINDOW);
1093 keymap->poll = vertex_paint_mode_poll;
1094
1095 /* Weight Paint mode */
1096 keymap = WM_keymap_ensure(keyconf, "Weight Paint", SPACE_EMPTY, RGN_TYPE_WINDOW);
1097 keymap->poll = weight_paint_mode_poll;
1098
1099 /* Weight paint's Vertex Selection Mode. */
1100 keymap = WM_keymap_ensure(
1101 keyconf, "Paint Vertex Selection (Weight, Vertex)", SPACE_EMPTY, RGN_TYPE_WINDOW);
1102 keymap->poll = vert_paint_poll;
1103
1104 /* Image/Texture Paint mode */
1105 keymap = WM_keymap_ensure(keyconf, "Image Paint", SPACE_EMPTY, RGN_TYPE_WINDOW);
1107
1108 /* face-mask mode */
1109 keymap = WM_keymap_ensure(
1110 keyconf, "Paint Face Mask (Weight, Vertex, Texture)", SPACE_EMPTY, RGN_TYPE_WINDOW);
1111 keymap->poll = facemask_paint_poll;
1112
1113 /* paint stroke */
1114 keymap = paint_stroke_modal_keymap(keyconf);
1115 WM_modalkeymap_assign(keymap, "SCULPT_OT_brush_stroke");
1116
1117 /* Curves Sculpt mode. */
1118 keymap = WM_keymap_ensure(keyconf, "Sculpt Curves", SPACE_EMPTY, RGN_TYPE_WINDOW);
1119 keymap->poll = curves_sculpt_poll;
1120
1121 /* sculpt expand. */
1122 expand::modal_keymap(keyconf);
1123}
float BKE_brush_unprojected_size_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1308
const float * BKE_brush_color_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1161
void BKE_brush_size_set(Paint *paint, Brush *brush, int size)
Definition brush.cc:1248
void BKE_brush_unprojected_size_set(Paint *paint, Brush *brush, float unprojected_size)
Definition brush.cc:1295
void BKE_brush_tag_unsaved_changes(Brush *brush)
Definition brush.cc:764
int BKE_brush_size_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1264
SpaceImage * CTX_wm_space_image(const bContext *C)
SpaceLink * CTX_wm_space_data(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:1710
PaletteColor * BKE_palette_color_add(Palette *palette)
Definition paint.cc:1433
void BKE_palette_sort_hsv(tPaletteColorHSV *color_array, int totcol)
Definition paint.cc:1477
void BKE_palette_sort_svh(tPaletteColorHSV *color_array, int totcol)
Definition paint.cc:1514
void BKE_palette_color_remove(Palette *palette, PaletteColor *color)
Definition paint.cc:1394
void BKE_palette_sort_vhs(tPaletteColorHSV *color_array, int totcol)
Definition paint.cc:1551
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Definition paint.cc:650
Paint * BKE_paint_get_active_from_context(const bContext *C)
Definition paint.cc:476
Palette * BKE_palette_add(Main *bmain, const char *name)
Definition paint.cc:1427
bool BKE_palette_from_hash(Main *bmain, GHash *color_table, const char *name)
Definition paint.cc:1580
void BKE_palette_sort_luminance(tPaletteColorHSV *color_array, int totcol)
Definition paint.cc:1574
Brush * BKE_paint_brush(Paint *paint)
Definition paint.cc:645
void BKE_paint_palette_set(Paint *paint, Palette *palette)
Definition paint.cc:1380
PaintMode BKE_paintmode_get_active_from_context(const bContext *C)
Definition paint.cc:505
PaintMode
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
@ RPT_INFO
Definition BKE_report.hh:35
#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(...)
#define MAX_ID_NAME
Definition DNA_ID.h:373
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:705
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:730
@ ID_PAL
@ OB_MODE_PAINT_GREASE_PENCIL
@ RGN_TYPE_WINDOW
@ SPACE_EMPTY
@ SPACE_IMAGE
@ TEX_REPEAT
@ TEX_IMAGE
@ MTEX_MAP_MODE_STENCIL
@ 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:618
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
BLI_INLINE void IMB_colormanagement_scene_linear_to_srgb_v3(float srgb[3], const float scene_linear[3])
void IMB_sampleImageAtLocation(ImBuf *ibuf, float x, float y, float scene_linear_rgb[3])
Definition interp.cc:14
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
@ PROP_SKIP_SAVE
Definition RNA_types.hh:344
@ PROP_HIDDEN
Definition RNA_types.hh:338
#define C
Definition RandGen.cpp:29
#define NC_WINDOW
Definition WM_types.hh:375
#define NC_BRUSH
Definition WM_types.hh:385
@ KM_PRESS
Definition WM_types.hh:311
@ KM_RELEASE
Definition WM_types.hh:312
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
#define NA_EDITED
Definition WM_types.hh:584
volatile int lock
#define U
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
nullptr float
uint col
#define pow
#define abs
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_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 PAINT_OT_sample_color(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:111
static wmOperatorStatus palette_color_delete_exec(bContext *C, wmOperator *)
Definition paint_ops.cc:215
static void PALETTE_OT_join(wmOperatorType *ot)
Definition paint_ops.cc:517
StencilConstraint
Definition paint_ops.cc:548
@ STENCIL_CONSTRAINT_Y
Definition paint_ops.cc:550
@ STENCIL_CONSTRAINT_X
Definition paint_ops.cc:549
static bool stencil_control_poll(bContext *C)
Definition paint_ops.cc:768
void ED_operatortypes_paint()
Definition paint_ops.cc:969
static void PALETTE_OT_extract_from_image(wmOperatorType *ot)
Definition paint_ops.cc:307
static void BRUSH_OT_stencil_reset_transform(wmOperatorType *ot)
Definition paint_ops.cc:933
static wmOperatorStatus palette_sort_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:329
static bool palette_poll(bContext *C)
Definition paint_ops.cc:156
static wmOperatorStatus palette_join_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:471
static wmOperatorStatus stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition paint_ops.cc:713
static void BRUSH_OT_stencil_fit_image_aspect(wmOperatorType *ot)
Definition paint_ops.cc:877
static wmOperatorStatus palette_color_add_exec(bContext *C, wmOperator *)
Definition paint_ops.cc:169
static void stencil_control_calculate(StencilControlData *scd, const int mval[2])
Definition paint_ops.cc:657
static wmOperatorStatus stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition paint_ops.cc:604
static void stencil_set_target(StencilControlData *scd)
Definition paint_ops.cc:572
static wmOperatorStatus palette_new_exec(bContext *C, wmOperator *)
Definition paint_ops.cc:129
void ED_operatormacros_paint()
Definition paint_ops.cc:953
static wmOperatorStatus palette_extract_img_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:257
static void PALETTE_OT_new(wmOperatorType *ot)
Definition paint_ops.cc:142
static void PALETTE_OT_color_delete(wmOperatorType *ot)
Definition paint_ops.cc:229
StencilControlMode
Definition paint_ops.cc:537
@ STENCIL_SCALE
Definition paint_ops.cc:539
@ STENCIL_TRANSLATE
Definition paint_ops.cc:538
@ STENCIL_ROTATE
Definition paint_ops.cc:540
StencilTextureMode
Definition paint_ops.cc:543
@ STENCIL_SECONDARY
Definition paint_ops.cc:545
@ STENCIL_PRIMARY
Definition paint_ops.cc:544
static void PALETTE_OT_color_move(wmOperatorType *ot)
Definition paint_ops.cc:447
static wmOperatorStatus brush_scale_size_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:54
static void PALETTE_OT_color_add(wmOperatorType *ot)
Definition paint_ops.cc:201
#define PIXEL_MARGIN
static wmOperatorStatus stencil_reset_transform_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:898
static void BRUSH_OT_stencil_control(wmOperatorType *ot)
Definition paint_ops.cc:785
static wmOperatorStatus palette_color_move_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:425
static void stencil_restore(StencilControlData *scd)
Definition paint_ops.cc:643
static bool palette_extract_img_poll(bContext *C)
Definition paint_ops.cc:244
static void PALETTE_OT_sort(wmOperatorType *ot)
Definition paint_ops.cc:399
static void stencil_control_cancel(bContext *, wmOperator *op)
Definition paint_ops.cc:650
static wmOperatorStatus stencil_fit_image_aspect_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:820
void ED_keymap_paint(wmKeyConfig *keyconf)
const char * name
#define fabsf
#define sqrtf
#define atan2f
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
int RNA_int_get(PointerRNA *ptr, const char *name)
float RNA_float_get(PointerRNA *ptr, const char *name)
std::string RNA_string_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:3677
struct MTex mtex
float stencil_pos[2]
short ob_mode
float stencil_dimension[2]
float mask_stencil_pos[2]
struct BrushGpencilSettings * gpencil_settings
float unprojected_size
struct MTex mask_mtex
float mask_stencil_dimension[2]
float weight
char name[258]
Definition DNA_ID.h:432
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:562
StencilControlMode mode
Definition paint_ops.cc:561
short xrepeat
struct Image * ima
short extend
short yrepeat
wmEventType type
Definition WM_types.hh:757
short val
Definition WM_types.hh:759
int mval[2]
Definition WM_types.hh:763
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:4237
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:895
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)