Blender V5.0
paint_image.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9
10#include <cfloat>
11#include <cmath>
12#include <cstdio>
13#include <cstring>
14
15#include "MEM_guardedalloc.h"
16
17#include "BLI_listbase.h"
18#include "BLI_math_color.h"
19#include "BLI_math_vector.hh"
20#include "BLI_rand.hh"
21#include "BLI_string.h"
22#include "BLI_utildefines.h"
23
24#include "IMB_imbuf.hh"
25#include "IMB_imbuf_types.hh"
26
27#include "DNA_brush_types.h"
28#include "DNA_material_types.h"
29#include "DNA_mesh_types.h"
30#include "DNA_node_types.h"
31#include "DNA_object_types.h"
32#include "DNA_scene_types.h"
33
34#include "BKE_brush.hh"
35#include "BKE_colorband.hh"
36#include "BKE_context.hh"
37#include "BKE_curves.hh"
38#include "BKE_grease_pencil.hh"
39#include "BKE_image.hh"
40#include "BKE_library.hh"
41#include "BKE_main.hh"
42#include "BKE_material.hh"
43#include "BKE_mesh.hh"
44#include "BKE_node_runtime.hh"
45#include "BKE_object.hh"
46#include "BKE_paint.hh"
47#include "BKE_paint_types.hh"
48#include "BKE_scene.hh"
49
50#include "NOD_texture.h"
51
52#include "DEG_depsgraph.hh"
54
55#include "UI_view2d.hh"
56
57#include "ED_grease_pencil.hh"
58#include "ED_image.hh"
59#include "ED_object.hh"
60#include "ED_paint.hh"
61#include "ED_screen.hh"
62
63#include "WM_api.hh"
64#include "WM_message.hh"
65#include "WM_toolsystem.hh"
66#include "WM_types.hh"
67
68#include "RNA_access.hh"
69#include "RNA_define.hh"
70
72
73#include "paint_intern.hh"
74
75/* -------------------------------------------------------------------- */
78
85
90
95
96/* Image paint Partial Redraw & Dirty Region. */
97
102
104 ImBuf *ibuf, int x, int y, int w, int h, int *tx, int *ty, int *tw, int *th)
105{
106 int srcx = 0, srcy = 0;
107
108 IMB_rectclip(ibuf, nullptr, &x, &y, &srcx, &srcy, &w, &h);
109
110 *tw = ((x + w - 1) >> ED_IMAGE_UNDO_TILE_BITS);
111 *th = ((y + h - 1) >> ED_IMAGE_UNDO_TILE_BITS);
112 *tx = (x >> ED_IMAGE_UNDO_TILE_BITS);
113 *ty = (y >> ED_IMAGE_UNDO_TILE_BITS);
114}
115
117 Image *ima, ImBuf *ibuf, ImageUser *iuser, int x, int y, int w, int h, bool find_old)
118{
119 ImBuf *tmpibuf = nullptr;
120 int tilex, tiley, tilew, tileh, tx, ty;
121 int srcx = 0, srcy = 0;
122
123 IMB_rectclip(ibuf, nullptr, &x, &y, &srcx, &srcy, &w, &h);
124
125 if (w == 0 || h == 0) {
126 return;
127 }
128
129 rcti rect_to_merge;
130 BLI_rcti_init(&rect_to_merge, x, x + w, y, y + h);
131 BLI_rcti_do_minmax_rcti(&imapaintpartial.dirty_region, &rect_to_merge);
132
133 imapaint_region_tiles(ibuf, x, y, w, h, &tilex, &tiley, &tilew, &tileh);
134
136
137 for (ty = tiley; ty <= tileh; ty++) {
138 for (tx = tilex; tx <= tilew; tx++) {
140 undo_tiles, ima, ibuf, &tmpibuf, iuser, tx, ty, nullptr, nullptr, false, find_old);
141 }
142 }
143
144 BKE_image_mark_dirty(ima, ibuf);
145
146 if (tmpibuf) {
147 IMB_freeImBuf(tmpibuf);
148 }
149}
150
152 SpaceImage *sima, Image *image, ImBuf *ibuf, ImageUser *iuser, short texpaint)
153{
154 if (BLI_rcti_is_empty(&imapaintpartial.dirty_region)) {
155 return;
156 }
157
159 imapaintpartial.dirty_region.xmin,
160 imapaintpartial.dirty_region.ymin,
161 imapaintpartial.dirty_region.xmax,
162 imapaintpartial.dirty_region.ymax);
163
164 /* When buffer is partial updated the planes should be set to a larger value than 8. This will
165 * make sure that partial updating is working but uses more GPU memory as the gpu texture will
166 * have 4 channels. When so the whole texture needs to be re-uploaded to the GPU using the new
167 * texture format. */
168 if (ibuf != nullptr && ibuf->planes == 8) {
169 ibuf->planes = 32;
171 return;
172 }
173
174 /* TODO: should set_tpage create ->rect? */
175 if (texpaint || (sima && sima->lock)) {
176 const int w = BLI_rcti_size_x(&imapaintpartial.dirty_region);
177 const int h = BLI_rcti_size_y(&imapaintpartial.dirty_region);
178 /* Testing with partial update in uv editor too. */
180 image, iuser, imapaintpartial.dirty_region.xmin, imapaintpartial.dirty_region.ymin, w, h);
181 }
182}
183
185
186/* -------------------------------------------------------------------- */
189
191{
192 int i, j;
193 BlurKernel *kernel = MEM_new<BlurKernel>("BlurKernel");
194
195 float radius;
196 int side;
197 eBlurKernelType type = static_cast<eBlurKernelType>(br->blur_mode);
198
199 if (proj) {
200 radius = 0.5f;
201
202 side = kernel->side = 2;
203 kernel->side_squared = kernel->side * kernel->side;
204 kernel->wdata = MEM_malloc_arrayN<float>(kernel->side_squared, "blur kernel data");
205 kernel->pixel_len = radius;
206 }
207 else {
208 if (br->blur_kernel_radius <= 0) {
209 br->blur_kernel_radius = 1;
210 }
211
212 radius = br->blur_kernel_radius;
213
214 side = kernel->side = radius * 2 + 1;
215 kernel->side_squared = kernel->side * kernel->side;
216 kernel->wdata = MEM_malloc_arrayN<float>(kernel->side_squared, "blur kernel data");
217 kernel->pixel_len = br->blur_kernel_radius;
218 }
219
220 switch (type) {
221 case KERNEL_BOX:
222 for (i = 0; i < kernel->side_squared; i++) {
223 kernel->wdata[i] = 1.0;
224 }
225 break;
226
227 case KERNEL_GAUSSIAN: {
228 /* at 3.0 standard deviations distance, kernel is about zero */
229 float standard_dev = radius / 3.0f;
230
231 /* make the necessary adjustment to the value for use in the normal distribution formula */
232 standard_dev = -standard_dev * standard_dev * 2;
233
234 for (i = 0; i < side; i++) {
235 for (j = 0; j < side; j++) {
236 float idist = radius - i;
237 float jdist = radius - j;
238 float value = exp((idist * idist + jdist * jdist) / standard_dev);
239
240 kernel->wdata[i + j * side] = value;
241 }
242 }
243
244 break;
245 }
246
247 default:
248 printf("unidentified kernel type, aborting\n");
250 MEM_delete(kernel);
251 return nullptr;
252 }
253
254 return kernel;
255}
256
258{
259 if (kernel->wdata) {
260 MEM_freeN(kernel->wdata);
261 }
262}
263
265
266/* -------------------------------------------------------------------- */
269
271{
272 Scene *scene = CTX_data_scene(C);
273 ToolSettings *settings = scene->toolsettings;
274
275 return BKE_paint_brush(&settings->imapaint.paint);
276}
277
278static bool image_paint_poll_ex(bContext *C, bool check_tool)
279{
280 Object *obact;
281
282 if (!image_paint_brush(C)) {
283 return false;
284 }
285
286 obact = CTX_data_active_object(C);
287 if ((obact && obact->mode & OB_MODE_TEXTURE_PAINT) && CTX_wm_region_view3d(C)) {
288 if (!check_tool || WM_toolsystem_active_tool_is_brush(C)) {
289 return true;
290 }
291 }
292 else {
294
295 if (sima) {
296 if (sima->image != nullptr &&
298 {
299 return false;
300 }
301 if (sima->mode == SI_MODE_PAINT) {
302 const ARegion *region = CTX_wm_region(C);
303 if (region->regiontype == RGN_TYPE_WINDOW) {
304 return true;
305 }
306 }
307 }
308 }
309
310 return false;
311}
312
314{
315 return image_paint_poll_ex(C, true);
316}
317
319{
320 return image_paint_poll_ex(C, false);
321}
322
324{
325 const Scene *scene = CTX_data_scene(C);
326 const ToolSettings *settings = scene->toolsettings;
327 const ImagePaintSettings &image_paint_settings = settings->imapaint;
328 Brush *brush = image_paint_brush(C);
329
331 if (brush && (brush->image_brush_type == IMAGE_PAINT_BRUSH_TYPE_CLONE)) {
332 if (image_paint_settings.clone) {
333 return true;
334 }
335 }
336 }
337
338 return false;
339}
340
342
343/* -------------------------------------------------------------------- */
346
347bool paint_use_opacity_masking(const Paint *paint, const Brush *brush)
348{
349 return ((brush->flag & BRUSH_AIRBRUSH) || (brush->flag & BRUSH_DRAG_DOT) ||
350 (brush->flag & BRUSH_ANCHORED) ||
351 ELEM(brush->image_brush_type,
355 (brush->flag & BRUSH_USE_GRADIENT) ||
357 (brush->mtex.tex && !ELEM(brush->mtex.brush_map_mode,
361 false :
362 true);
363}
364
365void paint_brush_color_get(const Paint *paint,
366 Brush *br,
367 std::optional<blender::float3> &initial_hsv_jitter,
368 bool invert,
369 float distance,
370 float pressure,
371 float r_color[3])
372{
373 if (invert) {
374 copy_v3_v3(r_color, BKE_brush_secondary_color_get(paint, br));
375 }
376 else {
377 const std::optional<BrushColorJitterSettings> color_jitter_settings =
379 if (br->flag & BRUSH_USE_GRADIENT) {
380 float color_gr[4];
381 switch (br->gradient_stroke_mode) {
383 BKE_colorband_evaluate(br->gradient, pressure, color_gr);
384 break;
386 float coord = fmod(distance / br->gradient_spacing, 1.0);
387 BKE_colorband_evaluate(br->gradient, coord, color_gr);
388 break;
389 }
392 break;
393 }
394 }
395 copy_v3_v3(r_color, color_gr);
396 }
397 else if (color_jitter_settings) {
398 /* Perform color jitter with sRGB transfer function. This is inconsistent with other
399 * paint modes which do it in linear space. But arguably it's better to do it in the
400 * more perceptually uniform color space. */
401 blender::float3 color = BKE_brush_color_get(paint, br);
402 linearrgb_to_srgb_v3_v3(color, color);
404 *color_jitter_settings, *initial_hsv_jitter, distance, pressure, color);
405 srgb_to_linearrgb_v3_v3(r_color, color);
406 }
407 else {
408 copy_v3_v3(r_color, BKE_brush_color_get(paint, br));
409 }
410 }
411}
412
414{
415 /* init mtex nodes */
416 if (brush) {
417 MTex *mtex = &brush->mtex;
418 if (mtex->tex && mtex->tex->nodetree) {
419 /* has internal flag to detect it only does it once */
421 }
422 mtex = &brush->mask_mtex;
423 if (mtex->tex && mtex->tex->nodetree) {
425 }
426 }
427}
428
430{
431 if (brush) {
432 MTex *mtex = &brush->mtex;
433 if (mtex->tex && mtex->tex->nodetree) {
434 ntreeTexEndExecTree(mtex->tex->nodetree->runtime->execdata);
435 }
436 mtex = &brush->mask_mtex;
437 if (mtex->tex && mtex->tex->nodetree) {
438 ntreeTexEndExecTree(mtex->tex->nodetree->runtime->execdata);
439 }
440 }
441}
442
443bool get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
444{
445 ScrArea *area = CTX_wm_area(C);
446 if (area && area->spacetype == SPACE_IMAGE) {
447 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
448 if (sima->mode == SI_MODE_PAINT) {
449 ARegion *region = CTX_wm_region(C);
450 ED_space_image_get_zoom(sima, region, zoomx, zoomy);
451 return true;
452 }
453 }
454
455 *zoomx = *zoomy = 1;
456
457 return false;
458}
459
461
462/* -------------------------------------------------------------------- */
465
466static void toggle_paint_cursor(Scene &scene, bool enable)
467{
468 ToolSettings *settings = scene.toolsettings;
469 Paint &p = settings->imapaint.paint;
470
471 if (p.runtime->paint_cursor && !enable) {
472 WM_paint_cursor_end(static_cast<wmPaintCursor *>(p.runtime->paint_cursor));
473 p.runtime->paint_cursor = nullptr;
475 }
476 else if (enable) {
478 }
479}
480
482{
483 ToolSettings *settings = scene->toolsettings;
484 ImagePaintSettings *imapaint = &settings->imapaint;
485 bool enabled = false;
486
487 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
489
490 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
491 if (area->spacetype == SPACE_IMAGE) {
492 if (((SpaceImage *)area->spacedata.first)->mode == SI_MODE_PAINT) {
493 enabled = true;
494 }
495 }
496 }
497 }
498
499 if (enabled) {
501
503 }
504 else {
506 }
507}
508
510
511/* -------------------------------------------------------------------- */
514
515struct GrabClone {
516 float startoffset[2];
518};
519
521{
522 const Scene *scene = CTX_data_scene(C);
523 ToolSettings *settings = scene->toolsettings;
524 ImagePaintSettings &image_paint_settings = settings->imapaint;
525 float delta[2];
526
527 RNA_float_get_array(op->ptr, "delta", delta);
528 add_v2_v2(image_paint_settings.clone_offset, delta);
530}
531
538
540{
541 const Scene *scene = CTX_data_scene(C);
542 const ToolSettings *settings = scene->toolsettings;
543 const ImagePaintSettings &image_paint_settings = settings->imapaint;
544 GrabClone *cmv;
545
546 cmv = MEM_callocN<GrabClone>("GrabClone");
547 copy_v2_v2(cmv->startoffset, image_paint_settings.clone_offset);
548 cmv->startx = event->xy[0];
549 cmv->starty = event->xy[1];
550 op->customdata = cmv;
551
553
555}
556
558{
559 const Scene *scene = CTX_data_scene(C);
560 ToolSettings *settings = scene->toolsettings;
561 ImagePaintSettings &image_paint_settings = settings->imapaint;
562 ARegion *region = CTX_wm_region(C);
563 GrabClone *cmv = static_cast<GrabClone *>(op->customdata);
564 float startfx, startfy, fx, fy, delta[2];
565 int xmin = region->winrct.xmin, ymin = region->winrct.ymin;
566
567 switch (event->type) {
568 case LEFTMOUSE:
569 case MIDDLEMOUSE:
570 case RIGHTMOUSE: /* XXX hardcoded */
571 MEM_freeN(cmv);
572 return OPERATOR_FINISHED;
573 case MOUSEMOVE:
574 /* mouse moved, so move the clone image */
576 &region->v2d, cmv->startx - xmin, cmv->starty - ymin, &startfx, &startfy);
577 UI_view2d_region_to_view(&region->v2d, event->xy[0] - xmin, event->xy[1] - ymin, &fx, &fy);
578
579 delta[0] = fx - startfx;
580 delta[1] = fy - startfy;
581 RNA_float_set_array(op->ptr, "delta", delta);
582
583 copy_v2_v2(image_paint_settings.clone_offset, cmv->startoffset);
584
585 grab_clone_apply(C, op);
586 break;
587 default: {
588 break;
589 }
590 }
591
593}
594
595static void grab_clone_cancel(bContext * /*C*/, wmOperator *op)
596{
597 GrabClone *cmv = static_cast<GrabClone *>(op->customdata);
598 MEM_delete(cmv);
599}
600
602{
603 /* identifiers */
604 ot->name = "Grab Clone";
605 ot->idname = "PAINT_OT_grab_clone";
606 ot->description = "Move the clone source image";
607
608 /* API callbacks. */
609 ot->exec = grab_clone_exec;
610 ot->invoke = grab_clone_invoke;
611 ot->modal = grab_clone_modal;
612 ot->cancel = grab_clone_cancel;
614
615 /* flags */
617
618 /* properties */
620 "delta",
621 2,
622 nullptr,
623 -FLT_MAX,
624 FLT_MAX,
625 "Delta",
626 "Delta offset of clone image in 0.0 to 1.0 coordinates",
627 -1.0f,
628 1.0f);
629}
630
632
633/* -------------------------------------------------------------------- */
636
638{
639 using namespace blender;
640 const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
641 if (!mesh_eval) {
642 mesh_eval = (const Mesh *)ob->data;
643 }
644
645 const std::optional<Bounds<float3>> bounds = mesh_eval->bounds_min_max();
646 if (!bounds) {
647 return float3(0.0f);
648 }
649
650 return math::midpoint(bounds->min, bounds->max);
651}
652
654{
655 const Curves &curves = *static_cast<const Curves *>(ob->data);
656 const std::optional<blender::Bounds<blender::float3>> bounds =
657 curves.geometry.wrap().bounds_min_max();
658 if (bounds.has_value()) {
659 return blender::math::midpoint(bounds->min, bounds->max);
660 }
661 return blender::float3(0);
662}
663
665{
666 using namespace blender;
667 const GreasePencil &grease_pencil = *static_cast<const GreasePencil *>(ob->data);
668 const std::optional<Bounds<float3>> bounds = grease_pencil.bounds_min_max(frame);
669 if (bounds.has_value()) {
670 return blender::math::midpoint(bounds->min, bounds->max);
671 }
672 return float3(0.0f);
673}
674
675/* TODO: Move this out of paint image... */
676void paint_init_pivot(Object *ob, Scene *scene, Paint *paint)
677{
678 blender::bke::PaintRuntime &paint_runtime = *paint->runtime;
679
680 blender::float3 location;
681 switch (ob->type) {
682 case OB_MESH:
683 location = paint_init_pivot_mesh(ob);
684 break;
685 case OB_CURVES:
686 location = paint_init_pivot_curves(ob);
687 break;
688 case OB_GREASE_PENCIL:
689 location = paint_init_pivot_grease_pencil(ob, scene->r.cfra);
690 break;
691 default:
693 paint_runtime.last_stroke_valid = false;
694 return;
695 }
696
697 mul_m4_v3(ob->object_to_world().ptr(), location);
698
699 paint_runtime.last_stroke_valid = true;
700 paint_runtime.average_stroke_counter = 1;
701 copy_v3_v3(paint_runtime.average_stroke_accum, location);
702}
703
705 Scene &scene,
706 Depsgraph &depsgraph,
707 Object &ob)
708{
709 Image *ima = nullptr;
710 ImagePaintSettings &imapaint = scene.toolsettings->imapaint;
711
712 /* This has to stay here to regenerate the texture paint
713 * cache in case we are loading a file */
715
716 ED_paint_proj_mesh_data_check(scene, ob, nullptr, nullptr, nullptr, nullptr);
717
718 /* entering paint mode also sets image to editors */
719 if (imapaint.mode == IMAGEPAINT_MODE_MATERIAL) {
720 /* set the current material active paint slot on image editor */
722
723 if (ma && ma->texpaintslot) {
724 ima = ma->texpaintslot[ma->paint_active_slot].ima;
725 }
726 }
727 else if (imapaint.mode == IMAGEPAINT_MODE_IMAGE) {
728 ima = imapaint.canvas;
729 }
730
731 if (ima) {
732 ED_space_image_sync(&bmain, ima, false);
733 }
734
736
737 BKE_paint_init(&bmain, &scene, PaintMode::Texture3D);
738
739 BKE_paint_brushes_validate(&bmain, &imapaint.paint);
740
741 if (U.glreslimit != 0) {
743 }
744 BKE_image_paint_set_mipmap(&bmain, false);
745
746 toggle_paint_cursor(scene, true);
747
748 Mesh *mesh = BKE_mesh_from_object(&ob);
749 BLI_assert(mesh != nullptr);
751
752 /* Ensure we have evaluated data for bounding box. */
754
755 /* Set pivot to bounding box center. */
756 Object *ob_eval = DEG_get_evaluated(&depsgraph, &ob);
757 paint_init_pivot(ob_eval ? ob_eval : &ob, &scene, &imapaint.paint);
758
760}
761
771
773{
775
776 if (U.glreslimit != 0) {
778 }
779 BKE_image_paint_set_mipmap(&bmain, true);
780 toggle_paint_cursor(scene, false);
781
782 Mesh *mesh = BKE_mesh_from_object(&ob);
783 BLI_assert(mesh != nullptr);
786}
787
795
797{
799 if (ob == nullptr || ob->type != OB_MESH) {
800 return false;
801 }
802 if (ob->data == nullptr || !ID_IS_EDITABLE(ob->data) || ID_IS_OVERRIDE_LIBRARY(ob->data)) {
803 return false;
804 }
805
806 return true;
807}
808
810{
811 using namespace blender::ed;
813 Main &bmain = *CTX_data_main(C);
814 Scene &scene = *CTX_data_scene(C);
816 const int mode_flag = OB_MODE_TEXTURE_PAINT;
817 const bool is_mode_set = (ob.mode & mode_flag) != 0;
818
819 if (!is_mode_set) {
820 if (!object::mode_compat_set(C, &ob, eObjectMode(mode_flag), op->reports)) {
821 return OPERATOR_CANCELLED;
822 }
823 }
824
825 if (ob.mode & mode_flag) {
826 ED_object_texture_paint_mode_exit_ex(bmain, scene, ob);
827 }
828 else {
831 }
832
833 WM_msg_publish_rna_prop(mbus, &ob.id, &ob, Object, mode);
834
836
837 return OPERATOR_FINISHED;
838}
839
841{
842 /* identifiers */
843 ot->name = "Texture Paint Mode";
844 ot->idname = "PAINT_OT_texture_paint_toggle";
845 ot->description = "Toggle texture paint mode in 3D view";
846
847 /* API callbacks. */
850
851 /* flags */
853}
854
856
857/* -------------------------------------------------------------------- */
860
862{
864 Brush *br = BKE_paint_brush(paint);
865
866 if (BKE_paint_use_unified_color(paint)) {
870 }
871 else if (br) {
875 }
876 else {
877 return OPERATOR_CANCELLED;
878 }
879
881
882 return OPERATOR_FINISHED;
883}
884
886{
890 return true;
891 }
892 }
893 else {
895 if (ob != nullptr) {
897 return true;
898 }
901 {
902 return true;
903 }
904 }
905 }
906 return false;
907}
908
910{
911 /* identifiers */
912 ot->name = "Swap Colors";
913 ot->idname = "PAINT_OT_brush_colors_flip";
914 ot->description = "Swap primary and secondary brush colors";
915
916 /* API callbacks. */
919
920 /* flags */
921 ot->flag = OPTYPE_REGISTER;
922}
923
925
926/* -------------------------------------------------------------------- */
929
930void ED_imapaint_bucket_fill(bContext *C, float const color[3], wmOperator *op, const int mouse[2])
931{
933
934 if (sima && sima->image) {
935 Image *ima = sima->image;
936
938
939 const float mouse_init[2] = {float(mouse[0]), float(mouse[1])};
940 paint_2d_bucket_fill(C, color, nullptr, mouse_init, nullptr, nullptr);
941
943
944 DEG_id_tag_update(&ima->id, 0);
945 }
946}
947
949{
952 return true;
953 }
954 }
955
956 return false;
957}
958
964
969
974
979
984
void BKE_brush_color_sync_legacy(Brush *brush)
Definition brush.cc:1227
const float * BKE_brush_color_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1161
const float * BKE_brush_secondary_color_get(const Paint *paint, const Brush *brush)
Definition brush.cc:1205
std::optional< BrushColorJitterSettings > BKE_brush_color_jitter_get_settings(const Paint *paint, const Brush *brush)
Definition brush.cc:1170
void BKE_brush_tag_unsaved_changes(Brush *brush)
Definition brush.cc:764
bool BKE_colorband_evaluate(const ColorBand *coba, float in, float out[4])
Definition colorband.cc:396
SpaceImage * CTX_wm_space_image(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmMsgBus * CTX_wm_message_bus(const bContext *C)
Low-level operations for curves.
Low-level operations for grease pencil.
void BKE_image_update_gputexture(Image *ima, ImageUser *iuser, int x, int y, int w, int h)
Definition image_gpu.cc:913
void BKE_image_mark_dirty(Image *image, ImBuf *ibuf)
void BKE_image_paint_set_mipmap(Main *bmain, bool mipmap)
Definition image_gpu.cc:937
void BKE_image_free_all_gputextures(Main *bmain)
Definition image_gpu.cc:586
void BKE_image_partial_update_mark_full_update(Image *image)
Mark the whole image to be updated.
General operations, lookup, etc. for materials.
void BKE_texpaint_slots_refresh_object(Scene *scene, Object *ob)
Material * BKE_object_material_get(Object *ob, short act)
Mesh * BKE_mesh_from_object(Object *ob)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
blender::float3 BKE_paint_randomize_color(const BrushColorJitterSettings &color_jitter, const blender::float3 &initial_hsv_jitter, const float distance, const float pressure, const blender::float3 &color)
Definition paint.cc:1964
bool BKE_paint_select_elem_test(const Object *ob)
Definition paint.cc:1665
bool BKE_paint_select_vert_test(const Object *ob)
Definition paint.cc:1647
void BKE_paint_init(Main *bmain, Scene *sce, PaintMode mode, bool ensure_brushes=true)
Definition paint.cc:1840
bool BKE_paint_use_unified_color(const Paint *paint)
Definition paint.cc:601
Paint * BKE_paint_get_active_from_context(const bContext *C)
Definition paint.cc:476
Brush * BKE_paint_brush(Paint *paint)
Definition paint.cc:645
bool BKE_paint_select_face_test(const Object *ob)
Definition paint.cc:1640
void BKE_paint_brushes_validate(Main *bmain, Paint *paint)
Definition paint.cc:1125
void BKE_scene_graph_evaluated_ensure(Depsgraph *depsgraph, Main *bmain)
Definition scene.cc:2626
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3])
void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3])
void mul_m4_v3(const float M[4][4], float r[3])
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 add_v2_v2(float r[2], const float a[2])
MINLINE void swap_v3_v3(float a[3], float b[3])
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:198
void BLI_rcti_init_minmax(struct rcti *rect)
Definition rct.cc:474
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition rct.cc:414
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:194
bool BLI_rcti_is_empty(const struct rcti *rect)
void BLI_rcti_do_minmax_rcti(struct rcti *rect, const struct rcti *other)
#define ELEM(...)
void DEG_id_tag_update(ID *id, unsigned int flags)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1118
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:705
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:730
eBlurKernelType
@ KERNEL_BOX
@ KERNEL_GAUSSIAN
@ BRUSH_DRAG_DOT
@ BRUSH_ANCHORED
@ BRUSH_USE_GRADIENT
@ BRUSH_AIRBRUSH
@ IMAGE_PAINT_BRUSH_TYPE_FILL
@ IMAGE_PAINT_BRUSH_TYPE_DRAW
@ IMAGE_PAINT_BRUSH_TYPE_CLONE
@ IMAGE_PAINT_BRUSH_TYPE_SOFTEN
@ IMAGE_PAINT_BRUSH_TYPE_SMEAR
@ BRUSH_GRADIENT_SPACING_CLAMP
@ BRUSH_GRADIENT_PRESSURE
@ BRUSH_GRADIENT_SPACING_REPEAT
eObjectMode
@ OB_MODE_SCULPT
@ OB_MODE_TEXTURE_PAINT
@ OB_MODE_VERTEX_PAINT
Object is a sort of wrapper for general info.
@ OB_GREASE_PENCIL
@ OB_MESH
@ OB_CURVES
#define IMAGEPAINT_MODE_IMAGE
#define IMAGEPAINT_MODE_MATERIAL
@ RGN_TYPE_WINDOW
@ SPACE_IMAGE
@ SI_MODE_PAINT
@ MTEX_MAP_MODE_3D
@ MTEX_MAP_MODE_STENCIL
@ MTEX_MAP_MODE_TILED
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
void ED_space_image_sync(Main *bmain, Image *image, bool ignore_render_viewer)
Definition image_edit.cc:70
bool ED_image_tools_paint_poll(bContext *C)
void ED_space_image_get_zoom(SpaceImage *sima, const ARegion *region, float *r_zoomx, float *r_zoomy)
void ED_paint_cursor_start(Paint *paint, bool(*poll)(bContext *C))
void * ED_image_paint_tile_push(PaintTileMap *paint_tile_map, Image *image, ImBuf *ibuf, ImBuf **tmpibuf, ImageUser *iuser, int x_tile, int y_tile, unsigned short **r_mask, bool **r_valid, bool use_thread_lock, bool find_prev)
void ED_image_undo_push_begin(const char *name, PaintMode paint_mode)
void ED_image_undo_push_end()
PaintTileMap * ED_image_paint_tile_map_get()
bool ED_paint_proj_mesh_data_check(Scene &scene, Object &ob, bool *r_has_uvs, bool *r_has_mat, bool *r_has_tex, bool *r_has_stencil)
#define ED_IMAGE_UNDO_TILE_BITS
Definition ED_paint.hh:113
void ED_region_tag_redraw(ARegion *region)
Definition area.cc:618
void IMB_partial_display_buffer_update_delayed(ImBuf *ibuf, int xmin, int ymin, int xmax, int ymax)
void IMB_rectclip(ImBuf *dbuf, const ImBuf *sbuf, int *destx, int *desty, int *srcx, int *srcy, int *width, int *height)
Definition rectop.cc:307
void IMB_freeImBuf(ImBuf *ibuf)
Read Guarded memory(de)allocation.
void ntreeTexEndExecTree(struct bNodeTreeExec *exec)
struct bNodeTreeExec * ntreeTexBeginExecTree(struct bNodeTree *ntree)
#define C
Definition RandGen.cpp:29
void UI_view2d_region_to_view(const View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
Definition view2d.cc:1668
#define NC_BRUSH
Definition WM_types.hh:385
#define ND_MODE
Definition WM_types.hh:445
#define NC_SCENE
Definition WM_types.hh:378
@ OPTYPE_BLOCKING
Definition WM_types.hh:184
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
#define NA_EDITED
Definition WM_types.hh:584
#define U
BPy_StructRNA * depsgraph
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition btDbvt.cpp:299
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
static RandomNumberGenerator from_random_seed()
Definition rand.cc:288
nullptr float
#define printf(...)
#define exp
float distance(VecOp< float, D >, VecOp< float, D >) RET
VecBase< float, 3 > float3
bool enabled
CCL_NAMESPACE_BEGIN ccl_device float invert(const float color, const float factor)
Definition invert.h:11
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
ccl_device_inline float2 fmod(const float2 a, const float b)
bool grease_pencil_vertex_painting_poll(bContext *C)
bool grease_pencil_painting_poll(bContext *C)
bool mode_compat_set(bContext *C, Object *ob, eObjectMode mode, ReportList *reports)
T midpoint(const T &a, const T &b)
VecBase< float, 3 > float3
void paint_cursor_delete_textures()
void paint_delete_blur_kernel(BlurKernel *kernel)
static wmOperatorStatus brush_colors_flip_exec(bContext *C, wmOperator *)
static wmOperatorStatus grab_clone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void ED_object_texture_paint_mode_enter_ex(Main &bmain, Scene &scene, Depsgraph &depsgraph, Object &ob)
static bool image_paint_2d_clone_poll(bContext *C)
bool ED_image_tools_paint_poll(bContext *C)
static Brush * image_paint_brush(bContext *C)
static bool image_paint_poll_ex(bContext *C, bool check_tool)
static bool texture_paint_poll(bContext *C)
bool vert_paint_poll(bContext *C)
static void grab_clone_cancel(bContext *, wmOperator *op)
static blender::float3 paint_init_pivot_mesh(Object *ob)
void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, ImageUser *iuser, short texpaint)
void ED_imapaint_bucket_fill(bContext *C, float const color[3], wmOperator *op, const int mouse[2])
void paint_brush_init_tex(Brush *brush)
static bool texture_paint_toggle_poll(bContext *C)
void ED_imapaint_dirty_region(Image *ima, ImBuf *ibuf, ImageUser *iuser, int x, int y, int w, int h, bool find_old)
static wmOperatorStatus grab_clone_exec(bContext *C, wmOperator *op)
static blender::float3 paint_init_pivot_grease_pencil(Object *ob, const int frame)
void ED_object_texture_paint_mode_exit(bContext *C)
bool facemask_paint_poll(bContext *C)
bool image_texture_paint_poll(bContext *C)
void paint_brush_color_get(const Paint *paint, Brush *br, std::optional< blender::float3 > &initial_hsv_jitter, bool invert, float distance, float pressure, float r_color[3])
blender::float3 seed_hsv_jitter()
bool image_paint_poll_ignore_tool(bContext *C)
static ImagePaintPartialRedraw imapaintpartial
void PAINT_OT_texture_paint_toggle(wmOperatorType *ot)
void ED_space_image_paint_update(Main *bmain, wmWindowManager *wm, Scene *scene)
bool mask_paint_poll(bContext *C)
static wmOperatorStatus grab_clone_modal(bContext *C, wmOperator *op, const wmEvent *event)
BlurKernel * paint_new_blur_kernel(Brush *br, bool proj)
static blender::float3 paint_init_pivot_curves(Object *ob)
void ED_object_texture_paint_mode_enter(bContext *C)
static void grab_clone_apply(bContext *C, wmOperator *op)
void PAINT_OT_brush_colors_flip(wmOperatorType *ot)
bool get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
static bool brush_colors_flip_poll(bContext *C)
void PAINT_OT_grab_clone(wmOperatorType *ot)
void paint_brush_exit_tex(Brush *brush)
static wmOperatorStatus texture_paint_toggle_exec(bContext *C, wmOperator *op)
bool paint_use_opacity_masking(const Paint *paint, const Brush *brush)
void ED_object_texture_paint_mode_exit_ex(Main &bmain, Scene &scene, Object &ob)
void imapaint_region_tiles(ImBuf *ibuf, int x, int y, int w, int h, int *tx, int *ty, int *tw, int *th)
static void toggle_paint_cursor(Scene &scene, bool enable)
void paint_init_pivot(Object *ob, Scene *scene, Paint *paint)
void set_imapaintpartial(ImagePaintPartialRedraw *ippr)
void ED_imapaint_clear_partial_redraw()
ImagePaintPartialRedraw * get_imapaintpartial()
void paint_2d_bucket_fill(const bContext *C, const float color[3], Brush *br, const float mouse_init[2], const float mouse_final[2], void *ps)
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
PropertyRNA * RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
#define FLT_MAX
Definition stdcycles.h:14
float * wdata
float secondary_color[3]
struct ColorBand * gradient
int blur_kernel_radius
struct MTex mtex
char image_brush_type
char gradient_stroke_mode
struct MTex mask_mtex
int gradient_spacing
float color[3]
CurvesGeometry geometry
float startoffset[2]
unsigned char planes
struct Image * canvas
void * first
char brush_map_mode
struct Tex * tex
short paint_active_slot
struct TexPaintSlot * texpaintslot
struct UnifiedPaintSettings unified_paint_settings
PaintRuntimeHandle * runtime
struct ToolSettings * toolsettings
struct RenderData r
ListBase spacedata
struct Image * image
struct Image * ima
struct bNodeTree * nodetree
struct ImagePaintSettings imapaint
bNodeTreeRuntimeHandle * runtime
ListBase areabase
blender::float3 average_stroke_accum
int ymin
int xmin
wmEventType type
Definition WM_types.hh:757
int xy[2]
Definition WM_types.hh:761
const char * name
Definition WM_types.hh:1033
struct ReportList * reports
struct wmOperatorType * type
struct PointerRNA * ptr
i
Definition text_draw.cc:230
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)
@ RIGHTMOUSE
@ MOUSEMOVE
@ LEFTMOUSE
@ MIDDLEMOUSE
wmOperatorType * ot
Definition wm_files.cc:4237
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)
bool WM_paint_cursor_end(wmPaintCursor *handle)
bool WM_toolsystem_active_tool_is_brush(const bContext *C)
void WM_toolsystem_update_from_context_view3d(bContext *C)
bScreen * WM_window_get_active_screen(const wmWindow *win)