Blender V4.5
brush.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#include <array>
9#include <optional>
10
11#include "MEM_guardedalloc.h"
12
13/* Allow using deprecated functionality for .blend file I/O. */
14#define DNA_DEPRECATED_ALLOW
15
16#include "DNA_ID.h"
17#include "DNA_brush_types.h"
18#include "DNA_defaults.h"
19#include "DNA_material_types.h"
20#include "DNA_scene_types.h"
21
22#include "BLI_listbase.h"
23#include "BLI_math_base.hh"
24#include "BLI_rand.h"
25
26#include "BLT_translation.hh"
27
28#include "BKE_asset.hh"
29#include "BKE_bpath.hh"
30#include "BKE_brush.hh"
31#include "BKE_colortools.hh"
32#include "BKE_gpencil_legacy.h"
33#include "BKE_grease_pencil.hh"
34#include "BKE_idprop.hh"
35#include "BKE_idtype.hh"
36#include "BKE_lib_id.hh"
37#include "BKE_lib_query.hh"
38#include "BKE_lib_remap.hh"
39#include "BKE_main.hh"
40#include "BKE_material.hh"
41#include "BKE_paint.hh"
42#include "BKE_preview_image.hh"
43#include "BKE_texture.h"
44
46#include "IMB_imbuf.hh"
47#include "IMB_imbuf_types.hh"
48
49#include "RE_texture.h" /* RE_texture_evaluate */
50
51#include "BLO_read_write.hh"
52
53static void brush_init_data(ID *id)
54{
55 Brush *brush = reinterpret_cast<Brush *>(id);
57
59
60 /* enable fake user by default */
61 id_fake_user_set(&brush->id);
62
63 /* the default alpha falloff curve */
65}
66
67static void brush_copy_data(Main * /*bmain*/,
68 std::optional<Library *> /*owner_library*/,
69 ID *id_dst,
70 const ID *id_src,
71 const int flag)
72{
73 Brush *brush_dst = reinterpret_cast<Brush *>(id_dst);
74 const Brush *brush_src = reinterpret_cast<const Brush *>(id_src);
75 if (brush_src->icon_imbuf) {
76 brush_dst->icon_imbuf = IMB_dupImBuf(brush_src->icon_imbuf);
77 }
78
79 if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
80 BKE_previewimg_id_copy(&brush_dst->id, &brush_src->id);
81 }
82 else {
83 brush_dst->preview = nullptr;
84 }
85
86 brush_dst->curve = BKE_curvemapping_copy(brush_src->curve);
88
92
93 if (brush_src->gpencil_settings != nullptr) {
95 __func__, *(brush_src->gpencil_settings));
101 brush_src->gpencil_settings->curve_jitter);
102
108 brush_src->gpencil_settings->curve_rand_uv);
110 brush_src->gpencil_settings->curve_rand_hue);
115 }
116 if (brush_src->curves_sculpt_settings != nullptr) {
118 __func__, *(brush_src->curves_sculpt_settings));
121 }
122
123 /* enable fake user by default */
124 id_fake_user_set(&brush_dst->id);
125}
126
163
164static void brush_make_local(Main *bmain, ID *id, const int flags)
165{
166 if (!ID_IS_LINKED(id)) {
167 return;
168 }
169
170 Brush *brush = reinterpret_cast<Brush *>(id);
171 const bool lib_local = (flags & LIB_ID_MAKELOCAL_FULL_LIBRARY) != 0;
172
173 bool force_local, force_copy;
174 BKE_lib_id_make_local_generic_action_define(bmain, id, flags, &force_local, &force_copy);
175
176 if (force_local) {
177 BKE_lib_id_clear_library_data(bmain, &brush->id, flags);
178 BKE_lib_id_expand_local(bmain, &brush->id, flags);
179
180 /* enable fake user by default */
181 id_fake_user_set(&brush->id);
182 }
183 else if (force_copy) {
184 Brush *brush_new = reinterpret_cast<Brush *>(
185 BKE_id_copy(bmain, &brush->id)); /* Ensures FAKE_USER is set */
186
187 id_us_min(&brush_new->id);
188
189 BLI_assert(brush_new->id.flag & ID_FLAG_FAKEUSER);
190 BLI_assert(brush_new->id.us == 1);
191
192 /* Setting `newid` is mandatory for complex #make_lib_local logic. */
193 ID_NEW_SET(brush, brush_new);
194
195 if (!lib_local) {
196 BKE_libblock_remap(bmain, brush, brush_new, ID_REMAP_SKIP_INDIRECT_USAGE);
197 }
198 }
199}
200
215
216static void brush_foreach_path(ID *id, BPathForeachPathData *bpath_data)
217{
218 Brush *brush = reinterpret_cast<Brush *>(id);
219 if (brush->icon_filepath[0] != '\0') {
221 bpath_data, brush->icon_filepath, sizeof(brush->icon_filepath));
222 }
223}
224
225static void brush_blend_write(BlendWriter *writer, ID *id, const void *id_address)
226{
227 Brush *brush = reinterpret_cast<Brush *>(id);
228
229 BLO_write_id_struct(writer, Brush, id_address, &brush->id);
230 BKE_id_blend_write(writer, &brush->id);
231
232 if (brush->curve) {
233 BKE_curvemapping_blend_write(writer, brush->curve);
234 }
235
236 if (brush->automasking_cavity_curve) {
238 }
239
240 if (brush->curve_rand_hue) {
242 }
243 if (brush->curve_rand_saturation) {
245 }
246 if (brush->curve_rand_value) {
248 }
249
250 if (brush->gpencil_settings) {
252
255 }
256 if (brush->gpencil_settings->curve_strength) {
258 }
259 if (brush->gpencil_settings->curve_jitter) {
261 }
264 }
267 }
268 if (brush->gpencil_settings->curve_rand_uv) {
270 }
271 if (brush->gpencil_settings->curve_rand_hue) {
273 }
276 }
279 }
280 }
281 if (brush->curves_sculpt_settings) {
284 }
285 if (brush->gradient) {
286 BLO_write_struct(writer, ColorBand, brush->gradient);
287 }
288
289 BKE_previewimg_blend_write(writer, brush->preview);
290}
291
292static void brush_blend_read_data(BlendDataReader *reader, ID *id)
293{
294 Brush *brush = reinterpret_cast<Brush *>(id);
295
296 /* Falloff curve. */
297 BLO_read_struct(reader, CurveMapping, &brush->curve);
298
299 BLO_read_struct(reader, ColorBand, &brush->gradient);
300
301 if (brush->curve) {
302 BKE_curvemapping_blend_read(reader, brush->curve);
303 }
304 else {
306 }
307
309 if (brush->automasking_cavity_curve) {
311 }
312 else {
314 }
315
317 if (brush->curve_rand_hue) {
319 }
320 else {
322 }
323
325 if (brush->curve_rand_saturation) {
327 }
328 else {
330 }
331
333 if (brush->curve_rand_value) {
335 }
336 else {
338 }
339
340 /* grease pencil */
342 if (brush->gpencil_settings != nullptr) {
346
353
356 }
357
358 if (brush->gpencil_settings->curve_strength) {
360 }
361
362 if (brush->gpencil_settings->curve_jitter) {
364 }
365
368 }
369
372 }
373
374 if (brush->gpencil_settings->curve_rand_uv) {
376 }
377
378 if (brush->gpencil_settings->curve_rand_hue) {
380 }
381
384 }
385
388 }
389 }
390
392 if (brush->curves_sculpt_settings) {
396 }
397 }
398
399 BLO_read_struct(reader, PreviewImage, &brush->preview);
400 BKE_previewimg_blend_read(reader, brush->preview);
401
402 brush->icon_imbuf = nullptr;
403 brush->has_unsaved_changes = false;
404
405 /* Prior to 5.0, the brush->size value is expected to be the radius, not the diameter. To ensure
406 * correct behavior, convert this when reading newer files. */
407 if (BLO_read_fileversion_get(reader) >= 500) {
408 brush->size = std::max(brush->size / 2, 1);
409 brush->unprojected_radius = std::max(brush->unprojected_radius / 2, 0.001f);
410 }
411}
412
414{
415 Brush *brush = reinterpret_cast<Brush *>(id);
416
417 /* Update brush settings depending on availability of other IDs. */
418 if (brush->gpencil_settings != nullptr) {
420 if (!brush->gpencil_settings->material) {
422 }
423 }
424 else {
425 brush->gpencil_settings->material = nullptr;
426 }
427 }
428}
429
430static void brush_asset_metadata_ensure(void *asset_ptr, AssetMetaData *asset_data)
431{
432 using namespace blender;
433 using namespace blender::bke;
434
435 Brush *brush = reinterpret_cast<Brush *>(asset_ptr);
436 BLI_assert(GS(brush->id.name) == ID_BR);
437
438 /* Most names copied from brush RNA (not all are available there though). */
439 constexpr std::array mode_map{
440 std::tuple{"use_paint_sculpt", OB_MODE_SCULPT, "sculpt_brush_type"},
441 std::tuple{"use_paint_vertex", OB_MODE_VERTEX_PAINT, "vertex_brush_type"},
442 std::tuple{"use_paint_weight", OB_MODE_WEIGHT_PAINT, "weight_brush_type"},
443 std::tuple{"use_paint_image", OB_MODE_TEXTURE_PAINT, "image_brush_type"},
444 /* Sculpt UVs in the image editor while in edit mode. */
445 std::tuple{"use_paint_uv_sculpt", OB_MODE_EDIT, "image_brush_type"},
446 std::tuple{"use_paint_grease_pencil", OB_MODE_PAINT_GREASE_PENCIL, "gpencil_brush_type"},
447 /* Note: Not defined in brush RNA, own name. */
448 std::tuple{
449 "use_sculpt_grease_pencil", OB_MODE_SCULPT_GREASE_PENCIL, "gpencil_sculpt_brush_type"},
450 std::tuple{
451 "use_vertex_grease_pencil", OB_MODE_VERTEX_GREASE_PENCIL, "gpencil_vertex_brush_type"},
452 std::tuple{"use_weight_gpencil", OB_MODE_WEIGHT_GREASE_PENCIL, "gpencil_weight_brush_type"},
453 std::tuple{"use_paint_sculpt_curves", OB_MODE_SCULPT_CURVES, "curves_sculpt_brush_type"},
454 };
455
456 for (const auto &[prop_name, mode, tool_prop_name] : mode_map) {
457 /* Only add booleans for supported modes. */
458 if (!(brush->ob_mode & mode)) {
459 continue;
460 }
461 auto mode_property = idprop::create_bool(prop_name, true);
462 BKE_asset_metadata_idprop_ensure(asset_data, mode_property.release());
463
464 if (std::optional<int> brush_tool = BKE_paint_get_brush_type_from_obmode(brush, mode)) {
465 auto type_property = idprop::create(tool_prop_name, *brush_tool);
466 BKE_asset_metadata_idprop_ensure(asset_data, type_property.release());
467 }
468 else {
470 }
471 }
472}
473
475 /*pre_save_fn*/ brush_asset_metadata_ensure,
476 /*on_mark_asset_fn*/ brush_asset_metadata_ensure,
477};
478
480 /*id_code*/ Brush::id_type,
481 /*id_filter*/ FILTER_ID_BR,
482 /*dependencies_id_types*/
484 /*main_listbase_index*/ INDEX_ID_BR,
485 /*struct_size*/ sizeof(Brush),
486 /*name*/ "Brush",
487 /*name_plural*/ N_("brushes"),
488 /*translation_context*/ BLT_I18NCONTEXT_ID_BRUSH,
490 /*asset_type_info*/ &AssetType_BR,
491
492 /*init_data*/ brush_init_data,
493 /*copy_data*/ brush_copy_data,
494 /*free_data*/ brush_free_data,
495 /*make_local*/ brush_make_local,
496 /*foreach_id*/ brush_foreach_id,
497 /*foreach_cache*/ nullptr,
498 /*foreach_path*/ brush_foreach_path,
499 /*owner_pointer_get*/ nullptr,
500
501 /*blend_write*/ brush_blend_write,
502 /*blend_read_data*/ brush_blend_read_data,
503 /*blend_read_after_liblink*/ brush_blend_read_after_liblink,
504
505 /*blend_read_undo_preserve*/ nullptr,
506
507 /*lib_override_apply_post*/ nullptr,
508};
509
511
513{
515 BLI_rng_srandom(brush_rng, 31415682);
516}
517
519{
520 if (brush_rng == nullptr) {
521 return;
522 }
524 brush_rng = nullptr;
525}
526
528{
529
530 const Brush *brush_def = DNA_struct_default_get(Brush);
531
532#define FROM_DEFAULT(member) \
533 memcpy((void *)&brush->member, (void *)&brush_def->member, sizeof(brush->member))
534#define FROM_DEFAULT_PTR(member) memcpy(brush->member, brush_def->member, sizeof(brush->member))
535
538 FROM_DEFAULT(weight);
540 FROM_DEFAULT(alpha);
541 FROM_DEFAULT(hardness);
542 FROM_DEFAULT(autosmooth_factor);
543 FROM_DEFAULT(topology_rake_factor);
544 FROM_DEFAULT(crease_pinch_factor);
545 FROM_DEFAULT(normal_radius_factor);
546 FROM_DEFAULT(wet_paint_radius_factor);
547 FROM_DEFAULT(area_radius_factor);
548 FROM_DEFAULT(disconnected_distance_max);
549 FROM_DEFAULT(sculpt_plane);
550 FROM_DEFAULT(plane_offset);
551 FROM_DEFAULT(normal_weight);
552 FROM_DEFAULT(fill_threshold);
554 FROM_DEFAULT(sampling_flag);
555 FROM_DEFAULT_PTR(rgb);
556 FROM_DEFAULT_PTR(secondary_rgb);
557 FROM_DEFAULT(spacing);
558 FROM_DEFAULT(smooth_stroke_radius);
559 FROM_DEFAULT(smooth_stroke_factor);
560 FROM_DEFAULT(rate);
561 FROM_DEFAULT(jitter);
562 FROM_DEFAULT(texture_sample_bias);
563 FROM_DEFAULT(texture_overlay_alpha);
564 FROM_DEFAULT(mask_overlay_alpha);
565 FROM_DEFAULT(cursor_overlay_alpha);
567 FROM_DEFAULT_PTR(add_col);
568 FROM_DEFAULT_PTR(sub_col);
569 FROM_DEFAULT(stencil_pos);
570 FROM_DEFAULT(stencil_dimension);
571 FROM_DEFAULT(mtex);
572 FROM_DEFAULT(mask_mtex);
573 FROM_DEFAULT(falloff_shape);
574 FROM_DEFAULT(tip_scale_x);
575 FROM_DEFAULT(tip_roundness);
576
577#undef FROM_DEFAULT
578#undef FROM_DEFAULT_PTR
579}
580
581/* Datablock add/copy/free/make_local */
582
583Brush *BKE_brush_add(Main *bmain, const char *name, const eObjectMode ob_mode)
584{
585 Brush *brush = BKE_id_new<Brush>(bmain, name);
586
587 brush->ob_mode = ob_mode;
588
589 if (ob_mode == OB_MODE_SCULPT_CURVES) {
591 }
592 else if (ELEM(ob_mode,
597 {
599 }
600
601 return brush;
602}
603
605{
606 if (brush->gpencil_settings == nullptr) {
607 brush->gpencil_settings = MEM_callocN<BrushGpencilSettings>("BrushGpencilSettings");
608 }
609
610 brush->gpencil_settings->draw_smoothlvl = 1;
611 brush->gpencil_settings->flag = 0;
612 brush->gpencil_settings->flag |= GP_BRUSH_USE_PRESSURE;
613 brush->gpencil_settings->draw_strength = 1.0f;
614 brush->gpencil_settings->draw_jitter = 0.0f;
615 brush->gpencil_settings->flag |= GP_BRUSH_USE_JITTER_PRESSURE;
616
617 /* curves */
618 brush->gpencil_settings->curve_sensitivity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
619 brush->gpencil_settings->curve_strength = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
620 brush->gpencil_settings->curve_jitter = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
621
622 brush->gpencil_settings->curve_rand_pressure = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
623 brush->gpencil_settings->curve_rand_strength = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
624 brush->gpencil_settings->curve_rand_uv = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
625 brush->gpencil_settings->curve_rand_hue = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
626 brush->gpencil_settings->curve_rand_saturation = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
627 brush->gpencil_settings->curve_rand_value = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
628}
629
631{
632 if (brush->id.tag & ID_TAG_INDIRECT) {
633 return false;
634 }
635 if (ID_REAL_USERS(brush) <= 1 && ID_EXTRA_USERS(brush) == 0 &&
637 {
638 return false;
639 }
640
641 BKE_id_delete(bmain, brush);
642
643 return true;
644}
645
647 Brush *brush,
648 eDupli_ID_Flags /*dupflag*/,
649 /*eLibIDDuplicateFlags*/ uint duplicate_options)
650{
651 const bool is_subprocess = (duplicate_options & LIB_ID_DUPLICATE_IS_SUBPROCESS) != 0;
652 const bool is_root_id = (duplicate_options & LIB_ID_DUPLICATE_IS_ROOT_ID) != 0;
653
655
656 if (!is_subprocess) {
658 }
659 if (is_root_id) {
660 duplicate_options &= ~LIB_ID_DUPLICATE_IS_ROOT_ID;
661 }
662
663 constexpr int id_copy_flag = LIB_ID_COPY_DEFAULT;
664
665 Brush *new_brush = reinterpret_cast<Brush *>(
666 BKE_id_copy_for_duplicate(bmain, &brush->id, dupflag, id_copy_flag));
667
668 /* Currently this duplicates everything and the passed in value of `dupflag` is ignored. Ideally,
669 * this should both check user preferences and do further filtering based on eDupli_ID_Flags. */
670 auto dependencies_cb = [&](const LibraryIDLinkCallbackData *cb_data) -> int {
671 if (cb_data->cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_EMBEDDED_NOT_OWNING)) {
672 return IDWALK_NOP;
673 }
674 if (cb_data->cb_flag & IDWALK_CB_LOOPBACK) {
675 return IDWALK_NOP;
676 }
677
678 BKE_id_copy_for_duplicate(bmain, *cb_data->id_pointer, dupflag, id_copy_flag);
679 return IDWALK_NOP;
680 };
681
682 BKE_library_foreach_ID_link(bmain, &new_brush->id, dependencies_cb, nullptr, IDWALK_RECURSE);
683
684 if (!is_subprocess) {
685 /* This code will follow into all ID links using an ID tagged with ID_TAG_NEW. */
686 BKE_libblock_relink_to_newid(bmain, &new_brush->id, 0);
687
688#ifndef NDEBUG
689 /* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those flags. */
690 ID *id_iter;
691 FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
692 BLI_assert((id_iter->tag & ID_TAG_NEW) == 0);
693 }
695#endif
696
697 /* Cleanup. */
699 }
700
701 return new_brush;
702}
703
705{
706 if (brush->curves_sculpt_settings == nullptr) {
707 brush->curves_sculpt_settings = MEM_callocN<BrushCurvesSculptSettings>(__func__);
708 }
709 BrushCurvesSculptSettings *settings = brush->curves_sculpt_settings;
711 settings->add_amount = 1;
712 settings->points_per_curve = 8;
713 settings->minimum_length = 0.01f;
714 settings->curve_length = 0.3f;
715 settings->curve_radius = 0.01f;
716 settings->density_add_attempts = 100;
717 settings->curve_parameter_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
718}
719
721{
722 if (brush && ID_IS_LINKED(brush)) {
723 brush->has_unsaved_changes = true;
724 }
725}
726
728{
729 LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
730 if (brush->ob_mode & ob_mode) {
731 return brush;
732 }
733 }
734 return nullptr;
735}
736
738{
739 /* create a fake brush and set it to the defaults */
740 Brush def = blender::dna::shallow_zero_initialize();
741 brush_defaults(&def);
742
743#define BR_TEST(field, t) \
744 if (br->field != def.field) { \
745 printf("br->" #field " = %" #t ";\n", br->field); \
746 } \
747 ((void)0)
748
749#define BR_TEST_FLAG(_f) \
750 if ((br->flag & _f) && !(def.flag & _f)) { \
751 printf("br->flag |= " #_f ";\n"); \
752 } \
753 else if (!(br->flag & _f) && (def.flag & _f)) { \
754 printf("br->flag &= ~" #_f ";\n"); \
755 } \
756 ((void)0)
757
758#define BR_TEST_FLAG_OVERLAY(_f) \
759 if ((br->overlay_flags & _f) && !(def.overlay_flags & _f)) { \
760 printf("br->overlay_flags |= " #_f ";\n"); \
761 } \
762 else if (!(br->overlay_flags & _f) && (def.overlay_flags & _f)) { \
763 printf("br->overlay_flags &= ~" #_f ";\n"); \
764 } \
765 ((void)0)
766
767 /* print out any non-default brush state */
768 BR_TEST(normal_weight, f);
769
770 BR_TEST(blend, d);
771 BR_TEST(size, d);
772
773 /* br->flag */
797
804
805 BR_TEST(jitter, f);
806 BR_TEST(spacing, d);
807 BR_TEST(smooth_stroke_radius, d);
808 BR_TEST(smooth_stroke_factor, f);
809 BR_TEST(rate, f);
810
811 BR_TEST(alpha, f);
812
813 BR_TEST(sculpt_plane, d);
814
815 BR_TEST(plane_offset, f);
816
817 BR_TEST(autosmooth_factor, f);
818
819 BR_TEST(topology_rake_factor, f);
820
821 BR_TEST(crease_pinch_factor, f);
822
823 BR_TEST(plane_trim, f);
824
825 BR_TEST(texture_sample_bias, f);
826 BR_TEST(texture_overlay_alpha, d);
827
828 BR_TEST(add_col[0], f);
829 BR_TEST(add_col[1], f);
830 BR_TEST(add_col[2], f);
831 BR_TEST(add_col[3], f);
832 BR_TEST(sub_col[0], f);
833 BR_TEST(sub_col[1], f);
834 BR_TEST(sub_col[2], f);
835 BR_TEST(sub_col[3], f);
836
837 printf("\n");
838
839#undef BR_TEST
840#undef BR_TEST_FLAG
841}
842
844{
845 CurveMapping *cumap = nullptr;
846 CurveMap *cuma = nullptr;
847
848 if (!b->curve) {
849 b->curve = BKE_curvemapping_add(1, 0, 0, 1, 1);
850 }
851 cumap = b->curve;
853 cumap->preset = preset;
854
855 cuma = b->curve->cm;
857 BKE_curvemapping_changed(cumap, false);
859}
860
861const MTex *BKE_brush_mask_texture_get(const Brush *brush, const eObjectMode object_mode)
862{
863 if (object_mode == OB_MODE_SCULPT) {
864 return &brush->mtex;
865 }
866 return &brush->mask_mtex;
867}
868
869const MTex *BKE_brush_color_texture_get(const Brush *brush, const eObjectMode object_mode)
870{
871 if (object_mode == OB_MODE_SCULPT) {
872 return &brush->mask_mtex;
873 }
874 return &brush->mtex;
875}
876
878 const Brush *br,
879 const MTex *mtex,
880 const float point[3],
881 float rgba[4],
882 const int thread,
883 ImagePool *pool)
884{
886 float intensity = 1.0;
887 bool hasrgb = false;
888
889 if (mtex == nullptr || mtex->tex == nullptr) {
890 intensity = 1;
891 }
892 else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
893 /* Get strength by feeding the vertex
894 * location directly into a texture */
895 hasrgb = RE_texture_evaluate(mtex, point, thread, pool, false, false, &intensity, rgba);
896 }
897 else if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
898 float rotation = -mtex->rot;
899 const float point_2d[2] = {point[0], point[1]};
900 float x, y;
901 float co[3];
902
903 x = point_2d[0] - br->stencil_pos[0];
904 y = point_2d[1] - br->stencil_pos[1];
905
906 if (rotation > 0.001f || rotation < -0.001f) {
907 const float angle = atan2f(y, x) + rotation;
908 const float flen = sqrtf(x * x + y * y);
909
910 x = flen * cosf(angle);
911 y = flen * sinf(angle);
912 }
913
914 if (fabsf(x) > br->stencil_dimension[0] || fabsf(y) > br->stencil_dimension[1]) {
915 zero_v4(rgba);
916 return 0.0f;
917 }
918 x /= (br->stencil_dimension[0]);
919 y /= (br->stencil_dimension[1]);
920
921 co[0] = x;
922 co[1] = y;
923 co[2] = 0.0f;
924
925 hasrgb = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba);
926 }
927 else {
928 float rotation = -mtex->rot;
929 const float point_2d[2] = {point[0], point[1]};
930 float x = 0.0f, y = 0.0f; /* Quite warnings */
931 float invradius = 1.0f; /* Quite warnings */
932 float co[3];
933
934 if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
935 /* keep coordinates relative to mouse */
936
937 rotation -= ups->brush_rotation;
938
939 x = point_2d[0] - ups->tex_mouse[0];
940 y = point_2d[1] - ups->tex_mouse[1];
941
942 /* use pressure adjusted size for fixed mode */
943 invradius = 1.0f / ups->pixel_radius;
944 }
945 else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
946 /* leave the coordinates relative to the screen */
947
948 /* use unadjusted size for tiled mode */
949 invradius = 1.0f / ups->start_pixel_radius;
950
951 x = point_2d[0];
952 y = point_2d[1];
953 }
954 else if (mtex->brush_map_mode == MTEX_MAP_MODE_RANDOM) {
955 rotation -= ups->brush_rotation;
956 /* these contain a random coordinate */
957 x = point_2d[0] - ups->tex_mouse[0];
958 y = point_2d[1] - ups->tex_mouse[1];
959
960 invradius = 1.0f / ups->pixel_radius;
961 }
962
963 x *= invradius;
964 y *= invradius;
965
966 /* it is probably worth optimizing for those cases where
967 * the texture is not rotated by skipping the calls to
968 * atan2, sqrtf, sin, and cos. */
969 if (rotation > 0.001f || rotation < -0.001f) {
970 const float angle = atan2f(y, x) + rotation;
971 const float flen = sqrtf(x * x + y * y);
972
973 x = flen * cosf(angle);
974 y = flen * sinf(angle);
975 }
976
977 co[0] = x;
978 co[1] = y;
979 co[2] = 0.0f;
980
981 hasrgb = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba);
982 }
983
984 intensity += br->texture_sample_bias;
985
986 if (!hasrgb) {
987 rgba[0] = intensity;
988 rgba[1] = intensity;
989 rgba[2] = intensity;
990 rgba[3] = 1.0f;
991 }
992 /* For consistency, sampling always returns color in linear space */
993 else if (ups->do_linear_conversion) {
995 }
996
997 return intensity;
998}
999
1001 const Scene *scene, Brush *br, const float point[2], const int thread, ImagePool *pool)
1002{
1004 MTex *mtex = &br->mask_mtex;
1005 float rgba[4], intensity;
1006
1007 if (!mtex->tex) {
1008 return 1.0f;
1009 }
1011 float rotation = -mtex->rot;
1012 const float point_2d[2] = {point[0], point[1]};
1013 float x, y;
1014 float co[3];
1015
1016 x = point_2d[0] - br->mask_stencil_pos[0];
1017 y = point_2d[1] - br->mask_stencil_pos[1];
1018
1019 if (rotation > 0.001f || rotation < -0.001f) {
1020 const float angle = atan2f(y, x) + rotation;
1021 const float flen = sqrtf(x * x + y * y);
1022
1023 x = flen * cosf(angle);
1024 y = flen * sinf(angle);
1025 }
1026
1027 if (fabsf(x) > br->mask_stencil_dimension[0] || fabsf(y) > br->mask_stencil_dimension[1]) {
1028 zero_v4(rgba);
1029 return 0.0f;
1030 }
1031 x /= (br->mask_stencil_dimension[0]);
1032 y /= (br->mask_stencil_dimension[1]);
1033
1034 co[0] = x;
1035 co[1] = y;
1036 co[2] = 0.0f;
1037
1038 RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba);
1039 }
1040 else {
1041 float rotation = -mtex->rot;
1042 const float point_2d[2] = {point[0], point[1]};
1043 float x = 0.0f, y = 0.0f; /* Quite warnings */
1044 float invradius = 1.0f; /* Quite warnings */
1045 float co[3];
1046
1047 if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
1048 /* keep coordinates relative to mouse */
1049
1050 rotation -= ups->brush_rotation_sec;
1051
1052 x = point_2d[0] - ups->mask_tex_mouse[0];
1053 y = point_2d[1] - ups->mask_tex_mouse[1];
1054
1055 /* use pressure adjusted size for fixed mode */
1056 invradius = 1.0f / ups->pixel_radius;
1057 }
1058 else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
1059 /* leave the coordinates relative to the screen */
1060
1061 /* use unadjusted size for tiled mode */
1062 invradius = 1.0f / ups->start_pixel_radius;
1063
1064 x = point_2d[0];
1065 y = point_2d[1];
1066 }
1067 else if (mtex->brush_map_mode == MTEX_MAP_MODE_RANDOM) {
1068 rotation -= ups->brush_rotation_sec;
1069 /* these contain a random coordinate */
1070 x = point_2d[0] - ups->mask_tex_mouse[0];
1071 y = point_2d[1] - ups->mask_tex_mouse[1];
1072
1073 invradius = 1.0f / ups->pixel_radius;
1074 }
1075
1076 x *= invradius;
1077 y *= invradius;
1078
1079 /* it is probably worth optimizing for those cases where
1080 * the texture is not rotated by skipping the calls to
1081 * atan2, sqrtf, sin, and cos. */
1082 if (rotation > 0.001f || rotation < -0.001f) {
1083 const float angle = atan2f(y, x) + rotation;
1084 const float flen = sqrtf(x * x + y * y);
1085
1086 x = flen * cosf(angle);
1087 y = flen * sinf(angle);
1088 }
1089
1090 co[0] = x;
1091 co[1] = y;
1092 co[2] = 0.0f;
1093
1094 RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba);
1095 }
1096
1097 CLAMP(intensity, 0.0f, 1.0f);
1098
1099 switch (br->mask_pressure) {
1101 intensity = ((1.0f - intensity) < ups->size_pressure_value) ? 1.0f : 0.0f;
1102 break;
1104 intensity = ups->size_pressure_value + intensity * (1.0f - ups->size_pressure_value);
1105 break;
1106 default:
1107 break;
1108 }
1109
1110 return intensity;
1111}
1112
1113/* Unified Size / Strength / Color */
1114
1115/* XXX: be careful about setting size and unprojected radius
1116 * because they depend on one another
1117 * these functions do not set the other corresponding value
1118 * this can lead to odd behavior if size and unprojected
1119 * radius become inconsistent.
1120 * the biggest problem is that it isn't possible to change
1121 * unprojected radius because a view context is not
1122 * available. my usual solution to this is to use the
1123 * ratio of change of the size to change the unprojected
1124 * radius. Not completely convinced that is correct.
1125 * In any case, a better solution is needed to prevent
1126 * inconsistency. */
1127
1128const float *BKE_brush_color_get(const Scene *scene, const Paint *paint, const Brush *brush)
1129{
1132 }
1133 return brush->rgb;
1134}
1135
1137const std::optional<BrushColorJitterSettings> BKE_brush_color_jitter_get_settings(
1138 const Scene *scene, const Paint *paint, const Brush *brush)
1139{
1142 return std::nullopt;
1143 }
1144
1147 settings.color_jitter_flag,
1148 settings.hsv_jitter[0],
1149 settings.hsv_jitter[1],
1150 settings.hsv_jitter[2],
1151 settings.curve_rand_hue,
1152 settings.curve_rand_saturation,
1153 settings.curve_rand_value,
1154 };
1155 }
1156
1157 if ((brush->flag2 & BRUSH_JITTER_COLOR) == 0) {
1158 return std::nullopt;
1159 }
1160
1162 brush->color_jitter_flag,
1163 brush->hsv_jitter[0],
1164 brush->hsv_jitter[1],
1165 brush->hsv_jitter[2],
1166 brush->curve_rand_hue,
1167 brush->curve_rand_saturation,
1168 brush->curve_rand_value,
1169 };
1170}
1171
1172const float *BKE_brush_secondary_color_get(const Scene *scene,
1173 const Paint *paint,
1174 const Brush *brush)
1175{
1178 }
1179 return brush->secondary_rgb;
1180}
1181
1182void BKE_brush_color_set(Scene *scene, const Paint *paint, Brush *brush, const float color[3])
1183{
1186 copy_v3_v3(ups->rgb, color);
1187 }
1188 else {
1189 copy_v3_v3(brush->rgb, color);
1191 }
1192}
1193
1195{
1197
1198 /* make sure range is sane */
1200
1201 if (ups->flag & UNIFIED_PAINT_SIZE) {
1202 ups->size = size;
1203 }
1204 else {
1205 brush->size = size;
1207 }
1208}
1209
1210int BKE_brush_size_get(const Scene *scene, const Brush *brush)
1211{
1213 int size = (ups->flag & UNIFIED_PAINT_SIZE) ? ups->size : brush->size;
1214
1215 return size;
1216}
1217
1218bool BKE_brush_use_locked_size(const Scene *scene, const Brush *brush)
1219{
1220 const short us_flag = scene->toolsettings->unified_paint_settings.flag;
1221
1222 return (us_flag & UNIFIED_PAINT_SIZE) ? (us_flag & UNIFIED_PAINT_BRUSH_LOCK_SIZE) :
1223 (brush->flag & BRUSH_LOCK_SIZE);
1224}
1225
1227{
1228 return brush->flag & BRUSH_SIZE_PRESSURE;
1229}
1230
1232{
1233 return brush->flag & BRUSH_ALPHA_PRESSURE;
1234}
1235
1236void BKE_brush_unprojected_radius_set(Scene *scene, Brush *brush, float unprojected_radius)
1237{
1239
1240 if (ups->flag & UNIFIED_PAINT_SIZE) {
1241 ups->unprojected_radius = unprojected_radius;
1242 }
1243 else {
1244 brush->unprojected_radius = unprojected_radius;
1246 }
1247}
1248
1250{
1252
1253 return (ups->flag & UNIFIED_PAINT_SIZE) ? ups->unprojected_radius : brush->unprojected_radius;
1254}
1255
1256void BKE_brush_alpha_set(Scene *scene, Brush *brush, float alpha)
1257{
1259
1260 if (ups->flag & UNIFIED_PAINT_ALPHA) {
1261 ups->alpha = alpha;
1262 }
1263 else {
1264 brush->alpha = alpha;
1266 }
1267}
1268
1269float BKE_brush_alpha_get(const Scene *scene, const Brush *brush)
1270{
1272
1273 return (ups->flag & UNIFIED_PAINT_ALPHA) ? ups->alpha : brush->alpha;
1274}
1275
1276float BKE_brush_weight_get(const Scene *scene, const Brush *brush)
1277{
1279
1280 return (ups->flag & UNIFIED_PAINT_WEIGHT) ? ups->weight : brush->weight;
1281}
1282
1283void BKE_brush_weight_set(const Scene *scene, Brush *brush, float value)
1284{
1286
1287 if (ups->flag & UNIFIED_PAINT_WEIGHT) {
1288 ups->weight = value;
1289 }
1290 else {
1291 brush->weight = value;
1293 }
1294}
1295
1297{
1299
1300 return (ups->flag & UNIFIED_PAINT_INPUT_SAMPLES) ? ups->input_samples : brush->input_samples;
1301}
1302
1303void BKE_brush_input_samples_set(const Scene *scene, Brush *brush, int value)
1304{
1306
1307 if (ups->flag & UNIFIED_PAINT_INPUT_SAMPLES) {
1308 ups->input_samples = value;
1309 }
1310 else {
1311 brush->input_samples = value;
1313 }
1314}
1315
1316void BKE_brush_scale_unprojected_radius(float *unprojected_radius,
1317 int new_brush_size,
1318 int old_brush_size)
1319{
1320 float scale = new_brush_size;
1321 /* avoid division by zero */
1322 if (old_brush_size != 0) {
1323 scale /= float(old_brush_size);
1324 }
1325 (*unprojected_radius) *= scale;
1326}
1327
1328void BKE_brush_scale_size(int *r_brush_size,
1329 float new_unprojected_radius,
1330 float old_unprojected_radius)
1331{
1332 float scale = new_unprojected_radius;
1333 /* avoid division by zero */
1334 if (old_unprojected_radius != 0) {
1335 scale /= new_unprojected_radius;
1336 }
1337 (*r_brush_size) = int(float(*r_brush_size) * scale);
1338}
1339
1340void BKE_brush_jitter_pos(const Scene &scene,
1341 const Brush &brush,
1342 const float pos[2],
1343 float jitterpos[2])
1344{
1345 float rand_pos[2];
1346 float spread;
1347 int diameter;
1348
1349 do {
1350 rand_pos[0] = BLI_rng_get_float(brush_rng) - 0.5f;
1351 rand_pos[1] = BLI_rng_get_float(brush_rng) - 0.5f;
1352 } while (len_squared_v2(rand_pos) > square_f(0.5f));
1353
1354 if (brush.flag & BRUSH_ABSOLUTE_JITTER) {
1355 diameter = 2 * brush.jitter_absolute;
1356 spread = 1.0;
1357 }
1358 else {
1359 diameter = 2 * BKE_brush_size_get(&scene, &brush);
1360 spread = brush.jitter;
1361 }
1362 /* find random position within a circle of diameter 1 */
1363 jitterpos[0] = pos[0] + 2 * rand_pos[0] * diameter * spread;
1364 jitterpos[1] = pos[1] + 2 * rand_pos[1] * diameter * spread;
1365}
1366
1368{
1369 /* we multiply with brush radius as an optimization for the brush
1370 * texture sampling functions */
1371 if (mask) {
1374 }
1375 else {
1378 }
1379}
1380
1382 const CurveMapping *cumap,
1383 const blender::Span<float> distances,
1384 const float brush_radius,
1385 const blender::MutableSpan<float> factors)
1386{
1387 BLI_assert(factors.size() == distances.size());
1388
1389 const float radius_rcp = blender::math::rcp(brush_radius);
1390 switch (preset) {
1391 case BRUSH_CURVE_CUSTOM: {
1392 for (const int i : distances.index_range()) {
1393 const float distance = distances[i];
1394 if (distance >= brush_radius) {
1395 factors[i] = 0.0f;
1396 continue;
1397 }
1398 factors[i] *= BKE_curvemapping_evaluateF(cumap, 0, distance * radius_rcp);
1399 }
1400 break;
1401 }
1402 case BRUSH_CURVE_SHARP: {
1403 for (const int i : distances.index_range()) {
1404 const float distance = distances[i];
1405 if (distance >= brush_radius) {
1406 factors[i] = 0.0f;
1407 continue;
1408 }
1409 const float factor = 1.0f - distance * radius_rcp;
1410 factors[i] *= factor * factor;
1411 }
1412 break;
1413 }
1414 case BRUSH_CURVE_SMOOTH: {
1415 for (const int i : distances.index_range()) {
1416 const float distance = distances[i];
1417 if (distance >= brush_radius) {
1418 factors[i] = 0.0f;
1419 continue;
1420 }
1421 const float factor = 1.0f - distance * radius_rcp;
1422 factors[i] *= 3.0f * factor * factor - 2.0f * factor * factor * factor;
1423 }
1424 break;
1425 }
1426 case BRUSH_CURVE_SMOOTHER: {
1427 for (const int i : distances.index_range()) {
1428 const float distance = distances[i];
1429 if (distance >= brush_radius) {
1430 factors[i] = 0.0f;
1431 continue;
1432 }
1433 const float factor = 1.0f - distance * radius_rcp;
1434 factors[i] *= pow3f(factor) * (factor * (factor * 6.0f - 15.0f) + 10.0f);
1435 }
1436 break;
1437 }
1438 case BRUSH_CURVE_ROOT: {
1439 for (const int i : distances.index_range()) {
1440 const float distance = distances[i];
1441 if (distance >= brush_radius) {
1442 factors[i] = 0.0f;
1443 continue;
1444 }
1445 const float factor = 1.0f - distance * radius_rcp;
1446 factors[i] *= sqrtf(factor);
1447 }
1448 break;
1449 }
1450 case BRUSH_CURVE_LIN: {
1451 for (const int i : distances.index_range()) {
1452 const float distance = distances[i];
1453 if (distance >= brush_radius) {
1454 factors[i] = 0.0f;
1455 continue;
1456 }
1457 const float factor = 1.0f - distance * radius_rcp;
1458 factors[i] *= factor;
1459 }
1460 break;
1461 }
1462 case BRUSH_CURVE_CONSTANT: {
1463 for (const int i : distances.index_range()) {
1464 const float distance = distances[i];
1465 if (distance >= brush_radius) {
1466 factors[i] = 0.0f;
1467 }
1468 }
1469 break;
1470 }
1471 case BRUSH_CURVE_SPHERE: {
1472 for (const int i : distances.index_range()) {
1473 const float distance = distances[i];
1474 if (distance >= brush_radius) {
1475 factors[i] = 0.0f;
1476 continue;
1477 }
1478 const float factor = 1.0f - distance * radius_rcp;
1479 factors[i] *= sqrtf(2 * factor - factor * factor);
1480 }
1481 break;
1482 }
1483 case BRUSH_CURVE_POW4: {
1484 for (const int i : distances.index_range()) {
1485 const float distance = distances[i];
1486 if (distance >= brush_radius) {
1487 factors[i] = 0.0f;
1488 continue;
1489 }
1490 const float factor = 1.0f - distance * radius_rcp;
1491 factors[i] *= factor * factor * factor * factor;
1492 }
1493 break;
1494 }
1495 case BRUSH_CURVE_INVSQUARE: {
1496 for (const int i : distances.index_range()) {
1497 const float distance = distances[i];
1498 if (distance >= brush_radius) {
1499 factors[i] = 0.0f;
1500 continue;
1501 }
1502 const float factor = 1.0f - distance * radius_rcp;
1503 factors[i] *= factor * (2.0f - factor);
1504 }
1505 break;
1506 }
1507 }
1508}
1509
1511 const CurveMapping *cumap,
1512 const float distance,
1513 const float brush_radius)
1514{
1515 float p = distance;
1516 float strength = 1.0f;
1517
1518 if (p >= brush_radius) {
1519 return 0;
1520 }
1521
1522 p = p / brush_radius;
1523 p = 1.0f - p;
1524
1525 switch (preset) {
1526 case BRUSH_CURVE_CUSTOM:
1527 strength = BKE_curvemapping_evaluateF(cumap, 0, 1.0f - p);
1528 break;
1529 case BRUSH_CURVE_SHARP:
1530 strength = p * p;
1531 break;
1532 case BRUSH_CURVE_SMOOTH:
1533 strength = 3.0f * p * p - 2.0f * p * p * p;
1534 break;
1536 strength = pow3f(p) * (p * (p * 6.0f - 15.0f) + 10.0f);
1537 break;
1538 case BRUSH_CURVE_ROOT:
1539 strength = sqrtf(p);
1540 break;
1541 case BRUSH_CURVE_LIN:
1542 strength = p;
1543 break;
1545 strength = 1.0f;
1546 break;
1547 case BRUSH_CURVE_SPHERE:
1548 strength = sqrtf(2 * p - p * p);
1549 break;
1550 case BRUSH_CURVE_POW4:
1551 strength = p * p * p * p;
1552 break;
1554 strength = p * (2.0f - p);
1555 break;
1556 }
1557
1558 return strength;
1559}
1560
1561float BKE_brush_curve_strength(const Brush *br, float p, const float len)
1562{
1564}
1565
1566float BKE_brush_curve_strength_clamped(const Brush *br, float p, const float len)
1567{
1568 float strength = BKE_brush_curve_strength(br, p, len);
1569
1570 CLAMP(strength, 0.0f, 1.0f);
1571
1572 return strength;
1573}
1574
1575/* TODO: should probably be unified with BrushPainter stuff? */
1576static bool brush_gen_texture(const Brush *br,
1577 const int side,
1578 const bool use_secondary,
1579 float *rect)
1580{
1581 const MTex *mtex = (use_secondary) ? &br->mask_mtex : &br->mtex;
1582 if (mtex->tex == nullptr) {
1583 return false;
1584 }
1585
1586 const float step = 2.0 / side;
1587 int ix, iy;
1588 float x, y;
1589
1590 /* Do normalized canonical view coords for texture. */
1591 for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
1592 for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
1593 const float co[3] = {x, y, 0.0f};
1594
1595 float intensity;
1596 float rgba_dummy[4];
1597 RE_texture_evaluate(mtex, co, 0, nullptr, false, false, &intensity, rgba_dummy);
1598
1599 rect[iy * side + ix] = intensity;
1600 }
1601 }
1602
1603 return true;
1604}
1605
1606ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary, bool display_gradient)
1607{
1608 ImBuf *im = MEM_callocN<ImBuf>("radial control texture");
1609 int side = 512;
1610 int half = side / 2;
1611
1613
1614 float *rect_float = MEM_calloc_arrayN<float>(size_t(side) * size_t(side), "radial control rect");
1616
1617 im->x = im->y = side;
1618
1619 const bool have_texture = brush_gen_texture(br, side, secondary, im->float_buffer.data);
1620
1621 if (display_gradient || have_texture) {
1622 for (int i = 0; i < side; i++) {
1623 for (int j = 0; j < side; j++) {
1624 const float magn = sqrtf(pow2f(i - half) + pow2f(j - half));
1625 const float strength = BKE_brush_curve_strength_clamped(br, magn, half);
1626 im->float_buffer.data[i * side + j] = (have_texture) ?
1627 im->float_buffer.data[i * side + j] * strength :
1628 strength;
1629 }
1630 }
1631 }
1632
1633 return im;
1634}
1635
1637{
1638 switch (paint_mode) {
1639 case PaintMode::Sculpt: {
1640 if (brush->sculpt_brush_type == SCULPT_BRUSH_TYPE_MULTIPLANE_SCRAPE) {
1641 return true;
1642 }
1643
1645 (brush->tip_roundness < 1.0f || brush->tip_scale_x != 1.0f))
1646 {
1647 return true;
1648 }
1649
1650 break;
1651 }
1652 default: {
1653 break;
1654 }
1655 }
1656
1657 return false;
1658}
1659
1660/* -------------------------------------------------------------------- */
1663
1664namespace blender::bke::brush {
1666{
1667 return !ELEM(brush.sculpt_brush_type,
1668 /* These brushes, as currently coded, cannot support dynamic topology */
1683
1684 /* These brushes could handle dynamic topology,
1685 * but user feedback indicates it's better not to */
1688}
1716{
1717 /* TODO: Should this support Face Sets...? */
1718 return !ELEM(brush.sculpt_brush_type,
1723}
1725{
1726 return brush.sculpt_brush_type == SCULPT_BRUSH_TYPE_LAYER;
1727}
1729{
1730 return ELEM(brush.sculpt_brush_type, SCULPT_BRUSH_TYPE_PLANE);
1731}
1733{
1734 return ELEM(brush.sculpt_brush_type, SCULPT_BRUSH_TYPE_PLANE);
1735}
1737{
1738 return !(brush.flag & BRUSH_ANCHORED) && !(brush.flag & BRUSH_DRAG_DOT) &&
1739 !ELEM(brush.sculpt_brush_type,
1744}
1753{
1754 return ELEM(brush.sculpt_brush_type, SCULPT_BRUSH_TYPE_SNAKE_HOOK);
1755}
1757{
1758 return ELEM(brush.sculpt_brush_type, SCULPT_BRUSH_TYPE_LAYER, SCULPT_BRUSH_TYPE_CLOTH);
1759}
1761{
1762 return ELEM(brush.sculpt_brush_type,
1766}
1784{
1785 /* TODO: Should the face set brush be here...? */
1786 return !ELEM(brush.sculpt_brush_type,
1791}
1793{
1794 return ELEM(brush.sculpt_brush_type, SCULPT_BRUSH_TYPE_PAINT);
1795}
1812{
1813 return !(brush.flag & BRUSH_ANCHORED) && !(brush.flag & BRUSH_DRAG_DOT) &&
1814 !(brush.flag & BRUSH_LINE) && !(brush.flag & BRUSH_CURVE) &&
1815 !ELEM(brush.sculpt_brush_type,
1820}
1831{
1833}
1872} // namespace blender::bke::brush
1873
void BKE_asset_metadata_idprop_ensure(AssetMetaData *asset_data, IDProperty *prop)
Definition asset.cc:168
bool BKE_bpath_foreach_path_fixed_process(BPathForeachPathData *bpath_data, char *path, size_t path_maxncpy)
Definition bpath.cc:125
float BKE_curvemapping_evaluateF(const CurveMapping *cumap, int cur, float value)
void BKE_curvemapping_blend_read(BlendDataReader *reader, CurveMapping *cumap)
@ CURVEMAP_SLOPE_NEGATIVE
CurveMapping * BKE_curvemapping_copy(const CurveMapping *cumap)
void BKE_curvemapping_init(CurveMapping *cumap)
CurveMapping * BKE_curvemapping_add(int tot, float minx, float miny, float maxx, float maxy)
Definition colortools.cc:89
void BKE_curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope)
void BKE_curvemapping_free(CurveMapping *cumap)
void BKE_curvemapping_changed(CurveMapping *cumap, bool rem_doubles)
void BKE_curvemapping_blend_write(BlendWriter *writer, const CurveMapping *cumap)
Low-level operations for grease pencil.
@ IDTYPE_FLAGS_NO_ANIMDATA
Definition BKE_idtype.hh:46
@ IDTYPE_FLAGS_NO_MEMFILE_UNDO
Definition BKE_idtype.hh:55
IDTypeInfo IDType_ID_BR
Definition brush.cc:479
ID * BKE_id_copy_for_duplicate(Main *bmain, ID *id, eDupli_ID_Flags duplicate_flags, int copy_flags)
Definition lib_id.cc:777
void BKE_id_delete(Main *bmain, void *idv) ATTR_NONNULL()
void BKE_lib_id_expand_local(Main *bmain, ID *id, int flags)
Definition lib_id.cc:476
@ LIB_ID_COPY_NO_PREVIEW
@ LIB_ID_COPY_DEFAULT
void id_fake_user_set(ID *id)
Definition lib_id.cc:391
@ LIB_ID_MAKELOCAL_FULL_LIBRARY
void BKE_main_id_newptr_and_tag_clear(Main *bmain)
Definition lib_id.cc:1981
void BKE_lib_id_make_local_generic_action_define(Main *bmain, ID *id, int flags, bool *r_force_local, bool *r_force_copy)
Definition lib_id.cc:490
ID * BKE_id_copy(Main *bmain, const ID *id)
Definition lib_id.cc:772
void * BKE_id_new(Main *bmain, short type, const char *name)
Definition lib_id.cc:1495
void id_us_min(ID *id)
Definition lib_id.cc:361
void BKE_lib_id_clear_library_data(Main *bmain, ID *id, int flags)
Definition lib_id.cc:208
@ LIB_ID_DUPLICATE_IS_ROOT_ID
@ LIB_ID_DUPLICATE_IS_SUBPROCESS
void BKE_id_blend_write(BlendWriter *writer, ID *id)
Definition lib_id.cc:2611
#define BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data_, func_call_)
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
bool BKE_library_ID_is_indirectly_used(Main *bmain, void *idv)
Definition lib_query.cc:628
@ IDWALK_CB_LOOPBACK
@ IDWALK_CB_USER
@ IDWALK_CB_EMBEDDED_NOT_OWNING
@ IDWALK_CB_EMBEDDED
@ IDWALK_CB_NOP
void BKE_library_foreach_ID_link(Main *bmain, ID *id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, LibraryForeachIDFlag flag)
Definition lib_query.cc:431
@ IDWALK_RECURSE
@ IDWALK_NOP
void BKE_libblock_relink_to_newid(Main *bmain, ID *id, int remap_flag) ATTR_NONNULL()
Definition lib_remap.cc:919
@ ID_REMAP_SKIP_INDIRECT_USAGE
void void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, int remap_flags) ATTR_NONNULL(1
#define FOREACH_MAIN_ID_END
Definition BKE_main.hh:563
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
Definition BKE_main.hh:557
General operations, lookup, etc. for materials.
PaintMode
Definition BKE_paint.hh:93
bool BKE_paint_use_unified_color(const ToolSettings *tool_settings, const Paint *paint)
Definition paint.cc:592
CurveMapping * BKE_sculpt_default_cavity_curve()
Definition scene.cc:125
CurveMapping * BKE_paint_default_curve()
Definition scene.cc:140
std::optional< int > BKE_paint_get_brush_type_from_obmode(const Brush *brush, eObjectMode ob_mode)
Definition paint.cc:1280
void BKE_previewimg_blend_write(BlendWriter *writer, const PreviewImage *prv)
void BKE_previewimg_free(PreviewImage **prv)
void BKE_previewimg_blend_read(BlendDataReader *reader, PreviewImage *prv)
void BKE_previewimg_id_copy(ID *new_id, const ID *old_id)
void BKE_texture_mtex_foreach_id(struct LibraryForeachIDData *data, struct MTex *mtex)
Definition texture.cc:221
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
MINLINE float pow2f(float x)
MINLINE float square_f(float a)
MINLINE float pow3f(float x)
MINLINE float len_squared_v2(const float v[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void zero_v4(float r[4])
Random number functions.
struct RNG * BLI_rng_new(unsigned int seed)
Definition rand.cc:39
void BLI_rng_srandom(struct RNG *rng, unsigned int seed) ATTR_NONNULL(1)
Definition rand.cc:63
void BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1)
Definition rand.cc:53
float BLI_rng_get_float(struct RNG *rng) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition rand.cc:88
unsigned int uint
#define CLAMP(a, b, c)
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
int BLO_read_fileversion_get(BlendDataReader *reader)
Definition readfile.cc:5239
#define BLO_write_id_struct(writer, struct_name, id_address, id)
#define BLO_write_struct(writer, struct_name, data_ptr)
#define BLO_read_struct(reader, struct_name, ptr_p)
#define BLT_I18NCONTEXT_ID_BRUSH
ID and Library types, which are fundamental for SDNA.
@ ID_FLAG_FAKEUSER
Definition DNA_ID.h:682
@ INDEX_ID_BR
Definition DNA_ID.h:1255
@ ID_TAG_NEW
Definition DNA_ID.h:827
@ ID_TAG_INDIRECT
Definition DNA_ID.h:756
@ ID_BR
eBrushCurvePreset
@ BRUSH_CURVE_CUSTOM
@ BRUSH_CURVE_SHARP
@ BRUSH_CURVE_INVSQUARE
@ BRUSH_CURVE_SPHERE
@ BRUSH_CURVE_CONSTANT
@ BRUSH_CURVE_POW4
@ BRUSH_CURVE_ROOT
@ BRUSH_CURVE_SMOOTH
@ BRUSH_CURVE_SMOOTHER
@ BRUSH_CURVE_LIN
@ SCULPT_BRUSH_TYPE_DRAW_SHARP
@ SCULPT_BRUSH_TYPE_THUMB
@ SCULPT_BRUSH_TYPE_GRAB
@ SCULPT_BRUSH_TYPE_BOUNDARY
@ SCULPT_BRUSH_TYPE_DISPLACEMENT_SMEAR
@ SCULPT_BRUSH_TYPE_MASK
@ SCULPT_BRUSH_TYPE_DRAW_FACE_SETS
@ SCULPT_BRUSH_TYPE_DRAW
@ SCULPT_BRUSH_TYPE_CLAY
@ SCULPT_BRUSH_TYPE_CLOTH
@ SCULPT_BRUSH_TYPE_PINCH
@ SCULPT_BRUSH_TYPE_SMEAR
@ SCULPT_BRUSH_TYPE_POSE
@ SCULPT_BRUSH_TYPE_CLAY_THUMB
@ SCULPT_BRUSH_TYPE_MULTIPLANE_SCRAPE
@ SCULPT_BRUSH_TYPE_SIMPLIFY
@ SCULPT_BRUSH_TYPE_SNAKE_HOOK
@ SCULPT_BRUSH_TYPE_CREASE
@ SCULPT_BRUSH_TYPE_LAYER
@ SCULPT_BRUSH_TYPE_SLIDE_RELAX
@ SCULPT_BRUSH_TYPE_ELASTIC_DEFORM
@ SCULPT_BRUSH_TYPE_SMOOTH
@ SCULPT_BRUSH_TYPE_PAINT
@ SCULPT_BRUSH_TYPE_DISPLACEMENT_ERASER
@ SCULPT_BRUSH_TYPE_PLANE
@ SCULPT_BRUSH_TYPE_INFLATE
@ SCULPT_BRUSH_TYPE_BLOB
@ SCULPT_BRUSH_TYPE_ROTATE
@ SCULPT_BRUSH_TYPE_CLAY_STRIPS
@ GP_BRUSH_MATERIAL_PINNED
@ GP_BRUSH_USE_JITTER_PRESSURE
@ GP_BRUSH_USE_PRESSURE
@ BRUSH_OFFSET_PRESSURE
@ BRUSH_ORIGINAL_NORMAL
@ BRUSH_ALPHA_PRESSURE
@ BRUSH_SPACE_ATTEN
@ BRUSH_LOCK_ALPHA
@ BRUSH_FRONTFACE
@ BRUSH_ADAPTIVE_SPACE
@ BRUSH_DRAG_DOT
@ BRUSH_SPACING_PRESSURE
@ BRUSH_LINE
@ BRUSH_CURVE
@ BRUSH_EDGE_TO_EDGE
@ BRUSH_SMOOTH_STROKE
@ BRUSH_ACCUMULATE
@ BRUSH_DIR_IN
@ BRUSH_ANCHORED
@ BRUSH_CUSTOM_ICON
@ BRUSH_JITTER_PRESSURE
@ BRUSH_PLANE_TRIM
@ BRUSH_LOCK_SIZE
@ BRUSH_INVERSE_SMOOTH_PRESSURE
@ BRUSH_ABSOLUTE_JITTER
@ BRUSH_PERSISTENT
@ BRUSH_SIZE_PRESSURE
@ BRUSH_AIRBRUSH
@ BRUSH_SPACE
@ BRUSH_MASK_PRESSURE_RAMP
@ BRUSH_MASK_PRESSURE_CUTOFF
@ BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_RADIUS
@ BRUSH_OVERLAY_SECONDARY_OVERRIDE_ON_STROKE
@ BRUSH_OVERLAY_PRIMARY_OVERRIDE_ON_STROKE
@ BRUSH_OVERLAY_SECONDARY
@ BRUSH_OVERLAY_CURSOR
@ BRUSH_OVERLAY_CURSOR_OVERRIDE_ON_STROKE
@ BRUSH_OVERLAY_PRIMARY
#define MAX_BRUSH_PIXEL_RADIUS
@ BRUSH_JITTER_COLOR
@ CUMA_EXTEND_EXTRAPOLATE
eCurveMappingPreset
@ CURVE_PRESET_SMOOTH
@ CURVE_PRESET_SHARP
#define DNA_struct_default_get(struct_name)
eObjectMode
@ OB_MODE_VERTEX_GREASE_PENCIL
@ OB_MODE_EDIT
@ OB_MODE_WEIGHT_PAINT
@ OB_MODE_SCULPT
@ OB_MODE_SCULPT_CURVES
@ OB_MODE_PAINT_GREASE_PENCIL
@ OB_MODE_SCULPT_GREASE_PENCIL
@ OB_MODE_TEXTURE_PAINT
@ OB_MODE_WEIGHT_GREASE_PENCIL
@ OB_MODE_VERTEX_PAINT
@ UNIFIED_PAINT_COLOR_JITTER
@ UNIFIED_PAINT_WEIGHT
@ UNIFIED_PAINT_SIZE
@ UNIFIED_PAINT_BRUSH_LOCK_SIZE
@ UNIFIED_PAINT_ALPHA
@ UNIFIED_PAINT_INPUT_SAMPLES
@ MTEX_MAP_MODE_3D
@ MTEX_MAP_MODE_STENCIL
@ MTEX_MAP_MODE_TILED
@ MTEX_MAP_MODE_RANDOM
@ MTEX_MAP_MODE_VIEW
eDupli_ID_Flags
@ USER_DUP_LINKED_ID
@ USER_DUP_OBDATA
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
void IMB_colormanagement_colorspace_to_scene_linear_v3(float pixel[3], const ColorSpace *colorspace)
ImBuf * IMB_dupImBuf(const ImBuf *ibuf1)
void IMB_assign_float_buffer(ImBuf *ibuf, float *buffer_data, ImBufOwnership ownership)
void IMB_freeImBuf(ImBuf *ibuf)
@ IB_DO_NOT_TAKE_OWNERSHIP
Read Guarded memory(de)allocation.
BMesh const char void * data
void BKE_brush_jitter_pos(const Scene &scene, const Brush &brush, const float pos[2], float jitterpos[2])
Definition brush.cc:1340
void BKE_brush_weight_set(const Scene *scene, Brush *brush, float value)
Definition brush.cc:1283
const MTex * BKE_brush_mask_texture_get(const Brush *brush, const eObjectMode object_mode)
Definition brush.cc:861
float BKE_brush_curve_strength_clamped(const Brush *br, float p, const float len)
Definition brush.cc:1566
static void brush_defaults(Brush *brush)
Definition brush.cc:527
bool BKE_brush_use_alpha_pressure(const Brush *brush)
Definition brush.cc:1231
void BKE_brush_randomize_texture_coords(UnifiedPaintSettings *ups, bool mask)
Definition brush.cc:1367
float BKE_brush_weight_get(const Scene *scene, const Brush *brush)
Definition brush.cc:1276
float BKE_brush_curve_strength(const eBrushCurvePreset preset, const CurveMapping *cumap, const float distance, const float brush_radius)
Definition brush.cc:1510
float BKE_brush_unprojected_radius_get(const Scene *scene, const Brush *brush)
Definition brush.cc:1249
static void brush_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition brush.cc:225
#define BR_TEST(field, t)
int BKE_brush_size_get(const Scene *scene, const Brush *brush)
Definition brush.cc:1210
static void brush_free_data(ID *id)
Definition brush.cc:127
static AssetTypeInfo AssetType_BR
Definition brush.cc:474
static void brush_blend_read_after_liblink(BlendLibReader *, ID *id)
Definition brush.cc:413
const MTex * BKE_brush_color_texture_get(const Brush *brush, const eObjectMode object_mode)
Definition brush.cc:869
void BKE_brush_unprojected_radius_set(Scene *scene, Brush *brush, float unprojected_radius)
Definition brush.cc:1236
Brush * BKE_brush_first_search(Main *bmain, const eObjectMode ob_mode)
Definition brush.cc:727
void BKE_brush_size_set(Scene *scene, Brush *brush, int size)
Definition brush.cc:1194
static void brush_foreach_id(ID *id, LibraryForeachIDData *data)
Definition brush.cc:201
#define FROM_DEFAULT(member)
#define BR_TEST_FLAG_OVERLAY(_f)
const float * BKE_brush_secondary_color_get(const Scene *scene, const Paint *paint, const Brush *brush)
Definition brush.cc:1172
void BKE_brush_alpha_set(Scene *scene, Brush *brush, float alpha)
Definition brush.cc:1256
bool BKE_brush_use_size_pressure(const Brush *brush)
Definition brush.cc:1226
void BKE_brush_input_samples_set(const Scene *scene, Brush *brush, int value)
Definition brush.cc:1303
static void brush_init_data(ID *id)
Definition brush.cc:53
bool BKE_brush_has_cube_tip(const Brush *brush, PaintMode paint_mode)
Definition brush.cc:1636
static void brush_make_local(Main *bmain, ID *id, const int flags)
Definition brush.cc:164
static void brush_copy_data(Main *, std::optional< Library * >, ID *id_dst, const ID *id_src, const int flag)
Definition brush.cc:67
void BKE_brush_init_curves_sculpt_settings(Brush *brush)
Definition brush.cc:704
Brush * BKE_brush_add(Main *bmain, const char *name, const eObjectMode ob_mode)
Definition brush.cc:583
void BKE_brush_system_init()
Definition brush.cc:512
#define FROM_DEFAULT_PTR(member)
ImBuf * BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary, bool display_gradient)
Definition brush.cc:1606
static bool brush_gen_texture(const Brush *br, const int side, const bool use_secondary, float *rect)
Definition brush.cc:1576
void BKE_brush_color_set(Scene *scene, const Paint *paint, Brush *brush, const float color[3])
Definition brush.cc:1182
static RNG * brush_rng
Definition brush.cc:510
void BKE_brush_curve_preset(Brush *b, eCurveMappingPreset preset)
Definition brush.cc:843
static void brush_blend_read_data(BlendDataReader *reader, ID *id)
Definition brush.cc:292
void BKE_brush_calc_curve_factors(const eBrushCurvePreset preset, const CurveMapping *cumap, const blender::Span< float > distances, const float brush_radius, const blender::MutableSpan< float > factors)
Definition brush.cc:1381
const std::optional< BrushColorJitterSettings > BKE_brush_color_jitter_get_settings(const Scene *scene, const Paint *paint, const Brush *brush)
Definition brush.cc:1137
void BKE_brush_init_gpencil_settings(Brush *brush)
Definition brush.cc:604
Brush * BKE_brush_duplicate(Main *bmain, Brush *brush, eDupli_ID_Flags, uint duplicate_options)
Definition brush.cc:646
float BKE_brush_sample_masktex(const Scene *scene, Brush *br, const float point[2], const int thread, ImagePool *pool)
Definition brush.cc:1000
static void brush_foreach_path(ID *id, BPathForeachPathData *bpath_data)
Definition brush.cc:216
void BKE_brush_scale_size(int *r_brush_size, float new_unprojected_radius, float old_unprojected_radius)
Definition brush.cc:1328
float BKE_brush_alpha_get(const Scene *scene, const Brush *brush)
Definition brush.cc:1269
const float * BKE_brush_color_get(const Scene *scene, const Paint *paint, const Brush *brush)
Definition brush.cc:1128
void BKE_brush_debug_print_state(Brush *br)
Definition brush.cc:737
bool BKE_brush_delete(Main *bmain, Brush *brush)
Definition brush.cc:630
bool BKE_brush_use_locked_size(const Scene *scene, const Brush *brush)
Definition brush.cc:1218
void BKE_brush_scale_unprojected_radius(float *unprojected_radius, int new_brush_size, int old_brush_size)
Definition brush.cc:1316
static void brush_asset_metadata_ensure(void *asset_ptr, AssetMetaData *asset_data)
Definition brush.cc:430
void BKE_brush_tag_unsaved_changes(Brush *brush)
Definition brush.cc:720
#define BR_TEST_FLAG(_f)
void BKE_brush_system_exit()
Definition brush.cc:518
int BKE_brush_input_samples_get(const Scene *scene, const Brush *brush)
Definition brush.cc:1296
float BKE_brush_sample_tex_3d(const Scene *scene, const Brush *br, const MTex *mtex, const float point[3], float rgba[4], const int thread, ImagePool *pool)
Definition brush.cc:877
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr int64_t size() const
Definition BLI_span.hh:252
constexpr IndexRange index_range() const
Definition BLI_span.hh:401
Definition half.h:41
#define sinf(x)
#define cosf(x)
#define atan2f(x, y)
#define fabsf(x)
#define sqrtf(x)
uint pos
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
#define printf(...)
float distance(VecOp< float, D >, VecOp< float, D >) RET
#define ID_EXTRA_USERS(id)
#define FILTER_ID_MA
#define MEM_SAFE_FREE(v)
#define FILTER_ID_BR
#define ID_IS_LINKED(_id)
#define FILTER_ID_TE
#define ID_REAL_USERS(id)
#define FILTER_ID_PC
#define ID_NEW_SET(_id, _idn)
#define FILTER_ID_IM
#define GS(a)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_dupallocN(const void *vmemh)
Definition mallocn.cc:143
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
bool supports_sculpt_plane(const Brush &brush)
Definition brush.cc:1783
bool supports_secondary_cursor_color(const Brush &brush)
Definition brush.cc:1796
bool supports_auto_smooth(const Brush &brush)
Definition brush.cc:1715
bool supports_jitter(const Brush &brush)
Definition brush.cc:1736
bool supports_space_attenuation(const Brush &brush)
Definition brush.cc:1821
bool supports_persistence(const Brush &brush)
Definition brush.cc:1756
bool supports_tilt(const Brush &brush)
Definition brush.cc:1864
bool supports_inverted_direction(const Brush &brush)
Definition brush.cc:1834
bool supports_rake_factor(const Brush &brush)
Definition brush.cc:1752
bool supports_plane_depth(const Brush &brush)
Definition brush.cc:1732
bool supports_accumulate(const Brush &brush)
Definition brush.cc:1689
bool supports_gravity(const Brush &brush)
Definition brush.cc:1851
bool supports_smooth_stroke(const Brush &brush)
Definition brush.cc:1811
bool supports_plane_offset(const Brush &brush)
Definition brush.cc:1767
bool supports_pinch_factor(const Brush &brush)
Definition brush.cc:1760
bool supports_color(const Brush &brush)
Definition brush.cc:1792
bool supports_random_texture_angle(const Brush &brush)
Definition brush.cc:1775
bool supports_strength_pressure(const Brush &brush)
Definition brush.cc:1830
bool supports_dyntopo(const Brush &brush)
Definition brush.cc:1665
bool supports_height(const Brush &brush)
Definition brush.cc:1724
bool supports_topology_rake(const Brush &brush)
Definition brush.cc:1704
bool supports_plane_height(const Brush &brush)
Definition brush.cc:1728
bool supports_normal_weight(const Brush &brush)
Definition brush.cc:1745
std::unique_ptr< IDProperty, IDPropertyDeleter > create_bool(StringRef prop_name, bool value, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_BOOLEAN, set its name and value.
std::unique_ptr< IDProperty, IDPropertyDeleter > create(StringRef prop_name, int32_t value, eIDPropertyFlag flags={})
Allocate a new IDProperty of type IDP_INT, set its name and value.
T rcp(const T &a)
static ePaintOverlayControlFlags overlay_flags
Definition paint.cc:248
The meta-data of an asset. By creating and giving this for a data-block (ID.asset_data),...
struct CurveMapping * curve_parameter_falloff
struct CurveMapping * curve_sensitivity
struct CurveMapping * curve_strength
struct CurveMapping * curve_jitter
struct CurveMapping * curve_rand_pressure
struct CurveMapping * curve_rand_strength
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
struct CurveMapping * curve_rand_uv
struct Material * material
struct Material * material_alt
struct CurveMapping * curve_rand_value
struct ImBuf * icon_imbuf
struct ColorBand * gradient
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
struct MTex mtex
float stencil_pos[2]
float unprojected_radius
float stencil_dimension[2]
int curve_preset
struct CurveMapping * curve
float texture_sample_bias
struct CurveMapping * curve_rand_value
float mask_stencil_pos[2]
struct BrushGpencilSettings * gpencil_settings
char has_unsaved_changes
char icon_filepath[1024]
PreviewImage * preview
struct CurveMapping * automasking_cavity_curve
struct BrushCurvesSculptSettings * curves_sculpt_settings
struct MTex mask_mtex
int mask_pressure
float mask_stencil_dimension[2]
struct PaintCurve * paint_curve
Definition DNA_ID.h:404
int tag
Definition DNA_ID.h:424
int us
Definition DNA_ID.h:425
short flag
Definition DNA_ID.h:420
ImBufFloatBuffer float_buffer
char brush_map_mode
struct Tex * tex
ListBase brushes
Definition BKE_main.hh:271
Definition rand.cc:33
struct ToolSettings * toolsettings
struct UnifiedPaintSettings unified_paint_settings
struct CurveMapping * curve_rand_value
struct CurveMapping * curve_rand_saturation
struct CurveMapping * curve_rand_hue
const ColorSpaceHandle * colorspace
i
Definition text_draw.cc:230
bool RE_texture_evaluate(const MTex *mtex, const float vec[3], const int thread, ImagePool *pool, const bool skip_load_image, const bool texnode_preview, float *r_intensity, float r_rgba[4])
static int blend(const Tex *tex, const float texvec[3], TexResult *texres)
uint len
#define N_(msgid)
uint8_t flag
Definition wm_window.cc:139