Blender V4.3
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
9#include <cstddef>
10#include <cstdlib>
11#include <cstring>
12
13#include "MEM_guardedalloc.h"
14
15#include "BLI_listbase.h"
16#include "BLI_math_vector.h"
17#include "BLI_string.h"
18#include "BLI_utildefines.h"
19
20#include "IMB_interp.hh"
21
22#include "DNA_brush_types.h"
24#include "DNA_object_types.h"
25#include "DNA_scene_types.h"
26
27#include "BKE_brush.hh"
28#include "BKE_context.hh"
29#include "BKE_image.hh"
30#include "BKE_lib_id.hh"
31#include "BKE_main.hh"
32#include "BKE_paint.hh"
33#include "BKE_report.hh"
34
35#include "ED_image.hh"
36#include "ED_paint.hh"
37#include "ED_screen.hh"
38
39#include "WM_api.hh"
40#include "WM_toolsystem.hh"
41#include "WM_types.hh"
42
43#include "RNA_access.hh"
44#include "RNA_define.hh"
45
47#include "paint_hide.hh"
48#include "paint_intern.hh"
49#include "paint_mask.hh"
50#include "sculpt_intern.hh"
51
53{
54 Scene *scene = CTX_data_scene(C);
56 Brush *brush = BKE_paint_brush(paint);
57 float scalar = RNA_float_get(op->ptr, "scalar");
58
59 /* Grease Pencil brushes in Paint mode do not use unified size. */
60 const bool use_unified_size = !(brush && brush->gpencil_settings &&
62
63 if (brush) {
64 /* Pixel radius. */
65 {
66 const int old_size = (use_unified_size) ? BKE_brush_size_get(scene, brush) : brush->size;
67 int size = int(scalar * old_size);
68
69 if (abs(old_size - size) < U.pixelsize) {
70 if (scalar > 1) {
71 size += U.pixelsize;
72 }
73 else if (scalar < 1) {
74 size -= U.pixelsize;
75 }
76 }
77
78 if (use_unified_size) {
79 BKE_brush_size_set(scene, brush, size);
80 }
81 else {
82 brush->size = max_ii(size, 1);
84 }
85 }
86
87 /* Unprojected radius. */
88 {
89 float unprojected_radius = scalar * (use_unified_size ?
91 brush->unprojected_radius);
92
93 if (unprojected_radius < 0.001f) { /* XXX magic number */
94 unprojected_radius = 0.001f;
95 }
96
97 if (use_unified_size) {
98 BKE_brush_unprojected_radius_set(scene, brush, unprojected_radius);
99 }
100 else {
101 brush->unprojected_radius = unprojected_radius;
103 }
104 }
105
107 }
108
109 return OPERATOR_FINISHED;
110}
111
113{
114 /* identifiers */
115 ot->name = "Scale Sculpt/Paint Brush Size";
116 ot->description = "Change brush size by a scalar";
117 ot->idname = "BRUSH_OT_scale_size";
118
119 /* api callbacks */
121
122 /* flags */
123 ot->flag = 0;
124
125 RNA_def_float(ot->srna, "scalar", 1, 0, 2, "Scalar", "Factor to scale brush size by", 0, 2);
126}
127
128/* Palette operators */
129
130static int palette_new_exec(bContext *C, wmOperator * /*op*/)
131{
133 Main *bmain = CTX_data_main(C);
134 Palette *palette;
135
136 palette = BKE_palette_add(bmain, "Palette");
137
138 BKE_paint_palette_set(paint, palette);
139
140 return OPERATOR_FINISHED;
141}
142
144{
145 /* identifiers */
146 ot->name = "Add New Palette";
147 ot->description = "Add new palette";
148 ot->idname = "PALETTE_OT_new";
149
150 /* api callbacks */
152
153 /* flags */
155}
156
157static bool palette_poll(bContext *C)
158{
160
161 if (paint && paint->palette != nullptr && ID_IS_EDITABLE(paint->palette) &&
163 {
164 return true;
165 }
166
167 return false;
168}
169
171{
172 Scene *scene = CTX_data_scene(C);
175 Palette *palette = paint->palette;
177
178 color = BKE_palette_color_add(palette);
179 palette->active_color = BLI_listbase_count(&palette->colors) - 1;
180
181 const Brush *brush = BKE_paint_brush_for_read(paint);
182 if (brush) {
183 if (ELEM(mode,
190 {
191 copy_v3_v3(color->rgb, BKE_brush_color_get(scene, paint, brush));
192 color->value = 0.0;
193 }
194 else if (mode == PaintMode::Weight) {
195 zero_v3(color->rgb);
196 color->value = brush->weight;
197 }
198 }
199
200 return OPERATOR_FINISHED;
201}
202
204{
205 /* identifiers */
206 ot->name = "New Palette Color";
207 ot->description = "Add new color to active palette";
208 ot->idname = "PALETTE_OT_color_add";
209
210 /* api callbacks */
213 /* flags */
215}
216
218{
220 Palette *palette = paint->palette;
221 PaletteColor *color = static_cast<PaletteColor *>(
222 BLI_findlink(&palette->colors, palette->active_color));
223
224 if (color) {
225 BKE_palette_color_remove(palette, color);
226 }
227
228 return OPERATOR_FINISHED;
229}
230
232{
233 /* identifiers */
234 ot->name = "Delete Palette Color";
235 ot->description = "Remove active color from palette";
236 ot->idname = "PALETTE_OT_color_delete";
237
238 /* api callbacks */
241 /* flags */
243}
244
245/* --- Extract Palette from Image. */
247{
249 if ((sl != nullptr) && (sl->spacetype == SPACE_IMAGE)) {
251 Image *image = sima->image;
252 ImageUser iuser = sima->iuser;
253 return BKE_image_has_ibuf(image, &iuser);
254 }
255
256 return false;
257}
258
260{
261 const int threshold = RNA_int_get(op->ptr, "threshold");
262
263 Main *bmain = CTX_data_main(C);
264 bool done = false;
265
267 Image *image = sima->image;
268 ImageUser iuser = sima->iuser;
269 void *lock;
270 ImBuf *ibuf;
271 GHash *color_table = BLI_ghash_int_new(__func__);
272
273 ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
274
275 if (ibuf && ibuf->byte_buffer.data) {
276 /* Extract all colors. */
277 const int range = int(pow(10.0f, threshold));
278 for (int row = 0; row < ibuf->y; row++) {
279 for (int col = 0; col < ibuf->x; col++) {
280 float color[4];
281 IMB_sampleImageAtLocation(ibuf, float(col), float(row), false, color);
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, false);
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_cnew_array<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->rgb[0], color->rgb[1], color->rgb[2], &h, &s, &v);
352 col_elm = &color_array[t];
353 copy_v3_v3(col_elm->rgb, color->rgb);
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->rgb, 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 */
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 */
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->rgb, color->rgb);
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 */
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
604static int stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *event)
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 = static_cast<StencilControlData *>(MEM_mallocN(sizeof(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
713static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *event)
714{
715 StencilControlData *scd = static_cast<StencilControlData *>(op->customdata);
716
717 if (event->type == scd->launch_event && event->val == KM_RELEASE) {
719 WM_event_add_notifier(C, NC_WINDOW, nullptr);
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) {
730 WM_event_add_notifier(C, NC_WINDOW, nullptr);
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 */
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
872 WM_event_add_notifier(C, NC_WINDOW, nullptr);
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 */
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
928 WM_event_add_notifier(C, NC_WINDOW, nullptr);
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 */
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 */
998 WM_operatortype_append(BRUSH_OT_asset_activate);
999 WM_operatortype_append(BRUSH_OT_asset_save_as);
1000 WM_operatortype_append(BRUSH_OT_asset_edit_metadata);
1001 WM_operatortype_append(BRUSH_OT_asset_load_preview);
1002 WM_operatortype_append(BRUSH_OT_asset_delete);
1003 WM_operatortype_append(BRUSH_OT_asset_save);
1004 WM_operatortype_append(BRUSH_OT_asset_revert);
1005
1006 /* image */
1016
1017 /* weight */
1025
1026 /* uv */
1030
1031 /* vertex selection */
1039
1040 /* vertex */
1045
1051
1052 /* face-select */
1060
1062
1063 /* partial visibility */
1064 WM_operatortype_append(hide::PAINT_OT_hide_show_all);
1065 WM_operatortype_append(hide::PAINT_OT_hide_show_masked);
1066 WM_operatortype_append(hide::PAINT_OT_hide_show);
1067 WM_operatortype_append(hide::PAINT_OT_hide_show_lasso_gesture);
1068 WM_operatortype_append(hide::PAINT_OT_hide_show_line_gesture);
1069 WM_operatortype_append(hide::PAINT_OT_hide_show_polyline_gesture);
1070 WM_operatortype_append(hide::PAINT_OT_visibility_invert);
1071 WM_operatortype_append(hide::PAINT_OT_visibility_filter);
1072
1073 /* paint masking */
1074 WM_operatortype_append(mask::PAINT_OT_mask_flood_fill);
1075 WM_operatortype_append(mask::PAINT_OT_mask_lasso_gesture);
1076 WM_operatortype_append(mask::PAINT_OT_mask_box_gesture);
1077 WM_operatortype_append(mask::PAINT_OT_mask_line_gesture);
1078 WM_operatortype_append(mask::PAINT_OT_mask_polyline_gesture);
1079}
1080
1082{
1083 using namespace blender::ed::sculpt_paint;
1084 wmKeyMap *keymap;
1085
1086 keymap = WM_keymap_ensure(keyconf, "Paint Curve", SPACE_EMPTY, RGN_TYPE_WINDOW);
1087 keymap->poll = paint_curve_poll;
1088
1089 /* Sculpt mode */
1090 keymap = WM_keymap_ensure(keyconf, "Sculpt", SPACE_EMPTY, RGN_TYPE_WINDOW);
1091 keymap->poll = SCULPT_mode_poll;
1092
1093 /* Vertex Paint mode */
1094 keymap = WM_keymap_ensure(keyconf, "Vertex Paint", SPACE_EMPTY, RGN_TYPE_WINDOW);
1095 keymap->poll = vertex_paint_mode_poll;
1096
1097 /* Weight Paint mode */
1098 keymap = WM_keymap_ensure(keyconf, "Weight Paint", SPACE_EMPTY, RGN_TYPE_WINDOW);
1099 keymap->poll = weight_paint_mode_poll;
1100
1101 /* Weight paint's Vertex Selection Mode. */
1102 keymap = WM_keymap_ensure(
1103 keyconf, "Paint Vertex Selection (Weight, Vertex)", SPACE_EMPTY, RGN_TYPE_WINDOW);
1104 keymap->poll = vert_paint_poll;
1105
1106 /* Image/Texture Paint mode */
1107 keymap = WM_keymap_ensure(keyconf, "Image Paint", SPACE_EMPTY, RGN_TYPE_WINDOW);
1109
1110 /* face-mask mode */
1111 keymap = WM_keymap_ensure(
1112 keyconf, "Paint Face Mask (Weight, Vertex, Texture)", SPACE_EMPTY, RGN_TYPE_WINDOW);
1113 keymap->poll = facemask_paint_poll;
1114
1115 /* paint stroke */
1116 keymap = paint_stroke_modal_keymap(keyconf);
1117 WM_modalkeymap_assign(keymap, "SCULPT_OT_brush_stroke");
1118
1119 /* Curves Sculpt mode. */
1120 keymap = WM_keymap_ensure(keyconf, "Sculpt Curves", SPACE_EMPTY, RGN_TYPE_WINDOW);
1121 keymap->poll = curves_sculpt_poll;
1122
1123 /* sculpt expand. */
1124 expand::modal_keymap(keyconf);
1125}
float BKE_brush_unprojected_radius_get(const Scene *scene, const Brush *brush)
Definition brush.cc:1133
int BKE_brush_size_get(const Scene *scene, const Brush *brush)
Definition brush.cc:1075
void BKE_brush_unprojected_radius_set(Scene *scene, Brush *brush, float unprojected_radius)
Definition brush.cc:1120
void BKE_brush_size_set(Scene *scene, Brush *brush, int size)
Definition brush.cc:1059
const float * BKE_brush_color_get(const Scene *scene, const Paint *paint, const Brush *brush)
Definition brush.cc:1029
void BKE_brush_tag_unsaved_changes(Brush *brush)
Definition brush.cc:621
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:1657
PaletteColor * BKE_palette_color_add(Palette *palette)
Definition paint.cc:1392
void BKE_palette_sort_hsv(tPaletteColorHSV *color_array, int totcol)
Definition paint.cc:1520
bool BKE_palette_from_hash(Main *bmain, GHash *color_table, const char *name, bool linear)
Definition paint.cc:1544
PaintMode
Definition BKE_paint.hh:99
void BKE_palette_sort_svh(tPaletteColorHSV *color_array, int totcol)
Definition paint.cc:1526
void BKE_palette_color_remove(Palette *palette, PaletteColor *color)
Definition paint.cc:1364
void BKE_palette_sort_vhs(tPaletteColorHSV *color_array, int totcol)
Definition paint.cc:1532
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Definition paint.cc:654
Paint * BKE_paint_get_active_from_context(const bContext *C)
Definition paint.cc:477
Palette * BKE_palette_add(Main *bmain, const char *name)
Definition paint.cc:1386
void BKE_palette_sort_luminance(tPaletteColorHSV *color_array, int totcol)
Definition paint.cc:1538
Brush * BKE_paint_brush(Paint *paint)
Definition paint.cc:649
void BKE_paint_palette_set(Paint *paint, Palette *palette)
Definition paint.cc:1350
PaintMode BKE_paintmode_get_active_from_context(const bContext *C)
Definition paint.cc:506
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert(a)
Definition BLI_assert.h:50
bool BLI_ghash_haskey(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:819
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition BLI_ghash.c:707
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c:860
GHash * BLI_ghash_int_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void void bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL()
Definition listbase.cc:435
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int max_ii(int a, int b)
#define M_PI
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)
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:377
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:658
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:683
@ ID_PAL
@ OB_MODE_PAINT_GREASE_PENCIL
Object is a sort of wrapper for general info.
@ RGN_TYPE_WINDOW
@ SPACE_EMPTY
@ SPACE_IMAGE
@ TEX_IMAGE
@ MTEX_MAP_MODE_STENCIL
@ TEX_REPEAT
@ 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:634
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:125
void IMB_sampleImageAtLocation(ImBuf *ibuf, float x, float y, bool make_linear_rgb, float color[4])
Definition interp.cc:13
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
PropertyFlag
Definition RNA_types.hh:201
@ PROP_SKIP_SAVE
Definition RNA_types.hh:245
@ PROP_HIDDEN
Definition RNA_types.hh:239
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define NC_WINDOW
Definition WM_types.hh:342
#define NC_BRUSH
Definition WM_types.hh:352
@ KM_PRESS
Definition WM_types.hh:284
@ KM_RELEASE
Definition WM_types.hh:285
#define NA_EDITED
Definition WM_types.hh:550
volatile int lock
ATTR_WARN_UNUSED_RESULT const BMVert * v
unsigned int U
Definition btGjkEpa3.h:78
pow(value.r - subtrahend, 2.0)") .do_static_compilation(true)
#define atan2f(x, y)
#define fabsf(x)
#define sqrtf(x)
int len
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
uint col
IndexRange range
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
ccl_device_inline float4 mask(const int4 mask, const float4 a)
bool paint_supports_texture(PaintMode mode)
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:993
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:978
void PAINT_OT_face_vert_reveal(wmOperatorType *ot)
static void BRUSH_OT_scale_size(wmOperatorType *ot)
Definition paint_ops.cc:112
static int palette_color_move_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:425
static int stencil_fit_image_aspect_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:820
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 bool palette_poll(bContext *C)
Definition paint_ops.cc:157
static void BRUSH_OT_stencil_fit_image_aspect(wmOperatorType *ot)
Definition paint_ops.cc:877
static void stencil_control_calculate(StencilControlData *scd, const int mval[2])
Definition paint_ops.cc:657
static int palette_join_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:471
static int 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 int palette_new_exec(bContext *C, wmOperator *)
Definition paint_ops.cc:130
static int palette_extract_img_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:259
void ED_operatormacros_paint()
Definition paint_ops.cc:953
static void PALETTE_OT_new(wmOperatorType *ot)
Definition paint_ops.cc:143
static void PALETTE_OT_color_delete(wmOperatorType *ot)
Definition paint_ops.cc:231
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 int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition paint_ops.cc:713
static int palette_color_delete_exec(bContext *C, wmOperator *)
Definition paint_ops.cc:217
static void PALETTE_OT_color_move(wmOperatorType *ot)
Definition paint_ops.cc:447
static int palette_sort_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:329
static void PALETTE_OT_color_add(wmOperatorType *ot)
Definition paint_ops.cc:203
#define PIXEL_MARGIN
static int 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 int brush_scale_size_exec(bContext *C, wmOperator *op)
Definition paint_ops.cc:52
static void stencil_restore(StencilControlData *scd)
Definition paint_ops.cc:643
static bool palette_extract_img_poll(bContext *C)
Definition paint_ops.cc:246
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 int palette_color_add_exec(bContext *C, wmOperator *)
Definition paint_ops.cc:170
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:3560
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
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
short val
Definition WM_types.hh:724
int mval[2]
Definition WM_types.hh:728
short type
Definition WM_types.hh:722
bool(* poll)(struct bContext *)
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1036
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
PropertyRNA * prop
Definition WM_types.hh:1092
StructRNA * srna
Definition WM_types.hh:1080
void(* cancel)(bContext *C, wmOperator *op)
Definition WM_types.hh:1028
struct ReportList * reports
struct PointerRNA * ptr
ccl_device_inline int abs(int x)
Definition util/math.h:120
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:4125
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:897
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)